Rollup merge of #153532 - jdonszelmann:attributes-containing-rustc, r=petrochenkov Attributes containing rustc r? @petrochenkov I noticed that attributes *containing* the word rustc as a segment also error with a message referring to "starting with rustc". The first commit shows this going wrong by re-exporting `#[test]`, a built-in macro, from a module called rustc. The 2nd commit addresses this by changing the diagnostic. However, given the wording I wonder if the real solution shouldn't be to allow attributes containing a `rustc` segment and only disallow them when they start. In other words, actually implement the behavior that the original diagnostic pointed out.
diff --git a/.mailmap b/.mailmap index c0333b4..1723208 100644 --- a/.mailmap +++ b/.mailmap
@@ -262,6 +262,7 @@ Guillaume Gomez <guillaume1.gomez@gmail.com> ggomez <ggomez@ggo.ifr.lan> Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <ggomez@ggo.ifr.lan> Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <guillaume.gomez@huawei.com> +Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <contact@guillaume-gomez.fr> gnzlbg <gonzalobg88@gmail.com> <gnzlbg@users.noreply.github.com> hamidreza kalbasi <hamidrezakalbasi@protonmail.com> Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com>
diff --git a/Cargo.lock b/Cargo.lock index 1f2b417..0d54197 100644 --- a/Cargo.lock +++ b/Cargo.lock
@@ -1296,9 +1296,9 @@ [[package]] name = "ena" -version = "0.14.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] @@ -1422,12 +1422,13 @@ [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -3421,14 +3422,14 @@ [[package]] name = "rustc-build-sysroot" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b881c015c729b43105bbd3702a9bdecee28fafaa21126d1d62e454ec011a4b7" +checksum = "eec3905e8201688412f6f4b1f6c86d38b3ee6578f59ba85f41330a3af61e8365" dependencies = [ "anyhow", "rustc_version", "tempfile", - "toml 0.8.23", + "toml 1.1.0+spec-1.1.0", "walkdir", ] @@ -4021,7 +4022,6 @@ "rustc_hir", "rustc_index", "rustc_infer", - "rustc_lint", "rustc_lint_defs", "rustc_macros", "rustc_middle", @@ -4573,7 +4573,6 @@ "rustc_data_structures", "rustc_errors", "rustc_hir", - "rustc_index", "rustc_macros", "rustc_middle", "rustc_serialize", @@ -5197,9 +5196,9 @@ [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ "serde_core", ] @@ -5462,9 +5461,9 @@ [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc", @@ -5695,7 +5694,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ - "indexmap", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -5710,7 +5708,7 @@ dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.3", + "serde_spanned 1.1.0", "toml_datetime 0.7.3", "toml_parser", "toml_writer", @@ -5718,6 +5716,21 @@ ] [[package]] +name = "toml" +version = "1.1.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.0", +] + +[[package]] name = "toml_datetime" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5736,6 +5749,15 @@ ] [[package]] +name = "toml_datetime" +version = "1.1.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" +dependencies = [ + "serde_core", +] + +[[package]] name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5764,11 +5786,11 @@ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ - "winnow 0.7.13", + "winnow 1.0.0", ] [[package]] @@ -5779,9 +5801,9 @@ [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tracing" @@ -6768,6 +6790,12 @@ ] [[package]] +name = "winnow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" + +[[package]] name = "winsplit" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6946,3 +6974,9 @@ "quote", "syn 2.0.110", ] + +[[package]] +name = "zlib-rs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
diff --git a/RELEASES.md b/RELEASES.md index f180d74..c396cd8 100644 --- a/RELEASES.md +++ b/RELEASES.md
@@ -1,3 +1,17 @@ +Version 1.94.1 (2026-03-26) +=========================== + +<a id="1.94.1"></a> + +* [Fix `std::thread::spawn` on wasm32-wasip1-threads](https://github.com/rust-lang/rust/pull/153634) +* [Remove new methods added to `std::os::windows::fs::OpenOptionsExt`](https://github.com/rust-lang/rust/pull/153491) + The new methods were unstable, but the trait itself is not sealed and so + cannot be extended with non-default methods. +* [Clippy: fix ICE in `match_same_arms`](https://github.com/rust-lang/rust-clippy/pull/16685) +* [Cargo: update tar to 0.4.45](https://github.com/rust-lang/cargo/pull/16769) + This resolves CVE-2026-33055 and CVE-2026-33056. Users of crates.io are not affected. + See [blog](https://blog.rust-lang.org/2026/03/21/cve-2026-33056/) for more details. + Version 1.94.0 (2026-03-05) ==========================
diff --git a/bootstrap.example.toml b/bootstrap.example.toml index f3b2a64..25e2ca5 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml
@@ -826,7 +826,8 @@ # in the sysroot. It is required for running nvptx tests. #rust.llvm-bitcode-linker = false -# Whether to deny warnings in crates +# Whether to deny warnings in crates. Set to `false` to avoid +# error: warnings are denied by `build.warnings` configuration #rust.deny-warnings = true # Print backtrace on internal compiler errors during bootstrap
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 74cc1ec..71ec1c5 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs
@@ -120,8 +120,8 @@ fn eq(&self, names: &&[Symbol]) -> bool { } } -impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx: rustc_span::HashStableContext> HashStable<Hcx> for Path { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.segments.len().hash_stable(hcx, hasher); for segment in &self.segments { segment.ident.hash_stable(hcx, hasher); @@ -938,7 +938,7 @@ pub enum PatKind { Never, /// A guard pattern (e.g., `x if guard(x)`). - Guard(Box<Pat>, Box<Expr>), + Guard(Box<Pat>, Box<Guard>), /// Parentheses in patterns used for grouping (i.e., `(PAT)`). Paren(Box<Pat>), @@ -1346,7 +1346,7 @@ pub struct Arm { /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`. pub pat: Box<Pat>, /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`. - pub guard: Option<Box<Expr>>, + pub guard: Option<Box<Guard>>, /// Match arm body. Omitted if the pattern is a never pattern. pub body: Option<Box<Expr>>, pub span: Span, @@ -3954,6 +3954,18 @@ impl ConstBlockItem { pub const IDENT: Ident = Ident { name: kw::Underscore, span: DUMMY_SP }; } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct Guard { + pub cond: Expr, + pub span_with_leading_if: Span, +} + +impl Guard { + pub fn span(&self) -> Span { + self.cond.span + } +} + // Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum ItemKind {
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 72e7b27..369fe12 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -876,11 +876,15 @@ pub trait AttributeExt: Debug { /// a doc comment) will return `false`. fn is_doc_comment(&self) -> Option<Span>; + /// Returns true if the attribute's first *and only* path segment is equal to the passed-in + /// symbol. #[inline] fn has_name(&self, name: Symbol) -> bool { self.name().map(|x| x == name).unwrap_or(false) } + /// Returns true if the attribute's first *and only* path segment is any of the passed-in + /// symbols. #[inline] fn has_any_name(&self, names: &[Symbol]) -> bool { names.iter().any(|&name| self.has_name(name)) @@ -889,6 +893,7 @@ fn has_any_name(&self, names: &[Symbol]) -> bool { /// get the span of the entire attribute fn span(&self) -> Span; + /// Returns whether the attribute is a path, without any arguments. fn is_word(&self) -> bool; fn path(&self) -> SmallVec<[Symbol; 1]> { @@ -911,11 +916,14 @@ fn has_any_name(&self, names: &[Symbol]) -> bool { /// * `#[deprecated(note = "note", ...)]` returns `Some("note")`. fn deprecation_note(&self) -> Option<Ident>; + /// Returns whether this attribute is any of the proc macro attributes. + /// i.e. `proc_macro`, `proc_macro_attribute` or `proc_macro_derive`. fn is_proc_macro_attr(&self) -> bool { [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] .iter() .any(|kind| self.has_name(*kind)) } + /// Returns true if this attribute is `#[automatically_deived]`. fn is_automatically_derived_attr(&self) -> bool; /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index f825130..62ec063 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs
@@ -94,6 +94,7 @@ pub enum MetaVarKind { }, Path, Vis, + Guard, TT, } @@ -114,6 +115,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { MetaVarKind::Meta { .. } => sym::meta, MetaVarKind::Path => sym::path, MetaVarKind::Vis => sym::vis, + MetaVarKind::Guard => sym::guard, MetaVarKind::TT => sym::tt, }; write!(f, "{sym}") @@ -1124,6 +1126,7 @@ pub enum NonterminalKind { Meta, Path, Vis, + Guard, TT, } @@ -1161,6 +1164,7 @@ pub fn from_symbol( sym::meta => NonterminalKind::Meta, sym::path => NonterminalKind::Path, sym::vis => NonterminalKind::Vis, + sym::guard => NonterminalKind::Guard, sym::tt => NonterminalKind::TT, _ => return None, }) @@ -1182,6 +1186,7 @@ fn symbol(self) -> Symbol { NonterminalKind::Meta => sym::meta, NonterminalKind::Path => sym::path, NonterminalKind::Vis => sym::vis, + NonterminalKind::Guard => sym::guard, NonterminalKind::TT => sym::tt, } }
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 8d8e8ff..8953391 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -138,8 +138,8 @@ fn decode(_d: &mut D) -> Self { } } -impl<CTX> HashStable<CTX> for LazyAttrTokenStream { - fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for LazyAttrTokenStream { + fn hash_stable(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { panic!("Attempted to compute stable hash for LazyAttrTokenStream"); } } @@ -824,11 +824,11 @@ fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self { } } -impl<CTX> HashStable<CTX> for TokenStream +impl<Hcx> HashStable<Hcx> for TokenStream where - CTX: crate::HashStableContext, + Hcx: crate::HashStableContext, { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { for sub_tt in self.iter() { sub_tt.hash_stable(hcx, hasher); }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index bdf290f..6aa8d5f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs
@@ -442,6 +442,7 @@ pub fn ctxt(&self) -> Option<FnCtxt> { FormatArguments, FormatPlaceholder, GenericParamKind, + Guard, Impl, ImplPolarity, Inline,
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 51994c2..3a27962 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -1,5 +1,4 @@ use std::collections::hash_map::Entry; -use std::fmt::Write; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; @@ -124,13 +123,9 @@ pub(crate) fn lower_inline_asm( self.dcx().emit_err(ClobberAbiNotSupported { abi_span: *abi_span }); } Err(supported_abis) => { - let mut abis = format!("`{}`", supported_abis[0]); - for m in &supported_abis[1..] { - let _ = write!(abis, ", `{m}`"); - } self.dcx().emit_err(InvalidAbiClobberAbi { abi_span: *abi_span, - supported_abis: abis, + supported_abis: supported_abis.to_vec().into(), }); } } @@ -164,15 +159,12 @@ pub(crate) fn lower_inline_asm( asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch { asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else( |supported_register_classes| { - let mut register_classes = - format!("`{}`", supported_register_classes[0]); - for m in &supported_register_classes[1..] { - let _ = write!(register_classes, ", `{m}`"); - } self.dcx().emit_err(InvalidRegisterClass { op_span: *op_sp, reg_class, - supported_register_classes: register_classes, + supported_register_classes: supported_register_classes + .to_vec() + .into(), }); asm::InlineAsmRegClass::Err }, @@ -272,23 +264,20 @@ pub(crate) fn lower_inline_asm( } let valid_modifiers = class.valid_modifiers(asm_arch.unwrap()); if !valid_modifiers.contains(&modifier) { - let sub = if !valid_modifiers.is_empty() { - let mut mods = format!("`{}`", valid_modifiers[0]); - for m in &valid_modifiers[1..] { - let _ = write!(mods, ", `{m}`"); - } - InvalidAsmTemplateModifierRegClassSub::SupportModifier { - class_name: class.name(), - modifiers: mods, - } - } else { + let sub = if valid_modifiers.is_empty() { InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier { class_name: class.name(), } + } else { + InvalidAsmTemplateModifierRegClassSub::SupportModifier { + class_name: class.name(), + modifiers: valid_modifiers.to_vec().into(), + } }; self.dcx().emit_err(InvalidAsmTemplateModifierRegClass { placeholder_span, op_span: op_sp, + modifier: modifier.to_string(), sub, }); }
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 0044913..022f9e3 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -146,12 +146,10 @@ pub(crate) fn lower_delegation( let (param_count, c_variadic) = self.param_count(sig_id); - let mut generics = - self.lower_delegation_generics(delegation, sig_id, item_id, span); + let mut generics = self.uplift_delegation_generics(delegation, sig_id, item_id); let body_id = self.lower_delegation_body( delegation, - item_id, is_method, param_count, &mut generics, @@ -166,10 +164,8 @@ pub(crate) fn lower_delegation( let generics = self.arena.alloc(hir::Generics { has_where_clause_predicates: false, - params: self.arena.alloc_from_iter(generics.all_params(item_id, span, self)), - predicates: self - .arena - .alloc_from_iter(generics.all_predicates(item_id, span, self)), + params: self.arena.alloc_from_iter(generics.all_params(span, self)), + predicates: self.arena.alloc_from_iter(generics.all_predicates(span, self)), span, where_clause_span: span, }); @@ -294,19 +290,22 @@ fn lower_delegation_decl( let decl_param_count = param_count - c_variadic as usize; let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)), + kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig( + sig_id, + hir::InferDelegationSig::Input(arg), + )), span, })); let output = self.arena.alloc(hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::InferDelegation( + kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig( sig_id, - hir::InferDelegationKind::Output(self.arena.alloc(hir::DelegationGenerics { + hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationGenerics { child_args_segment_id: generics.child.args_segment_id, parent_args_segment_id: generics.parent.args_segment_id, })), - ), + )), span, }); @@ -399,7 +398,6 @@ fn generate_arg( fn lower_delegation_body( &mut self, delegation: &Delegation, - item_id: NodeId, is_method: bool, param_count: usize, generics: &mut GenericsGenerationResults<'hir>, @@ -434,7 +432,18 @@ fn lower_delegation_body( args.push(arg); } - let final_expr = this.finalize_body_lowering(delegation, item_id, args, generics, span); + // If we have no params in signature function but user still wrote some code in + // delegation body, then add this code as first arg, eventually an error will be shown, + // also nested delegations may need to access information about this code (#154332), + // so it is better to leave this code as opposed to bodies of extern functions, + // which are completely erased from existence. + if param_count == 0 + && let Some(block) = block + { + args.push(this.lower_target_expr(&block)); + } + + let final_expr = this.finalize_body_lowering(delegation, args, generics, span); (this.arena.alloc_from_iter(parameters), final_expr) }) @@ -471,7 +480,6 @@ fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> { fn finalize_body_lowering( &mut self, delegation: &Delegation, - item_id: NodeId, args: Vec<hir::Expr<'hir>>, generics: &mut GenericsGenerationResults<'hir>, span: Span, @@ -501,7 +509,7 @@ fn finalize_body_lowering( // FIXME(fn_delegation): proper support for parent generics propagation // in method call scenario. - let segment = self.process_segment(item_id, span, &segment, &mut generics.child, false); + let segment = self.process_segment(span, &segment, &mut generics.child, false); let segment = self.arena.alloc(segment); self.arena.alloc(hir::Expr { @@ -528,7 +536,7 @@ fn finalize_body_lowering( new_path.segments = self.arena.alloc_from_iter( new_path.segments.iter().enumerate().map(|(idx, segment)| { let mut process_segment = |result, add_lifetimes| { - self.process_segment(item_id, span, segment, result, add_lifetimes) + self.process_segment(span, segment, result, add_lifetimes) }; if idx + 2 == len { @@ -544,8 +552,7 @@ fn finalize_body_lowering( hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } hir::QPath::TypeRelative(ty, segment) => { - let segment = - self.process_segment(item_id, span, segment, &mut generics.child, false); + let segment = self.process_segment(span, segment, &mut generics.child, false); hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) } @@ -569,7 +576,6 @@ fn finalize_body_lowering( fn process_segment( &mut self, - item_id: NodeId, span: Span, segment: &hir::PathSegment<'hir>, result: &mut GenericsGenerationResult<'hir>, @@ -577,15 +583,14 @@ fn process_segment( ) -> hir::PathSegment<'hir> { let details = result.generics.args_propagation_details(); - // The first condition is needed when there is SelfAndUserSpecified case, - // we don't want to propagate generics params in this situation. - let segment = if details.should_propagate - && let Some(args) = result - .generics - .into_hir_generics(self, item_id, span) - .into_generic_args(self, add_lifetimes, span) - { - hir::PathSegment { args: Some(args), ..segment.clone() } + let segment = if details.should_propagate { + let generics = result.generics.into_hir_generics(self, span); + let args = generics.into_generic_args(self, add_lifetimes, span); + + // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). + let args = if args.is_empty() { None } else { Some(args) }; + + hir::PathSegment { args, ..segment.clone() } } else { segment.clone() };
diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index d6d8819..4e960e3 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs
@@ -5,10 +5,8 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::{bug, ty}; -use rustc_span::sym::{self}; use rustc_span::symbol::kw; use rustc_span::{Ident, Span}; -use thin_vec::{ThinVec, thin_vec}; use crate::{LoweringContext, ResolverAstLoweringExt}; @@ -16,34 +14,33 @@ pub(super) enum DelegationGenerics<T> { /// User-specified args are present: `reuse foo::<String>;`. UserSpecified, /// The default case when no user-specified args are present: `reuse Trait::foo;`. - Default(Option<T>), + Default(T), /// In free-to-trait reuse, when user specified args for trait `reuse Trait::<i32>::foo;` /// in this case we need to both generate `Self` and process user args. - SelfAndUserSpecified(Option<T>), + SelfAndUserSpecified(T), /// In delegations from trait impl to other entities like free functions or trait functions, /// we want to generate a function whose generics matches generics of signature function /// in trait. - TraitImpl(Option<T>, bool /* Has user-specified args */), + TraitImpl(T, bool /* Has user-specified args */), } -/// Used for storing either AST generics or their lowered HIR version. Firstly we obtain -/// AST generics either from local function from AST index or from external function -/// through `tcx`. Next, at some point of generics processing we need to lower those -/// generics to HIR, for this purpose we use `into_hir_generics` that lowers AST generics -/// and replaces Ast variant with Hir. Such approach is useful as we can call this method -/// at any time knowing that lowering will occur at most only once. Then, in order to obtain generic +/// Used for storing either ty generics or their uplifted HIR version. First we obtain +/// ty generics. Next, at some point of generics processing we need to uplift those +/// generics to HIR, for this purpose we use `into_hir_generics` that uplifts ty generics +/// and replaces Ty variant with Hir. Such approach is useful as we can call this method +/// at any time knowing that uplifting will occur at most only once. Then, in order to obtain generic /// params or args we use `hir_generics_or_empty` or `into_generic_args` functions. -/// There also may be situations when we obtained AST generics but never lowered them to HIR, +/// There also may be situations when we obtained ty generics but never uplifted them to HIR, /// meaning we did not propagate them and thus we do not need to generate generic params /// (i.e., method call scenarios), in such a case this approach helps -/// a lot as if `into_hir_generics` will not be called then lowering will not happen. -pub(super) enum HirOrAstGenerics<'hir> { - Ast(DelegationGenerics<Generics>), +/// a lot as if `into_hir_generics` will not be called then uplifting will not happen. +pub(super) enum HirOrTyGenerics<'hir> { + Ty(DelegationGenerics<&'hir [ty::GenericParamDef]>), Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), } pub(super) struct GenericsGenerationResult<'hir> { - pub(super) generics: HirOrAstGenerics<'hir>, + pub(super) generics: HirOrTyGenerics<'hir>, pub(super) args_segment_id: Option<HirId>, } @@ -78,35 +75,31 @@ fn args_propagation_details(&self) -> GenericArgsPropagationDetails { } } -impl<'hir> HirOrAstGenerics<'hir> { +impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, - item_id: NodeId, span: Span, - ) -> &mut HirOrAstGenerics<'hir> { - if let HirOrAstGenerics::Ast(generics) = self { - let process_params = |generics: &mut Generics| { - ctx.lower_delegation_generic_params(item_id, span, &mut generics.params) + ) -> &mut HirOrTyGenerics<'hir> { + if let HirOrTyGenerics::Ty(params) = self { + let mut uplift_params = |generics: &'hir [ty::GenericParamDef]| { + ctx.uplift_delegation_generic_params(span, generics) }; - let hir_generics = match generics { + let hir_generics = match params { DelegationGenerics::UserSpecified => DelegationGenerics::UserSpecified, - DelegationGenerics::Default(generics) => { - DelegationGenerics::Default(generics.as_mut().map(process_params)) + DelegationGenerics::Default(params) => { + DelegationGenerics::Default(uplift_params(params)) } - DelegationGenerics::SelfAndUserSpecified(generics) => { - DelegationGenerics::SelfAndUserSpecified(generics.as_mut().map(process_params)) + DelegationGenerics::SelfAndUserSpecified(params) => { + DelegationGenerics::SelfAndUserSpecified(uplift_params(params)) } - DelegationGenerics::TraitImpl(generics, user_specified) => { - DelegationGenerics::TraitImpl( - generics.as_mut().map(process_params), - *user_specified, - ) + DelegationGenerics::TraitImpl(params, user_specified) => { + DelegationGenerics::TraitImpl(uplift_params(params), *user_specified) } }; - *self = HirOrAstGenerics::Hir(hir_generics); + *self = HirOrTyGenerics::Hir(hir_generics); } self @@ -114,14 +107,12 @@ pub(super) fn into_hir_generics( fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { match self { - HirOrAstGenerics::Ast(_) => hir::Generics::empty(), - HirOrAstGenerics::Hir(hir_generics) => match hir_generics { + HirOrTyGenerics::Ty(_) => hir::Generics::empty(), + HirOrTyGenerics::Hir(hir_generics) => match hir_generics { DelegationGenerics::UserSpecified => hir::Generics::empty(), DelegationGenerics::Default(generics) | DelegationGenerics::SelfAndUserSpecified(generics) - | DelegationGenerics::TraitImpl(generics, _) => { - generics.unwrap_or(hir::Generics::empty()) - } + | DelegationGenerics::TraitImpl(generics, _) => generics, }, } } @@ -131,43 +122,41 @@ pub(super) fn into_generic_args( ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, add_lifetimes: bool, span: Span, - ) -> Option<&'hir hir::GenericArgs<'hir>> { + ) -> &'hir hir::GenericArgs<'hir> { match self { - HirOrAstGenerics::Ast(_) => { - bug!("Attempting to get generic args before lowering to HIR") + HirOrTyGenerics::Ty(_) => { + bug!("Attempting to get generic args before uplifting to HIR") } - HirOrAstGenerics::Hir(hir_generics) => match hir_generics { - DelegationGenerics::UserSpecified => None, + HirOrTyGenerics::Hir(hir_generics) => match hir_generics { + DelegationGenerics::UserSpecified => hir::GenericArgs::NONE, DelegationGenerics::Default(generics) | DelegationGenerics::SelfAndUserSpecified(generics) - | DelegationGenerics::TraitImpl(generics, _) => generics.map(|generics| { + | DelegationGenerics::TraitImpl(generics, _) => { ctx.create_generics_args_from_params(generics.params, add_lifetimes, span) - }), + } }, } } pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { match self { - HirOrAstGenerics::Ast(ast_generics) => ast_generics.args_propagation_details(), - HirOrAstGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(), + HirOrTyGenerics::Ty(ty_generics) => ty_generics.args_propagation_details(), + HirOrTyGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(), } } } -impl<'a> GenericsGenerationResult<'a> { - fn new(generics: DelegationGenerics<Generics>) -> GenericsGenerationResult<'a> { - GenericsGenerationResult { - generics: HirOrAstGenerics::Ast(generics), - args_segment_id: None, - } +impl<'hir> GenericsGenerationResult<'hir> { + fn new( + generics: DelegationGenerics<&'hir [ty::GenericParamDef]>, + ) -> GenericsGenerationResult<'hir> { + GenericsGenerationResult { generics: HirOrTyGenerics::Ty(generics), args_segment_id: None } } } impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_params( &mut self, - item_id: NodeId, span: Span, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator<Item = hir::GenericParam<'hir>> { @@ -176,21 +165,14 @@ pub(super) fn all_params( // method call will be supported (if HIR generics were not obtained // then it means that we did not propagated them, thus we do not need // to generate params). - let parent = self - .parent - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .params; + let mut create_params = |result: &mut GenericsGenerationResult<'hir>| { + result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().params + }; - let child = self - .child - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .params; + let parent = create_params(&mut self.parent); + let child = create_params(&mut self.child); - // Order generics, firstly we have parent and child lifetimes, + // Order generics, first we have parent and child lifetimes, // then parent and child types and consts. // `generics_of` in `rustc_hir_analysis` will order them anyway, // however we want the order to be consistent in HIR too. @@ -203,13 +185,12 @@ pub(super) fn all_params( .copied() } - /// As we add hack predicates(`'a: 'a`) for all lifetimes (see `lower_delegation_generic_params` + /// As we add hack predicates(`'a: 'a`) for all lifetimes (see `uplift_delegation_generic_params` /// and `generate_lifetime_predicate` functions) we need to add them to delegation generics. /// Those predicates will not affect resulting predicate inheritance and folding /// in `rustc_hir_analysis`, as we inherit all predicates from delegation signature. pub(super) fn all_predicates( &mut self, - item_id: NodeId, span: Span, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator<Item = hir::WherePredicate<'hir>> { @@ -218,31 +199,23 @@ pub(super) fn all_predicates( // method call will be supported (if HIR generics were not obtained // then it means that we did not propagated them, thus we do not need // to generate predicates). - self.parent - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .predicates - .into_iter() - .chain( - self.child - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .predicates - .into_iter(), - ) - .copied() + let mut create_predicates = |result: &mut GenericsGenerationResult<'hir>| { + result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().predicates + }; + + let parent = create_predicates(&mut self.parent); + let child = create_predicates(&mut self.child); + + parent.into_iter().chain(child).copied() } } impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { - pub(super) fn lower_delegation_generics( + pub(super) fn uplift_delegation_generics( &mut self, delegation: &Delegation, sig_id: DefId, item_id: NodeId, - span: Span, ) -> GenericsGenerationResults<'hir> { let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.local_def_id(item_id))); @@ -251,15 +224,16 @@ pub(super) fn lower_delegation_generics( let len = segments.len(); let child_user_specified = segments[len - 1].args.is_some(); + let sig_params = &self.tcx.generics_of(sig_id).own_params[..]; + // If we are in trait impl always generate function whose generics matches // those that are defined in trait. if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) { // Considering parent generics, during signature inheritance // we will take those args that are in trait impl header trait ref. - let parent = GenericsGenerationResult::new(DelegationGenerics::Default(None)); + let parent = GenericsGenerationResult::new(DelegationGenerics::TraitImpl(&[], true)); - let generics = self.get_external_generics(sig_id, false, span); - let child = DelegationGenerics::TraitImpl(generics, child_user_specified); + let child = DelegationGenerics::TraitImpl(sig_params, child_user_specified); let child = GenericsGenerationResult::new(child); return GenericsGenerationResults { parent, child }; @@ -268,38 +242,37 @@ pub(super) fn lower_delegation_generics( let delegation_in_free_ctx = !matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. }); - let root_function_in_trait = - matches!(self.tcx.def_kind(self.tcx.parent(sig_id)), DefKind::Trait); - - let generate_self = delegation_in_free_ctx && root_function_in_trait; - - let parent_generics_factory = |this: &mut Self, user_specified: bool| { - this.get_parent_generics(this.tcx.parent(sig_id), generate_self, user_specified, span) - }; + let sig_parent = self.tcx.parent(sig_id); + let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait); let can_add_generics_to_parent = len >= 2 && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| { matches!(self.tcx.def_kind(def_id), DefKind::Trait | DefKind::TraitAlias) }); + let generate_self = delegation_in_free_ctx && sig_in_trait; let parent_generics = if can_add_generics_to_parent { + let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params[..]; + if segments[len - 2].args.is_some() { if generate_self { - DelegationGenerics::SelfAndUserSpecified(parent_generics_factory(self, true)) + // Take only first Self parameter, it is trait so Self must be present. + DelegationGenerics::SelfAndUserSpecified(&sig_parent_params[..1]) } else { DelegationGenerics::UserSpecified } } else { - DelegationGenerics::Default(parent_generics_factory(self, false)) + let skip_self = usize::from(!generate_self); + DelegationGenerics::Default(&sig_parent_params[skip_self..]) } } else { - DelegationGenerics::Default(None) + DelegationGenerics::<&'hir [ty::GenericParamDef]>::Default(&[]) }; let child_generics = if child_user_specified { DelegationGenerics::UserSpecified } else { - DelegationGenerics::Default(self.get_external_generics(sig_id, false, span)) + DelegationGenerics::Default(sig_params) }; GenericsGenerationResults { @@ -308,59 +281,70 @@ pub(super) fn lower_delegation_generics( } } - fn lower_delegation_generic_params( + fn uplift_delegation_generic_params( &mut self, - item_id: NodeId, span: Span, - params: &mut ThinVec<GenericParam>, + params: &'hir [ty::GenericParamDef], ) -> &'hir hir::Generics<'hir> { - for p in params.iter_mut() { - // We want to create completely new params, so we generate - // a new id, otherwise assertions will be triggered. - p.id = self.next_node_id(); + let params = self.arena.alloc_from_iter(params.iter().map(|p| { + let def_kind = match p.kind { + GenericParamDefKind::Lifetime => DefKind::LifetimeParam, + GenericParamDefKind::Type { .. } => DefKind::TyParam, + GenericParamDefKind::Const { .. } => DefKind::ConstParam, + }; - // Remove default params, as they are not supported on functions - // and there will duplicate DefId when we try to lower them later. - match &mut p.kind { - GenericParamKind::Lifetime => {} - GenericParamKind::Type { default } => *default = None, - GenericParamKind::Const { default, .. } => *default = None, + let param_ident = Ident::new(p.name, span); + let def_name = Some(param_ident.name); + let path_data = def_kind.def_path_data(def_name); + let node_id = self.next_node_id(); + + let def_id = self.create_def(node_id, def_name, def_kind, path_data, span); + + let kind = match p.kind { + GenericParamDefKind::Lifetime => { + hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } + } + GenericParamDefKind::Type { synthetic, .. } => { + hir::GenericParamKind::Type { default: None, synthetic } + } + GenericParamDefKind::Const { .. } => { + let hir_id = self.next_id(); + let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id)); + + hir::GenericParamKind::Const { + ty: self.arena.alloc(hir::Ty { kind, hir_id, span }), + default: None, + } + } + }; + + // Important: we don't use `self.next_id()` as we want to execute + // `lower_node_id` routine so param's id is added to `self.children`. + let hir_id = self.lower_node_id(node_id); + + hir::GenericParam { + hir_id, + colon_span: Some(span), + def_id, + kind, + name: hir::ParamName::Plain(param_ident), + pure_wrt_drop: p.pure_wrt_drop, + source: hir::GenericParamSource::Generics, + span, } - - // Note that we use self.disambiguator here, if we will create new every time - // we will get ICE if params have the same name. - self.resolver.insert_new_def_id( - p.id, - self.tcx - .create_def( - self.local_def_id(item_id), - Some(p.ident.name), - match p.kind { - GenericParamKind::Lifetime => DefKind::LifetimeParam, - GenericParamKind::Type { .. } => DefKind::TyParam, - GenericParamKind::Const { .. } => DefKind::ConstParam, - }, - None, - &mut self.disambiguator, - ) - .def_id(), - ); - } - - // Fallback to default generic param lowering, we modified them in the loop above. - let params = self.arena.alloc_from_iter( - params.iter().map(|p| self.lower_generic_param(p, hir::GenericParamSource::Generics)), - ); + })); // HACK: for now we generate predicates such that all lifetimes are early bound, // we can not not generate early-bound lifetimes, but we can't know which of them // are late-bound at this level of compilation. - // FIXME(fn_delegation): proper support for late bound lifetimes. + let predicates = + self.arena.alloc_from_iter(params.iter().filter_map(|p| { + p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span)) + })); + self.arena.alloc(hir::Generics { params, - predicates: self.arena.alloc_from_iter(params.iter().filter_map(|p| { - p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span)) - })), + predicates, has_where_clause_predicates: false, where_clause_span: span, span, @@ -376,11 +360,9 @@ fn generate_lifetime_predicate( this.arena.alloc(hir::Lifetime { hir_id: this.next_id(), ident: p.name.ident(), - kind: rustc_hir::LifetimeKind::Param(p.def_id), - source: rustc_hir::LifetimeSource::Path { - angle_brackets: rustc_hir::AngleBrackets::Full, - }, - syntax: rustc_hir::LifetimeSyntax::ExplicitBound, + kind: hir::LifetimeKind::Param(p.def_id), + source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full }, + syntax: hir::LifetimeSyntax::ExplicitBound, }) }; @@ -408,7 +390,7 @@ fn create_generics_args_from_params( self.arena.alloc(hir::GenericArgs { args: self.arena.alloc_from_iter(params.iter().filter_map(|p| { // Skip self generic arg, we do not need to propagate it. - if p.name.ident().name == kw::SelfUpper { + if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { return None; } @@ -472,117 +454,4 @@ fn create_generics_args_from_params( span_ext: span, }) } - - fn get_external_generics( - &mut self, - id: DefId, - processing_parent: bool, - span: Span, - ) -> Option<Generics> { - let generics = self.tcx.generics_of(id); - if generics.own_params.is_empty() { - return None; - } - - // Skip first Self parameter if we are in trait, it will be added later. - let to_skip = (processing_parent && generics.has_self) as usize; - - Some(Generics { - params: generics - .own_params - .iter() - .skip(to_skip) - .map(|p| GenericParam { - attrs: Default::default(), - bounds: Default::default(), - colon_span: None, - id: self.next_node_id(), - ident: Ident::new(p.name, span), - is_placeholder: false, - kind: match p.kind { - GenericParamDefKind::Lifetime => GenericParamKind::Lifetime, - GenericParamDefKind::Type { .. } => { - GenericParamKind::Type { default: None } - } - GenericParamDefKind::Const { .. } => self.map_const_kind(p, span), - }, - }) - .collect(), - where_clause: Default::default(), - span, - }) - } - - fn map_const_kind(&mut self, p: &ty::GenericParamDef, span: Span) -> GenericParamKind { - let const_type = self.tcx.type_of(p.def_id).instantiate_identity(); - - let (type_symbol, res) = match const_type.kind() { - ty::Bool => (sym::bool, Res::PrimTy(hir::PrimTy::Bool)), - ty::Uint(uint) => (uint.name(), Res::PrimTy(hir::PrimTy::Uint(*uint))), - ty::Int(int) => (int.name(), Res::PrimTy(hir::PrimTy::Int(*int))), - ty::Char => (sym::char, Res::PrimTy(hir::PrimTy::Char)), - _ => { - self.tcx - .dcx() - .span_delayed_bug(span, format!("Unexpected const type: {}", const_type)); - - (sym::dummy, Res::Err) - } - }; - - let node_id = self.next_node_id(); - - self.resolver.insert_partial_res(node_id, hir::def::PartialRes::new(res)); - - GenericParamKind::Const { - ty: Box::new(Ty { - id: node_id, - kind: TyKind::Path( - None, - Path { - segments: thin_vec![PathSegment { - ident: Ident::new(type_symbol, span), - id: self.next_node_id(), - args: None - }], - span, - tokens: None, - }, - ), - span, - tokens: None, - }), - span, - default: None, - } - } - - fn get_parent_generics( - &mut self, - id: DefId, - add_self: bool, - user_specified: bool, - span: Span, - ) -> Option<Generics> { - // If args are user-specified we still maybe need to add self. - let mut generics = - if user_specified { None } else { self.get_external_generics(id, true, span) }; - - if add_self { - generics.get_or_insert_default().params.insert( - 0, - GenericParam { - id: self.next_node_id(), - ident: Ident::new(kw::SelfUpper, span), - attrs: Default::default(), - bounds: vec![], - is_placeholder: false, - kind: GenericParamKind::Type { default: None }, - colon_span: None, - }, - ); - } - - generics - } }
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 1eb7272..95b8bb4 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -1,5 +1,5 @@ -use rustc_errors::DiagArgFromDisplay; use rustc_errors::codes::*; +use rustc_errors::{DiagArgFromDisplay, DiagSymbolList}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; @@ -191,10 +191,10 @@ pub(crate) struct ClobberAbiNotSupported { #[derive(Diagnostic)] #[note("the following ABIs are supported on this target: {$supported_abis}")] #[diag("invalid ABI for `clobber_abi`")] -pub(crate) struct InvalidAbiClobberAbi { +pub(crate) struct InvalidAbiClobberAbi<'a> { #[primary_span] pub abi_span: Span, - pub supported_abis: String, + pub supported_abis: DiagSymbolList<&'a str>, } #[derive(Diagnostic)] @@ -215,17 +215,18 @@ pub(crate) struct InvalidRegisterClass { #[primary_span] pub op_span: Span, pub reg_class: Symbol, - pub supported_register_classes: String, + pub supported_register_classes: DiagSymbolList<Symbol>, } #[derive(Diagnostic)] -#[diag("invalid asm template modifier for this register class")] +#[diag("invalid asm template modifier `{$modifier}` for this register class")] pub(crate) struct InvalidAsmTemplateModifierRegClass { #[primary_span] #[label("template modifier")] pub placeholder_span: Span, #[label("argument")] pub op_span: Span, + pub modifier: String, #[subdiagnostic] pub sub: InvalidAsmTemplateModifierRegClassSub, } @@ -235,7 +236,7 @@ pub(crate) enum InvalidAsmTemplateModifierRegClassSub { #[note( "the `{$class_name}` register class supports the following template modifiers: {$modifiers}" )] - SupportModifier { class_name: Symbol, modifiers: String }, + SupportModifier { class_name: Symbol, modifiers: DiagSymbolList<char> }, #[note("the `{$class_name}` register class does not support template modifiers")] DoesNotSupportModifier { class_name: Symbol }, }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 920ca8a..b6bc122 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -640,7 +640,7 @@ fn wrap_in_try_constructor( fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { let pat = self.lower_pat(&arm.pat); - let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond)); + let guard = arm.guard.as_ref().map(|guard| self.lower_expr(&guard.cond)); let hir_id = self.next_id(); let span = self.lower_span(arm.span); self.lower_attrs(hir_id, &arm.attrs, arm.span, Target::Arm); @@ -663,7 +663,7 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { } else if let Some(body) = &arm.body { self.dcx().emit_err(NeverPatternWithBody { span: body.span }); } else if let Some(g) = &arm.guard { - self.dcx().emit_err(NeverPatternWithGuard { span: g.span }); + self.dcx().emit_err(NeverPatternWithGuard { span: g.span() }); } // We add a fake `loop {}` arm body so that it typecks to `!`. The mir lowering of never
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a2be51c..5fcc8f0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -678,7 +678,7 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { lowerer.lower_node(def_id); - for (&child_def_id, &owner) in &map { + for (child_def_id, owner) in map { tcx.feed_delayed_owner(child_def_id, owner); } } @@ -1265,7 +1265,7 @@ fn lower_assoc_item_constraint( }; gen_args_ctor.into_generic_args(self) } else { - self.arena.alloc(hir::GenericArgs::none()) + hir::GenericArgs::NONE }; let kind = match &constraint.kind { AssocItemConstraintKind::Equality { term } => {
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index aece455..40d42ff 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -133,8 +133,11 @@ fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { self.lower_range_end(end, e2.is_some()), ); } - PatKind::Guard(inner, cond) => { - break hir::PatKind::Guard(self.lower_pat(inner), self.lower_expr(cond)); + PatKind::Guard(inner, guard) => { + break hir::PatKind::Guard( + self.lower_pat(inner), + self.lower_expr(&guard.cond), + ); } PatKind::Slice(pats) => break self.lower_pat_slice(pats), PatKind::Rest => {
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index bdb0981..ee46bdc 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -27,10 +27,9 @@ use rustc_ast_pretty::pprust::{self, State}; use rustc_attr_parsing::validate_attr; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{DiagCtxtHandle, LintBuffer}; +use rustc_errors::{DiagCtxtHandle, Diagnostic, LintBuffer}; use rustc_feature::Features; use rustc_session::Session; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, PATTERNS_IN_FNS_WITHOUT_BODY, UNUSED_VISIBILITIES, @@ -174,17 +173,19 @@ fn check_type_alias_where_clause_location( { let mut state = State::new(); + let mut needs_comma = !ty_alias.after_where_clause.predicates.is_empty(); if !ty_alias.after_where_clause.has_where_token { state.space(); state.word_space("where"); + } else if !needs_comma { + state.space(); } - let mut first = ty_alias.after_where_clause.predicates.is_empty(); for p in &ty_alias.generics.where_clause.predicates { - if !first { + if needs_comma { state.word_space(","); } - first = false; + needs_comma = true; state.print_where_predicate(p); } @@ -761,7 +762,7 @@ fn check_c_variadic_type(&self, fk: FnKind<'a>, attrs: &'a AttrVec) { match fn_ctxt { FnCtxt::Foreign => return, FnCtxt::Free | FnCtxt::Assoc(_) => { - if !self.sess.target.arch.supports_c_variadic_definitions() { + if !self.sess.target.supports_c_variadic_definitions() { self.dcx().emit_err(errors::CVariadicNotSupported { variadic_span: variadic_param.span, target: &*self.sess.target.llvm_target, @@ -1424,7 +1425,7 @@ fn visit_item(&mut self, item: &'a Item) { UNUSED_VISIBILITIES, item.id, item.vis.span, - BuiltinLintDiag::UnusedVisibility(item.vis.span), + errors::UnusedVisibility { span: item.vis.span }, ) } @@ -1731,14 +1732,19 @@ fn visit_fn(&mut self, fk: FnKind<'a>, attrs: &AttrVec, span: Span, id: NodeId) Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if let Some(ident) = ident { - self.lint_buffer.buffer_lint( + let is_foreign = matches!(ctxt, FnCtxt::Foreign); + self.lint_buffer.dyn_buffer_lint( PATTERNS_IN_FNS_WITHOUT_BODY, id, span, - BuiltinLintDiag::PatternsInFnsWithoutBody { - span, - ident, - is_foreign: matches!(ctxt, FnCtxt::Foreign), + move |dcx, level| { + let sub = errors::PatternsInFnsWithoutBodySub { ident, span }; + if is_foreign { + errors::PatternsInFnsWithoutBody::Foreign { sub } + } else { + errors::PatternsInFnsWithoutBody::Bodiless { sub } + } + .into_diag(dcx, level) }, ) } @@ -1828,11 +1834,30 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { Some((right, snippet)) } }; - self.lint_buffer.buffer_lint( + let left_sp = self + .sess + .source_map() + .span_extend_prev_while(err.span, char::is_whitespace) + .unwrap_or(err.span); + self.lint_buffer.dyn_buffer_lint( DEPRECATED_WHERE_CLAUSE_LOCATION, item.id, err.span, - BuiltinLintDiag::DeprecatedWhereclauseLocation(err.span, sugg), + move |dcx, level| { + let suggestion = match sugg { + Some((right_sp, sugg)) => { + errors::DeprecatedWhereClauseLocationSugg::MoveToEnd { + left: left_sp, + right: right_sp, + sugg, + } + } + None => errors::DeprecatedWhereClauseLocationSugg::RemoveWhere { + span: err.span, + }, + }; + errors::DeprecatedWhereClauseLocation { suggestion }.into_diag(dcx, level) + }, ); }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 390c155..b3a22c0 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1150,3 +1150,72 @@ pub(crate) struct RequiresRustAbi { #[label("not using the Rust ABI because of this")] pub extern_abi_span: Span, } + +#[derive(Diagnostic)] +#[diag("visibility qualifiers have no effect on `const _` declarations")] +#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] +pub(crate) struct UnusedVisibility { + #[suggestion( + "remove the qualifier", + style = "short", + code = "", + applicability = "machine-applicable" + )] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion( + "remove `mut` from the parameter", + code = "{ident}", + applicability = "machine-applicable" +)] +pub(crate) struct PatternsInFnsWithoutBodySub { + #[primary_span] + pub span: Span, + + pub ident: Ident, +} + +#[derive(Diagnostic)] +pub(crate) enum PatternsInFnsWithoutBody { + #[diag("patterns aren't allowed in foreign function declarations")] + Foreign { + #[subdiagnostic] + sub: PatternsInFnsWithoutBodySub, + }, + #[diag("patterns aren't allowed in functions without bodies")] + Bodiless { + #[subdiagnostic] + sub: PatternsInFnsWithoutBodySub, + }, +} + +#[derive(Diagnostic)] +#[diag("where clause not allowed here")] +#[note("see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information")] +pub(crate) struct DeprecatedWhereClauseLocation { + #[subdiagnostic] + pub suggestion: DeprecatedWhereClauseLocationSugg, +} + +#[derive(Subdiagnostic)] +pub(crate) enum DeprecatedWhereClauseLocationSugg { + #[multipart_suggestion( + "move it to the end of the type declaration", + applicability = "machine-applicable" + )] + MoveToEnd { + #[suggestion_part(code = "")] + left: Span, + #[suggestion_part(code = "{sugg}")] + right: Span, + + sugg: String, + }, + #[suggestion("remove this `where`", code = "", applicability = "machine-applicable")] + RemoveWhere { + #[primary_span] + span: Span, + }, +}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index a72ed84..f46ce8f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1649,6 +1649,85 @@ fn print_mac(&mut self, m: &ast::MacCall) { ); } + fn inline_asm_template_and_operands<'asm>( + asm: &'asm ast::InlineAsm, + ) -> (String, Vec<&'asm InlineAsmOperand>) { + fn is_explicit_reg(op: &InlineAsmOperand) -> bool { + match op { + InlineAsmOperand::In { reg, .. } + | InlineAsmOperand::Out { reg, .. } + | InlineAsmOperand::InOut { reg, .. } + | InlineAsmOperand::SplitInOut { reg, .. } => { + matches!(reg, InlineAsmRegOrRegClass::Reg(_)) + } + InlineAsmOperand::Const { .. } + | InlineAsmOperand::Sym { .. } + | InlineAsmOperand::Label { .. } => false, + } + } + + // After macro expansion, named operands become positional. The grammar + // requires positional operands to precede explicit register operands, + // so we must reorder when any non-explicit operand follows an explicit + // one. When no reordering is needed, we use the original template + // string and operand order to avoid duplicating the Display logic in + // InlineAsmTemplatePiece. + let needs_reorder = { + let mut seen_explicit = false; + asm.operands.iter().any(|(op, _)| { + if is_explicit_reg(op) { + seen_explicit = true; + false + } else { + seen_explicit + } + }) + }; + + if !needs_reorder { + let template = InlineAsmTemplatePiece::to_string(&asm.template); + let operands = asm.operands.iter().map(|(op, _)| op).collect(); + return (template, operands); + } + + let mut non_explicit = Vec::new(); + let mut explicit = Vec::new(); + for (i, (op, _)) in asm.operands.iter().enumerate() { + if is_explicit_reg(op) { + explicit.push(i); + } else { + non_explicit.push(i); + } + } + let order = non_explicit.into_iter().chain(explicit).collect::<Vec<_>>(); + + // Build old-index -> new-index mapping for template renumbering. + let mut old_to_new = vec![0usize; asm.operands.len()]; + for (new_idx, old_idx) in order.iter().copied().enumerate() { + old_to_new[old_idx] = new_idx; + } + + // Remap template placeholder indices and reuse the existing Display + // impl to build the template string. + let remapped = asm + .template + .iter() + .map(|piece| match piece { + InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span } => { + InlineAsmTemplatePiece::Placeholder { + operand_idx: old_to_new[*operand_idx], + modifier: *modifier, + span: *span, + } + } + other => other.clone(), + }) + .collect::<Vec<_>>(); + let template = InlineAsmTemplatePiece::to_string(&remapped); + let operands = order.iter().map(|&idx| &asm.operands[idx].0).collect(); + (template, operands) + } + fn print_inline_asm(&mut self, asm: &ast::InlineAsm) { enum AsmArg<'a> { Template(String), @@ -1657,8 +1736,9 @@ enum AsmArg<'a> { Options(InlineAsmOptions), } - let mut args = vec![AsmArg::Template(InlineAsmTemplatePiece::to_string(&asm.template))]; - args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o))); + let (template, operands) = Self::inline_asm_template_and_operands(asm); + let mut args = vec![AsmArg::Template(template)]; + args.extend(operands.into_iter().map(AsmArg::Operand)); for (abi, _) in &asm.clobber_abis { args.push(AsmArg::ClobberAbi(*abi)); } @@ -1786,6 +1866,23 @@ fn print_qpath(&mut self, path: &ast::Path, qself: &ast::QSelf, colons_before_pa } } + /// Print a pattern, parenthesizing it if it is an or-pattern (`A | B`). + /// + /// Or-patterns have the lowest precedence among patterns, so they need + /// parentheses when nested inside `@` bindings, `&` references, or `box` + /// patterns — otherwise `x @ A | B` parses as `(x @ A) | B`, `&A | B` + /// parses as `(&A) | B`, etc. + fn print_pat_paren_if_or(&mut self, pat: &ast::Pat) { + let needs_paren = matches!(pat.kind, PatKind::Or(..)); + if needs_paren { + self.popen(); + } + self.print_pat(pat); + if needs_paren { + self.pclose(); + } + } + fn print_pat(&mut self, pat: &ast::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); @@ -1813,7 +1910,7 @@ fn print_pat(&mut self, pat: &ast::Pat) { if let Some(p) = sub { self.space(); self.word_space("@"); - self.print_pat(p); + self.print_pat_paren_if_or(p); } } PatKind::TupleStruct(qself, path, elts) => { @@ -1885,7 +1982,7 @@ fn print_pat(&mut self, pat: &ast::Pat) { } PatKind::Box(inner) => { self.word("box "); - self.print_pat(inner); + self.print_pat_paren_if_or(inner); } PatKind::Deref(inner) => { self.word("deref!"); @@ -1909,7 +2006,7 @@ fn print_pat(&mut self, pat: &ast::Pat) { self.print_pat(inner); self.pclose(); } else { - self.print_pat(inner); + self.print_pat_paren_if_or(inner); } } PatKind::Expr(e) => self.print_expr(e, FixupContext::default()), @@ -1926,12 +2023,12 @@ fn print_pat(&mut self, pat: &ast::Pat) { self.print_expr(e, FixupContext::default()); } } - PatKind::Guard(subpat, condition) => { + PatKind::Guard(subpat, guard) => { self.popen(); self.print_pat(subpat); self.space(); self.word_space("if"); - self.print_expr(condition, FixupContext::default()); + self.print_expr(&guard.cond, FixupContext::default()); self.pclose(); } PatKind::Slice(elts) => {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 0c59287..ad602d5 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -891,9 +891,9 @@ fn print_arm(&mut self, arm: &ast::Arm) { self.print_outer_attributes(&arm.attrs); self.print_pat(&arm.pat); self.space(); - if let Some(e) = &arm.guard { + if let Some(guard) = &arm.guard { self.word_space("if"); - self.print_expr(e, FixupContext::default()); + self.print_expr(&guard.cond, FixupContext::default()); self.space(); }
diff --git a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs index 118a410..edd9d9c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs +++ b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs
@@ -9,7 +9,7 @@ use thin_vec::ThinVec; use crate::attributes::prelude::Allow; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{OnDuplicate, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::{ArgParser, MetaItemOrLitParser}; use crate::target_checking::AllowedTargets; @@ -18,12 +18,12 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser { const PATH: &[Symbol] = &[sym::rustc_autodiff]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::Trait { body: false })), Allow(Target::Method(MethodKind::TraitImpl)), ]); const TEMPLATE: AttributeTemplate = template!(
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index f3612af..4ff2240 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs
@@ -2,18 +2,18 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AttrStyle, NodeId, token}; use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Diagnostic; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::CfgEntry; use rustc_hir::{AttrPath, Target}; use rustc_parse::exp; use rustc_parse::parser::{Parser, Recovery}; use rustc_session::Session; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::UNREACHABLE_CFG_SELECT_PREDICATES; use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; use crate::parser::{AllowExprMetavar, MetaItemOrLitParser}; -use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry}; +use crate::{AttributeParser, ParsedDescription, ShouldEmit, errors, parse_cfg_entry}; #[derive(Clone)] pub enum CfgSelectPredicate { @@ -153,11 +153,17 @@ fn lint_unreachable( let branch_is_unreachable = |predicate: CfgSelectPredicate, wildcard_span| { let span = predicate.span(); - p.psess.buffer_lint( + p.psess.dyn_buffer_lint( UNREACHABLE_CFG_SELECT_PREDICATES, span, lint_node_id, - BuiltinLintDiag::UnreachableCfg { span, wildcard_span }, + move |dcx, level| match wildcard_span { + Some(wildcard_span) => { + errors::UnreachableCfgSelectPredicateWildcard { span, wildcard_span } + .into_diag(dcx, level) + } + None => errors::UnreachableCfgSelectPredicate { span }.into_diag(dcx, level), + }, ); };
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs index df1e569..3396976 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs
@@ -8,7 +8,6 @@ impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser { Allow(Target::Enum), Allow(Target::Union), ]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 652a783..dbf289e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -12,7 +12,6 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser { const PATH: &[Symbol] = &[sym::optimize]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), @@ -68,7 +67,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ColdParser { impl<S: Stage> SingleAttributeParser<S> for CoverageParser { const PATH: &[Symbol] = &[sym::coverage]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), @@ -119,7 +117,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for ExportNameParser { const PATH: &[rustc_span::Symbol] = &[sym::export_name]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Static), @@ -157,7 +154,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcObjcClassParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); @@ -189,7 +185,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcObjcSelectorParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); @@ -587,6 +582,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser { r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, + r#"kernel_hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, @@ -595,7 +591,6 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser { r#"realtime = "nonblocking|blocking|caller""#, ]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { @@ -654,7 +649,9 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib Some(sym::memtag) => apply(SanitizerSet::MEMTAG), Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK), Some(sym::thread) => apply(SanitizerSet::THREAD), - Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS), + Some(sym::hwaddress) | Some(sym::kernel_hwaddress) => { + apply(SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS) + } Some(sym::realtime) => match value.value_as_str() { Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking), Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking), @@ -679,6 +676,7 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib sym::shadow_call_stack, sym::thread, sym::hwaddress, + sym::kernel_hwaddress, sym::realtime, ], ); @@ -724,7 +722,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEiiForeignItemParser { impl<S: Stage> SingleAttributeParser<S> for PatchableFunctionEntryParser { const PATH: &[Symbol] = &[sym::patchable_function_entry]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 2d2994c..72a0945 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
@@ -10,7 +10,6 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser { const PATH: &[Symbol] = &[sym::crate_name]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -84,7 +83,6 @@ fn extend( impl<S: Stage> SingleAttributeParser<S> for RecursionLimitParser { const PATH: &[Symbol] = &[sym::recursion_limit]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -107,7 +105,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser { const PATH: &[Symbol] = &[sym::move_size_limit]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -130,7 +127,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for TypeLengthLimitParser { const PATH: &[Symbol] = &[sym::type_length_limit]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -153,7 +149,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser { const PATH: &[Symbol] = &[sym::pattern_complexity_limit]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -213,7 +208,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser { impl<S: Stage> SingleAttributeParser<S> for WindowsSubsystemParser { const PATH: &[Symbol] = &[sym::windows_subsystem]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index a2c7e45..804b54e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -34,7 +34,6 @@ fn get<S: Stage>( pub(crate) struct DeprecatedParser; impl<S: Stage> SingleAttributeParser<S> for DeprecatedParser { const PATH: &[Symbol] = &[sym::deprecated]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn),
diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs index 4a89cf6..9f3d1e2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs
@@ -4,7 +4,7 @@ use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::{Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{OnDuplicate, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; use crate::target_checking::{ALL_TARGETS, AllowedTargets}; @@ -12,7 +12,6 @@ pub(crate) struct DoNotRecommendParser; impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser { const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Checked in check_attr. const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index f896863..099a75e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs
@@ -1,10 +1,12 @@ use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; +use rustc_errors::msg; use rustc_feature::template; use rustc_hir::Target; use rustc_hir::attrs::{ AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow, }; use rustc_hir::lints::AttributeLintKind; +use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, edition, sym}; use thin_vec::ThinVec; @@ -481,15 +483,19 @@ macro_rules! no_args_and_not_crate_level { } macro_rules! no_args_and_crate_level { ($ident: ident) => {{ + no_args_and_crate_level!($ident, |span| {}); + }}; + ($ident: ident, |$span:ident| $extra_validation:block) => {{ if let Err(span) = args.no_args() { expected_no_args(cx, span); return; } - let span = path.span(); - if !check_attr_crate_level(cx, span) { + let $span = path.span(); + if !check_attr_crate_level(cx, $span) { return; } - self.attribute.$ident = Some(span); + $extra_validation + self.attribute.$ident = Some($span); }}; } macro_rules! string_arg_and_crate_level { @@ -553,7 +559,17 @@ macro_rules! string_arg_and_crate_level { ), Some(sym::fake_variadic) => no_args_and_not_crate_level!(fake_variadic), Some(sym::search_unbox) => no_args_and_not_crate_level!(search_unbox), - Some(sym::rust_logo) => no_args_and_crate_level!(rust_logo), + Some(sym::rust_logo) => no_args_and_crate_level!(rust_logo, |span| { + if !cx.features().rustdoc_internals() { + feature_err( + cx.sess(), + sym::rustdoc_internals, + span, + msg!("the `#[doc(rust_logo)]` attribute is used for Rust branding"), + ) + .emit(); + } + }), Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args), Some(sym::test) => { let Some(list) = args.list() else {
diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs index 71d10b2..ee5c507 100644 --- a/compiler/rustc_attr_parsing/src/attributes/dummy.rs +++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs
@@ -2,7 +2,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_span::{Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{OnDuplicate, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; use crate::target_checking::{ALL_TARGETS, AllowedTargets}; @@ -10,7 +10,6 @@ pub(crate) struct RustcDummyParser; impl<S: Stage> SingleAttributeParser<S> for RustcDummyParser { const PATH: &[Symbol] = &[sym::rustc_dummy]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index 767200b..82cec25 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs
@@ -11,7 +11,6 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser { const PATH: &[Symbol] = &[sym::inline]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), @@ -68,7 +67,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser { const PATH: &[Symbol] = &[sym::rustc_force_inline]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn),
diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs index 3be9b9d..5f61081 100644 --- a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs
@@ -16,7 +16,6 @@ impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser { ]); const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"); const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index c4a4831..52ab4ac 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -22,7 +22,6 @@ impl<S: Stage> SingleAttributeParser<S> for LinkNameParser { const PATH: &[Symbol] = &[sym::link_name]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::ForeignFn), @@ -466,7 +465,6 @@ fn parse_link_import_name_type<S: Stage>( impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser { const PATH: &[Symbol] = &[sym::link_section]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Static), @@ -541,7 +539,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcStdInternalSymbolParser { impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser { const PATH: &[Symbol] = &[sym::link_ordinal]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::ForeignFn), @@ -583,8 +580,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for LinkageParser { const PATH: &[Symbol] = &[sym::linkage]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; - const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn),
diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 00d4068..86dde5b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
@@ -130,7 +130,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser { impl<S: Stage> SingleAttributeParser<S> for MacroExportParser { const PATH: &[Symbol] = &[sym::macro_export]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ @@ -168,7 +167,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser { const PATH: &[Symbol] = &[sym::collapse_debuginfo]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!( List: &["no", "external", "yes"],
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 223c889..6714764 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -124,14 +124,8 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static { /// If you need the parser to accept more than one path, use [`AttributeParser`] instead const PATH: &[Symbol]; - /// Configures the precedence of attributes with the same `PATH` on a syntax node. - const ATTRIBUTE_ORDER: AttributeOrder; - /// Configures what to do when when the same attribute is /// applied more than once on the same syntax node. - /// - /// [`ATTRIBUTE_ORDER`](Self::ATTRIBUTE_ORDER) specified which one is assumed to be correct, - /// and this specified whether to, for example, warn or error on the other one. const ON_DUPLICATE: OnDuplicate<S>; const ALLOWED_TARGETS: AllowedTargets; @@ -162,21 +156,8 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S> <T as SingleAttributeParser<S>>::TEMPLATE, |group: &mut Single<T, S>, cx, args| { if let Some(pa) = T::convert(cx, args) { - match T::ATTRIBUTE_ORDER { - // keep the first and report immediately. ignore this attribute - AttributeOrder::KeepInnermost => { - if let Some((_, unused)) = group.1 { - T::ON_DUPLICATE.exec::<T>(cx, cx.attr_span, unused); - return; - } - } - // keep the new one and warn about the previous, - // then replace - AttributeOrder::KeepOutermost => { - if let Some((_, used)) = group.1 { - T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span); - } - } + if let Some((_, used)) = group.1 { + T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span); } group.1 = Some((pa, cx.attr_span)); @@ -206,7 +187,7 @@ pub(crate) enum OnDuplicate<S: Stage> { /// Custom function called when a duplicate attribute is found. /// /// - `unused` is the span of the attribute that was unused or bad because of some - /// duplicate reason (see [`AttributeOrder`]) + /// duplicate reason /// - `used` is the span of the attribute that was used in favor of the unused attribute Custom(fn(cx: &AcceptContext<'_, '_, S>, used: Span, unused: Span)), } @@ -223,8 +204,8 @@ fn exec<P: SingleAttributeParser<S>>( OnDuplicate::WarnButFutureError => cx.warn_unused_duplicate_future_error(used, unused), OnDuplicate::Error => { cx.emit_err(UnusedMultiple { - this: used, - other: unused, + this: unused, + other: used, name: Symbol::intern( &P::PATH.into_iter().map(|i| i.to_string()).collect::<Vec<_>>().join(".."), ), @@ -236,30 +217,6 @@ fn exec<P: SingleAttributeParser<S>>( } } -pub(crate) enum AttributeOrder { - /// Duplicates after the innermost instance of the attribute will be an error/warning. - /// Only keep the lowest attribute. - /// - /// Attributes are processed from bottom to top, so this raises a warning/error on all the attributes - /// further above the lowest one: - /// ``` - /// #[stable(since="1.0")] //~ WARNING duplicated attribute - /// #[stable(since="2.0")] - /// ``` - KeepInnermost, - - /// Duplicates before the outermost instance of the attribute will be an error/warning. - /// Only keep the highest attribute. - /// - /// Attributes are processed from bottom to top, so this raises a warning/error on all the attributes - /// below the highest one: - /// ``` - /// #[path="foo.rs"] - /// #[path="bar.rs"] //~ WARNING duplicated attribute - /// ``` - KeepOutermost, -} - /// An even simpler version of [`SingleAttributeParser`]: /// now automatically check that there are no arguments provided to the attribute. /// @@ -284,7 +241,6 @@ fn default() -> Self { impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> { const PATH: &[Symbol] = T::PATH; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE; const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!(Word);
diff --git a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs index 8456ce7..7f37210 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
@@ -4,7 +4,6 @@ impl<S: Stage> SingleAttributeParser<S> for MustNotSuspendParser { const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Struct),
diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index 673e2c9..f1ce810 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs
@@ -4,7 +4,6 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser { const PATH: &[Symbol] = &[sym::must_use]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn),
diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs index b60f8e3..6b5eee7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/path.rs +++ b/compiler/rustc_attr_parsing/src/attributes/path.rs
@@ -4,7 +4,6 @@ impl<S: Stage> SingleAttributeParser<S> for PathParser { const PATH: &[Symbol] = &[sym::path]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Error(Target::Crate)]);
diff --git a/compiler/rustc_attr_parsing/src/attributes/prelude.rs b/compiler/rustc_attr_parsing/src/attributes/prelude.rs index 65c408f..53adf7e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prelude.rs
@@ -12,8 +12,8 @@ #[doc(hidden)] pub(super) use crate::attributes::{ - AcceptMapping, AttributeOrder, AttributeParser, CombineAttributeParser, ConvertFn, - NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, + AcceptMapping, AttributeParser, CombineAttributeParser, ConvertFn, NoArgsAttributeParser, + OnDuplicate, SingleAttributeParser, }; // contexts #[doc(hidden)]
diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs index f9ace7e..aca0e94 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs
@@ -25,7 +25,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroAttributeParser { pub(crate) struct ProcMacroDeriveParser; impl<S: Stage> SingleAttributeParser<S> for ProcMacroDeriveParser { const PATH: &[Symbol] = &[sym::proc_macro_derive]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!( @@ -46,7 +45,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib pub(crate) struct RustcBuiltinMacroParser; impl<S: Stage> SingleAttributeParser<S> for RustcBuiltinMacroParser { const PATH: &[Symbol] = &[sym::rustc_builtin_macro]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const TEMPLATE: AttributeTemplate =
diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index 8eb902b..15d9d34 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs
@@ -5,7 +5,7 @@ use rustc_hir::attrs::{AttributeKind, MirDialect, MirPhase}; use rustc_span::{Span, Symbol, sym}; -use super::{AttributeOrder, OnDuplicate}; +use super::OnDuplicate; use crate::attributes::SingleAttributeParser; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; @@ -18,8 +18,6 @@ impl<S: Stage> SingleAttributeParser<S> for CustomMirParser { const PATH: &[rustc_span::Symbol] = &[sym::custom_mir]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; - const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index 5782f94..e809ad9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs
@@ -28,7 +28,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAllocatorZeroedVariantParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function"); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { let Some(name) = args.name_value().and_then(NameValueParser::value_as_str) else { cx.expected_name_value(cx.attr_span, None);
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index e8b4cb3..15772d8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
@@ -31,7 +31,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcMustImplementOneOfParser { const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { let Some(list) = args.list() else { @@ -105,7 +104,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitAutorefsParser { impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStartParser { const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["start"]); @@ -120,7 +118,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEndParser { const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["end"]); @@ -135,7 +132,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser { const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["N"]); @@ -193,7 +189,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcInheritOverflowChecksParser { impl<S: Stage> SingleAttributeParser<S> for RustcLintOptDenyFieldAccessParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]); const TEMPLATE: AttributeTemplate = template!(Word); @@ -373,7 +368,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDeprecatedSafe2024Parser { Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), ]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { @@ -441,7 +435,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcNeverTypeOptionsParser { const PATH: &[Symbol] = &[sym::rustc_never_type_options]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const TEMPLATE: AttributeTemplate = template!(List: &[ r#"fallback = "unit", "never", "no""#, r#"diverging_block_default = "unit", "never""#, @@ -592,7 +585,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcLintUntrackedQueryInformationPa impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser { const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); @@ -610,7 +602,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcScalableVectorParser { const PATH: &[Symbol] = &[sym::rustc_scalable_vector]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]); @@ -636,7 +627,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for LangParser { const PATH: &[Symbol] = &[sym::lang]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); @@ -981,8 +971,6 @@ fn extend( impl<S: Stage> SingleAttributeParser<S> for RustcIfThisChangedParser { const PATH: &[Symbol] = &[sym::rustc_if_this_changed]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; - const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ @@ -1147,7 +1135,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser { impl<S: Stage> SingleAttributeParser<S> for RustcDiagnosticItemParser { const PATH: &[Symbol] = &[sym::rustc_diagnostic_item]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Trait), @@ -1220,7 +1207,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSymbolNameParser { Allow(Target::Impl { of_trait: false }), ]); const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { if let Err(span) = args.no_args() { @@ -1245,7 +1231,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDefPathParser { Allow(Target::Impl { of_trait: false }), ]); const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { if let Err(span) = args.no_args() { @@ -1275,7 +1260,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcStrictCoherenceParser { impl<S: Stage> SingleAttributeParser<S> for RustcReservationImplParser { const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); @@ -1311,7 +1295,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for PreludeImportParser { impl<S: Stage> SingleAttributeParser<S> for RustcDocPrimitiveParser { const PATH: &[Symbol] = &[sym::rustc_doc_primitive]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 2775eab..db0350f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
@@ -7,7 +7,6 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser { const PATH: &[Symbol] = &[sym::ignore]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); @@ -41,7 +40,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for ShouldPanicParser { const PATH: &[Symbol] = &[sym::should_panic]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Error(Target::WherePredicate)]); @@ -98,7 +96,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for ReexportTestHarnessMainParser { const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); @@ -126,7 +123,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAbiParser { const PATH: &[Symbol] = &[sym::rustc_abi]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]); - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::TyAlias), Allow(Target::Fn), @@ -197,7 +193,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEvaluateWhereClausesParser { impl<S: Stage> SingleAttributeParser<S> for TestRunnerParser { const PATH: &[Symbol] = &[sym::test_runner]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["path"]); @@ -226,7 +221,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib impl<S: Stage> SingleAttributeParser<S> for RustcTestMarkerParser { const PATH: &[Symbol] = &[sym::rustc_test_marker]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Const),
diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index c09e151..c418d1d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs
@@ -1,9 +1,7 @@ use std::mem; use super::prelude::*; -use crate::attributes::{ - AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, -}; +use crate::attributes::{NoArgsAttributeParser, OnDuplicate, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; use crate::target_checking::Policy::{Allow, Warn}; @@ -12,7 +10,6 @@ pub(crate) struct RustcSkipDuringMethodDispatchParser; impl<S: Stage> SingleAttributeParser<S> for RustcSkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs index 58b4a0b..c381740 100644 --- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs
@@ -6,7 +6,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcMacroTransparencyParser { const PATH: &[Symbol] = &[sym::rustc_macro_transparency]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Custom(|cx, used, unused| { cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes"); });
diff --git a/compiler/rustc_attr_parsing/src/errors.rs b/compiler/rustc_attr_parsing/src/errors.rs new file mode 100644 index 0000000..d423641 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/errors.rs
@@ -0,0 +1,52 @@ +use rustc_errors::MultiSpan; +use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_span::{Span, Symbol}; + +#[derive(Diagnostic)] +#[diag("`{$name}` attribute cannot be used at crate level")] +pub(crate) struct InvalidAttrAtCrateLevel { + #[primary_span] + pub span: Span, + #[suggestion( + "perhaps you meant to use an outer attribute", + code = "#[", + applicability = "machine-applicable", + style = "verbose" + )] + pub pound_to_opening_bracket: Span, + pub name: Symbol, + #[subdiagnostic] + pub item: Option<ItemFollowingInnerAttr>, +} + +#[derive(Clone, Copy, Subdiagnostic)] +#[label("the inner attribute doesn't annotate this item")] +pub(crate) struct ItemFollowingInnerAttr { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("unreachable configuration predicate")] +pub(crate) struct UnreachableCfgSelectPredicate { + #[label("this configuration predicate is never reached")] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("most attributes are not supported in `where` clauses")] +#[help("only `#[cfg]` and `#[cfg_attr]` are supported")] +pub(crate) struct UnsupportedAttributesInWhere { + #[primary_span] + pub span: MultiSpan, +} + +#[derive(Diagnostic)] +#[diag("unreachable configuration predicate")] +pub(crate) struct UnreachableCfgSelectPredicateWildcard { + #[label("this configuration predicate is never reached")] + pub span: Span, + + #[label("always matches")] + pub wildcard_span: Span, +}
diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index fa66dec..7305c4b 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs
@@ -269,6 +269,11 @@ pub fn parse_attribute_list( mut emit_lint: impl FnMut(LintId, Span, AttributeLintKind), ) -> Vec<Attribute> { let mut attributes = Vec::new(); + // We store the attributes we intend to discard at the end of this function in order to + // check they are applied to the right target and error out if necessary. In practice, we + // end up dropping only derive attributes and derive helpers, both being fully processed + // at macro expansion. + let mut dropped_attributes = Vec::new(); let mut attr_paths: Vec<RefPathParser<'_>> = Vec::new(); let mut early_parsed_state = EarlyParsedState::default(); @@ -304,7 +309,7 @@ pub fn parse_attribute_list( kind: DocFragmentKind::Sugared(*comment_kind), span: attr_span, comment: *symbol, - })) + })); } ast::AttrKind::Normal(n) => { attr_paths.push(PathParser(&n.item.path)); @@ -393,29 +398,33 @@ pub fn parse_attribute_list( Self::check_target(&accept.allowed_targets, target, &mut cx); } } else { - // If we're here, we must be compiling a tool attribute... Or someone - // forgot to parse their fancy new attribute. Let's warn them in any case. - // If you are that person, and you really think your attribute should - // remain unparsed, carefully read the documentation in this module and if - // you still think so you can add an exception to this assertion. - - // FIXME(jdonszelmann): convert other attributes, and check with this that - // we caught em all - // const FIXME_TEMPORARY_ATTR_ALLOWLIST: &[Symbol] = &[sym::cfg]; - // assert!( - // self.tools.contains(&parts[0]) || true, - // // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]), - // "attribute {path} wasn't parsed and isn't a know tool attribute", - // ); - - attributes.push(Attribute::Unparsed(Box::new(AttrItem { + let attr = AttrItem { path: attr_path.clone(), args: self .lower_attr_args(n.item.args.unparsed_ref().unwrap(), lower_span), id: HashIgnoredAttrId { attr_id: attr.id }, style: attr.style, span: attr_span, - }))); + }; + + if !matches!(self.stage.should_emit(), ShouldEmit::Nothing) + && target == Target::Crate + { + self.check_invalid_crate_level_attr_item(&attr, n.item.span()); + } + + let attr = Attribute::Unparsed(Box::new(attr)); + + if self.tools.contains(&parts[0]) + // FIXME: this can be removed once #152369 has been merged. + // https://github.com/rust-lang/rust/pull/152369 + || [sym::allow, sym::deny, sym::expect, sym::forbid, sym::warn] + .contains(&parts[0]) + { + attributes.push(attr); + } else { + dropped_attributes.push(attr); + } } } } @@ -431,6 +440,12 @@ pub fn parse_attribute_list( } } + if !matches!(self.stage.should_emit(), ShouldEmit::Nothing) + && target == Target::WherePredicate + { + self.check_invalid_where_predicate_attrs(attributes.iter().chain(&dropped_attributes)); + } + attributes }
diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index db09572..93eb5a0 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs
@@ -79,6 +79,7 @@ // tidy-alphabetical-start #![feature(decl_macro)] #![feature(iter_intersperse)] +#![feature(try_blocks)] #![recursion_limit = "256"] // tidy-alphabetical-end @@ -99,6 +100,7 @@ pub mod parser; mod early_parsed; +mod errors; mod safety; mod session_diagnostics; mod target_checking;
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index bab8300..7321260 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -594,29 +594,108 @@ pub(crate) struct AttributeParseError<'a> { pub(crate) suggestions: Vec<String>, } +impl<'a> AttributeParseError<'a> { + fn render_expected_specific_argument<G>( + &self, + diag: &mut Diag<'_, G>, + possibilities: &[Symbol], + strings: bool, + ) where + G: EmissionGuarantee, + { + let quote = if strings { '"' } else { '`' }; + match possibilities { + &[] => {} + &[x] => { + diag.span_label( + self.span, + format!("the only valid argument here is {quote}{x}{quote}"), + ); + } + [first, second] => { + diag.span_label( + self.span, + format!("valid arguments are {quote}{first}{quote} or {quote}{second}{quote}"), + ); + } + [first @ .., second_to_last, last] => { + let mut res = String::new(); + for i in first { + res.push_str(&format!("{quote}{i}{quote}, ")); + } + res.push_str(&format!("{quote}{second_to_last}{quote} or {quote}{last}{quote}")); + + diag.span_label(self.span, format!("valid arguments are {res}")); + } + } + } + + fn render_expected_specific_argument_list<G>( + &self, + diag: &mut Diag<'_, G>, + possibilities: &[Symbol], + strings: bool, + ) where + G: EmissionGuarantee, + { + let description = self.description(); + + let quote = if strings { '"' } else { '`' }; + match possibilities { + &[] => {} + &[x] => { + diag.span_label( + self.span, + format!( + "this {description} is only valid with {quote}{x}{quote} as an argument" + ), + ); + } + [first, second] => { + diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument")); + } + [first @ .., second_to_last, last] => { + let mut res = String::new(); + for i in first { + res.push_str(&format!("{quote}{i}{quote}, ")); + } + res.push_str(&format!("{quote}{second_to_last}{quote} or {quote}{last}{quote}")); + + diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}")); + } + } + } + + fn description(&self) -> &'static str { + match self.description { + ParsedDescription::Attribute => "attribute", + ParsedDescription::Macro => "macro", + } + } +} + impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { let name = self.path.to_string(); - let description = match self.description { - ParsedDescription::Attribute => "attribute", - ParsedDescription::Macro => "macro", - }; + let description = self.description(); let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input")); diag.span(self.attr_span); diag.code(E0539); - match self.reason { + match &self.reason { AttributeParseErrorReason::ExpectedStringLiteral { byte_string } => { if let Some(start_point_span) = byte_string { diag.span_suggestion( - start_point_span, + *start_point_span, "consider removing the prefix", "", Applicability::MaybeIncorrect, ); diag.note("expected a normal string literal, not a byte string literal"); + // Avoid emitting an "attribute must be of the form" suggestion, as the + // attribute is likely to be well-formed already. return diag; } else { diag.span_label(self.span, "expected a string literal here"); @@ -693,62 +772,14 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { strings, list: false, } => { - let quote = if strings { '"' } else { '`' }; - match possibilities { - &[] => {} - &[x] => { - diag.span_label( - self.span, - format!("the only valid argument here is {quote}{x}{quote}"), - ); - } - [first, second] => { - diag.span_label(self.span, format!("valid arguments are {quote}{first}{quote} or {quote}{second}{quote}")); - } - [first @ .., second_to_last, last] => { - let mut res = String::new(); - for i in first { - res.push_str(&format!("{quote}{i}{quote}, ")); - } - res.push_str(&format!( - "{quote}{second_to_last}{quote} or {quote}{last}{quote}" - )); - - diag.span_label(self.span, format!("valid arguments are {res}")); - } - } + self.render_expected_specific_argument(&mut diag, *possibilities, *strings); } AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings, list: true, } => { - let quote = if strings { '"' } else { '`' }; - match possibilities { - &[] => {} - &[x] => { - diag.span_label( - self.span, - format!( - "this {description} is only valid with {quote}{x}{quote} as an argument" - ), - ); - } - [first, second] => { - diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument")); - } - [first @ .., second_to_last, last] => { - let mut res = String::new(); - for i in first { - res.push_str(&format!("{quote}{i}{quote}, ")); - } - res.push_str(&format!( - "{quote}{second_to_last}{quote} or {quote}{last}{quote}" - )); - - diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}")); - } - } + self.render_expected_specific_argument_list(&mut diag, *possibilities, *strings); } AttributeParseErrorReason::ExpectedIdentifier => { diag.span_label(self.span, "expected a valid identifier here");
diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index fb00547..253a089 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs
@@ -1,14 +1,18 @@ use std::borrow::Cow; use rustc_ast::AttrStyle; -use rustc_errors::DiagArgValue; +use rustc_errors::{DiagArgValue, MultiSpan, StashKey}; use rustc_feature::Features; +use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::AttributeLintKind; -use rustc_hir::{MethodKind, Target}; -use rustc_span::sym; +use rustc_hir::{AttrItem, Attribute, MethodKind, Target}; +use rustc_span::{BytePos, Span, Symbol, sym}; use crate::AttributeParser; use crate::context::{AcceptContext, Stage}; +use crate::errors::{ + InvalidAttrAtCrateLevel, ItemFollowingInnerAttr, UnsupportedAttributesInWhere, +}; use crate::session_diagnostics::InvalidTarget; use crate::target_checking::Policy::Allow; @@ -96,6 +100,25 @@ pub(crate) fn check_target( return; } + if matches!(cx.attr_path.segments.as_ref(), [sym::repr]) && target == Target::Crate { + // The allowed targets of `repr` depend on its arguments. They can't be checked using + // the `AttributeParser` code. + let span = cx.attr_span; + let item = + cx.cx.first_line_of_next_item(span).map(|span| ItemFollowingInnerAttr { span }); + + let pound_to_opening_bracket = cx.attr_span.until(cx.inner_span); + + cx.dcx() + .create_err(InvalidAttrAtCrateLevel { + span, + pound_to_opening_bracket, + name: sym::repr, + item, + }) + .emit(); + } + match allowed_targets.is_allowed(target) { AllowedResult::Allowed => {} AllowedResult::Warn => { @@ -163,6 +186,113 @@ pub(crate) fn check_crate_level(target: Target, cx: &mut AcceptContext<'_, 'sess cx.emit_lint(rustc_session::lint::builtin::UNUSED_ATTRIBUTES, kind, attr_span); } + + // FIXME: Fix "Cannot determine resolution" error and remove built-in macros + // from this check. + pub(crate) fn check_invalid_crate_level_attr_item(&self, attr: &AttrItem, inner_span: Span) { + // Check for builtin attributes at the crate level + // which were unsuccessfully resolved due to cannot determine + // resolution for the attribute macro error. + const ATTRS_TO_CHECK: &[Symbol] = + &[sym::derive, sym::test, sym::test_case, sym::global_allocator, sym::bench]; + + // FIXME(jdonszelmann): all attrs should be combined here cleaning this up some day. + if let Some(name) = ATTRS_TO_CHECK.iter().find(|attr_to_check| matches!(attr.path.segments.as_ref(), [segment] if segment == *attr_to_check)) { + let span = attr.span; + let name = *name; + + let item = self.first_line_of_next_item(span).map(|span| ItemFollowingInnerAttr { span }); + + let err = self.dcx().create_err(InvalidAttrAtCrateLevel { + span, + pound_to_opening_bracket: span.until(inner_span), + name, + item, + }); + + self.dcx().try_steal_replace_and_emit_err( + attr.path.span, + StashKey::UndeterminedMacroResolution, + err, + ); + } + } + + fn first_line_of_next_item(&self, span: Span) -> Option<Span> { + // We can't exactly call `tcx.hir_free_items()` here because it's too early and querying + // this would create a circular dependency. Instead, we resort to getting the original + // source code that follows `span` and find the next item from here. + + self.sess() + .source_map() + .span_to_source(span, |content, _, span_end| { + let mut source = &content[span_end..]; + let initial_source_len = source.len(); + let span = try { + loop { + let first = source.chars().next()?; + + if first.is_whitespace() { + let split_idx = source.find(|c: char| !c.is_whitespace())?; + source = &source[split_idx..]; + } else if source.starts_with("//") { + let line_idx = source.find('\n')?; + source = &source[line_idx + '\n'.len_utf8()..]; + } else if source.starts_with("/*") { + // FIXME: support nested comments. + let close_idx = source.find("*/")?; + source = &source[close_idx + "*/".len()..]; + } else if first == '#' { + // FIXME: properly find the end of the attributes in order to accurately + // skip them. This version just consumes the source code until the next + // `]`. + let close_idx = source.find(']')?; + source = &source[close_idx + ']'.len_utf8()..]; + } else { + let lo = span_end + initial_source_len - source.len(); + let last_line = source.split('\n').next().map(|s| s.trim_end())?; + + let hi = lo + last_line.len(); + let lo = BytePos(lo as u32); + let hi = BytePos(hi as u32); + let next_item_span = Span::new(lo, hi, span.ctxt(), None); + + break next_item_span; + } + } + }; + + Ok(span) + }) + .ok() + .flatten() + } + + pub(crate) fn check_invalid_where_predicate_attrs<'attr>( + &self, + attrs: impl IntoIterator<Item = &'attr Attribute>, + ) { + // FIXME(where_clause_attrs): Currently, as the following check shows, + // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed + // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`) + // in where clauses. After that, this function would become useless. + let spans = attrs + .into_iter() + // FIXME: We shouldn't need to special-case `doc`! + .filter(|attr| { + matches!( + attr, + Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_)) + | Attribute::Unparsed(_) + ) + }) + .map(|attr| attr.span()) + .collect::<Vec<_>>(); + if !spans.is_empty() { + self.dcx() + .emit_err(UnsupportedAttributesInWhere { span: MultiSpan::from_spans(spans) }); + } + } } /// Takes a list of `allowed_targets` for an attribute, and the `target` the attribute was applied to.
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7bbce73..cddb37c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -588,8 +588,6 @@ fn visit_pat(&mut self, p: &'hir hir::Pat<'hir>) { } // for dbg!(x) which may take ownership, suggest dbg!(&x) instead - // but here we actually do not check whether the macro name is `dbg!` - // so that we may extend the scope a bit larger to cover more cases fn suggest_ref_for_dbg_args( &self, body: &hir::Expr<'_>, @@ -603,29 +601,41 @@ fn suggest_ref_for_dbg_args( }); let Some(var_info) = var_info else { return }; let arg_name = var_info.name; - struct MatchArgFinder { - expr_span: Span, - match_arg_span: Option<Span>, + struct MatchArgFinder<'tcx> { + tcx: TyCtxt<'tcx>, + move_span: Span, arg_name: Symbol, + match_arg_span: Option<Span> = None, } - impl Visitor<'_> for MatchArgFinder { + impl Visitor<'_> for MatchArgFinder<'_> { fn visit_expr(&mut self, e: &hir::Expr<'_>) { // dbg! is expanded into a match pattern, we need to find the right argument span - if let hir::ExprKind::Match(expr, ..) = &e.kind - && let hir::ExprKind::Path(hir::QPath::Resolved( - _, - path @ Path { segments: [seg], .. }, - )) = &expr.kind - && seg.ident.name == self.arg_name - && self.expr_span.source_callsite().contains(expr.span) + if let hir::ExprKind::Match(scrutinee, ..) = &e.kind + && let hir::ExprKind::Tup(args) = scrutinee.kind + && e.span.macro_backtrace().any(|expn| { + expn.macro_def_id.is_some_and(|macro_def_id| { + self.tcx.is_diagnostic_item(sym::dbg_macro, macro_def_id) + }) + }) { - self.match_arg_span = Some(path.span); + for arg in args { + if let hir::ExprKind::Path(hir::QPath::Resolved( + _, + path @ Path { segments: [seg], .. }, + )) = &arg.kind + && seg.ident.name == self.arg_name + && self.move_span.source_equal(arg.span) + { + self.match_arg_span = Some(path.span); + return; + } + } } hir::intravisit::walk_expr(self, e); } } - let mut finder = MatchArgFinder { expr_span: move_span, match_arg_span: None, arg_name }; + let mut finder = MatchArgFinder { tcx: self.infcx.tcx, move_span, arg_name, .. }; finder.visit_expr(body); if let Some(macro_arg_span) = finder.match_arg_span { err.span_suggestion_verbose( @@ -1569,10 +1579,8 @@ fn suggest_adding_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, def_id: DefId, let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id()); - let Some(hir_generics) = tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| tcx.hir_get_generics(def_id)) + let Some(hir_generics) = + tcx.hir_get_generics(tcx.typeck_root_def_id_local(self.mir_def_id())) else { return; };
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 8b4bda8..86d7119 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1274,12 +1274,9 @@ fn explain_captures( if let ty::Param(param_ty) = *self_ty.kind() && let generics = self.infcx.tcx.generics_of(self.mir_def_id()) && let param = generics.type_param(param_ty, self.infcx.tcx) - && let Some(hir_generics) = self - .infcx - .tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| self.infcx.tcx.hir_get_generics(def_id)) + && let Some(hir_generics) = self.infcx.tcx.hir_get_generics( + self.infcx.tcx.typeck_root_def_id_local(self.mir_def_id()), + ) && let spans = hir_generics .predicates .iter()
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 152a767..e2d684e 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -616,9 +616,4 @@ fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { } })]); } - - fn try_eagerly_normalize_alias(&mut self, _alias: ty::AliasTy<'tcx>) -> Ty<'tcx> { - // Past hir typeck, so we don't have to worry about type inference anymore. - self.type_checker.infcx.next_ty_var(self.span()) - } }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index aeba5ee..e96c6c7 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -476,12 +476,10 @@ fn build(self) -> UniversalRegions<'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); - // If this is a 'root' body (not a closure/coroutine/inline const), then // there are no extern regions, so the local regions start at the same // position as the (empty) sub-list of extern regions - let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { + let first_local_index = if !self.infcx.tcx.is_typeck_child(self.mir_def.to_def_id()) { first_extern_index } else { // If this is a closure, coroutine, or inline-const, then the late-bound regions from the enclosing @@ -583,7 +581,7 @@ fn build(self) -> UniversalRegions<'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { @@ -614,7 +612,7 @@ fn defining_ty(&self) -> DefiningTy<'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id { + if self.mir_def == typeck_root_def_id { let args = self.infcx.replace_free_regions_with_nll_infer_vars( NllRegionVariableOrigin::FreeRegion, identity_args, @@ -660,7 +658,7 @@ fn compute_indices( defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); let renumbered_args = defining_ty.args(); @@ -948,16 +946,14 @@ fn for_each_late_bound_region_in_recursive_scope<'tcx>( mut mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id()); - // Walk up the tree, collecting late-bound regions until we hit the typeck root loop { for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f); - if mir_def_id.to_def_id() == typeck_root_def_id { - break; - } else { + if tcx.is_typeck_child(mir_def_id.to_def_id()) { mir_def_id = tcx.local_parent(mir_def_id); + } else { + break; } } }
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 30391e7..afa393a 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -224,16 +224,18 @@ pub(crate) fn expand_with_mode( } _ => None, }, - Annotatable::AssocItem(assoc_item, Impl { of_trait: _ }) => match &assoc_item.kind { - ast::AssocItemKind::Fn(box ast::Fn { sig, ident, generics, .. }) => Some(( - assoc_item.vis.clone(), - sig.clone(), - ident.clone(), - generics.clone(), - true, - )), - _ => None, - }, + Annotatable::AssocItem(assoc_item, _ctxt @ (Impl { of_trait: _ } | Trait)) => { + match &assoc_item.kind { + ast::AssocItemKind::Fn(box ast::Fn { sig, ident, generics, .. }) => Some(( + assoc_item.vis.clone(), + sig.clone(), + ident.clone(), + generics.clone(), + true, + )), + _ => None, + } + } _ => None, }) else { dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); @@ -393,14 +395,14 @@ fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool { } Annotatable::Item(iitem.clone()) } - Annotatable::AssocItem(ref mut assoc_item, i @ Impl { .. }) => { + Annotatable::AssocItem(ref mut assoc_item, ctxt @ (Impl { .. } | Trait)) => { if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) { assoc_item.attrs.push(attr); } if assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) { has_inline_never = true; } - Annotatable::AssocItem(assoc_item.clone(), i) + Annotatable::AssocItem(assoc_item.clone(), ctxt) } Annotatable::Stmt(ref mut stmt) => { match stmt.kind { @@ -441,7 +443,7 @@ fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool { } let d_annotatable = match &item { - Annotatable::AssocItem(_, _) => { + Annotatable::AssocItem(_, ctxt) => { let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(d_fn); let d_fn = Box::new(ast::AssocItem { attrs: d_attrs, @@ -451,7 +453,7 @@ fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool { kind: assoc_item, tokens: None, }); - Annotatable::AssocItem(d_fn, Impl { of_trait: false }) + Annotatable::AssocItem(d_fn, *ctxt) } Annotatable::Item(_) => { let mut d_fn = ecx.item(span, d_attrs, ItemKind::Fn(d_fn));
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 1bce3c0..85ad8a63 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -180,7 +180,7 @@ fn usize(&self) -> Box<Ty> { } fn ptr_alignment(&self) -> Box<Ty> { - let path = self.cx.std_path(&[sym::ptr, sym::Alignment]); + let path = self.cx.std_path(&[sym::mem, sym::Alignment]); let path = self.cx.path(self.span, path); self.cx.ty_path(path) }
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml index 3367562..c11fc59 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
@@ -43,7 +43,7 @@ # TARGET_TRIPLE: x86_64-pc-windows-gnu steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features if: matrix.os == 'ubuntu-latest' @@ -56,7 +56,7 @@ run: .github/scripts/free-disk-space.sh - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml deleted file mode 100644 index 95a4dcd..0000000 --- a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml +++ /dev/null
@@ -1,18 +0,0 @@ -name: Security audit -on: - workflow_dispatch: - schedule: - - cron: '0 10 * * 1' # every monday at 10:00 UTC -permissions: - issues: write - checks: write -jobs: - audit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: | - sed -i 's/components.*/components = []/' rust-toolchain.toml - - uses: rustsec/audit-check@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml index 07d9af4..7f9fd0c 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -19,12 +19,22 @@ RUSTFLAGS: "-Dwarnings" jobs: + todo_check: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v6 + + - name: Check todo + run: ./y.sh check-todo + rustfmt: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Avoid installing rustc-dev run: | @@ -78,14 +88,14 @@ TARGET_TRIPLE: x86_64-pc-windows-gnu steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features if: matrix.os == 'ubuntu-latest' run: cat /proc/cpuinfo - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} @@ -127,7 +137,7 @@ timeout-minutes: 60 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features run: cat /proc/cpuinfo @@ -149,13 +159,13 @@ timeout-minutes: 60 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features run: cat /proc/cpuinfo - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} @@ -201,10 +211,10 @@ TARGET_TRIPLE: x86_64-pc-windows-gnu steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} @@ -223,7 +233,7 @@ run: tar cvfJ cg_clif.tar.xz dist - name: Upload prebuilt cg_clif - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: cg_clif-${{ matrix.env.TARGET_TRIPLE }} path: cg_clif.tar.xz @@ -232,7 +242,7 @@ runs-on: ubuntu-latest timeout-minutes: 10 if: ${{ github.ref == 'refs/heads/main' }} - needs: [rustfmt, test, bench, dist] + needs: [todo_check, rustfmt, test, bench, dist] permissions: contents: write # for creating the dev tag and release @@ -242,7 +252,7 @@ cancel-in-progress: true steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Download all built artifacts uses: actions/download-artifact@v4
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml index b22725f..0f91bc1 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -11,13 +11,13 @@ timeout-minutes: 60 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features run: cat /proc/cpuinfo - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} @@ -31,13 +31,13 @@ timeout-minutes: 60 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: CPU features run: cat /proc/cpuinfo - name: Cache cargo target dir - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: build/cg_clif key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index afc1d0d..2d84d2c 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -28,9 +28,9 @@ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" dependencies = [ "allocator-api2", ] @@ -43,42 +43,46 @@ [[package]] name = "cranelift-assembler-x64" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0377b13bf002a0774fcccac4f1102a10f04893d24060cf4b7350c87e4cbb647c" +checksum = "4f248321c6a7d4de5dcf2939368e96a397ad3f53b6a076e38d0104d1da326d37" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa027979140d023b25bf7509fb7ede3a54c3d3871fb5ead4673c4b633f671a2" +checksum = "ab6d78ff1f7d9bf8b7e1afbedbf78ba49e38e9da479d4c8a2db094e22f64e2bc" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618e4da87d9179a70b3c2f664451ca8898987aa6eb9f487d16988588b5d8cc40" +checksum = "6b6005ba640213a5b95382aeaf6b82bf028309581c8d7349778d66f27dc1180b" dependencies = [ "cranelift-entity", + "wasmtime-internal-core", ] [[package]] name = "cranelift-bitset" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db53764b5dad233b37b8f5dc54d3caa9900c54579195e00f17ea21f03f71aaa7" +checksum = "81fb5b134a12b559ff0c0f5af0fcd755ad380723b5016c4e0d36f74d39485340" +dependencies = [ + "wasmtime-internal-core", +] [[package]] name = "cranelift-codegen" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae927f1d8c0abddaa863acd201471d56e7fc6c3925104f4861ed4dc3e28b421" +checksum = "85837de8be7f17a4034a6b08816f05a3144345d2091937b39d415990daca28f4" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -90,21 +94,22 @@ "cranelift-entity", "cranelift-isle", "gimli", - "hashbrown", + "hashbrown 0.16.1", + "libm", "log", "regalloc2", "rustc-hash", "serde", "smallvec", "target-lexicon", - "wasmtime-internal-math", + "wasmtime-internal-core", ] [[package]] name = "cranelift-codegen-meta" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fcf1e3e6757834bd2584f4cbff023fcc198e9279dcb5d684b4bb27a9b19f54" +checksum = "e433faa87d38e5b8ff469e44a26fea4f93e58abd7a7c10bad9810056139700c9" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +119,34 @@ [[package]] name = "cranelift-codegen-shared" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "205dcb9e6ccf9d368b7466be675ff6ee54a63e36da6fe20e72d45169cf6fd254" +checksum = "5397ba61976e13944ca71230775db13ee1cb62849701ed35b753f4761ed0a9b7" [[package]] name = "cranelift-control" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "108eca9fcfe86026054f931eceaf57b722c1b97464bf8265323a9b5877238817" +checksum = "cc81c88765580720eb30f4fc2c1bfdb75fcbf3094f87b3cd69cecca79d77a245" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d96496910065d3165f84ff8e1e393916f4c086f88ac8e1b407678bc78735aa" +checksum = "463feed5d46cf8763f3ba3045284cf706dd161496e20ec9c14afbb4ba09b9e66" dependencies = [ "cranelift-bitset", + "wasmtime-internal-core", ] [[package]] name = "cranelift-frontend" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e303983ad7e23c850f24d9c41fc3cb346e1b930f066d3966545e4c98dac5c9fb" +checksum = "a4c5eca7696c1c04ab4c7ed8d18eadbb47d6cc9f14ec86fe0881bf1d7e97e261" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +156,15 @@ [[package]] name = "cranelift-isle" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b0cf8d867d891245836cac7abafb0a5b0ea040a019d720702b3b8bcba40bfa" +checksum = "f1153844610cc9c6da8cf10ce205e45da1a585b7688ed558aa808bbe2e4e6d77" [[package]] name = "cranelift-jit" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf1e35da6eca2448395f483eb172ce71dd7842f7dc96f44bb8923beafe43c6d" +checksum = "41836de8321b303d3d4188e58cc09c30c7645337342acfcfb363732695cae098" dependencies = [ "anyhow", "cranelift-codegen", @@ -176,9 +182,9 @@ [[package]] name = "cranelift-module" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "792ba2a54100e34f8a36e3e329a5207cafd1f0918a031d34695db73c163fdcc7" +checksum = "b731f66cb1b69b60a74216e632968ebdbb95c488d26aa1448ec226ae0ffec33e" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +193,9 @@ [[package]] name = "cranelift-native" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24b641e315443e27807b69c440fe766737d7e718c68beb665a2d69259c77bf3" +checksum = "a97b583fe9a60f06b0464cee6be5a17f623fd91b217aaac99b51b339d19911af" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +204,9 @@ [[package]] name = "cranelift-object" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecba1f219a201cf946150538e631defd620c5051b62c52ecb89a0004bab263d4" +checksum = "9809d2d419cd18f17377f4ce64a7ad22eeda0d042c08833d3796657f1ddebc82" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +219,9 @@ [[package]] name = "cranelift-srcgen" -version = "0.128.3" +version = "0.130.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e378a54e7168a689486d67ee1f818b7e5356e54ae51a1d7a53f4f13f7f8b7a" +checksum = "8594dc6bb4860fa8292f1814c76459dbfb933e1978d8222de6380efce45c7cee" [[package]] name = "crc32fast" @@ -233,24 +239,25 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "fallible-iterator" -version = "0.3.0" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "gimli" -version = "0.32.3" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" dependencies = [ - "fallible-iterator", + "fnv", + "hashbrown 0.16.1", "indexmap", "stable_deref_trait", ] @@ -260,6 +267,12 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "foldhash", ] @@ -272,12 +285,12 @@ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -325,12 +338,12 @@ [[package]] name = "object" -version = "0.37.3" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc" dependencies = [ "crc32fast", - "hashbrown", + "hashbrown 0.16.1", "indexmap", "memchr", ] @@ -355,13 +368,13 @@ [[package]] name = "regalloc2" -version = "0.13.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08effbc1fa53aaebff69521a5c05640523fab037b34a4a2c109506bc938246fa" +checksum = "952ddbfc6f9f64d006c3efd8c9851a6ba2f2b944ba94730db255d55006e0ffda" dependencies = [ "allocator-api2", "bumpalo", - "hashbrown", + "hashbrown 0.15.5", "log", "rustc-hash", "smallvec", @@ -468,24 +481,25 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] -name = "wasmtime-internal-jit-icache-coherence" -version = "41.0.3" +name = "wasmtime-internal-core" +version = "43.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bada5ca1cc47df7d14100e2254e187c2486b426df813cea2dd2553a7469f7674" +checksum = "e671917bb6856ae360cb59d7aaf26f1cfd042c7b924319dd06fd380739fc0b2e" dependencies = [ - "anyhow", - "cfg-if", - "libc", - "windows-sys 0.61.2", + "hashbrown 0.16.1", + "libm", ] [[package]] -name = "wasmtime-internal-math" -version = "41.0.3" +name = "wasmtime-internal-jit-icache-coherence" +version = "43.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf6f615d528eda9adc6eefb062135f831b5215c348f4c3ec3e143690c730605b" +checksum = "9b3112806515fac8495883885eb8dbdde849988ae91fe6beb544c0d7c0f4c9aa" dependencies = [ - "libm", + "cfg-if", + "libc", + "wasmtime-internal-core", + "windows-sys 0.61.2", ] [[package]]
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index a7b4664..6707557 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,15 +8,15 @@ [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.128.3", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.128.3" } -cranelift-module = { version = "0.128.3" } -cranelift-native = { version = "0.128.3" } -cranelift-jit = { version = "0.128.3", optional = true } -cranelift-object = { version = "0.128.3" } +cranelift-codegen = { version = "0.130.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.130.0" } +cranelift-module = { version = "0.130.0" } +cranelift-native = { version = "0.130.0" } +cranelift-jit = { version = "0.130.0", optional = true } +cranelift-object = { version = "0.130.0" } target-lexicon = "0.13" -gimli = { version = "0.32", default-features = false, features = ["write"] } -object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +gimli = { version = "0.33", default-features = false, features = ["write"] } +object = { version = "0.38.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.9.0", optional = true } @@ -24,12 +24,12 @@ [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-41.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
diff --git a/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs index 6251687..0720d72 100644 --- a/compiler/rustc_codegen_cranelift/build_system/main.rs +++ b/compiler/rustc_codegen_cranelift/build_system/main.rs
@@ -17,6 +17,7 @@ mod rustc_info; mod shared_utils; mod tests; +mod todo; mod utils; fn usage() { @@ -38,6 +39,7 @@ enum Command { Test, AbiCafe, Bench, + CheckTodo, } #[derive(Copy, Clone, Debug)] @@ -66,6 +68,7 @@ fn main() { Some("test") => Command::Test, Some("abi-cafe") => Command::AbiCafe, Some("bench") => Command::Bench, + Some("check-todo") => Command::CheckTodo, Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag), Some(command) => arg_error!("Unknown command {}", command), None => { @@ -139,6 +142,10 @@ fn main() { process::exit(0); } + if command == Command::CheckTodo { + todo::run(); + } + let rustup_toolchain_name = match (env::var("CARGO"), env::var("RUSTC"), env::var("RUSTDOC")) { (Ok(_), Ok(_), Ok(_)) => None, (_, Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), @@ -202,7 +209,7 @@ fn main() { )) }; match command { - Command::Prepare => { + Command::Prepare | Command::CheckTodo => { // Handled above } Command::Test => {
diff --git a/compiler/rustc_codegen_cranelift/build_system/todo.rs b/compiler/rustc_codegen_cranelift/build_system/todo.rs new file mode 100644 index 0000000..66b31a1 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/build_system/todo.rs
@@ -0,0 +1,70 @@ +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::{fs, process}; + +const EXTENSIONS: &[&str] = + &["rs", "py", "js", "sh", "c", "cpp", "h", "md", "css", "ftl", "toml", "yml", "yaml"]; + +fn has_supported_extension(path: &Path) -> bool { + path.extension().is_some_and(|ext| EXTENSIONS.iter().any(|e| ext == OsStr::new(e))) +} + +fn list_tracked_files() -> Result<Vec<PathBuf>, String> { + let output = Command::new("git") + .args(["ls-files", "-z"]) + .output() + .map_err(|e| format!("Failed to run `git ls-files`: {e}"))?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + return Err(format!("`git ls-files` failed: {stderr}")); + } + + let mut files = Vec::new(); + for entry in output.stdout.split(|b| *b == 0) { + if entry.is_empty() { + continue; + } + let path = std::str::from_utf8(entry).unwrap(); + files.push(PathBuf::from(path)); + } + + Ok(files) +} + +pub(crate) fn run() -> ! { + let files = list_tracked_files().unwrap(); + let mut error_count = 0; + // Avoid embedding the task marker in source so greps only find real occurrences. + let todo_marker = "todo".to_ascii_uppercase(); + + for file in files { + if !has_supported_extension(&file) { + continue; + } + + let bytes = fs::read(&file).unwrap(); + let contents = std::str::from_utf8(&bytes).unwrap(); + + for (i, line) in contents.split('\n').enumerate() { + let trimmed = line.trim(); + if trimmed.contains(&todo_marker) { + eprintln!( + "{}:{}: {} is used for tasks that should be done before merging a PR; if you want to leave a message in the codebase use FIXME", + file.display(), + i + 1, + todo_marker + ); + error_count += 1; + } + } + } + + if error_count == 0 { + process::exit(0); + } + + eprintln!("found {} {}(s)", error_count, todo_marker); + process::exit(1); +}
diff --git a/compiler/rustc_codegen_cranelift/build_system/usage.txt b/compiler/rustc_codegen_cranelift/build_system/usage.txt index 6c98087..572fe78 100644 --- a/compiler/rustc_codegen_cranelift/build_system/usage.txt +++ b/compiler/rustc_codegen_cranelift/build_system/usage.txt
@@ -6,6 +6,7 @@ ./y.sh test [--sysroot none|clif|llvm] [--out-dir DIR] [--download-dir DIR] [--no-unstable-features] [--frozen] [--skip-test TESTNAME] ./y.sh abi-cafe [--sysroot none|clif|llvm] [--out-dir DIR] [--download-dir DIR] [--no-unstable-features] [--frozen] ./y.sh bench [--sysroot none|clif|llvm] [--out-dir DIR] [--download-dir DIR] [--no-unstable-features] [--frozen] + ./y.sh check-todo OPTIONS: --sysroot none|clif|llvm
diff --git a/compiler/rustc_codegen_cranelift/clean_all.sh b/compiler/rustc_codegen_cranelift/clean_all.sh index 4dbd9da..32ed193 100755 --- a/compiler/rustc_codegen_cranelift/clean_all.sh +++ b/compiler/rustc_codegen_cranelift/clean_all.sh
@@ -2,9 +2,3 @@ set -e rm -rf target/ build_system/target download/ build/ dist/ - -# Kept for now in case someone updates their checkout of cg_clif before running clean_all.sh -# FIXME remove at some point in the future -rm y.bin y.bin.dSYM y.exe y.pdb 2>/dev/null || true -rm -rf rand/ regex/ simple-raytracer/ portable-simd/ abi-checker/ abi-cafe/ -rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
diff --git a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs index b7491b7..206c56e 100644 --- a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs +++ b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
@@ -33,24 +33,24 @@ fn main() { let n = f32x4([nan, nan, nan, nan]); unsafe { - let min0 = simd_fmin(x, y); - let min1 = simd_fmin(y, x); + let min0 = simd_minimum_number_nsz(x, y); + let min1 = simd_minimum_number_nsz(y, x); assert_eq!(min0.into_array(), min1.into_array()); let e = f32x4([1.0, 1.0, 3.0, 3.0]); assert_eq!(min0.into_array(), e.into_array()); - let minn = simd_fmin(x, n); + let minn = simd_minimum_number_nsz(x, n); assert_eq!(minn.into_array(), x.into_array()); - let minn = simd_fmin(y, n); + let minn = simd_minimum_number_nsz(y, n); assert_eq!(minn.into_array(), y.into_array()); - let max0 = simd_fmax(x, y); - let max1 = simd_fmax(y, x); + let max0 = simd_maximum_number_nsz(x, y); + let max1 = simd_maximum_number_nsz(y, x); assert_eq!(max0.into_array(), max1.into_array()); let e = f32x4([2.0, 2.0, 4.0, 4.0]); assert_eq!(max0.into_array(), e.into_array()); - let maxn = simd_fmax(x, n); + let maxn = simd_maximum_number_nsz(x, n); assert_eq!(maxn.into_array(), x.into_array()); - let maxn = simd_fmax(y, n); + let maxn = simd_maximum_number_nsz(y, n); assert_eq!(maxn.into_array(), y.into_array()); } }
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 5293b45..2180509 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -9,9 +9,9 @@ rustc_private, transparent_unions, auto_traits, - freeze_impls, - thread_local + freeze_impls )] +#![cfg_attr(not(all(windows, target_env = "gnu")), feature(thread_local))] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)]
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 10549cd..6734d19 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -1,13 +1,5 @@ -#![feature( - no_core, - lang_items, - never_type, - linkage, - extern_types, - thread_local, - repr_simd, - rustc_private -)] +#![feature(no_core, lang_items, never_type, extern_types, thread_local, repr_simd, rustc_private)] +#![cfg_attr(not(any(jit, target_vendor = "apple", windows)), feature(linkage))] #![no_core] #![allow(dead_code, non_camel_case_types, internal_features)]
diff --git a/compiler/rustc_codegen_cranelift/example/neon.rs b/compiler/rustc_codegen_cranelift/example/neon.rs index fb3e10a..98a2a7a 100644 --- a/compiler/rustc_codegen_cranelift/example/neon.rs +++ b/compiler/rustc_codegen_cranelift/example/neon.rs
@@ -1,6 +1,6 @@ // Most of these tests are copied from https://github.com/japaric/stdsimd/blob/0f4413d01c4f0c3ffbc5a69e9a37fbc7235b31a9/coresimd/arm/neon.rs -#![feature(portable_simd)] +#![cfg_attr(target_arch = "aarch64", feature(portable_simd))] #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*;
diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index 33db75f..f0e38ae 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs
@@ -1,15 +1,9 @@ -#![feature( - core_intrinsics, - coroutines, - stmt_expr_attributes, - coroutine_trait, - repr_simd, - tuple_trait, - unboxed_closures -)] +#![feature(core_intrinsics, coroutines, coroutine_trait, repr_simd, tuple_trait, unboxed_closures)] #![allow(internal_features)] #[cfg(target_arch = "x86_64")] +use std::arch::asm; +#[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; use std::hint::black_box; use std::io::Write; @@ -173,6 +167,9 @@ enum Never {} rust_call_abi(); + // #[cfg(target_arch = "x86_64")] + // inline_asm_call_custom_abi(); + const fn no_str() -> Option<Box<str>> { None } @@ -279,6 +276,17 @@ unsafe fn test_simd() { #[cfg(not(jit))] test_crc32(); + + #[cfg(not(jit))] + test_xmm_roundtrip(); + #[cfg(not(jit))] + if is_x86_feature_detected!("avx") { + test_ymm_roundtrip(); + } + #[cfg(not(jit))] + if is_x86_feature_detected!("avx512f") { + test_zmm_roundtrip(); + } } } @@ -576,6 +584,65 @@ unsafe fn test_mm_cvtps_ph() { assert_eq_m128i(r, e); } +#[cfg(target_arch = "x86_64")] +#[cfg(not(jit))] +unsafe fn test_xmm_roundtrip() { + unsafe { + let input = [1u8; 16]; + let mut output = [0u8; 16]; + + asm!( + "movups {xmm}, [{input}]", + "movups [{output}], {xmm}", + input = in(reg) input.as_ptr(), + output = in(reg) output.as_mut_ptr(), + xmm = out(xmm_reg) _, + ); + + assert_eq!(input, output); + } +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx")] +#[cfg(not(jit))] +unsafe fn test_ymm_roundtrip() { + unsafe { + let input = [1u8; 32]; + let mut output = [0u8; 32]; + + asm!( + "vmovups {ymm}, [{input}]", + "vmovups [{output}], {ymm}", + input = in(reg) input.as_ptr(), + output = in(reg) output.as_mut_ptr(), + ymm = out(ymm_reg) _, + ); + + assert_eq!(input, output); + } +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx512f")] +#[cfg(not(jit))] +unsafe fn test_zmm_roundtrip() { + unsafe { + let input = [1u8; 64]; + let mut output = [0u8; 64]; + + asm!( + "vmovups {zmm}, [{input}]", + "vmovups [{output}], {zmm}", + input = in(reg) input.as_ptr(), + output = in(reg) output.as_mut_ptr(), + zmm = out(zmm_reg) _, + ); + + assert_eq!(input, output); + } +} + fn test_checked_mul() { let u: Option<u8> = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); @@ -614,3 +681,18 @@ fn map(a: Option<(u8, Box<Instruction>)>) -> Option<Box<Instruction>> { Some((_, instr)) => Some(instr), } } + +// FIXME enable once inline asm sym references are stabilized in cg_clif +// #[cfg(target_arch = "x86_64")] +// fn inline_asm_call_custom_abi() { +// use std::arch::{asm, naked_asm}; +// +// #[unsafe(naked)] +// unsafe extern "custom" fn double() { +// naked_asm!("add rax, rax", "ret"); +// } +// +// let mut x: u64 = 21; +// unsafe { asm!("call {}", sym double, inout("rax") x) }; +// assert_eq!(x, 42); +// }
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch index 38bb43f..b7276e4 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
@@ -37,16 +37,7 @@ index bf2b6d59f88..d5ccce03bbf 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs -@@ -300,8 +300,6 @@ impl_atomic_primitive!(AtomicI32(i32), size("32"), align(4)); - impl_atomic_primitive!(AtomicU32(u32), size("32"), align(4)); - impl_atomic_primitive!(AtomicI64(i64), size("64"), align(8)); - impl_atomic_primitive!(AtomicU64(u64), size("64"), align(8)); --impl_atomic_primitive!(AtomicI128(i128), size("128"), align(16)); --impl_atomic_primitive!(AtomicU128(u128), size("128"), align(16)); - - #[cfg(target_pointer_width = "16")] - impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(2)); -@@ -3585,44 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { +@@ -3585,42 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { 8, u64 AtomicU64 } @@ -62,7 +53,6 @@ - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- rustc_diagnostic_item = "AtomicI128", - "i128", - "#![feature(integer_atomics)]\n\n", - atomic_min, atomic_max, @@ -81,7 +71,6 @@ - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- rustc_diagnostic_item = "AtomicU128", - "u128", - "#![feature(integer_atomics)]\n\n", - atomic_umin, atomic_umax,
diff --git a/compiler/rustc_codegen_cranelift/patches/0028-stdlib-Ensure-va_end-doesn-t-get-emitted-unless-VaList-is-a.patch b/compiler/rustc_codegen_cranelift/patches/0028-stdlib-Ensure-va_end-doesn-t-get-emitted-unless-VaList-is-a.patch deleted file mode 100644 index 2aa9316..0000000 --- a/compiler/rustc_codegen_cranelift/patches/0028-stdlib-Ensure-va_end-doesn-t-get-emitted-unless-VaList-is-a.patch +++ /dev/null
@@ -1,25 +0,0 @@ -From 116abc64add4d617104993a7a3011f20bcf31ef2 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Mon, 26 Jan 2026 16:20:58 +0000 -Subject: [PATCH] Ensure va_end doesn't get emitted unless VaList is actually - used - ---- - library/core/src/ffi/va_list.rs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs -index d0f1553..75129af 100644 ---- a/library/core/src/ffi/va_list.rs -+++ b/library/core/src/ffi/va_list.rs -@@ -217,6 +217,7 @@ impl Clone for VaList<'_> { - - #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] - impl<'f> const Drop for VaList<'f> { -+ #[inline] - fn drop(&mut self) { - // SAFETY: this variable argument list is being dropped, so won't be read from again. - unsafe { va_end(self) } --- -2.43.0 -
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index fe967c8..d4bb9be 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain.toml +++ b/compiler/rustc_codegen_cranelift/rust-toolchain.toml
@@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2026-02-18" +channel = "nightly-2026-03-25" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal"
diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index bb9f69b..2ca0c3c 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
@@ -63,18 +63,18 @@ # Note that RUSTFLAGS_BOOTSTRAP should always be added to the end of # RUSTFLAGS, since that causes RUSTFLAGS_BOOTSTRAP to override RUSTFLAGS. diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs -index a656927b1f6..44fc5546fac 100644 +index bc68bfe396..00143ef3ed 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs -@@ -2249,7 +2249,7 @@ pub fn parse_download_ci_llvm<'a>( - } +@@ -2230,7 +2230,7 @@ pub fn download_ci_rustc_commit<'a>( + return None; + } - #[cfg(not(test))] -- if b && dwn_ctx.is_running_on_ci && CiEnv::is_rust_lang_managed_ci_job() { -+ if false && dwn_ctx.is_running_on_ci && CiEnv::is_rust_lang_managed_ci_job() { - // On rust-lang CI, we must always rebuild LLVM if there were any modifications to it - panic!( - "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead." +- if dwn_ctx.is_running_on_ci() { ++ if false && dwn_ctx.is_running_on_ci() { + eprintln!("CI rustc commit matches with HEAD and we are in CI."); + eprintln!( + "\`rustc.download-ci\` functionality will be skipped as artifacts are not available." diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 330fb465de..a4593ed96f 100644 --- a/src/build_helper/src/git.rs
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 8712b41..71ff4ee 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -20,7 +20,6 @@ done git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed -git checkout -- tests/ui/proc-macro/pretty-print-hack/ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs # missing features @@ -152,7 +151,6 @@ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump rm -r tests/run-make/strip # same rm -r tests/run-make-cargo/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source -rm -r tests/run-make/translation # same rm -r tests/run-make-cargo/panic-immediate-abort-works # same rm -r tests/run-make-cargo/panic-immediate-abort-codegen # same rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 79a3214..b855e1f 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -45,8 +45,8 @@ enum OngoingModuleCodegen { Async(JoinHandle<Result<ModuleCodegenResult, String>>), } -impl<HCX> HashStable<HCX> for OngoingModuleCodegen { - fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for OngoingModuleCodegen { + fn hash_stable(&self, _: &mut Hcx, _: &mut StableHasher) { // do nothing } }
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 1daf428..b149885 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -120,9 +120,15 @@ fn codegen_global_asm_inner<'tcx>( } let symbol = tcx.symbol_name(instance); + let symbol_name = if tcx.sess.target.is_like_darwin { + format!("_{}", symbol.name) + } else { + symbol.name.to_owned() + }; + // FIXME handle the case where the function was made private to the // current codegen unit - global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span)); + global_asm.push_str(&escape_symbol_name(tcx, &symbol_name, span)); } GlobalAsmOperandRef::SymStatic { def_id } => { if cfg!(not(feature = "inline_asm_sym")) { @@ -134,7 +140,13 @@ fn codegen_global_asm_inner<'tcx>( let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); - global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span)); + let symbol_name = if tcx.sess.target.is_like_darwin { + format!("_{}", symbol.name) + } else { + symbol.name.to_owned() + }; + + global_asm.push_str(&escape_symbol_name(tcx, &symbol_name, span)); } } }
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index ac0da06..8100d56 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -3,8 +3,10 @@ use std::fmt::Write; use cranelift_codegen::isa::CallConv; +use rustc_abi::CanonAbi; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::LangItem; +use rustc_middle::ty::layout::FnAbiOf; use rustc_span::sym; use rustc_target::asm::*; use rustc_target::spec::Arch; @@ -120,21 +122,30 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( .unwrap(); let symbol = fx.tcx.symbol_name(instance); - // Pass a wrapper rather than the function itself as the function itself may not - // be exported from the main codegen unit and may thus be unreachable from the - // object file created by an external assembler. - let wrapper_name = format!( - "{}__inline_asm_{}_wrapper_n{}", - fx.symbol_name, - fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.inline_asm_index, - ); - fx.inline_asm_index += 1; - let sig = - get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); - create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); + if FullyMonomorphizedLayoutCx(fx.tcx) + .fn_abi_of_instance(instance, ty::List::empty()) + .conv + == CanonAbi::Custom + { + // We can't create a wrapper for custom ABI functions. + CInlineAsmOperand::Symbol { symbol: symbol.name.to_owned() } + } else { + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let wrapper_name = format!( + "{}__inline_asm_{}_wrapper_n{}", + fx.symbol_name, + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.inline_asm_index, + ); + fx.inline_asm_index += 1; + let sig = + get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); + create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); - CInlineAsmOperand::Symbol { symbol: wrapper_name } + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } } else { span_bug!(span, "invalid type for asm sym (fn)"); } @@ -548,22 +559,21 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String { match self.arch { InlineAsmArch::X86_64 => match reg { InlineAsmReg::X86(reg) - if reg as u32 >= X86InlineAsmReg::xmm0 as u32 - && reg as u32 <= X86InlineAsmReg::xmm15 as u32 => + if matches!( + reg.reg_class(), + X86InlineAsmRegClass::xmm_reg + | X86InlineAsmRegClass::ymm_reg + | X86InlineAsmRegClass::zmm_reg + ) => { - // rustc emits x0 rather than xmm0 - let class = match *modifier { - None | Some('x') => "xmm", - Some('y') => "ymm", - Some('z') => "zmm", - _ => unreachable!(), - }; - write!( - generated_asm, - "{class}{}", - reg as u32 - X86InlineAsmReg::xmm0 as u32 - ) - .unwrap(); + // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0 + let name = reg.name(); + if let Some(prefix) = modifier { + let index = &name[3..]; + write!(generated_asm, "{prefix}mm{index}").unwrap(); + } else { + write!(generated_asm, "{name}").unwrap(); + } } _ => reg .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier) @@ -575,7 +585,13 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String { CInlineAsmOperand::Const { ref value } => { generated_asm.push_str(value); } - CInlineAsmOperand::Symbol { ref symbol } => generated_asm.push_str(symbol), + CInlineAsmOperand::Symbol { ref symbol } => { + if binary_format == BinaryFormat::Macho { + generated_asm.push('_'); + } + + generated_asm.push_str(symbol); + } } } } @@ -716,12 +732,17 @@ fn save_register( InlineAsmArch::X86_64 => { match reg { InlineAsmReg::X86(reg) - if reg as u32 >= X86InlineAsmReg::xmm0 as u32 - && reg as u32 <= X86InlineAsmReg::xmm15 as u32 => + if matches!( + reg.reg_class(), + X86InlineAsmRegClass::xmm_reg + | X86InlineAsmRegClass::ymm_reg + | X86InlineAsmRegClass::zmm_reg + ) => { - // rustc emits x0 rather than xmm0 - write!(generated_asm, " movups [rbx+0x{:x}], ", offset.bytes()).unwrap(); - write!(generated_asm, "xmm{}", reg as u32 - X86InlineAsmReg::xmm0 as u32) + // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0 + let name = reg.name(); + let mov = if name.starts_with("xmm") { "movups" } else { "vmovups" }; + write!(generated_asm, " {mov} [rbx+0x{:x}], {name}", offset.bytes()) .unwrap(); } _ => { @@ -761,16 +782,17 @@ fn restore_register( InlineAsmArch::X86_64 => { match reg { InlineAsmReg::X86(reg) - if reg as u32 >= X86InlineAsmReg::xmm0 as u32 - && reg as u32 <= X86InlineAsmReg::xmm15 as u32 => + if matches!( + reg.reg_class(), + X86InlineAsmRegClass::xmm_reg + | X86InlineAsmRegClass::ymm_reg + | X86InlineAsmRegClass::zmm_reg + ) => { - // rustc emits x0 rather than xmm0 - write!( - generated_asm, - " movups xmm{}", - reg as u32 - X86InlineAsmReg::xmm0 as u32 - ) - .unwrap(); + // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0 + let name = reg.name(); + let mov = if name.starts_with("xmm") { "movups" } else { "vmovups" }; + write!(generated_asm, " {mov} {name}").unwrap(); } _ => { generated_asm.push_str(" mov ");
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 8b112e6..780550f 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -346,10 +346,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), sym::log10f128 => ("log10f128", 1, fx.tcx.types.f128, types::F128), - sym::fabsf16 => ("fabsf16", 1, fx.tcx.types.f16, types::F16), - sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32), - sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64), - sym::fabsf128 => ("fabsf128", 1, fx.tcx.types.f128, types::F128), sym::fmaf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), @@ -441,11 +437,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf32 | sym::copysignf64 => { CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) } - sym::fabsf16 => CValue::by_val(codegen_f16_f128::abs_f16(fx, args[0]), layout), - sym::fabsf128 => CValue::by_val(codegen_f16_f128::abs_f128(fx, args[0]), layout), - sym::fabsf32 - | sym::fabsf64 - | sym::floorf32 + sym::floorf32 | sym::floorf64 | sym::ceilf32 | sym::ceilf64 @@ -456,7 +448,6 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { - sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]), sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), @@ -1179,6 +1170,28 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, old); } + sym::fabs => { + intrinsic_args!(fx, args => (arg); intrinsic); + let layout = arg.layout(); + let ty::Float(float_ty) = layout.ty.kind() else { + span_bug!( + source_info.span, + "expected float type for fabs intrinsic: {:?}", + layout.ty + ); + }; + let x = arg.load_scalar(fx); + let val = match float_ty { + FloatTy::F32 | FloatTy::F64 => fx.bcx.ins().fabs(x), + // FIXME(bytecodealliance/wasmtime#8312): Use `fabsf16` once Cranelift + // backend lowerings are implemented. + FloatTy::F16 => codegen_f16_f128::abs_f16(fx, x), + FloatTy::F128 => codegen_f16_f128::abs_f128(fx, x), + }; + let val = CValue::by_val(val, layout); + ret.write_cvalue(fx, val); + } + sym::minimumf16 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 200cedf..cc2311a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -493,7 +493,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( } } - sym::simd_fmin | sym::simd_fmax => { + sym::simd_minimum_number_nsz | sym::simd_maximum_number_nsz => { intrinsic_args!(fx, args => (x, y); intrinsic); if !x.layout().ty.is_simd() { @@ -508,8 +508,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => unreachable!("{:?}", lane_ty), } match intrinsic { - sym::simd_fmin => crate::num::codegen_float_min(fx, x_lane, y_lane), - sym::simd_fmax => crate::num::codegen_float_max(fx, x_lane, y_lane), + sym::simd_minimum_number_nsz => { + crate::num::codegen_float_min(fx, x_lane, y_lane) + } + sym::simd_maximum_number_nsz => { + crate::num::codegen_float_max(fx, x_lane, y_lane) + } _ => unreachable!(), } });
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 82c2e91..cbbb0cc 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -46,7 +46,7 @@ use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; -use rustc_target::spec::{Abi, Arch, Env, Os}; +use rustc_target::spec::{Arch, CfgAbi, Env, Os}; pub use crate::config::*; use crate::prelude::*; @@ -178,7 +178,7 @@ fn target_config(&self, sess: &Session) -> TargetConfig { let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 && sess.target.os == Os::Windows && sess.target.env == Env::Gnu - && sess.target.abi != Abi::Llvm); + && sess.target.cfg_abi != CfgAbi::Llvm); // FIXME(f128): f128 math operations need f128 math symbols, which currently aren't always // filled in by compiler-builtins. The only libc that provides these currently is glibc.
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index 0459644..e583f3f 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -500,8 +500,8 @@ fn codegen_ptr_binop<'tcx>( // In Rust floating point min and max don't propagate NaN (not even SNaN). In Cranelift they do // however. For this reason it is necessary to use `a.is_nan() ? b : (a >= b ? b : a)` for -// `minnumf*` and `a.is_nan() ? b : (a <= b ? b : a)` for `maxnumf*`. NaN checks are done by -// comparing a float against itself. Only in case of NaN is it not equal to itself. +// `minimum_number_nsz` and `a.is_nan() ? b : (a <= b ? b : a)` for `maximum_number_nsz`. NaN checks +// are done by comparing a float against itself. Only in case of NaN is it not equal to itself. pub(crate) fn codegen_float_min(fx: &mut FunctionCx<'_, '_, '_>, a: Value, b: Value) -> Value { // FIXME(bytecodealliance/wasmtime#8312): Replace with Cranelift `fcmp` once // `f16`/`f128` backend lowerings have been added to Cranelift.
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 6add7f0..1d6d776 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1656,10 +1656,6 @@ fn catch_switch( unimplemented!(); } - fn get_funclet_cleanuppad(&self, _funclet: &Funclet) -> RValue<'gcc> { - unimplemented!(); - } - // Atomic Operations fn atomic_cmpxchg( &mut self, @@ -2278,6 +2274,8 @@ pub fn vector_reduce_max(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { }) } + /// Emits a SIMD min/max operation for floats. The semantics for each lane are: if one + /// side is NaN (QNaN or SNaN), the other side is returned. fn vector_extremum( &mut self, a: RValue<'gcc>, @@ -2286,8 +2284,9 @@ fn vector_extremum( ) -> RValue<'gcc> { let vector_type = a.get_type(); - // mask out the NaNs in b and replace them with the corresponding lane in a, so when a and - // b get compared & spliced together, we get the numeric values instead of NaNs. + // Mask out the NaNs (both QNaN and SNaN) in b and replace them with the corresponding lane + // in a, so when a and b get compared & spliced together, we get the numeric values instead + // of NaNs. let b_nan_mask = self.context.new_comparison(self.location, ComparisonOp::NotEquals, b, b); let mask_type = b_nan_mask.get_type(); let b_nan_mask_inverted = @@ -2309,7 +2308,7 @@ fn vector_extremum( self.context.new_bitcast(self.location, res, vector_type) } - pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_minimum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.vector_extremum(a, b, ExtremumOperation::Min) } @@ -2341,7 +2340,7 @@ pub fn vector_reduce_fmin(&mut self, _src: RValue<'gcc>) -> RValue<'gcc> { unimplemented!(); } - pub fn vector_fmax(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_maximum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.vector_extremum(a, b, ExtremumOperation::Max) }
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 3f1b33c..83ac627 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -23,11 +23,11 @@ IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; use rustc_data_structures::fx::FxHashSet; -use rustc_middle::bug; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_target::callconv::{ArgAbi, PassMode}; @@ -70,8 +70,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation sym::fmuladdf32 => "fmaf", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f32 sym::fmuladdf64 => "fma", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f64 - sym::fabsf32 => "fabsf", - sym::fabsf64 => "fabs", sym::minimumf32 => "fminimumf", sym::minimumf64 => "fminimum", sym::minimumf128 => { @@ -194,58 +192,29 @@ fn get_simple_function<'gcc, 'tcx>( } fn get_simple_function_f128<'gcc, 'tcx>( + span: Span, cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, -) -> Option<Function<'gcc>> { - if !cx.supports_f128_type { - return None; - } - +) -> Function<'gcc> { let f128_type = cx.type_f128(); let func_name = match name { sym::ceilf128 => "ceilf128", - sym::fabsf128 => "fabsf128", + sym::fabs => "fabsf128", sym::floorf128 => "floorf128", sym::truncf128 => "truncf128", sym::roundf128 => "roundf128", sym::round_ties_even_f128 => "roundevenf128", sym::sqrtf128 => "sqrtf128", - _ => return None, + _ => span_bug!(span, "used get_simple_function_f128 for non-unary f128 intrinsic"), }; - Some(cx.context.new_function( + cx.context.new_function( None, FunctionType::Extern, f128_type, &[cx.context.new_parameter(None, f128_type, "a")], func_name, false, - )) -} - -fn get_simple_function_f128_2args<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, -) -> Option<Function<'gcc>> { - if !cx.supports_f128_type { - return None; - } - - let f128_type = cx.type_f128(); - let func_name = match name { - sym::copysignf128 => "copysignf128", - _ => return None, - }; - Some(cx.context.new_function( - None, - FunctionType::Extern, - f128_type, - &[ - cx.context.new_parameter(None, f128_type, "a"), - cx.context.new_parameter(None, f128_type, "b"), - ], - func_name, - false, - )) + ) } fn f16_builtin<'gcc, 'tcx>( @@ -257,7 +226,7 @@ fn f16_builtin<'gcc, 'tcx>( let builtin_name = match name { sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", - sym::fabsf16 => "fabsf", + sym::fabs => "fabsf", sym::floorf16 => "__builtin_floorf", sym::fmaf16 => "fmaf", sym::powf16 => "__builtin_powf", @@ -297,11 +266,7 @@ fn codegen_intrinsic_call( let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); - // FIXME(antoyo): Only call get_simple_function_f128 and get_simple_function_f128_2args when - // it is the symbols for the supported f128 builtins. - let simple_func = get_simple_function(self, name) - .or_else(|| get_simple_function_f128(self, name)) - .or_else(|| get_simple_function_f128_2args(self, name)); + let simple_func = get_simple_function(self, name); let value = match name { _ if simple.is_some() => { @@ -322,7 +287,6 @@ fn codegen_intrinsic_call( } sym::ceilf16 | sym::copysignf16 - | sym::fabsf16 | sym::floorf16 | sym::fmaf16 | sym::powf16 @@ -331,6 +295,40 @@ fn codegen_intrinsic_call( | sym::round_ties_even_f16 | sym::sqrtf16 | sym::truncf16 => f16_builtin(self, name, args), + sym::ceilf128 + | sym::floorf128 + | sym::truncf128 + | sym::roundf128 + | sym::round_ties_even_f128 + | sym::sqrtf128 + if self.cx.supports_f128_type => + { + let func = get_simple_function_f128(span, self, name); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), + ) + } + sym::copysignf128 if self.cx.supports_f128_type => { + let f128_type = self.cx.type_f128(); + let func = self.cx.context.new_function( + None, + FunctionType::Extern, + f128_type, + &[ + self.cx.context.new_parameter(None, f128_type, "a"), + self.cx.context.new_parameter(None, f128_type, "b"), + ], + "copysignf128", + false, + ); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), + ) + } sym::fmaf128 => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( @@ -488,6 +486,23 @@ fn codegen_intrinsic_call( } } } + sym::fabs => 'fabs: { + let ty = args[0].layout.ty; + let ty::Float(float_ty) = *ty.kind() else { + span_bug!(span, "expected float type for fabs intrinsic: {:?}", ty); + }; + let func = match float_ty { + ty::FloatTy::F16 => break 'fabs f16_builtin(self, name, args), + ty::FloatTy::F32 => self.context.get_builtin_function("fabsf"), + ty::FloatTy::F64 => self.context.get_builtin_function("fabs"), + ty::FloatTy::F128 => get_simple_function_f128(span, self, name), + }; + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), + ) + } sym::raw_eq => { use rustc_abi::BackendRepr::*;
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 1263b22..4ca890f 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -811,7 +811,7 @@ macro_rules! return_error { }}; } let ty::Float(ref f) = *in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { @@ -1222,8 +1222,8 @@ fn non_ptr(t: Ty<'_>) -> Ty<'_> { simd_and: Uint, Int => and; simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors. simd_xor: Uint, Int => xor; - simd_fmin: Float => vector_fmin; - simd_fmax: Float => vector_fmax; + simd_minimum_number_nsz: Float => vector_minimum_number_nsz; + simd_maximum_number_nsz: Float => vector_maximum_number_nsz; } macro_rules! arith_unary {
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index d51adb6..1f59d25 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -3,16 +3,17 @@ use rustc_hir::def_id::DefId; use rustc_hir::find_attr; use rustc_middle::middle::codegen_fn_attrs::{ - CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, TargetFeature, }; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; +use rustc_span::sym; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; use crate::context::SimpleCx; -use crate::errors::SanitizerMemtagRequiresMte; +use crate::errors::{PackedStackBackchainNeedsSoftfloat, SanitizerMemtagRequiresMte}; use crate::llvm::AttributePlace::Function; use crate::llvm::{ self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects, Value, @@ -120,7 +121,8 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>( if enabled.contains(SanitizerSet::THREAD) { attrs.push(llvm::AttributeKind::SanitizeThread.create_attr(cx.llcx)); } - if enabled.contains(SanitizerSet::HWADDRESS) { + if enabled.contains(SanitizerSet::HWADDRESS) || enabled.contains(SanitizerSet::KERNELHWADDRESS) + { attrs.push(llvm::AttributeKind::SanitizeHWAddress.create_attr(cx.llcx)); } if enabled.contains(SanitizerSet::SHADOWCALLSTACK) { @@ -301,6 +303,36 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A Some(sspattr.create_attr(cx.llcx)) } +fn packed_stack_attr<'ll>( + cx: &SimpleCx<'ll>, + sess: &Session, + function_attributes: &Vec<TargetFeature>, +) -> Option<&'ll Attribute> { + if sess.target.arch != Arch::S390x { + return None; + } + if !sess.opts.unstable_opts.packed_stack { + return None; + } + + // The backchain and softfloat flags can be set via -Ctarget-features=... + // or via #[target_features(enable = ...)] so we have to check both possibilities + let have_backchain = sess.unstable_target_features.contains(&sym::backchain) + || function_attributes.iter().any(|feature| feature.name == sym::backchain); + let have_softfloat = sess.unstable_target_features.contains(&sym::soft_float) + || function_attributes.iter().any(|feature| feature.name == sym::soft_float); + + // If both, backchain and packedstack, are enabled LLVM cannot generate valid function entry points + // with the default ABI. However if the softfloat flag is set LLVM will switch to the softfloat + // ABI, where this works. + if have_backchain && !have_softfloat { + sess.dcx().emit_err(PackedStackBackchainNeedsSoftfloat); + return None; + } + + Some(llvm::CreateAttrString(cx.llcx, "packed-stack")) +} + pub(crate) fn target_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> &'ll Attribute { let target_cpu = llvm_util::target_cpu(sess); llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) @@ -516,6 +548,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); } + if let Some(packed_stack) = packed_stack_attr(cx, sess, &codegen_fn_attrs.target_features) { + to_add.push(packed_stack); + } to_add.extend(patchable_function_entry_attrs( cx, sess,
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index ffa5827..515b571 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -36,7 +36,7 @@ use crate::common::AsCCharPtr; use crate::errors::{ CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, ParseTargetMachineConfig, - UnknownCompression, WithLlvmError, WriteBytecode, + UnsupportedCompression, WithLlvmError, WriteBytecode, }; use crate::llvm::diagnostic::OptimizationDiagnosticKind::*; use crate::llvm::{self, DiagnosticInfo}; @@ -225,7 +225,7 @@ pub(crate) fn target_machine_factory( let triple = SmallCStr::new(&versioned_llvm_target(sess)); let cpu = SmallCStr::new(llvm_util::target_cpu(sess)); let features = CString::new(target_features.join(",")).unwrap(); - let abi = SmallCStr::new(&sess.target.llvm_abiname); + let abi = SmallCStr::new(sess.target.llvm_abiname.desc()); let trap_unreachable = sess.opts.unstable_opts.trap_unreachable.unwrap_or(sess.target.trap_unreachable); let emit_stack_size_section = sess.opts.unstable_opts.emit_stack_sizes; @@ -248,7 +248,7 @@ pub(crate) fn target_machine_factory( if llvm::LLVMRustLLVMHasZlibCompression() { llvm::CompressionKind::Zlib } else { - sess.dcx().emit_warn(UnknownCompression { algorithm: "zlib" }); + sess.dcx().emit_warn(UnsupportedCompression { algorithm: "zlib" }); llvm::CompressionKind::None } } @@ -256,7 +256,7 @@ pub(crate) fn target_machine_factory( if llvm::LLVMRustLLVMHasZstdCompression() { llvm::CompressionKind::Zstd } else { - sess.dcx().emit_warn(UnknownCompression { algorithm: "zstd" }); + sess.dcx().emit_warn(UnsupportedCompression { algorithm: "zstd" }); llvm::CompressionKind::None } } @@ -644,6 +644,10 @@ pub(crate) unsafe fn llvm_optimize( sanitize_kernel_address_recover: config .sanitizer_recover .contains(SanitizerSet::KERNELADDRESS), + sanitize_kernel_hwaddress: config.sanitizer.contains(SanitizerSet::KERNELHWADDRESS), + sanitize_kernel_hwaddress_recover: config + .sanitizer_recover + .contains(SanitizerSet::KERNELHWADDRESS), }) } else { None
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index d00e706..2276809 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -210,10 +210,14 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { } pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) { - if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) + || attrs.sanitizers.disabled.contains(SanitizerSet::KERNELADDRESS) + { unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) }; } - if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) + || attrs.sanitizers.disabled.contains(SanitizerSet::KERNELHWADDRESS) + { unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) }; } }
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2d91caf..4e79e4f 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1297,10 +1297,6 @@ fn catch_switch( ret } - fn get_funclet_cleanuppad(&self, funclet: &Funclet<'ll>) -> &'ll Value { - funclet.cleanuppad() - } - // Atomic Operations fn atomic_cmpxchg( &mut self, @@ -1605,12 +1601,16 @@ fn write_operand_repeatedly_unoptimized( *self = Self::build(self.cx, next_bb); } - pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.call_intrinsic("llvm.minnum", &[self.val_ty(lhs)], &[lhs, rhs]) + pub(crate) fn minimum_number_nsz(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + let call = self.call_intrinsic("llvm.minimumnum", &[self.val_ty(lhs)], &[lhs, rhs]); + unsafe { llvm::LLVMRustSetNoSignedZeros(call) }; + call } - pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.call_intrinsic("llvm.maxnum", &[self.val_ty(lhs)], &[lhs, rhs]) + pub(crate) fn maximum_number_nsz(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + let call = self.call_intrinsic("llvm.maximumnum", &[self.val_ty(lhs)], &[lhs, rhs]); + unsafe { llvm::LLVMRustSetNoSignedZeros(call) }; + call } pub(crate) fn insert_element(
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index cc4c5e2..e02c4ae 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -28,7 +28,7 @@ use rustc_span::{DUMMY_SP, Span, Spanned, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{ - Abi, Arch, Env, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport, Target, TlsModel, + Arch, CfgAbi, Env, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport, Target, TlsModel, }; use smallvec::SmallVec; @@ -344,7 +344,7 @@ pub(crate) unsafe fn create_module<'ll>( if sess.target.is_like_msvc || (sess.target.options.os == Os::Windows && sess.target.options.env == Env::Gnu - && sess.target.options.abi == Abi::Llvm) + && sess.target.options.cfg_abi == CfgAbi::Llvm) { match sess.opts.cg.control_flow_guard { CFGuard::Disabled => {} @@ -509,14 +509,13 @@ pub(crate) unsafe fn create_module<'ll>( // to workaround lld as the LTO plugin not // correctly setting target-abi for the LTO object // FIXME: https://github.com/llvm/llvm-project/issues/50591 - // If llvm_abiname is empty, emit nothing. let llvm_abiname = &sess.target.options.llvm_abiname; - if matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) && !llvm_abiname.is_empty() { + if matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) { llvm::add_module_flag_str( llmod, llvm::ModuleFlagMergeBehavior::Error, "target-abi", - llvm_abiname, + llvm_abiname.desc(), ); }
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 9fb4065..caec20d 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -182,9 +182,9 @@ pub(crate) struct CopyBitcode { #[derive(Diagnostic)] #[diag( - "unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo" + "unsupported debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo" )] -pub(crate) struct UnknownCompression { +pub(crate) struct UnsupportedCompression { pub algorithm: &'static str, } @@ -204,3 +204,10 @@ pub(crate) struct MismatchedDataLayout<'a> { pub(crate) struct FixedX18InvalidArch<'a> { pub arch: &'a str, } + +#[derive(Diagnostic)] +#[diag("`-Zpacked-stack` is incompatible with `backchain` target feature")] +#[note( + "enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes" +)] +pub(crate) struct PackedStackBackchainNeedsSoftfloat;
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index cc6ecee..39bf4c1 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -107,11 +107,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::fmuladdf64 => ("llvm.fmuladd", &[bx.type_f64()]), sym::fmuladdf128 => ("llvm.fmuladd", &[bx.type_f128()]), - sym::fabsf16 => ("llvm.fabs", &[bx.type_f16()]), - sym::fabsf32 => ("llvm.fabs", &[bx.type_f32()]), - sym::fabsf64 => ("llvm.fabs", &[bx.type_f64()]), - sym::fabsf128 => ("llvm.fabs", &[bx.type_f128()]), - // FIXME: LLVM currently mis-compile those intrinsics, re-enable them // when llvm/llvm-project#{139380,139381,140445} are fixed. //sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), @@ -502,6 +497,20 @@ fn codegen_intrinsic_call( } } + sym::fabs => { + let ty = args[0].layout.ty; + let ty::Float(f) = ty.kind() else { + span_bug!(span, "the `fabs` intrinsic requires a floating-point argument, got {:?}", ty); + }; + let llty = self.type_float_from_ty(*f); + let llvm_name = "llvm.fabs"; + self.call_intrinsic( + llvm_name, + &[llty], + &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), + ) + } + sym::raw_eq => { use BackendRepr::*; let tp_ty = fn_args.type_at(0); @@ -1936,7 +1945,7 @@ macro_rules! return_error { } let ty::Float(f) = in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); @@ -2770,8 +2779,8 @@ macro_rules! arith_binary { simd_and: Uint, Int => and; simd_or: Uint, Int => or; simd_xor: Uint, Int => xor; - simd_fmax: Float => maxnum; - simd_fmin: Float => minnum; + simd_maximum_number_nsz: Float => maximum_number_nsz; + simd_minimum_number_nsz: Float => minimum_number_nsz; } macro_rules! arith_unary {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7743847..7355d11 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -464,6 +464,8 @@ pub(crate) struct SanitizerOptions { pub sanitize_hwaddress_recover: bool, pub sanitize_kernel_address: bool, pub sanitize_kernel_address_recover: bool, + pub sanitize_kernel_hwaddress: bool, + pub sanitize_kernel_hwaddress_recover: bool, } /// LLVMRustRelocModel
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 45e16a7..3e0a6ef 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -16,7 +16,7 @@ use rustc_session::Session; use rustc_session::config::{PrintKind, PrintRequest}; use rustc_target::spec::{ - Abi, Arch, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, + Arch, CfgAbi, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, }; use smallvec::{SmallVec, smallvec}; @@ -252,7 +252,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea "fp16" => Some(LLVMFeature::new("fullfp16")), s => Some(LLVMFeature::new(s)), }, - + Arch::Bpf => match s { + "allows-misaligned-mem-access" if major < 22 => None, + s => Some(LLVMFeature::new(s)), + }, // Filter out features that are not supported by the current LLVM version Arch::PowerPC | Arch::PowerPC64 => match s { "power8-crypto" => Some(LLVMFeature::new("crypto")), @@ -362,7 +365,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { let target_arch = &sess.target.arch; let target_os = &sess.target.options.os; let target_env = &sess.target.options.env; - let target_abi = &sess.target.options.abi; + let target_abi = &sess.target.options.cfg_abi; let target_pointer_width = sess.target.pointer_width; let version = get_version(); let (major, _, _) = version; @@ -371,7 +374,9 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // Unsupported <https://github.com/llvm/llvm-project/issues/94434> (fixed in llvm22) (Arch::Arm64EC, _) if major < 22 => false, // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054> - (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, + (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => { + false + } // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981> (Arch::CSky, _) if major < 22 => false, // (fixed in llvm22) (Arch::PowerPC | Arch::PowerPC64, _) if major < 22 => false, // (fixed in llvm22) @@ -397,7 +402,9 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // ABI unsupported <https://github.com/llvm/llvm-project/issues/41838> (fixed in llvm22) (Arch::Sparc, _) if major < 22 => false, // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054> - (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, + (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => { + false + } // There are no known problems on other platforms, so the only requirement is that symbols // are available. `compiler-builtins` provides all symbols required for core `f128` // support, so this should work for everything else.
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 98d2c3f..19735a2 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -8,7 +8,7 @@ use rustc_middle::bug; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; -use rustc_target::spec::{Arch, Env, RustcAbi}; +use rustc_target::spec::{Arch, Env, LlvmAbi, RustcAbi}; use crate::builder::Builder; use crate::llvm::{Type, Value}; @@ -1077,7 +1077,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::Yes, ), - Arch::RiscV32 if target.llvm_abiname == "ilp32e" => { + Arch::RiscV32 if target.llvm_abiname == LlvmAbi::Ilp32e => { // FIXME: clang manually adjusts the alignment for this ABI. It notes: // // > To be compatible with GCC's behaviors, we force arguments with @@ -1186,9 +1186,10 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // Clang uses the LLVM implementation for these architectures. bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) } - Arch::Other(_) => { - // For custom targets, use the LLVM va_arg instruction as a fallback. - bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + Arch::Other(ref arch) => { + // Just to be safe we error out explicitly here, instead of crossing our fingers that + // the default LLVM implementation has the correct behavior for this target. + bug!("c-variadic functions are not currently implemented for custom target {arch}") } } }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7a3d5a6..20e75f0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -47,7 +47,7 @@ use rustc_span::Symbol; use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ - Abi, BinaryFormat, Cc, Env, LinkOutputKind, LinkSelfContainedComponents, + BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, Os, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, }; @@ -1917,7 +1917,7 @@ fn self_contained_components( LinkSelfContainedDefault::InferredForMusl => sess.crt_static(Some(crate_type)), LinkSelfContainedDefault::InferredForMingw => { sess.host == sess.target - && sess.target.abi != Abi::Uwp + && sess.target.cfg_abi != CfgAbi::Uwp && detect_self_contained_mingw(sess, linker) } } @@ -2767,6 +2767,10 @@ fn add_order_independent_options( cmd.pgo_gen(); } + if sess.opts.unstable_opts.instrument_mcount { + cmd.enable_profiling(); + } + if sess.opts.cg.control_flow_guard != CFGuard::Disabled { cmd.control_flow_guard(); }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 3ace1a8..eb908e1 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -18,7 +18,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_target::spec::{Abi, Arch, Cc, LinkOutputKind, LinkerFlavor, Lld, Os}; +use rustc_target::spec::{Arch, Cc, CfgAbi, LinkOutputKind, LinkerFlavor, Lld, Os}; use tracing::{debug, warn}; use super::command::Command; @@ -84,7 +84,7 @@ pub(crate) fn get_linker<'a>( // To comply with the Windows App Certification Kit, // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). let t = &sess.target; - if matches!(flavor, LinkerFlavor::Msvc(..)) && t.abi == Abi::Uwp { + if matches!(flavor, LinkerFlavor::Msvc(..)) && t.cfg_abi == CfgAbi::Uwp { if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(root_lib_path) = original_path.ancestors().nth(4) { @@ -135,7 +135,7 @@ pub(crate) fn get_linker<'a>( // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction // to the linker args construction. - assert!(cmd.get_args().is_empty() || sess.target.abi == Abi::Uwp); + assert!(cmd.get_args().is_empty() || sess.target.cfg_abi == CfgAbi::Uwp); match flavor { LinkerFlavor::Unix(Cc::No) if sess.target.os == Os::L4Re => { Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker> @@ -352,6 +352,7 @@ fn add_eh_frame_header(&mut self) {} fn add_no_exec(&mut self) {} fn add_as_needed(&mut self) {} fn reset_per_library_state(&mut self) {} + fn enable_profiling(&mut self) {} } impl dyn Linker + '_ { @@ -732,6 +733,19 @@ fn pgo_gen(&mut self) { self.link_or_cc_args(&["-u", "__llvm_profile_runtime"]); } + fn enable_profiling(&mut self) { + // This flag is also used when linking to choose target specific + // libraries needed to enable profiling. + self.cc_arg("-pg"); + // On windows-gnu targets, libgmon also needs to be linked, and this + // requires readding libraries to satisfy its dependencies. + if self.sess.target.is_like_windows { + self.cc_arg("-lgmon"); + self.cc_arg("-lkernel32"); + self.cc_arg("-lmsvcrt"); + } + } + fn control_flow_guard(&mut self) {} fn ehcont_guard(&mut self) {}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 240267c..f6544c0 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -20,7 +20,7 @@ use rustc_middle::bug; use rustc_session::Session; use rustc_span::sym; -use rustc_target::spec::{Abi, Os, RelocModel, Target, ef_avr_arch}; +use rustc_target::spec::{CfgAbi, LlvmAbi, Os, RelocModel, Target, ef_avr_arch}; use tracing::debug; use super::apple; @@ -295,10 +295,10 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { }; // Use the explicitly given ABI. - match sess.target.options.llvm_abiname.as_ref() { - "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, - "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2, - "n64" if !is_32bit => {} + match &sess.target.options.llvm_abiname { + LlvmAbi::O32 if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, + LlvmAbi::N32 if !is_32bit => e_flags |= elf::EF_MIPS_ABI2, + LlvmAbi::N64 if !is_32bit => {} // The rest is invalid (which is already ensured by the target spec check). s => bug!("invalid LLVM ABI `{}` for MIPS target", s), }; @@ -336,12 +336,12 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { // Set the appropriate flag based on ABI // This needs to match LLVM `RISCVELFStreamer.cpp` - match &*sess.target.llvm_abiname { - "ilp32" | "lp64" => (), - "ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE, - "ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE, + match &sess.target.llvm_abiname { + LlvmAbi::Ilp32 | LlvmAbi::Lp64 => (), + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE, + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE, // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. - "ilp32e" | "lp64e" => e_flags |= elf::EF_RISCV_RVE, + LlvmAbi::Ilp32e | LlvmAbi::Lp64e => e_flags |= elf::EF_RISCV_RVE, _ => bug!("unknown RISC-V ABI name"), } @@ -353,10 +353,10 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { // Set the appropriate flag based on ABI // This needs to match LLVM `LoongArchELFStreamer.cpp` - match &*sess.target.llvm_abiname { - "ilp32s" | "lp64s" => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT, - "ilp32f" | "lp64f" => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT, - "ilp32d" | "lp64d" => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT, + match &sess.target.llvm_abiname { + LlvmAbi::Ilp32s | LlvmAbi::Lp64s => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT, + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT, + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT, _ => bug!("unknown LoongArch ABI name"), } @@ -372,7 +372,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { } } Architecture::Csky => { - if matches!(sess.target.options.abi, Abi::AbiV2) { + if matches!(sess.target.options.cfg_abi, CfgAbi::AbiV2) { elf::EF_CSKY_ABIV2 } else { elf::EF_CSKY_ABIV1 @@ -383,14 +383,14 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { const EF_PPC64_ABI_ELF_V1: u32 = 1; const EF_PPC64_ABI_ELF_V2: u32 = 2; - match sess.target.options.llvm_abiname.as_ref() { + match sess.target.options.llvm_abiname { // If the flags do not correctly indicate the ABI, // linkers such as ld.lld assume that the ppc64 object files are always ELFv2 // which leads to broken binaries if ELFv1 is used for the object files. - "elfv1" => EF_PPC64_ABI_ELF_V1, - "elfv2" => EF_PPC64_ABI_ELF_V2, - "" if sess.target.options.binary_format.to_object() == BinaryFormat::Elf => { - bug!("No ABI specified for this PPC64 ELF target"); + LlvmAbi::ElfV1 => EF_PPC64_ABI_ELF_V1, + LlvmAbi::ElfV2 => EF_PPC64_ABI_ELF_V2, + _ if sess.target.options.binary_format.to_object() == BinaryFormat::Elf => { + bug!("invalid ABI specified for this PPC64 ELF target"); } // Fall back _ => EF_PPC64_ABI_UNKNOWN,
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 557b00b..3269fc5 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -199,6 +199,14 @@ fn exported_non_generic_symbols_provider_local<'tcx>( })) } + symbols.extend(sorted.iter().flat_map(|&(&def_id, &info)| { + tcx.codegen_fn_attrs(def_id).foreign_item_symbol_aliases.iter().map( + move |&(foreign_item, _linkage, _visibility)| { + (ExportedSymbol::NonGeneric(foreign_item), info) + }, + ) + })); + if tcx.entry_fn(()).is_some() { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index a0f46a2..de79acd 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -7,7 +7,7 @@ use rustc_middle::{bug, mir, span_bug}; use rustc_session::cstore::{DllCallingConvention, DllImport, DllImportSymbolType}; use rustc_span::Span; -use rustc_target::spec::{Abi, Env, Os, Target}; +use rustc_target::spec::{CfgAbi, Env, Os, Target}; use crate::traits::*; @@ -102,8 +102,8 @@ mod temp_stable_hash_impls { use crate::ModuleCodegen; - impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> { - fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) { + impl<Hcx, M> HashStable<Hcx> for ModuleCodegen<M> { + fn hash_stable(&self, _: &mut Hcx, _: &mut StableHasher) { // do nothing } } @@ -171,7 +171,7 @@ pub fn asm_const_to_str<'tcx>( } pub fn is_mingw_gnu_toolchain(target: &Target) -> bool { - target.os == Os::Windows && target.env == Env::Gnu && target.abi == Abi::Unspecified + target.os == Os::Windows && target.env == Env::Gnu && target.cfg_abi == CfgAbi::Unspecified } pub fn i686_decorated_name(
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 576df6e..cec84f6 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -733,14 +733,6 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)] - FloatingPointType { - #[primary_span] - span: Span, - name: Symbol, - in_ty: Ty<'tcx>, - }, - #[diag("invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`", code = E0511)] UnrecognizedIntrinsic { #[primary_span]
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index dcbd7f7..1b96be1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -214,18 +214,19 @@ fn do_call<Bx: BuilderMethods<'a, 'tcx>>( mir::UnwindAction::Continue => None, mir::UnwindAction::Unreachable => None, mir::UnwindAction::Terminate(reason) => { - if fx.mir[self.bb].is_cleanup && base::wants_wasm_eh(fx.cx.tcx().sess) { - // For wasm, we need to generate a nested `cleanuppad within %outer_pad` - // to catch exceptions during cleanup and call `panic_in_cleanup`. - Some(fx.terminate_block(reason, Some(self.bb))) - } else if fx.mir[self.bb].is_cleanup - && base::wants_new_eh_instructions(fx.cx.tcx().sess) - { + if fx.mir[self.bb].is_cleanup && base::wants_new_eh_instructions(fx.cx.tcx().sess) { // MSVC SEH will abort automatically if an exception tries to // propagate out from cleanup. + + // FIXME(@mirkootter): For wasm, we currently do not support terminate during + // cleanup, because this requires a few more changes: The current code + // caches the `terminate_block` for each function; funclet based code - however - + // requires a different terminate_block for each funclet + // Until this is implemented, we just do not unwind inside cleanup blocks + None } else { - Some(fx.terminate_block(reason, None)) + Some(fx.terminate_block(reason)) } } }; @@ -237,7 +238,7 @@ fn do_call<Bx: BuilderMethods<'a, 'tcx>>( if let Some(unwind_block) = unwind_block { let ret_llbb = if let Some((_, target)) = destination { - self.llbb_with_cleanup(fx, target) + fx.llbb(target) } else { fx.unreachable_block() }; @@ -308,7 +309,7 @@ fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>( ) -> MergingSucc { let unwind_target = match unwind { mir::UnwindAction::Cleanup(cleanup) => Some(self.llbb_with_cleanup(fx, cleanup)), - mir::UnwindAction::Terminate(reason) => Some(fx.terminate_block(reason, None)), + mir::UnwindAction::Terminate(reason) => Some(fx.terminate_block(reason)), mir::UnwindAction::Continue => None, mir::UnwindAction::Unreachable => None, }; @@ -316,7 +317,7 @@ fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>( if operands.iter().any(|x| matches!(x, InlineAsmOperandRef::Label { .. })) { assert!(unwind_target.is_none()); let ret_llbb = if let Some(target) = destination { - self.llbb_with_cleanup(fx, target) + fx.llbb(target) } else { fx.unreachable_block() }; @@ -333,7 +334,7 @@ fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>( MergingSucc::False } else if let Some(cleanup) = unwind_target { let ret_llbb = if let Some(target) = destination { - self.llbb_with_cleanup(fx, target) + fx.llbb(target) } else { fx.unreachable_block() }; @@ -1895,39 +1896,8 @@ fn unreachable_block(&mut self) -> Bx::BasicBlock { }) } - fn terminate_block( - &mut self, - reason: UnwindTerminateReason, - outer_catchpad_bb: Option<mir::BasicBlock>, - ) -> Bx::BasicBlock { - // mb_funclet_bb should be present if and only if the target is wasm and - // we're terminating because of an unwind in a cleanup block. In that - // case we have nested funclets and the inner catch_switch needs to know - // what outer catch_pad it is contained in. - debug_assert!( - outer_catchpad_bb.is_some() - == (base::wants_wasm_eh(self.cx.tcx().sess) - && reason == UnwindTerminateReason::InCleanup) - ); - - // When we aren't in a wasm InCleanup block, there's only one terminate - // block needed so we cache at START_BLOCK index. - let mut cache_bb = mir::START_BLOCK; - // In wasm eh InCleanup, use the outer funclet's cleanup BB as the cache - // key. - if let Some(outer_bb) = outer_catchpad_bb { - let cleanup_kinds = - self.cleanup_kinds.as_ref().expect("cleanup_kinds required for funclets"); - cache_bb = cleanup_kinds[outer_bb] - .funclet_bb(outer_bb) - .expect("funclet_bb should be in a funclet"); - - // Ensure the outer funclet is created first - if self.funclets[cache_bb].is_none() { - self.landing_pad_for(cache_bb); - } - } - if let Some((cached_bb, cached_reason)) = self.terminate_blocks[cache_bb] + fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock { + if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason { return cached_bb; @@ -1965,35 +1935,12 @@ fn terminate_block( // cp_terminate: // %cp = catchpad within %cs [null, i32 64, null] // ... - // - // By contrast, on WebAssembly targets, we specifically _do_ want to - // catch foreign exceptions. The situation with MSVC is a - // regrettable hack which we don't want to extend to other targets - // unless necessary. For WebAssembly, to generate catch(...) and - // catch only C++ exception instead of generating a catch_all, we - // need to call the intrinsics @llvm.wasm.get.exception and - // @llvm.wasm.get.ehselector in the catch pad. Since we don't do - // this, we generate a catch_all. We originally got this behavior - // by accident but it luckily matches our intention. llbb = Bx::append_block(self.cx, self.llfn, "cs_terminate"); + let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate"); let mut cs_bx = Bx::build(self.cx, llbb); - - // For wasm InCleanup blocks, our catch_switch is nested within the - // outer catchpad, so we need to provide it as the parent value to - // catch_switch. - let mut outer_cleanuppad = None; - if outer_catchpad_bb.is_some() { - // Get the outer funclet's catchpad - let outer_funclet = self.funclets[cache_bb] - .as_ref() - .expect("landing_pad_for didn't create funclet"); - outer_cleanuppad = Some(cs_bx.get_funclet_cleanuppad(outer_funclet)); - } - let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate"); - let cs = cs_bx.catch_switch(outer_cleanuppad, None, &[cp_llbb]); - drop(cs_bx); + let cs = cs_bx.catch_switch(None, None, &[cp_llbb]); bx = Bx::build(self.cx, cp_llbb); let null = @@ -2014,18 +1961,13 @@ fn terminate_block( } else { // Specifying more arguments than necessary usually doesn't // hurt, but the `WasmEHPrepare` LLVM pass does not recognize - // anything other than a single `null` as a `catch_all` block, + // anything other than a single `null` as a `catch (...)` block, // leading to problems down the line during instruction // selection. &[null] as &[_] }; funclet = Some(bx.catch_pad(cs, args)); - // On wasm, if we wanted to generate a catch(...) and only catch C++ - // exceptions, we'd call @llvm.wasm.get.exception and - // @llvm.wasm.get.ehselector selectors here. We want a catch_all so - // we leave them out. This is intentionally diverging from the MSVC - // behavior. } else { llbb = Bx::append_block(self.cx, self.llfn, "terminate"); bx = Bx::build(self.cx, llbb); @@ -2051,7 +1993,7 @@ fn terminate_block( bx.unreachable(); - self.terminate_blocks[cache_bb] = Some((llbb, reason)); + self.terminate_block = Some((llbb, reason)); llbb }
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 5c14d6f..93da121 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -90,11 +90,8 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// Cached unreachable block unreachable_block: Option<Bx::BasicBlock>, - /// Cached terminate upon unwinding block and its reason. For non-wasm - /// targets, there is at most one such block per function, stored at index - /// `START_BLOCK`. For wasm targets, each funclet needs its own terminate - /// block, indexed by the cleanup block that is the funclet's head. - terminate_blocks: IndexVec<mir::BasicBlock, Option<(Bx::BasicBlock, UnwindTerminateReason)>>, + /// Cached terminate upon unwinding block and its reason + terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>, /// A bool flag for each basic block indicating whether it is a cold block. /// A cold block is a block that is unlikely to be executed at runtime. @@ -230,7 +227,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( personality_slot: None, cached_llbbs, unreachable_block: None, - terminate_blocks: IndexVec::from_elem(None, &mir.basic_blocks), + terminate_block: None, cleanup_kinds, landing_pads: IndexVec::from_elem(None, &mir.basic_blocks), funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 05e94b8..2076e2b 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -552,12 +552,12 @@ fn select( fn set_personality_fn(&mut self, personality: Self::Function); - // These are used by everyone except msvc and wasm EH + // These are used by everyone except msvc fn cleanup_landing_pad(&mut self, pers_fn: Self::Function) -> (Self::Value, Self::Value); fn filter_landing_pad(&mut self, pers_fn: Self::Function); fn resume(&mut self, exn0: Self::Value, exn1: Self::Value); - // These are used by msvc and wasm EH + // These are used only by msvc fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet; fn cleanup_ret(&mut self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>); fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet; @@ -567,7 +567,6 @@ fn catch_switch( unwind: Option<Self::BasicBlock>, handlers: &[Self::BasicBlock], ) -> Self::Value; - fn get_funclet_cleanuppad(&self, funclet: &Self::Funclet) -> Self::Value; fn atomic_cmpxchg( &mut self,
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 61e8e43..c48b33e 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -1,6 +1,6 @@ use std::{fmt, mem}; -use rustc_errors::Diag; +use rustc_errors::{Diag, E0080}; use rustc_middle::mir::AssertKind; use rustc_middle::mir::interpret::{ AllocId, Provenance, ReportedErrorInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, @@ -8,7 +8,7 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::ConstInt; use rustc_middle::ty::layout::LayoutError; -use rustc_span::{Span, Symbol}; +use rustc_span::{DUMMY_SP, Span, Symbol}; use super::CompileTimeMachine; use crate::errors::{self, FrameNote}; @@ -164,36 +164,30 @@ pub fn get_span_and_frames<'tcx>( /// This will use the `mk` function for adding more information to the error. /// You can use it to add a stacktrace of current execution according to /// `get_span_and_frames` or just give context on where the const eval error happened. -pub(super) fn report<'tcx, C, F>( +pub(super) fn report<'tcx>( ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>, error: InterpErrorKind<'tcx>, - span: Span, - get_span_and_frames: C, - mk: F, -) -> ErrorHandled -where - C: FnOnce() -> (Span, Vec<FrameNote>), - F: FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>), -{ + mk: impl FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>), +) -> ErrorHandled { let tcx = ecx.tcx.tcx; // Special handling for certain errors match error { // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. - err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), + err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, DUMMY_SP), err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => { - ErrorHandled::TooGeneric(span) + ErrorHandled::TooGeneric(DUMMY_SP) } err_inval!(Layout(LayoutError::ReferencesError(guar))) => { // This can occur in infallible promoteds e.g. when a non-existent type or field is // encountered. - ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span) + ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), DUMMY_SP) } // Report remaining errors. _ => { - let (our_span, frames) = get_span_and_frames(); - let span = span.substitute_dummy(our_span); - let mut err = tcx.dcx().struct_span_err(our_span, error.to_string()); + let (span, frames) = super::get_span_and_frames(ecx.tcx, ecx.stack()); + let mut err = tcx.dcx().struct_span_err(span, error.to_string()); + err.code(E0080); if matches!( error, InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError {
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 2dbf2cc..ccfdf57 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -2,7 +2,6 @@ use either::{Left, Right}; use rustc_abi::{self as abi, BackendRepr}; -use rustc_errors::{E0080, msg}; use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo}; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; @@ -11,8 +10,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, throw_inval}; +use rustc_span::Span; use rustc_span::def_id::LocalDefId; -use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument, trace}; use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine}; @@ -88,7 +87,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>( &ret.clone().into(), ReturnContinuation::Stop { cleanup: false }, )?; - ecx.storage_live_for_always_live_locals()?; + ecx.push_stack_frame_done()?; // The main interpreter loop. while ecx.step()? { @@ -425,7 +424,7 @@ fn const_validate_mplace<'tcx>( cid: GlobalId<'tcx>, ) -> Result<(), ErrorHandled> { let alloc_id = mplace.ptr().provenance.unwrap().alloc_id(); - let mut ref_tracking = RefTracking::new(mplace.clone()); + let mut ref_tracking = RefTracking::new(mplace.clone(), mplace.layout.ty); let mut inner = false; while let Some((mplace, path)) = ref_tracking.next() { let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) { @@ -458,32 +457,20 @@ fn report_eval_error<'tcx>( let (error, backtrace) = error.into_parts(); backtrace.print_backtrace(); - super::report( - ecx, - error, - DUMMY_SP, - || super::get_span_and_frames(ecx.tcx, ecx.stack()), - |diag, span, frames| { - let num_frames = frames.len(); - // FIXME(oli-obk): figure out how to use structured diagnostics again. - diag.code(E0080); - diag.span_label( - span, - msg!( - "evaluation of `{$instance}` failed {$num_frames -> - [0] here - *[other] inside this call - }" - ), - ); - for frame in frames { - diag.subdiagnostic(frame); - } - // Add after the frame rendering above, as it adds its own `instance` args. - diag.arg("instance", with_no_trimmed_paths!(cid.instance.to_string())); - diag.arg("num_frames", num_frames); - }, - ) + super::report(ecx, error, |diag, span, frames| { + let num_frames = frames.len(); + diag.span_label( + span, + format!( + "evaluation of `{instance}` failed {where_}", + instance = with_no_trimmed_paths!(cid.instance.to_string()), + where_ = if num_frames == 0 { "here" } else { "inside this call" }, + ), + ); + for frame in frames { + diag.subdiagnostic(frame); + } + }) } #[inline(never)] @@ -506,20 +493,10 @@ fn report_validation_error<'tcx>( let raw_bytes = errors::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes }; - crate::const_eval::report( - ecx, - error, - DUMMY_SP, - || crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()), - move |diag, span, frames| { - // FIXME(oli-obk): figure out how to use structured diagnostics again. - diag.code(E0080); - diag.span_label(span, "it is undefined behavior to use this value"); - diag.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."); - for frame in frames { - diag.subdiagnostic(frame); - } - diag.subdiagnostic(raw_bytes); - }, - ) + crate::const_eval::report(ecx, error, move |diag, span, frames| { + diag.span_label(span, "it is undefined behavior to use this value"); + diag.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."); + assert!(frames.is_empty()); // we just report validation errors for the final const here + diag.subdiagnostic(raw_bytes); + }) }
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 ad4c9aa..0b5065f 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -37,7 +37,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness { } } Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => { - if find_attr!(tcx.hir_attrs(ti.hir_id()), RustcNonConstTraitMethod) { + if find_attr!(tcx, ti.hir_id(), RustcNonConstTraitMethod) { Constness::NotConst } else { tcx.trait_def(tcx.local_parent(def_id)).constness
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 0381571..0ac9f30 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -60,7 +60,7 @@ pub fn copy_fn_args(args: &[FnArg<'tcx, M::Provenance>]) -> Vec<OpTy<'tcx, M::Pr } /// Helper function for argument untupling. - pub(super) fn fn_arg_field( + fn fn_arg_project_field( &self, arg: &FnArg<'tcx, M::Provenance>, field: FieldIdx, @@ -404,166 +404,158 @@ pub fn init_stack_frame( // Push the "raw" frame -- this leaves locals uninitialized. self.push_stack_frame_raw(instance, body, destination, cont)?; + let preamble_span = self.frame().loc.unwrap_right(); // the span used for preamble errors - // If an error is raised here, pop the frame again to get an accurate backtrace. - // To this end, we wrap it all in a `try` block. - let res: InterpResult<'tcx> = try { - trace!( - "caller ABI: {:#?}, args: {:#?}", - caller_fn_abi, - args.iter() - .map(|arg| ( - arg.layout().ty, - match arg { - FnArg::Copy(op) => format!("copy({op:?})"), - FnArg::InPlace(mplace) => format!("in-place({mplace:?})"), - } - )) - .collect::<Vec<_>>() - ); - trace!( - "spread_arg: {:?}, locals: {:#?}", - body.spread_arg, - body.args_iter() - .map(|local| ( - local, - self.layout_of_local(self.frame(), local, None).unwrap().ty, - )) - .collect::<Vec<_>>() - ); - - // In principle, we have two iterators: Where the arguments come from, and where - // they go to. - - // The "where they come from" part is easy, we expect the caller to do any special handling - // that might be required here (e.g. for untupling). - // If `with_caller_location` is set we pretend there is an extra argument (that - // we will not pass; our `caller_location` intrinsic implementation walks the stack instead). - assert_eq!( - args.len() + if with_caller_location { 1 } else { 0 }, - caller_fn_abi.args.len(), - "mismatch between caller ABI and caller arguments", - ); - let mut caller_args = args - .iter() - .zip(caller_fn_abi.args.iter()) - .filter(|arg_and_abi| !arg_and_abi.1.is_ignore()); - - // Now we have to spread them out across the callee's locals, - // taking into account the `spread_arg`. If we could write - // this is a single iterator (that handles `spread_arg`), then - // `pass_argument` would be the loop body. It takes care to - // not advance `caller_iter` for ignored arguments. - let mut callee_args_abis = callee_fn_abi.args.iter().enumerate(); - // Determine whether there is a special VaList argument. This is always the - // last argument, and since arguments start at index 1 that's `arg_count`. - let va_list_arg = - callee_fn_abi.c_variadic.then(|| mir::Local::from_usize(body.arg_count)); - for local in body.args_iter() { - // Construct the destination place for this argument. At this point all - // locals are still dead, so we cannot construct a `PlaceTy`. - let dest = mir::Place::from(local); - // `layout_of_local` does more than just the instantiation we need to get the - // type, but the result gets cached so this avoids calling the instantiation - // query *again* the next time this local is accessed. - let ty = self.layout_of_local(self.frame(), local, None)?.ty; - if Some(local) == va_list_arg { - // This is the last callee-side argument of a variadic function. - // This argument is a VaList holding the remaining caller-side arguments. - self.storage_live(local)?; - - let place = self.eval_place(dest)?; - let mplace = self.force_allocation(&place)?; - - // Consume the remaining arguments by putting them into the variable argument - // list. - let varargs = self.allocate_varargs( - &mut caller_args, - // "Ignored" arguments aren't actually passed, so the callee should also - // ignore them. (`pass_argument` does this for regular arguments.) - (&mut callee_args_abis).filter(|(_, abi)| !abi.is_ignore()), - )?; - // When the frame is dropped, these variable arguments are deallocated. - self.frame_mut().va_list = varargs.clone(); - let key = self.va_list_ptr(varargs.into()); - - // Zero the VaList, so it is fully initialized. - self.write_bytes_ptr( - mplace.ptr(), - (0..mplace.layout.size.bytes()).map(|_| 0u8), - )?; - - // Store the "key" pointer in the right field. - let key_mplace = self.va_list_key_field(&mplace)?; - self.write_pointer(key, &key_mplace)?; - } else if Some(local) == body.spread_arg { - // Make the local live once, then fill in the value field by field. - self.storage_live(local)?; - // Must be a tuple - let ty::Tuple(fields) = ty.kind() else { - span_bug!(self.cur_span(), "non-tuple type for `spread_arg`: {ty}") - }; - for (i, field_ty) in fields.iter().enumerate() { - let dest = dest.project_deeper( - &[mir::ProjectionElem::Field(FieldIdx::from_usize(i), field_ty)], - *self.tcx, - ); - let (idx, callee_abi) = callee_args_abis.next().unwrap(); - self.pass_argument( - &mut caller_args, - callee_abi, - idx, - &dest, - field_ty, - /* already_live */ true, - )?; + trace!( + "caller ABI: {:#?}, args: {:#?}", + caller_fn_abi, + args.iter() + .map(|arg| ( + arg.layout().ty, + match arg { + FnArg::Copy(op) => format!("copy({op:?})"), + FnArg::InPlace(mplace) => format!("in-place({mplace:?})"), } - } else { - // Normal argument. Cannot mark it as live yet, it might be unsized! + )) + .collect::<Vec<_>>() + ); + trace!( + "spread_arg: {:?}, locals: {:#?}", + body.spread_arg, + body.args_iter() + .map(|local| (local, self.layout_of_local(self.frame(), local, None).unwrap().ty,)) + .collect::<Vec<_>>() + ); + + // In principle, we have two iterators: Where the arguments come from, and where + // they go to. + + // The "where they come from" part is easy, we expect the caller to do any special handling + // that might be required here (e.g. for untupling). + // If `with_caller_location` is set we pretend there is an extra argument (that + // we will not pass; our `caller_location` intrinsic implementation walks the stack instead). + assert_eq!( + args.len() + if with_caller_location { 1 } else { 0 }, + caller_fn_abi.args.len(), + "mismatch between caller ABI and caller arguments", + ); + let mut caller_args = args + .iter() + .zip(caller_fn_abi.args.iter()) + .filter(|arg_and_abi| !arg_and_abi.1.is_ignore()); + + // Now we have to spread them out across the callee's locals, + // taking into account the `spread_arg`. If we could write + // this is a single iterator (that handles `spread_arg`), then + // `pass_argument` would be the loop body. It takes care to + // not advance `caller_iter` for ignored arguments. + let mut callee_args_abis = callee_fn_abi.args.iter().enumerate(); + // Determine whether there is a special VaList argument. This is always the + // last argument, and since arguments start at index 1 that's `arg_count`. + let va_list_arg = callee_fn_abi.c_variadic.then(|| mir::Local::from_usize(body.arg_count)); + for local in body.args_iter() { + // Update the span that we show in case of an error to point to this argument. + self.frame_mut().loc = Right(body.local_decls[local].source_info.span); + // Construct the destination place for this argument. At this point all + // locals are still dead, so we cannot construct a `PlaceTy`. + let dest = mir::Place::from(local); + // `layout_of_local` does more than just the instantiation we need to get the + // type, but the result gets cached so this avoids calling the instantiation + // query *again* the next time this local is accessed. + let ty = self.layout_of_local(self.frame(), local, None)?.ty; + if Some(local) == va_list_arg { + // This is the last callee-side argument of a variadic function. + // This argument is a VaList holding the remaining caller-side arguments. + self.storage_live(local)?; + + let place = self.eval_place(dest)?; + let mplace = self.force_allocation(&place)?; + + // Consume the remaining arguments by putting them into the variable argument + // list. + let varargs = self.allocate_varargs( + &mut caller_args, + // "Ignored" arguments aren't actually passed, so the callee should also + // ignore them. (`pass_argument` does this for regular arguments.) + (&mut callee_args_abis).filter(|(_, abi)| !abi.is_ignore()), + )?; + // When the frame is dropped, these variable arguments are deallocated. + self.frame_mut().va_list = varargs.clone(); + let key = self.va_list_ptr(varargs.into()); + + // Zero the VaList, so it is fully initialized. + self.write_bytes_ptr(mplace.ptr(), (0..mplace.layout.size.bytes()).map(|_| 0u8))?; + + // Store the "key" pointer in the right field. + let key_mplace = self.va_list_key_field(&mplace)?; + self.write_pointer(key, &key_mplace)?; + } else if Some(local) == body.spread_arg { + // Make the local live once, then fill in the value field by field. + self.storage_live(local)?; + // Must be a tuple + let ty::Tuple(fields) = ty.kind() else { + span_bug!(self.cur_span(), "non-tuple type for `spread_arg`: {ty}") + }; + for (i, field_ty) in fields.iter().enumerate() { + let dest = dest.project_deeper( + &[mir::ProjectionElem::Field(FieldIdx::from_usize(i), field_ty)], + *self.tcx, + ); let (idx, callee_abi) = callee_args_abis.next().unwrap(); self.pass_argument( &mut caller_args, callee_abi, idx, &dest, - ty, - /* already_live */ false, + field_ty, + /* already_live */ true, )?; } + } else { + // Normal argument. Cannot mark it as live yet, it might be unsized! + let (idx, callee_abi) = callee_args_abis.next().unwrap(); + self.pass_argument( + &mut caller_args, + callee_abi, + idx, + &dest, + ty, + /* already_live */ false, + )?; } - // If the callee needs a caller location, pretend we consume one more argument from the ABI. - if instance.def.requires_caller_location(*self.tcx) { - callee_args_abis.next().unwrap(); - } - // Now we should have no more caller args or callee arg ABIs. - assert!( - callee_args_abis.next().is_none(), - "mismatch between callee ABI and callee body arguments" - ); - if caller_args.next().is_some() { - throw_ub_format!("calling a function with more arguments than it expected"); - } - // Don't forget to check the return type! - if !self.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? { - throw_ub!(AbiMismatchReturn { - caller_ty: caller_fn_abi.ret.layout.ty, - callee_ty: callee_fn_abi.ret.layout.ty - }); - } + } - // Protect return place for in-place return value passing. - // We only need to protect anything if this is actually an in-memory place. - if let Some(mplace) = destination_mplace { - M::protect_in_place_function_argument(self, &mplace)?; - } + // Don't forget to check the return type! + self.frame_mut().loc = Right(body.local_decls[mir::RETURN_PLACE].source_info.span); + if !self.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? { + throw_ub!(AbiMismatchReturn { + caller_ty: caller_fn_abi.ret.layout.ty, + callee_ty: callee_fn_abi.ret.layout.ty + }); + } + // Protect return place for in-place return value passing. + // We only need to protect anything if this is actually an in-memory place. + if let Some(mplace) = destination_mplace { + M::protect_in_place_function_argument(self, &mplace)?; + } - // Don't forget to mark "initially live" locals as live. - self.storage_live_for_always_live_locals()?; - }; - res.inspect_err_kind(|_| { - // Don't show the incomplete stack frame in the error stacktrace. - self.stack_mut().pop(); - }) + // For the final checks, use same span as preamble since it is unclear what else to do. + self.frame_mut().loc = Right(preamble_span); + // If the callee needs a caller location, pretend we consume one more argument from the ABI. + if instance.def.requires_caller_location(*self.tcx) { + callee_args_abis.next().unwrap(); + } + // Now we should have no more caller args or callee arg ABIs. + assert!( + callee_args_abis.next().is_none(), + "mismatch between callee ABI and callee body arguments" + ); + if caller_args.next().is_some() { + throw_ub_format!("calling a function with more arguments than it expected"); + } + + // Done! + self.push_stack_frame_done() } /// Initiate a call to this function -- pushing the stack frame and initializing the arguments. @@ -663,12 +655,17 @@ pub(super) fn init_fn_call( if caller_abi == ExternAbi::RustCall && !args.is_empty() { // Untuple let (untuple_arg, args) = args.split_last().unwrap(); + let ty::Tuple(untuple_fields) = untuple_arg.layout().ty.kind() else { + span_bug!(self.cur_span(), "untuple argument must be a tuple") + }; trace!("init_fn_call: Will pass last argument by untupling"); Cow::from( args.iter() + // The regular arguments. .map(|a| interp_ok(a.clone())) - .chain((0..untuple_arg.layout().fields.count()).map(|i| { - self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i)) + // The fields of the untupled argument. + .chain((0..untuple_fields.len()).map(|i| { + self.fn_arg_project_field(untuple_arg, FieldIdx::from_usize(i)) })) .collect::<InterpResult<'_, Vec<_>>>()?, )
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d5f69d7..1731118 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -575,10 +575,23 @@ pub fn eval_intrinsic( sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?, sym::copysignf128 => self.float_copysign_intrinsic::<Quad>(args, dest)?, - sym::fabsf16 => self.float_abs_intrinsic::<Half>(args, dest)?, - sym::fabsf32 => self.float_abs_intrinsic::<Single>(args, dest)?, - sym::fabsf64 => self.float_abs_intrinsic::<Double>(args, dest)?, - sym::fabsf128 => self.float_abs_intrinsic::<Quad>(args, dest)?, + sym::fabs => { + let arg = self.read_immediate(&args[0])?; + let ty::Float(float_ty) = arg.layout.ty.kind() else { + span_bug!( + self.cur_span(), + "non-float type for float intrinsic: {}", + arg.layout.ty, + ); + }; + let out_val = match float_ty { + FloatTy::F16 => self.unop_float_intrinsic::<Half>(intrinsic_name, arg)?, + FloatTy::F32 => self.unop_float_intrinsic::<Single>(intrinsic_name, arg)?, + FloatTy::F64 => self.unop_float_intrinsic::<Double>(intrinsic_name, arg)?, + FloatTy::F128 => self.unop_float_intrinsic::<Quad>(intrinsic_name, arg)?, + }; + self.write_scalar(out_val, dest)?; + } sym::floorf16 => self.float_round_intrinsic::<Half>( args, @@ -1020,6 +1033,22 @@ pub(crate) fn raw_eq_intrinsic( interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } + fn unop_float_intrinsic<F>( + &self, + name: Symbol, + arg: ImmTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, Scalar<M::Provenance>> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, + { + let x: F = arg.to_scalar().to_float()?; + match name { + // bitwise, no NaN adjustments + sym::fabs => interp_ok(x.abs().into()), + _ => bug!("not a unary float intrinsic: {}", name), + } + } + fn float_minmax<F>( &self, a: Scalar<M::Provenance>, @@ -1078,20 +1107,6 @@ fn float_copysign_intrinsic<F>( interp_ok(()) } - fn float_abs_intrinsic<F>( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, - { - let x: F = self.read_scalar(&args[0])?.to_float()?; - // bitwise, no NaN adjustments - self.write_scalar(x.abs(), dest)?; - interp_ok(()) - } - fn float_round<F>( &mut self, x: Scalar<M::Provenance>,
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index c47c512..d6cfc55 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs
@@ -174,8 +174,8 @@ enum Op { | sym::simd_le | sym::simd_gt | sym::simd_ge - | sym::simd_fmax - | sym::simd_fmin + | sym::simd_maximum_number_nsz + | sym::simd_minimum_number_nsz | sym::simd_saturating_add | sym::simd_saturating_sub | sym::simd_arith_offset => { @@ -211,8 +211,8 @@ enum Op { sym::simd_le => Op::MirOp(BinOp::Le), sym::simd_gt => Op::MirOp(BinOp::Gt), sym::simd_ge => Op::MirOp(BinOp::Ge), - sym::simd_fmax => Op::FMinMax(MinMax::MaximumNumberNsz), - sym::simd_fmin => Op::FMinMax(MinMax::MinimumNumberNsz), + sym::simd_maximum_number_nsz => Op::FMinMax(MinMax::MaximumNumberNsz), + sym::simd_minimum_number_nsz => Op::FMinMax(MinMax::MinimumNumberNsz), sym::simd_saturating_add => Op::SaturatingOp(BinOp::Add), sym::simd_saturating_sub => Op::SaturatingOp(BinOp::Sub), sym::simd_arith_offset => Op::WrappingOffset,
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index b0f3426..a737672 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -381,7 +381,7 @@ pub(crate) fn push_stack_frame_raw( let locals = IndexVec::from_elem(dead_local, &body.local_decls); let pre_frame = Frame { body, - loc: Right(body.span), // Span used for errors caused during preamble. + loc: Right(self.tcx.def_span(body.source.def_id())), // Span used for errors caused during preamble. return_cont, return_place: return_place.clone(), locals, @@ -408,7 +408,6 @@ pub(crate) fn push_stack_frame_raw( // Finish things up. M::after_stack_push(self)?; - self.frame_mut().loc = Left(mir::Location::START); // `tracing_separate_thread` is used to instruct the tracing_chrome [tracing::Layer] in Miri // to put the "frame" span on a separate trace thread/line than other spans, to make the // visualization in <https://ui.perfetto.dev> easier to interpret. It is set to a value of @@ -466,9 +465,11 @@ pub(super) fn cleanup_stack_frame( } } - /// In the current stack frame, mark all locals as live that are not arguments and don't have - /// `Storage*` annotations (this includes the return place). - pub(crate) fn storage_live_for_always_live_locals(&mut self) -> InterpResult<'tcx> { + /// Call this after `push_stack_frame_raw` and when all the other setup that needs to be done + /// is completed. + pub(crate) fn push_stack_frame_done(&mut self) -> InterpResult<'tcx> { + // Mark all locals as live that are not arguments and don't have `Storage*` annotations + // (this includes the return place, but not the arguments). self.storage_live(mir::RETURN_PLACE)?; let body = self.body(); @@ -478,6 +479,10 @@ pub(crate) fn storage_live_for_always_live_locals(&mut self) -> InterpResult<'tc self.storage_live(local)?; } } + + // Get ready to execute the first instruction in the stack frame. + self.frame_mut().loc = Left(mir::Location::START); + interp_ok(()) }
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 41a4cb2..de34005 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -47,9 +47,9 @@ macro_rules! err_validation_failure { ($where:expr, $msg:expr ) => {{ let where_ = &$where; - let path = if !where_.is_empty() { + let path = if !where_.projs.is_empty() { let mut path = String::new(); - write_path(&mut path, where_); + write_path(&mut path, &where_.projs); Some(path) } else { None @@ -59,6 +59,7 @@ macro_rules! err_validation_failure { use ValidationErrorKind::*; let msg = ValidationErrorKind::from($msg); err_ub!(ValidationError { + orig_ty: where_.orig_ty, path, ptr_bytes_warning: msg.ptr_bytes_warning(), msg: msg.to_string(), @@ -128,7 +129,6 @@ enum ExpectedKind { Reference, Box, RawPtr, - InitScalar, Bool, Char, Float, @@ -143,7 +143,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ExpectedKind::Reference => "expected a reference", ExpectedKind::Box => "expected a box", ExpectedKind::RawPtr => "expected a raw pointer", - ExpectedKind::InitScalar => "expected initialized scalar value", ExpectedKind::Bool => "expected a boolean", ExpectedKind::Char => "expected a unicode scalar value", ExpectedKind::Float => "expected a floating point number", @@ -236,7 +235,7 @@ fn fmt_range(r: WrappingRange, max_hi: u128) -> String { /// So we track a `Vec<PathElem>` where `PathElem` contains all the data we /// need to later print something for the user. #[derive(Copy, Clone, Debug)] -pub enum PathElem { +pub enum PathElem<'tcx> { Field(Symbol), Variant(Symbol), CoroutineState(VariantIdx), @@ -246,10 +245,22 @@ pub enum PathElem { Deref, EnumTag, CoroutineTag, - DynDowncast, + DynDowncast(Ty<'tcx>), Vtable, } +#[derive(Clone, Debug)] +pub struct Path<'tcx> { + orig_ty: Ty<'tcx>, + projs: Vec<PathElem<'tcx>>, +} + +impl<'tcx> Path<'tcx> { + fn new(ty: Ty<'tcx>) -> Self { + Self { orig_ty: ty, projs: vec![] } + } +} + /// Extra things to check for during validation of CTFE results. #[derive(Copy, Clone)] pub enum CtfeValidationMode { @@ -282,16 +293,10 @@ pub struct RefTracking<T, PATH = ()> { todo: Vec<(T, PATH)>, } -impl<T: Clone + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH> { +impl<T: Clone + Eq + Hash + std::fmt::Debug, PATH> RefTracking<T, PATH> { pub fn empty() -> Self { RefTracking { seen: FxHashSet::default(), todo: vec![] } } - pub fn new(val: T) -> Self { - let mut ref_tracking_for_consts = - RefTracking { seen: FxHashSet::default(), todo: vec![(val.clone(), PATH::default())] }; - ref_tracking_for_consts.seen.insert(val); - ref_tracking_for_consts - } pub fn next(&mut self) -> Option<(T, PATH)> { self.todo.pop() } @@ -306,8 +311,17 @@ fn track(&mut self, val: T, path: impl FnOnce() -> PATH) { } } +impl<'tcx, T: Clone + Eq + Hash + std::fmt::Debug> RefTracking<T, Path<'tcx>> { + pub fn new(val: T, ty: Ty<'tcx>) -> Self { + let mut ref_tracking_for_consts = + RefTracking { seen: FxHashSet::default(), todo: vec![(val.clone(), Path::new(ty))] }; + ref_tracking_for_consts.seen.insert(val); + ref_tracking_for_consts + } +} + /// Format a path -fn write_path(out: &mut String, path: &[PathElem]) { +fn write_path(out: &mut String, path: &[PathElem<'_>]) { use self::PathElem::*; for elem in path.iter() { @@ -325,7 +339,7 @@ fn write_path(out: &mut String, path: &[PathElem]) { // even use the usual syntax because we are just showing the projections, // not the root. Deref => write!(out, ".<deref>"), - DynDowncast => write!(out, ".<dyn-downcast>"), + DynDowncast(ty) => write!(out, ".<dyn-downcast({ty})>"), Vtable => write!(out, ".<vtable>"), } .unwrap() @@ -384,10 +398,9 @@ fn add_range(&mut self, offset: Size, size: Size) { struct ValidityVisitor<'rt, 'tcx, M: Machine<'tcx>> { /// The `path` may be pushed to, but the part that is present when a function - /// starts must not be changed! `visit_fields` and `visit_array` rely on - /// this stack discipline. - path: Vec<PathElem>, - ref_tracking: Option<&'rt mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>>, + /// starts must not be changed! `with_elem` relies on this stack discipline. + path: Path<'tcx>, + ref_tracking: Option<&'rt mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Path<'tcx>>>, /// `None` indicates this is not validating for CTFE (but for runtime). ctfe_mode: Option<CtfeValidationMode>, ecx: &'rt mut InterpCx<'tcx, M>, @@ -406,7 +419,12 @@ struct ValidityVisitor<'rt, 'tcx, M: Machine<'tcx>> { } impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { - fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem { + fn aggregate_field_path_elem( + &mut self, + layout: TyAndLayout<'tcx>, + field: usize, + field_ty: Ty<'tcx>, + ) -> PathElem<'tcx> { // First, check if we are projecting to a variant. match layout.variants { Variants::Multiple { tag_field, .. } => { @@ -476,7 +494,7 @@ fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) // dyn traits ty::Dynamic(..) => { assert_eq!(field, 0); - PathElem::DynDowncast + PathElem::DynDowncast(field_ty) } // nothing else has an aggregate layout @@ -486,17 +504,17 @@ fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) fn with_elem<R>( &mut self, - elem: PathElem, + elem: PathElem<'tcx>, f: impl FnOnce(&mut Self) -> InterpResult<'tcx, R>, ) -> InterpResult<'tcx, R> { // Remember the old state - let path_len = self.path.len(); + let path_len = self.path.projs.len(); // Record new element - self.path.push(elem); + self.path.projs.push(elem); // Perform operation let r = f(self)?; // Undo changes - self.path.truncate(path_len); + self.path.projs.truncate(path_len); // Done interp_ok(r) } @@ -680,8 +698,11 @@ fn check_safe_pointer( format!("encountered a {ptr_kind} pointing to uninhabited type {ty}") ) } - // Recursive checking - if let Some(ref_tracking) = self.ref_tracking.as_deref_mut() { + + // Recursive checking (but not inside `MaybeDangling` of course). + if let Some(ref_tracking) = self.ref_tracking.as_deref_mut() + && !self.may_dangle + { // Proceed recursively even for ZST, no reason to skip them! // `!` is a ZST and we want to validate it. if let Some(ctfe_mode) = self.ctfe_mode { @@ -795,10 +816,10 @@ fn check_safe_pointer( ref_tracking.track(place, || { // We need to clone the path anyway, make sure it gets created // with enough space for the additional `Deref`. - let mut new_path = Vec::with_capacity(path.len() + 1); - new_path.extend(path); - new_path.push(PathElem::Deref); - new_path + let mut new_projs = Vec::with_capacity(path.projs.len() + 1); + new_projs.extend(&path.projs); + new_projs.push(PathElem::Deref); + Path { projs: new_projs, orig_ty: path.orig_ty } }); } interp_ok(()) @@ -1219,7 +1240,7 @@ fn visit_field( field: usize, new_val: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - let elem = self.aggregate_field_path_elem(old_val.layout, field); + let elem = self.aggregate_field_path_elem(old_val.layout, field, new_val.layout.ty); self.with_elem(elem, move |this| this.visit_value(new_val)) } @@ -1384,7 +1405,7 @@ fn visit_value(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'t access.bad.start.bytes() / layout.size.bytes(), ) .unwrap(); - self.path.push(PathElem::ArrayElem(i)); + self.path.projs.push(PathElem::ArrayElem(i)); if matches!(kind, Ub(InvalidUninitBytes(_))) { err_validation_failure!(self.path, Uninit { expected }) @@ -1478,7 +1499,9 @@ fn visit_value(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'t BackendRepr::Scalar(scalar_layout) => { if !scalar_layout.is_uninit_valid() { // There is something to check here. - let scalar = self.read_scalar(val, ExpectedKind::InitScalar)?; + // We read directly via `ecx` since the read cannot fail -- we already read + // this field above when recursing into the field. + let scalar = self.ecx.read_scalar(val)?; self.visit_scalar(scalar, scalar_layout)?; } } @@ -1487,8 +1510,9 @@ fn visit_value(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'t // FIXME: find a way to also check ScalarPair when one side can be uninit but // the other must be init. if !a_layout.is_uninit_valid() && !b_layout.is_uninit_valid() { - let (a, b) = - self.read_immediate(val, ExpectedKind::InitScalar)?.to_scalar_pair(); + // We read directly via `ecx` since the read cannot fail -- we already read + // this field above when recursing into the field. + let (a, b) = self.ecx.read_immediate(val)?.to_scalar_pair(); self.visit_scalar(a, a_layout)?; self.visit_scalar(b, b_layout)?; } @@ -1508,13 +1532,15 @@ fn visit_value(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'t } impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { + /// The internal core entry point for all validation operations. fn validate_operand_internal( &mut self, val: &PlaceTy<'tcx, M::Provenance>, - path: Vec<PathElem>, - ref_tracking: Option<&mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>>, + path: Path<'tcx>, + ref_tracking: Option<&mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Path<'tcx>>>, ctfe_mode: Option<CtfeValidationMode>, reset_provenance_and_padding: bool, + start_in_may_dangle: bool, ) -> InterpResult<'tcx> { trace!("validate_operand_internal: {:?}, {:?}", *val, val.layout.ty); @@ -1532,7 +1558,7 @@ fn validate_operand_internal( ecx, reset_provenance_and_padding, data_bytes: reset_padding.then_some(RangeSet(Vec::new())), - may_dangle: false, + may_dangle: start_in_may_dangle, }; v.visit_value(val)?; v.reset_padding(val)?; @@ -1565,8 +1591,8 @@ fn validate_operand_internal( pub(crate) fn const_validate_operand( &mut self, val: &PlaceTy<'tcx, M::Provenance>, - path: Vec<PathElem>, - ref_tracking: &mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>, + path: Path<'tcx>, + ref_tracking: &mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Path<'tcx>>, ctfe_mode: CtfeValidationMode, ) -> InterpResult<'tcx> { self.validate_operand_internal( @@ -1575,6 +1601,7 @@ pub(crate) fn const_validate_operand( Some(ref_tracking), Some(ctfe_mode), /*reset_provenance*/ false, + /*start_in_may_dangle*/ false, ) } @@ -1595,36 +1622,40 @@ pub fn validate_operand( reset_provenance_and_padding, ?val, ); - // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's // still correct to not use `ctfe_mode`: that mode is for validation of the final constant // value, it rules out things like `UnsafeCell` in awkward places. if !recursive { return self.validate_operand_internal( val, - vec![], + Path::new(val.layout.ty), None, None, reset_provenance_and_padding, + /*start_in_may_dangle*/ false, ); } // Do a recursive check. let mut ref_tracking = RefTracking::empty(); self.validate_operand_internal( val, - vec![], + Path::new(val.layout.ty), Some(&mut ref_tracking), None, reset_provenance_and_padding, + /*start_in_may_dangle*/ false, )?; while let Some((mplace, path)) = ref_tracking.todo.pop() { - // Things behind reference do *not* have the provenance reset. + // Things behind reference do *not* have the provenance reset. In fact + // we treat the entire thing as being inside MaybeDangling, i.e., references + // do not have to be dereferenceable. self.validate_operand_internal( &mplace.into(), path, - Some(&mut ref_tracking), + None, // no further recursion None, /*reset_provenance_and_padding*/ false, + /*start_in_may_dangle*/ true, )?; } interp_ok(())
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index a9fff6d..33da1c5 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs
@@ -5,7 +5,6 @@ #![feature(never_type)] #![feature(slice_ptr_get)] #![feature(trait_alias)] -#![feature(try_blocks)] #![feature(unqualified_local_imports)] #![feature(yeet_expr)] #![warn(unqualified_local_imports)]
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 0332ff6..f358fff 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml
@@ -9,7 +9,7 @@ bitflags = "2.4.1" either = "1.0" elsa = "1.11.0" -ena = "0.14.4" +ena = "0.14.3" indexmap = "2.12.1" jobserver_crate = { version = "0.1.28", package = "jobserver" } measureme = "12.0.1"
diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs index bfc7556..d653847 100644 --- a/compiler/rustc_data_structures/src/aligned.rs +++ b/compiler/rustc_data_structures/src/aligned.rs
@@ -1,4 +1,7 @@ use std::marker::PointeeSized; +#[cfg(not(bootstrap))] +use std::mem::Alignment; +#[cfg(bootstrap)] use std::ptr::Alignment; /// Returns the ABI-required minimum alignment of a type in bytes.
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index c7c0d0a..06ab95d 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -181,22 +181,24 @@ fn decode(d: &mut D) -> Self { } } -// `PackedFingerprint` wraps a `Fingerprint`. Its purpose is to, on certain -// architectures, behave like a `Fingerprint` without alignment requirements. -// This behavior is only enabled on x86 and x86_64, where the impact of -// unaligned accesses is tolerable in small doses. -// -// This may be preferable to use in large collections of structs containing -// fingerprints, as it can reduce memory consumption by preventing the padding -// that the more strictly-aligned `Fingerprint` can introduce. An application of -// this is in the query dependency graph, which contains a large collection of -// `DepNode`s. As of this writing, the size of a `DepNode` decreases by ~30% -// (from 24 bytes to 17) by using the packed representation here, which -// noticeably decreases total memory usage when compiling large crates. -// -// The wrapped `Fingerprint` is private to reduce the chance of a client -// invoking undefined behavior by taking a reference to the packed field. -#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))] +/// `PackedFingerprint` wraps a `Fingerprint`. +/// Its purpose is to behave like a `Fingerprint` without alignment requirements. +/// +/// This may be preferable to use in large collections of structs containing +/// fingerprints, as it can reduce memory consumption by preventing the padding +/// that the more strictly-aligned `Fingerprint` can introduce. An application of +/// this is in the query dependency graph, which contains a large collection of +/// `DepNode`s. As of this writing, the size of a `DepNode` decreases by 25% +/// (from 24 bytes to 18) by using the packed representation here, which +/// noticeably decreases total memory usage when compiling large crates. +/// +/// (Unalignment was previously restricted to `x86` and `x86_64` hosts, but is +/// now enabled by default for all host architectures, in the hope that the +/// memory and cache savings should outweigh any unaligned access penalty.) +/// +/// The wrapped `Fingerprint` is private to reduce the chance of a client +/// invoking undefined behavior by taking a reference to the packed field. +#[repr(packed)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] pub struct PackedFingerprint(Fingerprint);
diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index 8079212..e196ff0 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs
@@ -103,11 +103,11 @@ fn hash<H: Hasher>(&self, s: &mut H) { } } -impl<T, CTX> HashStable<CTX> for Interned<'_, T> +impl<T, Hcx> HashStable<Hcx> for Interned<'_, T> where - T: HashStable<CTX>, + T: HashStable<Hcx>, { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.0.hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 2c62034..83cfa02 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -702,7 +702,7 @@ fn compress(&mut self, mut outcome_cb: impl FnMut(&O)) { self.apply_rewrites(&node_rewrites); } - node_rewrites.truncate(0); + node_rewrites.clear(); self.reused_node_vec = node_rewrites; }
diff --git a/compiler/rustc_data_structures/src/packed.rs b/compiler/rustc_data_structures/src/packed.rs index c892153..eef2533 100644 --- a/compiler/rustc_data_structures/src/packed.rs +++ b/compiler/rustc_data_structures/src/packed.rs
@@ -60,10 +60,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl<CTX> HashStable<CTX> for Pu128 { +impl<Hcx> HashStable<Hcx> for Pu128 { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - { self.0 }.hash_stable(ctx, hasher) + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + { self.0 }.hash_stable(hcx, hasher) } }
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 15e3e6e..49c5272 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -347,10 +347,10 @@ fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self { } } -impl<K: HashStable<CTX> + StableOrd, V: HashStable<CTX>, CTX> HashStable<CTX> for SortedMap<K, V> { +impl<K: HashStable<Hcx> + StableOrd, V: HashStable<Hcx>, Hcx> HashStable<Hcx> for SortedMap<K, V> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.data.hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.data.hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index f8e72d6..c9993d1 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -15,7 +15,7 @@ FromStableHash, SipHasher128Hash as StableHasherHash, StableSipHasher128 as StableHasher, }; -/// Something that implements `HashStable<CTX>` can be hashed in a way that is +/// Something that implements `HashStable<Hcx>` can be hashed in a way that is /// stable across multiple compilation sessions. /// /// Note that `HashStable` imposes rather more strict requirements than usual @@ -41,16 +41,16 @@ /// - `hash_stable()` must be independent of the host architecture. The /// `StableHasher` takes care of endianness and `isize`/`usize` platform /// differences. -pub trait HashStable<CTX> { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher); +pub trait HashStable<Hcx> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher); } /// Implement this for types that can be turned into stable keys like, for /// example, for DefId that can be converted to a DefPathHash. This is used for /// bringing maps into a predictable order before hashing them. -pub trait ToStableHashKey<HCX> { - type KeyType: Ord + Sized + HashStable<HCX>; - fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType; +pub trait ToStableHashKey<Hcx> { + type KeyType: Ord + Sized + HashStable<Hcx>; + fn to_stable_hash_key(&self, hcx: &Hcx) -> Self::KeyType; } /// Trait for marking a type as having a sort order that is @@ -136,9 +136,9 @@ fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering { /// Use `#[derive(HashStable_Generic)]` instead. macro_rules! impl_stable_traits_for_trivial_type { ($t:ty) => { - impl<CTX> $crate::stable_hasher::HashStable<CTX> for $t { + impl<Hcx> $crate::stable_hasher::HashStable<Hcx> for $t { #[inline] - fn hash_stable(&self, _: &mut CTX, hasher: &mut $crate::stable_hasher::StableHasher) { + fn hash_stable(&self, _: &mut Hcx, hasher: &mut $crate::stable_hasher::StableHasher) { ::std::hash::Hash::hash(self, hasher); } } @@ -177,9 +177,9 @@ impl $crate::stable_hasher::StableOrd for $t { // We need a custom impl as the default hash function will only hash half the bits. For stable // hashing we want to hash the full 128-bit hash. -impl<CTX> HashStable<CTX> for Hash128 { +impl<Hcx> HashStable<Hcx> for Hash128 { #[inline] - fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, _: &mut Hcx, hasher: &mut StableHasher) { self.as_u128().hash(hasher); } } @@ -192,64 +192,64 @@ impl StableOrd for Hash128 { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<CTX> HashStable<CTX> for ! { - fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for ! { + fn hash_stable(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { unreachable!() } } -impl<CTX, T> HashStable<CTX> for PhantomData<T> { - fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {} +impl<Hcx, T> HashStable<Hcx> for PhantomData<T> { + fn hash_stable(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {} } -impl<CTX> HashStable<CTX> for NonZero<u32> { +impl<Hcx> HashStable<Hcx> for NonZero<u32> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.get().hash_stable(ctx, hasher) + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.get().hash_stable(hcx, hasher) } } -impl<CTX> HashStable<CTX> for NonZero<usize> { +impl<Hcx> HashStable<Hcx> for NonZero<usize> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.get().hash_stable(ctx, hasher) + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.get().hash_stable(hcx, hasher) } } -impl<CTX> HashStable<CTX> for f32 { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for f32 { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let val: u32 = self.to_bits(); - val.hash_stable(ctx, hasher); + val.hash_stable(hcx, hasher); } } -impl<CTX> HashStable<CTX> for f64 { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for f64 { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let val: u64 = self.to_bits(); - val.hash_stable(ctx, hasher); + val.hash_stable(hcx, hasher); } } -impl<CTX> HashStable<CTX> for ::std::cmp::Ordering { +impl<Hcx> HashStable<Hcx> for ::std::cmp::Ordering { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (*self as i8).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (*self as i8).hash_stable(hcx, hasher); } } -impl<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) { +impl<T1: HashStable<Hcx>, Hcx> HashStable<Hcx> for (T1,) { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let (ref _0,) = *self; - _0.hash_stable(ctx, hasher); + _0.hash_stable(hcx, hasher); } } -impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2) { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { +impl<T1: HashStable<Hcx>, T2: HashStable<Hcx>, Hcx> HashStable<Hcx> for (T1, T2) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let (ref _0, ref _1) = *self; - _0.hash_stable(ctx, hasher); - _1.hash_stable(ctx, hasher); + _0.hash_stable(hcx, hasher); + _1.hash_stable(hcx, hasher); } } @@ -261,17 +261,17 @@ impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3) +impl<T1, T2, T3, Hcx> HashStable<Hcx> for (T1, T2, T3) where - T1: HashStable<CTX>, - T2: HashStable<CTX>, - T3: HashStable<CTX>, + T1: HashStable<Hcx>, + T2: HashStable<Hcx>, + T3: HashStable<Hcx>, { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let (ref _0, ref _1, ref _2) = *self; - _0.hash_stable(ctx, hasher); - _1.hash_stable(ctx, hasher); - _2.hash_stable(ctx, hasher); + _0.hash_stable(hcx, hasher); + _1.hash_stable(hcx, hasher); + _2.hash_stable(hcx, hasher); } } @@ -284,19 +284,19 @@ impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4) +impl<T1, T2, T3, T4, Hcx> HashStable<Hcx> for (T1, T2, T3, T4) where - T1: HashStable<CTX>, - T2: HashStable<CTX>, - T3: HashStable<CTX>, - T4: HashStable<CTX>, + T1: HashStable<Hcx>, + T2: HashStable<Hcx>, + T3: HashStable<Hcx>, + T4: HashStable<Hcx>, { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let (ref _0, ref _1, ref _2, ref _3) = *self; - _0.hash_stable(ctx, hasher); - _1.hash_stable(ctx, hasher); - _2.hash_stable(ctx, hasher); - _3.hash_stable(ctx, hasher); + _0.hash_stable(hcx, hasher); + _1.hash_stable(hcx, hasher); + _2.hash_stable(hcx, hasher); + _3.hash_stable(hcx, hasher); } } @@ -311,93 +311,93 @@ impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for ( const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] { - default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); +impl<T: HashStable<Hcx>, Hcx> HashStable<Hcx> for [T] { + default fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); for item in self { - item.hash_stable(ctx, hasher); + item.hash_stable(hcx, hasher); } } } -impl<CTX> HashStable<CTX> for [u8] { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); +impl<Hcx> HashStable<Hcx> for [u8] { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); hasher.write(self); } } -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> { +impl<T: HashStable<Hcx>, Hcx> HashStable<Hcx> for Vec<T> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self[..].hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self[..].hash_stable(hcx, hasher); } } -impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R> +impl<K, V, R, Hcx> HashStable<Hcx> for indexmap::IndexMap<K, V, R> where - K: HashStable<CTX> + Eq + Hash, - V: HashStable<CTX>, + K: HashStable<Hcx> + Eq + Hash, + V: HashStable<Hcx>, R: BuildHasher, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); for kv in self { - kv.hash_stable(ctx, hasher); + kv.hash_stable(hcx, hasher); } } } -impl<K, R, CTX> HashStable<CTX> for indexmap::IndexSet<K, R> +impl<K, R, Hcx> HashStable<Hcx> for indexmap::IndexSet<K, R> where - K: HashStable<CTX> + Eq + Hash, + K: HashStable<Hcx> + Eq + Hash, R: BuildHasher, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); for key in self { - key.hash_stable(ctx, hasher); + key.hash_stable(hcx, hasher); } } } -impl<A, const N: usize, CTX> HashStable<CTX> for SmallVec<[A; N]> +impl<A, const N: usize, Hcx> HashStable<Hcx> for SmallVec<[A; N]> where - A: HashStable<CTX>, + A: HashStable<Hcx>, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self[..].hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self[..].hash_stable(hcx, hasher); } } -impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> { +impl<T: ?Sized + HashStable<Hcx>, Hcx> HashStable<Hcx> for Box<T> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (**self).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); } } -impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> { +impl<T: ?Sized + HashStable<Hcx>, Hcx> HashStable<Hcx> for ::std::rc::Rc<T> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (**self).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); } } -impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> { +impl<T: ?Sized + HashStable<Hcx>, Hcx> HashStable<Hcx> for ::std::sync::Arc<T> { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (**self).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); } } -impl<CTX> HashStable<CTX> for str { +impl<Hcx> HashStable<Hcx> for str { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.as_bytes().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.as_bytes().hash_stable(hcx, hasher); } } @@ -409,9 +409,9 @@ impl StableOrd for &str { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<CTX> HashStable<CTX> for String { +impl<Hcx> HashStable<Hcx> for String { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self[..].hash_stable(hcx, hasher); } } @@ -424,26 +424,26 @@ impl StableOrd for String { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<HCX> ToStableHashKey<HCX> for String { +impl<Hcx> ToStableHashKey<Hcx> for String { type KeyType = String; #[inline] - fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { + fn to_stable_hash_key(&self, _: &Hcx) -> Self::KeyType { self.clone() } } -impl<HCX, T1: ToStableHashKey<HCX>, T2: ToStableHashKey<HCX>> ToStableHashKey<HCX> for (T1, T2) { +impl<Hcx, T1: ToStableHashKey<Hcx>, T2: ToStableHashKey<Hcx>> ToStableHashKey<Hcx> for (T1, T2) { type KeyType = (T1::KeyType, T2::KeyType); #[inline] - fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType { + fn to_stable_hash_key(&self, hcx: &Hcx) -> Self::KeyType { (self.0.to_stable_hash_key(hcx), self.1.to_stable_hash_key(hcx)) } } -impl<CTX> HashStable<CTX> for bool { +impl<Hcx> HashStable<Hcx> for bool { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (if *self { 1u8 } else { 0u8 }).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (if *self { 1u8 } else { 0u8 }).hash_stable(hcx, hasher); } } @@ -454,17 +454,17 @@ impl StableOrd for bool { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<T, CTX> HashStable<CTX> for Option<T> +impl<T, Hcx> HashStable<Hcx> for Option<T> where - T: HashStable<CTX>, + T: HashStable<Hcx>, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { if let Some(ref value) = *self { - 1u8.hash_stable(ctx, hasher); - value.hash_stable(ctx, hasher); + 1u8.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); } else { - 0u8.hash_stable(ctx, hasher); + 0u8.hash_stable(hcx, hasher); } } } @@ -476,81 +476,81 @@ impl<T: StableOrd> StableOrd for Option<T> { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } -impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2> +impl<T1, T2, Hcx> HashStable<Hcx> for Result<T1, T2> where - T1: HashStable<CTX>, - T2: HashStable<CTX>, + T1: HashStable<Hcx>, + T2: HashStable<Hcx>, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - mem::discriminant(self).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); match *self { - Ok(ref x) => x.hash_stable(ctx, hasher), - Err(ref x) => x.hash_stable(ctx, hasher), + Ok(ref x) => x.hash_stable(hcx, hasher), + Err(ref x) => x.hash_stable(hcx, hasher), } } } -impl<'a, T, CTX> HashStable<CTX> for &'a T +impl<'a, T, Hcx> HashStable<Hcx> for &'a T where - T: HashStable<CTX> + ?Sized, + T: HashStable<Hcx> + ?Sized, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - (**self).hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); } } -impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> { +impl<T, Hcx> HashStable<Hcx> for ::std::mem::Discriminant<T> { #[inline] - fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, _: &mut Hcx, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } } -impl<T, CTX> HashStable<CTX> for ::std::ops::RangeInclusive<T> +impl<T, Hcx> HashStable<Hcx> for ::std::ops::RangeInclusive<T> where - T: HashStable<CTX>, + T: HashStable<Hcx>, { #[inline] - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.start().hash_stable(ctx, hasher); - self.end().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.start().hash_stable(hcx, hasher); + self.end().hash_stable(hcx, hasher); } } -impl<I: Idx, T, CTX> HashStable<CTX> for IndexSlice<I, T> +impl<I: Idx, T, Hcx> HashStable<Hcx> for IndexSlice<I, T> where - T: HashStable<CTX>, + T: HashStable<Hcx>, { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); for v in &self.raw { - v.hash_stable(ctx, hasher); + v.hash_stable(hcx, hasher); } } } -impl<I: Idx, T, CTX> HashStable<CTX> for IndexVec<I, T> +impl<I: Idx, T, Hcx> HashStable<Hcx> for IndexVec<I, T> where - T: HashStable<CTX>, + T: HashStable<Hcx>, { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.len().hash_stable(ctx, hasher); + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + self.len().hash_stable(hcx, hasher); for v in &self.raw { - v.hash_stable(ctx, hasher); + v.hash_stable(hcx, hasher); } } } -impl<I: Idx, CTX> HashStable<CTX> for DenseBitSet<I> { - fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { +impl<I: Idx, Hcx> HashStable<Hcx> for DenseBitSet<I> { + fn hash_stable(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } } -impl<R: Idx, C: Idx, CTX> HashStable<CTX> for bit_set::BitMatrix<R, C> { - fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { +impl<R: Idx, C: Idx, Hcx> HashStable<Hcx> for bit_set::BitMatrix<R, C> { + fn hash_stable(&self, _hcx: &mut Hcx, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } } @@ -563,15 +563,15 @@ fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { // It is not safe to implement HashStable for HashSet, HashMap or any other collection type // with unstable but observable iteration order. // See https://github.com/rust-lang/compiler-team/issues/533 for further information. -impl<V, HCX> !HashStable<HCX> for std::collections::HashSet<V> {} -impl<K, V, HCX> !HashStable<HCX> for std::collections::HashMap<K, V> {} +impl<V, Hcx> !HashStable<Hcx> for std::collections::HashSet<V> {} +impl<K, V, Hcx> !HashStable<Hcx> for std::collections::HashMap<K, V> {} -impl<K, V, HCX> HashStable<HCX> for ::std::collections::BTreeMap<K, V> +impl<K, V, Hcx> HashStable<Hcx> for ::std::collections::BTreeMap<K, V> where - K: HashStable<HCX> + StableOrd, - V: HashStable<HCX>, + K: HashStable<Hcx> + StableOrd, + V: HashStable<Hcx>, { - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.len().hash_stable(hcx, hasher); for entry in self.iter() { entry.hash_stable(hcx, hasher); @@ -579,11 +579,11 @@ fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { } } -impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K> +impl<K, Hcx> HashStable<Hcx> for ::std::collections::BTreeSet<K> where - K: HashStable<HCX> + StableOrd, + K: HashStable<Hcx> + StableOrd, { - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.len().hash_stable(hcx, hasher); for entry in self.iter() { entry.hash_stable(hcx, hasher);
diff --git a/compiler/rustc_data_structures/src/stable_hasher/tests.rs b/compiler/rustc_data_structures/src/stable_hasher/tests.rs index 635f241..55a666d 100644 --- a/compiler/rustc_data_structures/src/stable_hasher/tests.rs +++ b/compiler/rustc_data_structures/src/stable_hasher/tests.rs
@@ -44,8 +44,8 @@ struct Foo { b: $ty, } - impl<CTX> HashStable<CTX> for Foo { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + impl<Hcx> HashStable<Hcx> for Foo { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.a.hash_stable(hcx, hasher); self.b.hash_stable(hcx, hasher); }
diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs index afa9bc3..184acfe 100644 --- a/compiler/rustc_data_structures/src/steal.rs +++ b/compiler/rustc_data_structures/src/steal.rs
@@ -71,8 +71,8 @@ pub fn is_stolen(&self) -> bool { } } -impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx, T: HashStable<Hcx>> HashStable<Hcx> for Steal<T> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.borrow().hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index b112ecc..966c34f 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -145,7 +145,9 @@ fn par_slice<I: DynSend>( const MAX_GROUP_COUNT: usize = 128; let group_size = items.len().div_ceil(MAX_GROUP_COUNT); - let groups = items.chunks_mut(group_size); + let mut groups = items.chunks_mut(group_size); + + let Some(first_group) = groups.next() else { return }; // Reverse the order of the later functions since Rayon executes them in reverse // order when using a single thread. This ensures the execution order matches @@ -159,6 +161,11 @@ fn par_slice<I: DynSend>( } }); } + + // Run the first function without spawning to avoid overwhelming stealing. + for i in first_group.iter_mut() { + guard.run(|| for_each(i)); + } }); }
diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index 94db421..32f8138 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs
@@ -55,7 +55,12 @@ pub unsafe trait Tag: Copy { /// Returns the number of bits available for use for tags in a pointer to `T` /// (this is based on `T`'s alignment). pub const fn bits_for<T: ?Sized + Aligned>() -> u32 { - crate::aligned::align_of::<T>().as_nonzero().trailing_zeros() + let alignment = crate::aligned::align_of::<T>(); + #[cfg(bootstrap)] + let alignment = alignment.as_nonzero(); + #[cfg(not(bootstrap))] + let alignment = alignment.as_nonzero_usize(); + alignment.trailing_zeros() } /// Returns the correct [`Tag::BITS`] constant for a set of tag values. @@ -257,12 +262,12 @@ fn hash<H: Hasher>(&self, state: &mut H) { } } -impl<'a, P, T, HCX> HashStable<HCX> for TaggedRef<'a, P, T> +impl<'a, P, T, Hcx> HashStable<Hcx> for TaggedRef<'a, P, T> where - P: HashStable<HCX> + Aligned + ?Sized, - T: Tag + HashStable<HCX>, + P: HashStable<Hcx> + Aligned + ?Sized, + T: Tag + HashStable<Hcx>, { - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.pointer().hash_stable(hcx, hasher); self.tag().hash_stable(hcx, hasher); }
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index 85b21a7..e663df5 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
@@ -32,8 +32,8 @@ unsafe fn from_usize(tag: usize) -> Self { } } -impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 { - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) { +impl<Hcx> crate::stable_hasher::HashStable<Hcx> for Tag2 { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut crate::stable_hasher::StableHasher) { (*self as u8).hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index eb29ef3..8a3b3e2 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs
@@ -143,9 +143,9 @@ pub fn copied(self) -> UnordItems<T, impl Iterator<Item = T>> { impl<T, I: Iterator<Item = T>> UnordItems<T, I> { #[inline] - pub fn into_sorted<HCX>(self, hcx: &HCX) -> Vec<T> + pub fn into_sorted<Hcx>(self, hcx: &Hcx) -> Vec<T> where - T: ToStableHashKey<HCX>, + T: ToStableHashKey<Hcx>, { self.collect_sorted(hcx, true) } @@ -168,9 +168,9 @@ pub fn into_sorted_stable_ord_by_key<K, C>(self, project_to_key: C) -> Vec<T> } #[inline] - pub fn collect_sorted<HCX, C>(self, hcx: &HCX, cache_sort_key: bool) -> C + pub fn collect_sorted<Hcx, C>(self, hcx: &Hcx, cache_sort_key: bool) -> C where - T: ToStableHashKey<HCX>, + T: ToStableHashKey<Hcx>, C: FromIterator<T> + BorrowMut<[T]>, { let mut items: C = self.0.collect(); @@ -315,9 +315,9 @@ pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> { /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation /// for `V` is expensive (e.g. a `DefId -> DefPathHash` lookup). #[inline] - pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<&V> + pub fn to_sorted<Hcx>(&self, hcx: &Hcx, cache_sort_key: bool) -> Vec<&V> where - V: ToStableHashKey<HCX>, + V: ToStableHashKey<Hcx>, { to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&x| x) } @@ -357,9 +357,9 @@ pub fn into_sorted_stable_ord(self) -> Vec<V> /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation /// for `V` is expensive (e.g. a `DefId -> DefPathHash` lookup). #[inline] - pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<V> + pub fn into_sorted<Hcx>(self, hcx: &Hcx, cache_sort_key: bool) -> Vec<V> where - V: ToStableHashKey<HCX>, + V: ToStableHashKey<Hcx>, { to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x) } @@ -415,9 +415,9 @@ fn from(value: UnordItems<V, I>) -> Self { } } -impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> { +impl<Hcx, V: Hash + Eq + HashStable<Hcx>> HashStable<Hcx> for UnordSet<V> { #[inline] - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { hash_iter_order_independent(self.inner.iter(), hcx, hasher); } } @@ -555,9 +555,9 @@ pub fn keys(&self) -> UnordItems<&K, impl Iterator<Item = &K>> { /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup). #[inline] - pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<(&K, &V)> + pub fn to_sorted<Hcx>(&self, hcx: &Hcx, cache_sort_key: bool) -> Vec<(&K, &V)> where - K: ToStableHashKey<HCX>, + K: ToStableHashKey<Hcx>, { to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k) } @@ -582,9 +582,9 @@ pub fn to_sorted_stable_ord(&self) -> Vec<(&K, &V)> /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup). #[inline] - pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<(K, V)> + pub fn into_sorted<Hcx>(self, hcx: &Hcx, cache_sort_key: bool) -> Vec<(K, V)> where - K: ToStableHashKey<HCX>, + K: ToStableHashKey<Hcx>, { to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |(k, _)| k) } @@ -610,9 +610,9 @@ pub fn into_sorted_stable_ord(self) -> Vec<(K, V)> /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup). #[inline] - pub fn values_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> impl Iterator<Item = &V> + pub fn values_sorted<Hcx>(&self, hcx: &Hcx, cache_sort_key: bool) -> impl Iterator<Item = &V> where - K: ToStableHashKey<HCX>, + K: ToStableHashKey<Hcx>, { to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k) .into_iter() @@ -638,9 +638,9 @@ fn index(&self, key: &Q) -> &V { } } -impl<HCX, K: Hash + Eq + HashStable<HCX>, V: HashStable<HCX>> HashStable<HCX> for UnordMap<K, V> { +impl<Hcx, K: Hash + Eq + HashStable<Hcx>, V: HashStable<Hcx>> HashStable<Hcx> for UnordMap<K, V> { #[inline] - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { hash_iter_order_independent(self.inner.iter(), hcx, hasher); } } @@ -701,23 +701,23 @@ fn from(value: UnordItems<T, I>) -> Self { } } -impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordBag<V> { +impl<Hcx, V: Hash + Eq + HashStable<Hcx>> HashStable<Hcx> for UnordBag<V> { #[inline] - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { hash_iter_order_independent(self.inner.iter(), hcx, hasher); } } #[inline] -fn to_sorted_vec<HCX, T, K, I>( - hcx: &HCX, +fn to_sorted_vec<Hcx, T, K, I>( + hcx: &Hcx, iter: I, cache_sort_key: bool, extract_key: fn(&T) -> &K, ) -> Vec<T> where I: Iterator<Item = T>, - K: ToStableHashKey<HCX>, + K: ToStableHashKey<Hcx>, { let mut items: Vec<T> = iter.collect(); if cache_sort_key { @@ -730,12 +730,12 @@ fn to_sorted_vec<HCX, T, K, I>( } fn hash_iter_order_independent< - HCX, - T: HashStable<HCX>, + Hcx, + T: HashStable<Hcx>, I: Iterator<Item = T> + ExactSizeIterator, >( mut it: I, - hcx: &mut HCX, + hcx: &mut Hcx, hasher: &mut StableHasher, ) { let len = it.len();
diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index aea5924..6d026bb 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs
@@ -6,12 +6,16 @@ //! //! This is currently used for query caching. -use std::fmt::Debug; +use std::fmt::{self, Debug}; use std::marker::PhantomData; +use std::ops::{Index, IndexMut}; use std::sync::atomic::{AtomicPtr, AtomicU32, AtomicUsize, Ordering}; use rustc_index::Idx; +#[cfg(test)] +mod tests; + struct Slot<V> { // We never construct &Slot<V> so it's fine for this to not be in an UnsafeCell. value: V, @@ -28,7 +32,7 @@ struct Slot<V> { #[derive(Copy, Clone, Debug)] struct SlotIndex { // the index of the bucket in VecCache (0 to 20) - bucket_idx: usize, + bucket_idx: BucketIndex, // the index of the slot within the bucket index_in_bucket: usize, } @@ -42,7 +46,7 @@ struct SlotIndex { let mut key = 0; loop { let si = SlotIndex::from_index(key); - entries[si.bucket_idx] = si.entries(); + entries[si.bucket_idx.to_usize()] = si.bucket_idx.capacity(); if key == 0 { key = 1; } else if key == (1 << 31) { @@ -57,48 +61,24 @@ struct SlotIndex { const BUCKETS: usize = 21; impl SlotIndex { - /// The total possible number of entries in the bucket - const fn entries(&self) -> usize { - if self.bucket_idx == 0 { 1 << 12 } else { 1 << (self.bucket_idx + 11) } - } - - // This unpacks a flat u32 index into identifying which bucket it belongs to and the offset - // within that bucket. As noted in the VecCache docs, buckets double in size with each index. - // Typically that would mean 31 buckets (2^0 + 2^1 ... + 2^31 = u32::MAX - 1), but to reduce - // the size of the VecCache struct and avoid uselessly small allocations, we instead have the - // first bucket have 2**12 entries. To simplify the math, the second bucket also 2**12 entries, - // and buckets double from there. - // - // We assert that [0, 2**32 - 1] uniquely map through this function to individual, consecutive - // slots (see `slot_index_exhaustive` in tests). + /// Unpacks a flat 32-bit index into a [`BucketIndex`] and a slot offset within that bucket. #[inline] const fn from_index(idx: u32) -> Self { - const FIRST_BUCKET_SHIFT: usize = 12; - if idx < (1 << FIRST_BUCKET_SHIFT) { - return SlotIndex { bucket_idx: 0, index_in_bucket: idx as usize }; - } - // We already ruled out idx 0, so this `ilog2` never panics (and the check optimizes away) - let bucket = idx.ilog2() as usize; - let entries = 1 << bucket; - SlotIndex { - bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1, - index_in_bucket: idx as usize - entries, - } + let (bucket_idx, index_in_bucket) = BucketIndex::from_flat_index(idx as usize); + SlotIndex { bucket_idx, index_in_bucket } } // SAFETY: Buckets must be managed solely by functions here (i.e., get/put on SlotIndex) and // `self` comes from SlotIndex::from_index #[inline] unsafe fn get<V: Copy>(&self, buckets: &[AtomicPtr<Slot<V>>; 21]) -> Option<(V, u32)> { - // SAFETY: `bucket_idx` is ilog2(u32).saturating_sub(11), which is at most 21, i.e., - // in-bounds of buckets. See `from_index` for computation. - let bucket = unsafe { buckets.get_unchecked(self.bucket_idx) }; + let bucket = &buckets[self.bucket_idx]; let ptr = bucket.load(Ordering::Acquire); // Bucket is not yet initialized: then we obviously won't find this entry in that bucket. if ptr.is_null() { return None; } - debug_assert!(self.index_in_bucket < self.entries()); + debug_assert!(self.index_in_bucket < self.bucket_idx.capacity()); // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this // must be inbounds. let slot = unsafe { ptr.add(self.index_in_bucket) }; @@ -131,7 +111,7 @@ fn bucket_ptr<V>(&self, bucket: &AtomicPtr<Slot<V>>) -> *mut Slot<V> { #[cold] #[inline(never)] - fn initialize_bucket<V>(bucket: &AtomicPtr<Slot<V>>, bucket_idx: usize) -> *mut Slot<V> { + fn initialize_bucket<V>(bucket: &AtomicPtr<Slot<V>>, bucket_idx: BucketIndex) -> *mut Slot<V> { static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); // If we are initializing the bucket, then acquire a global lock. @@ -145,8 +125,8 @@ fn initialize_bucket<V>(bucket: &AtomicPtr<Slot<V>>, bucket_idx: usize) -> *mut // OK, now under the allocator lock, if we're still null then it's definitely us that will // initialize this bucket. if ptr.is_null() { - let bucket_len = SlotIndex { bucket_idx, index_in_bucket: 0 }.entries(); - let bucket_layout = std::alloc::Layout::array::<Slot<V>>(bucket_len).unwrap(); + let bucket_layout = + std::alloc::Layout::array::<Slot<V>>(bucket_idx.capacity()).unwrap(); // This is more of a sanity check -- this code is very cold, so it's safe to pay a // little extra cost here. assert!(bucket_layout.size() > 0); @@ -167,12 +147,10 @@ fn initialize_bucket<V>(bucket: &AtomicPtr<Slot<V>>, bucket_idx: usize) -> *mut /// Returns true if this successfully put into the map. #[inline] fn put<V>(&self, buckets: &[AtomicPtr<Slot<V>>; 21], value: V, extra: u32) -> bool { - // SAFETY: `bucket_idx` is ilog2(u32).saturating_sub(11), which is at most 21, i.e., - // in-bounds of buckets. - let bucket = unsafe { buckets.get_unchecked(self.bucket_idx) }; + let bucket = &buckets[self.bucket_idx]; let ptr = self.bucket_ptr(bucket); - debug_assert!(self.index_in_bucket < self.entries()); + debug_assert!(self.index_in_bucket < self.bucket_idx.capacity()); // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this // must be inbounds. let slot = unsafe { ptr.add(self.index_in_bucket) }; @@ -209,12 +187,10 @@ fn initialize_bucket<V>(bucket: &AtomicPtr<Slot<V>>, bucket_idx: usize) -> *mut /// Inserts into the map, given that the slot is unique, so it won't race with other threads. #[inline] unsafe fn put_unique<V>(&self, buckets: &[AtomicPtr<Slot<V>>; 21], value: V, extra: u32) { - // SAFETY: `bucket_idx` is ilog2(u32).saturating_sub(11), which is at most 21, i.e., - // in-bounds of buckets. - let bucket = unsafe { buckets.get_unchecked(self.bucket_idx) }; + let bucket = &buckets[self.bucket_idx]; let ptr = self.bucket_ptr(bucket); - debug_assert!(self.index_in_bucket < self.entries()); + debug_assert!(self.index_in_bucket < self.bucket_idx.capacity()); // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this // must be inbounds. let slot = unsafe { ptr.add(self.index_in_bucket) }; @@ -254,7 +230,7 @@ pub struct VecCache<K: Idx, V, I> { // ... // Bucket 19: 1073741824 // Bucket 20: 2147483648 - // The total number of entries if all buckets are initialized is u32::MAX-1. + // The total number of entries if all buckets are initialized is 2^32. buckets: [AtomicPtr<Slot<V>>; BUCKETS], // In the compiler's current usage these are only *read* during incremental and self-profiling. @@ -289,7 +265,7 @@ fn drop(&mut self) { assert!(!std::mem::needs_drop::<K>()); assert!(!std::mem::needs_drop::<V>()); - for (idx, bucket) in self.buckets.iter().enumerate() { + for (idx, bucket) in BucketIndex::enumerate_buckets(&self.buckets) { let bucket = bucket.load(Ordering::Acquire); if !bucket.is_null() { let layout = std::alloc::Layout::array::<Slot<V>>(ENTRIES_BY_BUCKET[idx]).unwrap(); @@ -299,7 +275,7 @@ fn drop(&mut self) { } } - for (idx, bucket) in self.present.iter().enumerate() { + for (idx, bucket) in BucketIndex::enumerate_buckets(&self.present) { let bucket = bucket.load(Ordering::Acquire); if !bucket.is_null() { let layout = std::alloc::Layout::array::<Slot<()>>(ENTRIES_BY_BUCKET[idx]).unwrap(); @@ -365,5 +341,164 @@ pub fn len(&self) -> usize { } } -#[cfg(test)] -mod tests; +/// Index into an array of buckets. +/// +/// Using an enum lets us tell the compiler that values range from 0 to 20, +/// allowing array bounds checks to be optimized away, +/// without having to resort to pattern types or other unstable features. +#[derive(Clone, Copy, PartialEq, Eq)] +#[repr(usize)] +enum BucketIndex { + // tidy-alphabetical-start + Bucket00, + Bucket01, + Bucket02, + Bucket03, + Bucket04, + Bucket05, + Bucket06, + Bucket07, + Bucket08, + Bucket09, + Bucket10, + Bucket11, + Bucket12, + Bucket13, + Bucket14, + Bucket15, + Bucket16, + Bucket17, + Bucket18, + Bucket19, + Bucket20, + // tidy-alphabetical-end +} + +impl Debug for BucketIndex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Debug::fmt(&self.to_usize(), f) + } +} + +impl BucketIndex { + /// Capacity of bucket 0 (and also of bucket 1). + const BUCKET_0_CAPACITY: usize = 1 << (Self::NONZERO_BUCKET_SHIFT_ADJUST + 1); + /// Adjustment factor from the highest-set-bit-position of a flat index, + /// to its corresponding bucket number. + /// + /// For example, the first flat-index in bucket 2 is 8192. + /// Its highest-set-bit-position is `(8192).ilog2() == 13`, and subtracting + /// the adjustment factor of 11 gives the bucket number of 2. + const NONZERO_BUCKET_SHIFT_ADJUST: usize = 11; + + #[inline(always)] + const fn to_usize(self) -> usize { + self as usize + } + + #[inline(always)] + const fn from_raw(raw: usize) -> Self { + match raw { + // tidy-alphabetical-start + 00 => Self::Bucket00, + 01 => Self::Bucket01, + 02 => Self::Bucket02, + 03 => Self::Bucket03, + 04 => Self::Bucket04, + 05 => Self::Bucket05, + 06 => Self::Bucket06, + 07 => Self::Bucket07, + 08 => Self::Bucket08, + 09 => Self::Bucket09, + 10 => Self::Bucket10, + 11 => Self::Bucket11, + 12 => Self::Bucket12, + 13 => Self::Bucket13, + 14 => Self::Bucket14, + 15 => Self::Bucket15, + 16 => Self::Bucket16, + 17 => Self::Bucket17, + 18 => Self::Bucket18, + 19 => Self::Bucket19, + 20 => Self::Bucket20, + // tidy-alphabetical-end + _ => panic!("bucket index out of range"), + } + } + + /// Total number of slots in this bucket. + #[inline(always)] + const fn capacity(self) -> usize { + match self { + Self::Bucket00 => Self::BUCKET_0_CAPACITY, + // Bucket 1 has a capacity of `1 << (1 + 11) == pow(2, 12) == 4096`. + // Bucket 2 has a capacity of `1 << (2 + 11) == pow(2, 13) == 8192`. + _ => 1 << (self.to_usize() + Self::NONZERO_BUCKET_SHIFT_ADJUST), + } + } + + /// Converts a flat index in the range `0..=u32::MAX` into a bucket index, + /// and a slot offset within that bucket. + /// + /// Panics if `flat > u32::MAX`. + #[inline(always)] + const fn from_flat_index(flat: usize) -> (Self, usize) { + if flat > u32::MAX as usize { + panic!(); + } + + // If the index is in bucket 0, the conversion is trivial. + // This also avoids calling `ilog2` when `flat == 0`. + if flat < Self::BUCKET_0_CAPACITY { + return (Self::Bucket00, flat); + } + + // General-case conversion for a non-zero bucket index. + // + // | bucket | slot + // flat | ilog2 | index | offset + // ------------------------------ + // 4096 | 12 | 1 | 0 + // 4097 | 12 | 1 | 1 + // ... + // 8191 | 12 | 1 | 4095 + // 8192 | 13 | 2 | 0 + let highest_bit_pos = flat.ilog2() as usize; + let bucket_index = + BucketIndex::from_raw(highest_bit_pos - Self::NONZERO_BUCKET_SHIFT_ADJUST); + + // Clear the highest-set bit (which selects the bucket) to get the + // slot offset within this bucket. + let slot_offset = flat - (1 << highest_bit_pos); + + (bucket_index, slot_offset) + } + + #[inline(always)] + fn iter_all() -> impl ExactSizeIterator<Item = Self> { + (0usize..BUCKETS).map(BucketIndex::from_raw) + } + + #[inline(always)] + fn enumerate_buckets<T>(buckets: &[T; BUCKETS]) -> impl ExactSizeIterator<Item = (Self, &T)> { + BucketIndex::iter_all().zip(buckets) + } +} + +impl<T> Index<BucketIndex> for [T; BUCKETS] { + type Output = T; + + #[inline(always)] + fn index(&self, index: BucketIndex) -> &Self::Output { + // The optimizer should be able to see that see that a bucket index is + // always in-bounds, and omit the runtime bounds check. + &self[index.to_usize()] + } +} + +impl<T> IndexMut<BucketIndex> for [T; BUCKETS] { + #[inline(always)] + fn index_mut(&mut self, index: BucketIndex) -> &mut Self::Output { + &mut self[index.to_usize()] + } +}
diff --git a/compiler/rustc_data_structures/src/vec_cache/tests.rs b/compiler/rustc_data_structures/src/vec_cache/tests.rs index f588442..f12937a 100644 --- a/compiler/rustc_data_structures/src/vec_cache/tests.rs +++ b/compiler/rustc_data_structures/src/vec_cache/tests.rs
@@ -1,10 +1,46 @@ use super::*; #[test] +#[should_panic(expected = "bucket index out of range")] +fn bucket_index_n_buckets() { + BucketIndex::from_raw(BUCKETS); +} + +#[test] +fn bucket_index_round_trip() { + for i in 0..BUCKETS { + assert_eq!(BucketIndex::from_raw(i).to_usize(), i); + } +} + +#[test] +fn bucket_index_iter_all_len() { + let len = BucketIndex::iter_all().len(); + assert_eq!(len, BUCKETS); + + let len = BucketIndex::iter_all().collect::<Vec<_>>().len(); + assert_eq!(len, BUCKETS); + + let len = BucketIndex::enumerate_buckets(&[(); BUCKETS]).len(); + assert_eq!(len, BUCKETS); +} + +#[test] +fn bucket_index_capacity() { + // Check that the combined capacity of all buckets is 2^32 slots. + // That's 1 larger than `u32::MAX`, so store the total as a `u64`. + let mut total = 0u64; + for i in BucketIndex::iter_all() { + total += u64::try_from(i.capacity()).unwrap(); + } + assert_eq!(total, 1 << 32); +} + +#[test] #[cfg(not(miri))] -fn vec_cache_empty() { +fn vec_cache_empty_exhaustive() { let cache: VecCache<u32, u32, u32> = VecCache::default(); - for key in 0..u32::MAX { + for key in 0..=u32::MAX { assert!(cache.lookup(&key).is_none()); } } @@ -70,8 +106,8 @@ fn slot_entries_table() { #[test] fn bucket_entries_matches() { - for i in 0..BUCKETS { - assert_eq!(SlotIndex { bucket_idx: i, index_in_bucket: 0 }.entries(), ENTRIES_BY_BUCKET[i]); + for i in BucketIndex::iter_all() { + assert_eq!(i.capacity(), ENTRIES_BY_BUCKET[i]); } } @@ -84,13 +120,13 @@ fn slot_index_exhaustive() { } let slot_idx = SlotIndex::from_index(0); assert_eq!(slot_idx.index_in_bucket, 0); - assert_eq!(slot_idx.bucket_idx, 0); + assert_eq!(slot_idx.bucket_idx, BucketIndex::Bucket00); let mut prev = slot_idx; for idx in 1..=u32::MAX { let slot_idx = SlotIndex::from_index(idx); // SAFETY: Ensure indices don't go out of bounds of buckets. - assert!(slot_idx.index_in_bucket < slot_idx.entries()); + assert!(slot_idx.index_in_bucket < slot_idx.bucket_idx.capacity()); if prev.bucket_idx == slot_idx.bucket_idx { assert_eq!(prev.index_in_bucket + 1, slot_idx.index_in_bucket); @@ -98,8 +134,8 @@ fn slot_index_exhaustive() { assert_eq!(slot_idx.index_in_bucket, 0); } - assert_eq!(buckets[slot_idx.bucket_idx], slot_idx.entries() as u32); - assert_eq!(ENTRIES_BY_BUCKET[slot_idx.bucket_idx], slot_idx.entries(), "{}", idx); + assert_eq!(buckets[slot_idx.bucket_idx], slot_idx.bucket_idx.capacity() as u32); + assert_eq!(ENTRIES_BY_BUCKET[slot_idx.bucket_idx], slot_idx.bucket_idx.capacity(), "{idx}",); prev = slot_idx; }
diff --git a/compiler/rustc_errors/src/decorate_diag.rs b/compiler/rustc_errors/src/decorate_diag.rs index a11082e..61dd8f0 100644 --- a/compiler/rustc_errors/src/decorate_diag.rs +++ b/compiler/rustc_errors/src/decorate_diag.rs
@@ -1,7 +1,7 @@ /// This module provides types and traits for buffering lints until later in compilation. use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::sync::DynSend; +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::MultiSpan; use rustc_lint_defs::{BuiltinLintDiag, Lint, LintId}; @@ -10,7 +10,14 @@ /// We can't implement `Diagnostic` for `BuiltinLintDiag`, because decorating some of its /// variants requires types we don't have yet. So, handle that case separately. pub enum DecorateDiagCompat { - Dynamic(Box<dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static>), + Dynamic( + Box< + dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + + DynSync + + DynSend + + 'static, + >, + ), Builtin(BuiltinLintDiag), } @@ -20,7 +27,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { } } -impl<D: for<'a> Diagnostic<'a, ()> + DynSend + 'static> From<D> for DecorateDiagCompat { +impl<D: for<'a> Diagnostic<'a, ()> + DynSync + DynSend + 'static> From<D> for DecorateDiagCompat { #[inline] fn from(d: D) -> Self { Self::Dynamic(Box::new(|dcx, level| d.into_diag(dcx, level))) @@ -81,4 +88,21 @@ pub fn buffer_lint( diagnostic: decorate.into(), }); } + + pub fn dyn_buffer_lint< + F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSync + DynSend + 'static, + >( + &mut self, + lint: &'static Lint, + node_id: NodeId, + span: impl Into<MultiSpan>, + callback: F, + ) { + self.add_early_lint(BufferedEarlyLint { + lint_id: LintId::of(lint), + node_id, + span: Some(span.into()), + diagnostic: DecorateDiagCompat::Dynamic(Box::new(callback)), + }); + } }
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ceb7625..9525a45 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -7,7 +7,7 @@ use std::path::PathBuf; use std::thread::panicking; -use rustc_data_structures::sync::DynSend; +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg}; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; @@ -120,7 +120,9 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { } impl<'a> Diagnostic<'a, ()> - for Box<dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSend + 'static> + for Box< + dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static, + > { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { self(dcx, level)
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 225906d..7fd8913 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs
@@ -149,14 +149,14 @@ pub fn expect_item(self) -> Box<ast::Item> { pub fn expect_trait_item(self) -> Box<ast::AssocItem> { match self { Annotatable::AssocItem(i, AssocCtxt::Trait) => i, - _ => panic!("expected Item"), + _ => panic!("expected trait item"), } } pub fn expect_impl_item(self) -> Box<ast::AssocItem> { match self { Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i, - _ => panic!("expected Item"), + _ => panic!("expected impl item"), } } @@ -277,7 +277,8 @@ pub fn from_tts( // Emit the SEMICOLON_IN_EXPRESSIONS_FROM_MACROS deprecation lint. let is_local = true; - let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident); + let parser = + ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident, &[], &[]); ExpandResult::Ready(Box::new(parser)) } } @@ -377,8 +378,8 @@ fn expand<'cx>( /// Represents a thing that maps token trees to Macro Results pub trait TTMacroExpander: Any { - fn expand<'cx>( - &self, + fn expand<'cx, 'a: 'cx>( + &'a self, ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, @@ -394,8 +395,8 @@ impl<F: 'static> TTMacroExpander for F where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>, { - fn expand<'cx>( - &self, + fn expand<'cx, 'a: 'cx>( + &'a self, ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream,
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 640d074..c8ef295 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs
@@ -183,8 +183,8 @@ pub(crate) fn to_string(&self) -> String { } } - impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> { - $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>) + impl<'a, 'b> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a, 'b> { + $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>) -> Option<$AstTy> { Some(self.make(AstFragmentKind::$Kind).$make_ast()) })*
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index df6903d..fd2e4e3 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -222,11 +222,13 @@ fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self { pub(super) fn emit_frag_parse_err( mut e: Diag<'_>, - parser: &Parser<'_>, + parser: &mut Parser<'_>, orig_parser: &mut Parser<'_>, site_span: Span, arm_span: Span, kind: AstFragmentKind, + bindings: &[MacroRule], + matched_rule_bindings: &[MatcherLoc], ) -> ErrorGuaranteed { // FIXME(davidtwco): avoid depending on the error message text if parser.token == token::Eof @@ -285,6 +287,69 @@ pub(super) fn emit_frag_parse_err( }, _ => annotate_err_with_kind(&mut e, kind, site_span), }; + + let mut bindings_rules = vec![]; + for rule in bindings { + let MacroRule::Func { lhs, .. } = rule else { continue }; + for param in lhs { + let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue }; + bindings_rules.push(*bind); + } + } + + let mut matched_rule_bindings_rules = vec![]; + for param in matched_rule_bindings { + let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue }; + matched_rule_bindings_rules.push(*bind); + } + + let matched_rule_bindings_names: Vec<_> = + matched_rule_bindings_rules.iter().map(|bind| bind.name).collect(); + let bindings_name: Vec<_> = bindings_rules.iter().map(|bind| bind.name).collect(); + if parser.token.kind == token::Dollar { + parser.bump(); + if let token::Ident(name, _) = parser.token.kind { + if let Some(matched_name) = rustc_span::edit_distance::find_best_match_for_name( + &matched_rule_bindings_names[..], + name, + None, + ) { + e.span_suggestion_verbose( + parser.token.span, + "there is a macro metavariable with similar name", + format!("{matched_name}"), + Applicability::MaybeIncorrect, + ); + } else if bindings_name.contains(&name) { + e.span_label( + parser.token.span, + format!( + "there is an macro metavariable with this name in another macro matcher" + ), + ); + } else if let Some(matched_name) = + rustc_span::edit_distance::find_best_match_for_name(&bindings_name[..], name, None) + { + e.span_suggestion_verbose( + parser.token.span, + "there is a macro metavariable with a similar name in another macro matcher", + format!("{matched_name}"), + Applicability::MaybeIncorrect, + ); + } else { + let msg = matched_rule_bindings_names + .iter() + .map(|sym| format!("${}", sym)) + .collect::<Vec<_>>() + .join(", "); + + e.span_label(parser.token.span, format!("macro metavariable not found")); + if !matched_rule_bindings_names.is_empty() { + e.note(format!("available metavariable names are: {msg}")); + } + } + } + } e.emit() }
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 7ff49e0..fd5dac3 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -43,7 +43,7 @@ use crate::mbe::transcribe::transcribe; use crate::mbe::{self, KleeneOp}; -pub(crate) struct ParserAnyMacro<'a> { +pub(crate) struct ParserAnyMacro<'a, 'b> { parser: Parser<'a>, /// Span of the expansion site of the macro this parser is for @@ -55,10 +55,15 @@ pub(crate) struct ParserAnyMacro<'a> { arm_span: Span, /// Whether or not this macro is defined in the current crate is_local: bool, + bindings: &'b [MacroRule], + matched_rule_bindings: &'b [MatcherLoc], } -impl<'a> ParserAnyMacro<'a> { - pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment { +impl<'a, 'b> ParserAnyMacro<'a, 'b> { + pub(crate) fn make( + mut self: Box<ParserAnyMacro<'a, 'b>>, + kind: AstFragmentKind, + ) -> AstFragment { let ParserAnyMacro { site_span, macro_ident, @@ -67,13 +72,22 @@ pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> arm_span, is_trailing_mac, is_local, + bindings, + matched_rule_bindings, } = *self; let snapshot = &mut parser.create_snapshot_for_diagnostic(); let fragment = match parse_ast_fragment(parser, kind) { Ok(f) => f, Err(err) => { let guar = diagnostics::emit_frag_parse_err( - err, parser, snapshot, site_span, arm_span, kind, + err, + parser, + snapshot, + site_span, + arm_span, + kind, + bindings, + matched_rule_bindings, ); return kind.dummy(site_span, guar); } @@ -100,7 +114,7 @@ pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> fragment } - #[instrument(skip(cx, tts))] + #[instrument(skip(cx, tts, bindings, matched_rule_bindings))] pub(crate) fn from_tts<'cx>( cx: &'cx mut ExtCtxt<'a>, tts: TokenStream, @@ -108,6 +122,9 @@ pub(crate) fn from_tts<'cx>( arm_span: Span, is_local: bool, macro_ident: Ident, + // bindings and lhs is for diagnostics + bindings: &'b [MacroRule], + matched_rule_bindings: &'b [MatcherLoc], ) -> Self { Self { parser: Parser::new(&cx.sess.psess, tts, None), @@ -121,11 +138,13 @@ pub(crate) fn from_tts<'cx>( is_trailing_mac: cx.current_expansion.is_trailing_mac, arm_span, is_local, + bindings, + matched_rule_bindings, } } } -pub(super) enum MacroRule { +pub(crate) enum MacroRule { /// A function-style rule, for use with `m!()` Func { lhs: Vec<MatcherLoc>, lhs_span: Span, rhs: mbe::TokenTree }, /// An attr rule, for use with `#[m]` @@ -226,8 +245,8 @@ pub fn expand_derive( } impl TTMacroExpander for MacroRulesMacroExpander { - fn expand<'cx>( - &self, + fn expand<'cx, 'a: 'cx>( + &'a self, cx: &'cx mut ExtCtxt<'_>, sp: Span, input: TokenStream, @@ -337,7 +356,7 @@ fn description() -> &'static str { /// Expands the rules based macro defined by `rules` for a given input `arg`. #[instrument(skip(cx, transparency, arg, rules))] -fn expand_macro<'cx>( +fn expand_macro<'cx, 'a: 'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, def_span: Span, @@ -345,7 +364,7 @@ fn expand_macro<'cx>( name: Ident, transparency: Transparency, arg: TokenStream, - rules: &[MacroRule], + rules: &'a [MacroRule], ) -> Box<dyn MacResult + 'cx> { let psess = &cx.sess.psess; @@ -359,7 +378,7 @@ fn expand_macro<'cx>( match try_success_result { Ok((rule_index, rule, named_matches)) => { - let MacroRule::Func { rhs, .. } = rule else { + let MacroRule::Func { lhs, rhs, .. } = rule else { panic!("try_match_macro returned non-func rule"); }; let mbe::TokenTree::Delimited(rhs_span, _, rhs) = rhs else { @@ -388,7 +407,7 @@ fn expand_macro<'cx>( } // Let the context choose how to interpret the result. Weird, but useful for X-macros. - Box::new(ParserAnyMacro::from_tts(cx, tts, sp, arm_span, is_local, name)) + Box::new(ParserAnyMacro::from_tts(cx, tts, sp, arm_span, is_local, name, rules, lhs)) } Err(CanRetry::No(guar)) => { debug!("Will not retry matching as an error was emitted already"); @@ -724,7 +743,7 @@ pub fn compile_declarative_macro( let args = p.parse_token_tree(); check_args_parens(sess, sym::attr, &args); let args = parse_one_tt(args, RulePart::Pattern, sess, node_id, features, edition); - check_emission(check_lhs(sess, node_id, &args)); + check_emission(check_lhs(sess, features, node_id, &args)); if let Some(guar) = check_no_eof(sess, &p, "expected macro attr body") { return dummy_syn_ext(guar); } @@ -773,7 +792,7 @@ pub fn compile_declarative_macro( }; let lhs_tt = p.parse_token_tree(); let lhs_tt = parse_one_tt(lhs_tt, RulePart::Pattern, sess, node_id, features, edition); - check_emission(check_lhs(sess, node_id, &lhs_tt)); + check_emission(check_lhs(sess, features, node_id, &lhs_tt)); if let Err(e) = p.expect(exp!(FatArrow)) { return dummy_syn_ext(e.emit()); } @@ -870,21 +889,27 @@ fn check_args_empty(sess: &Session, args: &tokenstream::TokenTree) -> Result<(), } } -fn check_lhs(sess: &Session, node_id: NodeId, lhs: &mbe::TokenTree) -> Result<(), ErrorGuaranteed> { - let e1 = check_lhs_nt_follows(sess, node_id, lhs); +fn check_lhs( + sess: &Session, + features: &Features, + node_id: NodeId, + lhs: &mbe::TokenTree, +) -> Result<(), ErrorGuaranteed> { + let e1 = check_lhs_nt_follows(sess, features, node_id, lhs); let e2 = check_lhs_no_empty_seq(sess, slice::from_ref(lhs)); e1.and(e2) } fn check_lhs_nt_follows( sess: &Session, + features: &Features, node_id: NodeId, lhs: &mbe::TokenTree, ) -> Result<(), ErrorGuaranteed> { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. if let mbe::TokenTree::Delimited(.., delimited) = lhs { - check_matcher(sess, node_id, &delimited.tts) + check_matcher(sess, features, node_id, &delimited.tts) } else { let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; Err(sess.dcx().span_err(lhs.span(), msg)) @@ -989,12 +1014,13 @@ fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> Result<(), ErrorGuaranteed fn check_matcher( sess: &Session, + features: &Features, node_id: NodeId, matcher: &[mbe::TokenTree], ) -> Result<(), ErrorGuaranteed> { let first_sets = FirstSets::new(matcher); let empty_suffix = TokenSet::empty(); - check_matcher_core(sess, node_id, &first_sets, matcher, &empty_suffix)?; + check_matcher_core(sess, features, node_id, &first_sets, matcher, &empty_suffix)?; Ok(()) } @@ -1331,6 +1357,7 @@ fn add_all(&mut self, other: &Self) { // see `FirstSets::new`. fn check_matcher_core<'tt>( sess: &Session, + features: &Features, node_id: NodeId, first_sets: &FirstSets<'tt>, matcher: &'tt [mbe::TokenTree], @@ -1369,6 +1396,17 @@ fn check_matcher_core<'tt>( | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl { .. } | TokenTree::MetaVarExpr(..) => { + if let TokenTree::MetaVarDecl { kind: NonterminalKind::Guard, .. } = token + && !features.macro_guard_matcher() + { + feature_err( + sess, + sym::macro_guard_matcher, + token.span(), + "`guard` fragments in macro are unstable", + ) + .emit(); + } if token_can_be_followed_by_any(token) { // don't need to track tokens that work with any, last.replace_with_irrelevant(); @@ -1385,7 +1423,7 @@ fn check_matcher_core<'tt>( d.delim.as_close_token_kind(), span.close, )); - check_matcher_core(sess, node_id, first_sets, &d.tts, &my_suffix)?; + check_matcher_core(sess, features, node_id, first_sets, &d.tts, &my_suffix)?; // don't track non NT tokens last.replace_with_irrelevant(); @@ -1417,7 +1455,14 @@ fn check_matcher_core<'tt>( // At this point, `suffix_first` is built, and // `my_suffix` is some TokenSet that we can use // for checking the interior of `seq_rep`. - let next = check_matcher_core(sess, node_id, first_sets, &seq_rep.tts, my_suffix)?; + let next = check_matcher_core( + sess, + features, + node_id, + first_sets, + &seq_rep.tts, + my_suffix, + )?; if next.maybe_empty { last.add_all(&next); } else { @@ -1609,7 +1654,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } } NonterminalKind::Pat(PatParam { .. }) => { - const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"]; + const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`if let`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { FatArrow | Comma | Eq | Or => IsInFollow::Yes, @@ -1618,11 +1663,12 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, + TokenTree::MetaVarDecl { kind: NonterminalKind::Guard, .. } => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } NonterminalKind::Pat(PatWithOr) => { - const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"]; + const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`if let`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { FatArrow | Comma | Eq => IsInFollow::Yes, @@ -1631,6 +1677,17 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, + TokenTree::MetaVarDecl { kind: NonterminalKind::Guard, .. } => IsInFollow::Yes, + _ => IsInFollow::No(TOKENS), + } + } + NonterminalKind::Guard => { + const TOKENS: &[&str] = &["`=>`", "`,`", "`{`"]; + match tok { + TokenTree::Token(token) => match token.kind { + FatArrow | Comma | OpenBrace => IsInFollow::Yes, + _ => IsInFollow::No(TOKENS), + }, _ => IsInFollow::No(TOKENS), } }
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 09f006c..dcf2cd1 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -12,7 +12,8 @@ use rustc_session::parse::ParseSess; use rustc_span::hygiene::{LocalExpnId, Transparency}; use rustc_span::{ - Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans, + BytePos, Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, kw, sym, + with_metavar_spans, }; use smallvec::{SmallVec, smallvec}; @@ -556,6 +557,19 @@ fn transcribe_pnr<'tx>( ParseNtResult::Vis(vis) => { mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) } + ParseNtResult::Guard(guard) => { + // FIXME(macro_guard_matcher): + // Perhaps it would be better to treat the leading `if` as part of `ast::Guard` during parsing? + // Currently they are separate, but in macros we match and emit the leading `if` for `:guard` matchers, which creates some inconsistency. + + let leading_if_span = + guard.span_with_leading_if.with_hi(guard.span_with_leading_if.lo() + BytePos(2)); + let mut ts = + TokenStream::token_alone(token::Ident(kw::If, IdentIsRaw::No), leading_if_span); + ts.push_stream(TokenStream::from_ast(&guard.cond)); + + mk_delimited(guard.span_with_leading_if, MetaVarKind::Guard, ts) + } }; tscx.result.push(tt);
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index d74450e..acbcba9 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -773,7 +773,7 @@ pub struct BuiltinAttribute { DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature) ), gated!( - sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, r#"thread = "on|off""#]), ErrorPreceding, + sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kernel_hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, r#"thread = "on|off""#]), ErrorPreceding, EncodeCrossCrate::No, sanitize, experimental!(sanitize), ), gated!(
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e8ca20d..224b727 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs
@@ -473,7 +473,7 @@ pub fn internal(&self, feature: Symbol) -> bool { /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const (unstable, diagnostic_on_const, "1.93.0", Some(143874)), /// Allows giving on-move borrowck custom diagnostic messages for a type - (unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(150935)), + (unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(154181)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. @@ -569,6 +569,8 @@ pub fn internal(&self, feature: Symbol) -> bool { (unstable, macro_attr, "1.91.0", Some(143547)), /// Allow `macro_rules!` derive rules (unstable, macro_derive, "1.91.0", Some(143549)), + /// Allow `$x:guard` matcher in macros + (unstable, macro_guard_matcher, "CURRENT_RUSTC_VERSION", Some(153104)), /// Give access to additional metadata about declarative macro meta-variables. (unstable, macro_metavar_expr, "1.61.0", Some(83527)), /// Provides a way to concatenate identifiers using metavariable expressions. @@ -691,7 +693,7 @@ pub fn internal(&self, feature: Symbol) -> bool { /// Allows inconsistent bounds in where clauses. (unstable, trivial_bounds, "1.28.0", Some(48214)), /// Allows using `try {...}` expressions. - (unstable, try_blocks, "1.29.0", Some(31436)), + (unstable, try_blocks, "1.29.0", Some(154391)), /// Allows using `try bikeshed TargetType {...}` expressions. (unstable, try_blocks_heterogeneous, "1.94.0", Some(149488)), /// Allows `impl Trait` to be used inside type aliases (RFC 2515).
diff --git a/compiler/rustc_hir/src/attrs/mod.rs b/compiler/rustc_hir/src/attrs/mod.rs index 09fa144..b3c1dea 100644 --- a/compiler/rustc_hir/src/attrs/mod.rs +++ b/compiler/rustc_hir/src/attrs/mod.rs
@@ -13,6 +13,15 @@ mod encode_cross_crate; mod pretty_printing; +/// A trait for types that can provide a list of attributes given a `TyCtxt`. +/// +/// It allows `find_attr!` to accept either a `DefId`, `LocalDefId`, `OwnerId`, or `HirId`. +/// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`. +/// The concrete implementations are in `rustc_middle`. +pub trait HasAttrs<'tcx, Tcx> { + fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::Attribute]; +} + /// Finds attributes in sequences of attributes by pattern matching. /// /// A little like `matches` but for attributes. @@ -34,10 +43,12 @@ /// /// As a convenience, this macro can do that for you! /// -/// Instead of providing an attribute list, provide the `tcx` and a `DefId`. +/// Instead of providing an attribute list, provide the `tcx` and an id +/// (a `DefId`, `LocalDefId`, `OwnerId` or `HirId`). /// /// ```rust,ignore (illustrative) /// find_attr!(tcx, def_id, <pattern>) +/// find_attr!(tcx, hir_id, <pattern>) /// ``` /// /// Another common case is finding attributes applied to the root of the current crate. @@ -55,13 +66,14 @@ macro_rules! find_attr { $crate::find_attr!($tcx.hir_krate_attrs(), $pattern $(if $guard)? => $e) }; - ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)?) => { - $crate::find_attr!($tcx, $def_id, $pattern $(if $guard)? => ()).is_some() + ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)?) => { + $crate::find_attr!($tcx, $id, $pattern $(if $guard)? => ()).is_some() }; - ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ - #[allow(deprecated)] { - $crate::find_attr!($tcx.get_all_attrs($def_id), $pattern $(if $guard)? => $e) - } + ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ + $crate::find_attr!( + $crate::attrs::HasAttrs::get_attrs($id, &$tcx), + $pattern $(if $guard)? => $e + ) }};
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 21abb55..78bd709 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs
@@ -590,6 +590,13 @@ pub enum Res<Id = hir::HirId> { /// **Belongs to the type namespace.** ToolMod, + /// The resolution for an open module in a namespaced crate. E.g. `my_api` + /// in the namespaced crate `my_api::utils` when `my_api` isn't part of the + /// extern prelude. + /// + /// **Belongs to the type namespace.** + OpenMod(Symbol), + // Macro namespace /// An attribute that is *not* implemented via macro. /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives, @@ -705,11 +712,11 @@ fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { } } -impl<CTX: crate::HashStableContext> ToStableHashKey<CTX> for Namespace { +impl<Hcx: crate::HashStableContext> ToStableHashKey<Hcx> for Namespace { type KeyType = Namespace; #[inline] - fn to_stable_hash_key(&self, _: &CTX) -> Namespace { + fn to_stable_hash_key(&self, _: &Hcx) -> Namespace { *self } } @@ -838,6 +845,7 @@ pub fn opt_def_id(&self) -> Option<DefId> { | Res::SelfTyAlias { .. } | Res::SelfCtor(..) | Res::ToolMod + | Res::OpenMod(..) | Res::NonMacroAttr(..) | Res::Err => None, } @@ -869,6 +877,7 @@ pub fn descr(&self) -> &'static str { Res::Local(..) => "local variable", Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type", Res::ToolMod => "tool module", + Res::OpenMod(..) => "namespaced crate", Res::NonMacroAttr(attr_kind) => attr_kind.descr(), Res::Err => "unresolved item", } @@ -895,6 +904,7 @@ pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> { Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, + Res::OpenMod(sym) => Res::OpenMod(sym), Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, } @@ -911,6 +921,7 @@ pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<R Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, + Res::OpenMod(sym) => Res::OpenMod(sym), Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, }) @@ -936,9 +947,11 @@ pub fn macro_kinds(self) -> Option<MacroKinds> { pub fn ns(&self) -> Option<Namespace> { match self { Res::Def(kind, ..) => kind.ns(), - Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => { - Some(Namespace::TypeNS) - } + Res::PrimTy(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + | Res::ToolMod + | Res::OpenMod(..) => Some(Namespace::TypeNS), Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS), Res::NonMacroAttr(..) => Some(Namespace::MacroNS), Res::Err => None,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 9526143..57cf42c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs
@@ -397,12 +397,7 @@ pub fn invalid() -> Self { } pub fn args(&self) -> &GenericArgs<'hir> { - if let Some(ref args) = self.args { - args - } else { - const DUMMY: &GenericArgs<'_> = &GenericArgs::none(); - DUMMY - } + if let Some(ref args) = self.args { args } else { GenericArgs::NONE } } } @@ -643,14 +638,12 @@ pub struct GenericArgs<'hir> { } impl<'hir> GenericArgs<'hir> { - pub const fn none() -> Self { - Self { - args: &[], - constraints: &[], - parenthesized: GenericArgsParentheses::No, - span_ext: DUMMY_SP, - } - } + pub const NONE: &'hir GenericArgs<'hir> = &GenericArgs { + args: &[], + constraints: &[], + parenthesized: GenericArgsParentheses::No, + span_ext: DUMMY_SP, + }; /// Obtain the list of input types and the output type if the generic arguments are parenthesized. /// @@ -1264,6 +1257,8 @@ pub struct HashIgnoredAttrId { pub attr_id: AttrId, } +/// Many functions on this type have their documentation in the [`AttributeExt`] trait, +/// since they defer their implementation directly to that trait. #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)] pub enum Attribute { /// A parsed built-in attribute. @@ -3765,12 +3760,21 @@ pub struct DelegationGenerics { } #[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)] -pub enum InferDelegationKind<'hir> { +pub enum InferDelegationSig<'hir> { Input(usize), // Place generics info here, as we always specify output type for delegations. Output(&'hir DelegationGenerics), } +#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)] +pub enum InferDelegation<'hir> { + /// Infer the type of this `DefId` through `tcx.type_of(def_id).instantiate_identity()`, + /// used for const types propagation. + DefId(DefId), + /// Used during signature inheritance, `DefId` corresponds to the signature function. + Sig(DefId, InferDelegationSig<'hir>), +} + /// The various kinds of types recognized by the compiler. /// /// For an explanation of the `Unambig` generic parameter see the dev-guide: @@ -3780,7 +3784,7 @@ pub enum InferDelegationKind<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyKind<'hir, Unambig = ()> { /// Actual type should be inherited from `DefId` signature - InferDelegation(DefId, InferDelegationKind<'hir>), + InferDelegation(InferDelegation<'hir>), /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), /// A fixed length array (i.e., `[T; n]`). @@ -3931,7 +3935,7 @@ pub struct FnDecl<'hir> { impl<'hir> FnDecl<'hir> { pub fn opt_delegation_sig_id(&self) -> Option<DefId> { if let FnRetTy::Return(ty) = self.output - && let TyKind::InferDelegation(sig_id, _) = ty.kind + && let TyKind::InferDelegation(InferDelegation::Sig(sig_id, _)) = ty.kind { return Some(sig_id); } @@ -3940,8 +3944,8 @@ pub fn opt_delegation_sig_id(&self) -> Option<DefId> { pub fn opt_delegation_generics(&self) -> Option<&'hir DelegationGenerics> { if let FnRetTy::Return(ty) = self.output - && let TyKind::InferDelegation(_, kind) = ty.kind - && let InferDelegationKind::Output(generics) = kind + && let TyKind::InferDelegation(InferDelegation::Sig(_, kind)) = ty.kind + && let InferDelegationSig::Output(generics) = kind { return Some(generics); }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 80f0af9..c144f0b 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs
@@ -144,8 +144,8 @@ pub fn $method(&self) -> Option<DefId> { } } -impl<CTX> HashStable<CTX> for LangItem { - fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for LangItem { + fn hash_stable(&self, _: &mut Hcx, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } }
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 0ce9356..0dbd433 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -19,7 +19,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } -rustc_lint = { path = "../rustc_lint" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 32cfa30..06ccf61 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -952,10 +952,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); check_type_alias_type_params_are_used(tcx, def_id); + let ty = tcx.type_of(def_id).instantiate_identity(); + let span = tcx.def_span(def_id); if tcx.type_alias_is_lazy(def_id) { res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { - let ty = tcx.type_of(def_id).instantiate_identity(); - let span = tcx.def_span(def_id); let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation( span, @@ -966,6 +966,30 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Ok(()) })); check_variances_for_type_defn(tcx, def_id); + } else { + res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + // HACK: We sometimes incidentally check that const arguments have the correct + // type as a side effect of the anon const desugaring. To make this "consistent" + // for users we explicitly check `ConstArgHasType` clauses so that const args + // that don't go through an anon const still have their types checked. + // + // We use the unnormalized type as this mirrors the behaviour that we previously + // would have had when all const arguments were anon consts. + // + // Changing this to normalized obligations is a breaking change: + // `type Bar = [(); panic!()];` would become an error + if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty) + { + let filtered_obligations = + unnormalized_obligations.into_iter().filter(|o| { + matches!(o.predicate.kind().skip_binder(), + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) + if matches!(ct.kind(), ty::ConstKind::Param(..))) + }); + wfcx.ocx.register_obligations(filtered_obligations) + } + Ok(()) + })); } // Only `Node::Item` and `Node::ForeignItem` still have HIR based
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 4742099..b1dc593 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -111,10 +111,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::expf32 | sym::expf64 | sym::expf128 - | sym::fabsf16 - | sym::fabsf32 - | sym::fabsf64 - | sym::fabsf128 + | sym::fabs | sym::fadd_algebraic | sym::fdiv_algebraic | sym::field_offset @@ -463,10 +460,7 @@ pub(crate) fn check_intrinsic_type( (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128) } - sym::fabsf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::fabs => (1, 0, vec![param(0)], param(0)), sym::minimum_number_nsz_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::minimum_number_nsz_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), @@ -726,8 +720,8 @@ pub(crate) fn check_intrinsic_type( | sym::simd_and | sym::simd_or | sym::simd_xor - | sym::simd_fmin - | sym::simd_fmax + | sym::simd_minimum_number_nsz + | sym::simd_maximum_number_nsz | sym::simd_saturating_add | sym::simd_saturating_sub | sym::simd_carryless_mul => (1, 0, vec![param(0), param(0)], param(0)),
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 8865638..e31beca3 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; use rustc_index::Idx; @@ -849,13 +849,13 @@ fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) { /// re-use in incremental scenarios. We may sometimes need to rerun the /// type checker even when the HIR hasn't changed, and in those cases /// we can avoid reconstructing the region scope tree. -pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { - let typeck_root_def_id = tcx.typeck_root_def_id(def_id); +pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &ScopeTree { + let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id); if typeck_root_def_id != def_id { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f050fe2..96d0a56 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -15,6 +15,7 @@ use rustc_hir::{AmbigArg, ItemKind, find_attr}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt}; +use rustc_infer::traits::PredicateObligations; use rustc_lint_defs::builtin::SHADOWING_SUPERTRAIT_ITEMS; use rustc_macros::Diagnostic; use rustc_middle::mir::interpret::ErrorHandled; @@ -124,6 +125,20 @@ pub(super) fn register_wf_obligation( ty::ClauseKind::WellFormed(term), )); } + + pub(super) fn unnormalized_obligations( + &self, + span: Span, + ty: Ty<'tcx>, + ) -> Option<PredicateObligations<'tcx>> { + traits::wf::unnormalized_obligations( + self.ocx.infcx, + self.param_env, + ty.into(), + span, + self.body_def_id, + ) + } } pub(super) fn enter_wf_checking_ctxt<'tcx, F>( @@ -140,7 +155,12 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( let mut wfcx = WfCheckingCtxt { ocx, body_def_id, param_env }; - if !tcx.features().trivial_bounds() { + // As of now, bounds are only checked on lazy type aliases, they're ignored for most type + // aliases. So, only check for false global bounds if we're not ignoring bounds altogether. + let ignore_bounds = + tcx.def_kind(body_def_id) == DefKind::TyAlias && !tcx.type_alias_is_lazy(body_def_id); + + if !ignore_bounds && !tcx.features().trivial_bounds() { wfcx.check_false_global_bounds() } f(&mut wfcx)?;
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 866787a..ea98beb9 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -76,12 +76,12 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { | Node::Ctor(..) | Node::Field(_) => { let parent_id = tcx.hir_get_parent_item(hir_id); - Some(parent_id.to_def_id()) + Some(parent_id.def_id) } // FIXME(#43408) always enable this once `lazy_normalization` is // stable enough and does not need a feature gate anymore. Node::AnonConst(_) => { - let parent_did = tcx.parent(def_id.to_def_id()); + let parent_did = tcx.local_parent(def_id); debug!(?parent_did); let mut in_param_ty = false; @@ -175,7 +175,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } Node::ConstBlock(_) | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { - Some(tcx.typeck_root_def_id(def_id.to_def_id())) + Some(tcx.typeck_root_def_id_local(def_id)) } Node::OpaqueTy(&hir::OpaqueTy { origin: @@ -188,7 +188,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } else { assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); } - Some(fn_def_id.to_def_id()) + Some(fn_def_id) } Node::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty }, @@ -202,7 +202,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); // Opaque types are always nested within another item, and // inherit the generics of the item. - Some(parent.to_def_id()) + Some(parent) } // All of these nodes have no parent from which to inherit generics. @@ -380,7 +380,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { own_params.iter().map(|param| (param.def_id, param.index)).collect(); ty::Generics { - parent: parent_def_id, + parent: parent_def_id.map(LocalDefId::to_def_id), parent_count, own_params, param_def_id_to_index,
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9899923..8fd3d63 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -107,7 +107,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ); return ty::GenericPredicates { - parent: Some(tcx.parent(def_id.to_def_id())), + parent: Some(tcx.local_parent(def_id).to_def_id()), predicates: tcx.arena.alloc_from_iter(predicates), }; }
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 18244d6..5bb4166 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -925,7 +925,7 @@ fn visit_fn( hir::FnRetTy::Return(ty) => Some(ty), }; if let Some(ty) = output - && let hir::TyKind::InferDelegation(sig_id, _) = ty.kind + && let hir::TyKind::InferDelegation(hir::InferDelegation::Sig(sig_id, _)) = ty.kind { let bound_vars: Vec<_> = self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect();
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f2ae5c1..e65efd6 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -4,7 +4,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::{self as hir, AmbigArg, HirId}; -use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::print::{with_forced_trimmed_paths, with_types_for_suggestion}; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -451,7 +451,7 @@ fn infer_placeholder_type<'tcx>( err.span_suggestion( ty_span, format!("provide a type for the {kind}"), - format!("{colon} {ty}"), + with_types_for_suggestion!(format!("{colon} {ty}")), Applicability::MachineApplicable, ); } else {
diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 0b142c0..7302885 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs
@@ -138,7 +138,6 @@ fn create_mapping<'tcx>( tcx: TyCtxt<'tcx>, sig_id: DefId, def_id: LocalDefId, - args: &[ty::GenericArg<'tcx>], ) -> FxHashMap<u32, u32> { let mut mapping: FxHashMap<u32, u32> = Default::default(); @@ -176,13 +175,6 @@ fn create_mapping<'tcx>( } } - // If there are still unmapped lifetimes left and we are to map types and maybe self - // then skip them, now it is the case when we generated more lifetimes then needed. - // FIXME(fn_delegation): proper support for late bound lifetimes. - while args_index < args.len() && args[args_index].as_region().is_some() { - args_index += 1; - } - // If self after lifetimes insert mapping, relying that self is at 0 in sig parent. if matches!(self_pos_kind, SelfPositionKind::AfterLifetimes) { mapping.insert(0, args_index as u32); @@ -511,7 +503,7 @@ fn create_folder_and_args<'tcx>( child_args: &'tcx [ty::GenericArg<'tcx>], ) -> (ParamIndexRemapper<'tcx>, Vec<ty::GenericArg<'tcx>>) { let args = create_generic_args(tcx, sig_id, def_id, parent_args, child_args); - let remap_table = create_mapping(tcx, sig_id, def_id, &args); + let remap_table = create_mapping(tcx, sig_id, def_id); (ParamIndexRemapper { tcx, remap_table }, args) }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 18c9bac..91660fc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2830,6 +2830,7 @@ fn lower_resolved_const_path( | Res::SelfCtor(_) | Res::Local(_) | Res::ToolMod + | Res::OpenMod(..) | Res::NonMacroAttr(_) | Res::Err) => Const::new_error_with_message( tcx, @@ -2946,7 +2947,7 @@ fn require_type_const_attribute( ); if def_id.is_local() { let name = tcx.def_path_str(def_id); - err.span_suggestion( + err.span_suggestion_verbose( tcx.def_span(def_id).shrink_to_lo(), format!("add `type` before `const` for `{name}`"), format!("type "), @@ -2959,12 +2960,19 @@ fn require_type_const_attribute( } } - fn lower_delegation_ty(&self, idx: hir::InferDelegationKind<'tcx>) -> Ty<'tcx> { - let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); + fn lower_delegation_ty(&self, infer: hir::InferDelegation<'tcx>) -> Ty<'tcx> { + match infer { + hir::InferDelegation::DefId(def_id) => { + self.tcx().type_of(def_id).instantiate_identity() + } + rustc_hir::InferDelegation::Sig(_, idx) => { + let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); - match idx { - hir::InferDelegationKind::Input(idx) => delegation_sig[idx], - hir::InferDelegationKind::Output { .. } => *delegation_sig.last().unwrap(), + match idx { + hir::InferDelegationSig::Input(idx) => delegation_sig[idx], + hir::InferDelegationSig::Output { .. } => *delegation_sig.last().unwrap(), + } + } } } @@ -2974,7 +2982,7 @@ pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { let tcx = self.tcx(); let result_ty = match &hir_ty.kind { - hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx), + hir::TyKind::InferDelegation(infer) => self.lower_delegation_ty(*infer), hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl), hir::TyKind::Ref(region, mt) => {
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0e8bc9a..937bcee 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -85,8 +85,6 @@ use rustc_abi::{CVariadicStatus, ExternAbi}; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::lints::DelayedLint; -use rustc_lint::DecorateAttrLint; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{Const, Ty, TyCtxt}; @@ -147,23 +145,6 @@ pub fn provide(providers: &mut Providers) { }; } -pub fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { - match lint { - DelayedLint::AttributeParsing(attribute_lint) => { - tcx.emit_node_span_lint( - attribute_lint.lint_id.lint, - attribute_lint.id, - attribute_lint.span, - DecorateAttrLint { - sess: tcx.sess, - tcx: Some(tcx), - diagnostic: &attribute_lint.kind, - }, - ); - } - } -} - pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); @@ -182,42 +163,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _: R = tcx.ensure_result().crate_inherent_impls_overlap_check(()); }); - tcx.sess.time("emit_ast_lowering_delayed_lints", || { - // sanity check in debug mode that all lints are really noticed - // and we really will emit them all in the loop right below. - // - // during ast lowering, when creating items, foreign items, trait items and impl items - // we store in them whether they have any lints in their owner node that should be - // picked up by `hir_crate_items`. However, theoretically code can run between that - // boolean being inserted into the item and the owner node being created. - // We don't want any new lints to be emitted there - // (though honestly, you have to really try to manage to do that but still), - // but this check is there to catch that. - #[cfg(debug_assertions)] - { - // iterate over all owners - for owner_id in tcx.hir_crate_items(()).owners() { - // if it has delayed lints - if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { - if !delayed_lints.lints.is_empty() { - // assert that delayed_lint_items also picked up this item to have lints - assert!( - tcx.hir_crate_items(()).delayed_lint_items().any(|i| i == owner_id) - ); - } - } - } - } - - for owner_id in tcx.hir_crate_items(()).delayed_lint_items() { - if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { - for lint in &delayed_lints.lints { - emit_delayed_lint(lint, tcx); - } - } - } - }); - tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); // Make sure we evaluate all static and (non-associated) const items, even if unused.
diff --git a/compiler/rustc_hir_id/src/lib.rs b/compiler/rustc_hir_id/src/lib.rs index d6deed5..ffff3f9 100644 --- a/compiler/rustc_hir_id/src/lib.rs +++ b/compiler/rustc_hir_id/src/lib.rs
@@ -54,18 +54,18 @@ fn index(self) -> usize { } } -impl<CTX: HashStableContext> HashStable<CTX> for OwnerId { +impl<Hcx: HashStableContext> HashStable<Hcx> for OwnerId { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.to_stable_hash_key(hcx).hash_stable(hcx, hasher); } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for OwnerId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for OwnerId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { hcx.def_path_hash(self.to_def_id()) } } @@ -176,21 +176,21 @@ impl StableOrd for ItemLocalId { pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID }; -impl<CTX: rustc_span::HashStableContext> ToStableHashKey<CTX> for HirId { +impl<Hcx: rustc_span::HashStableContext> ToStableHashKey<Hcx> for HirId { type KeyType = (DefPathHash, ItemLocalId); #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> (DefPathHash, ItemLocalId) { + fn to_stable_hash_key(&self, hcx: &Hcx) -> (DefPathHash, ItemLocalId) { let def_path_hash = self.owner.def_id.to_stable_hash_key(hcx); (def_path_hash, self.local_id) } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for ItemLocalId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for ItemLocalId { type KeyType = ItemLocalId; #[inline] - fn to_stable_hash_key(&self, _: &CTX) -> ItemLocalId { + fn to_stable_hash_key(&self, _: &Hcx) -> ItemLocalId { *self } }
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 82b7c57..1a9c2a2 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -72,7 +72,7 @@ pub(crate) fn check_expr_closure( debug!(?bound_sig, ?liberated_sig); let parent_args = - GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id(expr_def_id.to_def_id())); + GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id_local(expr_def_id)); let tupled_upvars_ty = self.next_ty_var(expr_span);
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 6b77169..184c0d5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1660,14 +1660,6 @@ fn check_expr_array( expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let element_ty = if !args.is_empty() { - // This shouldn't happen unless there's another error - // (e.g., never patterns in inappropriate contexts). - if self.diverges.get() != Diverges::Maybe { - self.dcx() - .struct_span_err(expr.span, "unexpected divergence state in checking array") - .delay_as_bug(); - } - let coerce_to = expected .to_option(self) .and_then(|uty| { @@ -1879,7 +1871,7 @@ fn check_expr_struct_fields( if !ocx.try_evaluate_obligations().is_empty() { return Err(TypeError::Mismatch); } - Ok(adt_ty) + Ok(self.resolve_vars_if_possible(adt_ty)) }) .ok() });
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b6dfda3..9587b77 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -751,16 +751,6 @@ fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { adjustment::Adjust::Borrow(ref autoref) => { self.walk_autoref(expr, &place_with_id, autoref); } - - adjustment::Adjust::ReborrowPin(mutbl) => { - // Reborrowing a Pin is like a combinations of a deref and a borrow, so we do - // both. - let bk = match mutbl { - ty::Mutability::Not => ty::BorrowKind::Immutable, - ty::Mutability::Mut => ty::BorrowKind::Mutable, - }; - self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); - } } place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?; } @@ -1292,8 +1282,7 @@ fn cat_expr_adjusted_with<F>( adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::ReborrowPin(..) => { + | adjustment::Adjust::Borrow(_) => { // Result is an rvalue. Ok(self.cat_rvalue(expr.hir_id, target)) }
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index f7ecfb6..5aadf37 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -357,6 +357,11 @@ fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> { VecGraph::new(num_ty_vars, coercion_edges) } + /// If `ty` is an unresolved type variable, returns its root vid. + fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> { + Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) + } + /// Given a set of diverging vids and coercions, walk the HIR to gather a /// set of suggestions which can be applied to preserve fallback to unit. fn try_to_suggest_annotations(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index f817ca8..d50ac8d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -337,10 +337,6 @@ pub(crate) fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment Adjust::Pointer(_pointer_coercion) => { // FIXME(const_trait_impl): We should probably enforce these. } - Adjust::ReborrowPin(_mutability) => { - // FIXME(const_trait_impl): We could enforce these; they correspond to - // `&mut T: DerefMut` tho, so it's kinda moot. - } Adjust::Borrow(_) => { // No effects to enforce here. }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 0471fd9..f53259e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -276,7 +276,12 @@ pub(in super::super) fn check_argument_types( // Record all the argument types, with the args // produced from the above subtyping unification. - Ok(Some(formal_input_tys.to_vec())) + Ok(Some( + formal_input_tys + .iter() + .map(|&ty| self.resolve_vars_if_possible(ty)) + .collect(), + )) }) .ok() })
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 734e513..fe8a9a9 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -82,7 +82,7 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef &tcx.typeck(def_id).used_trait_imports } -fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { +fn typeck_root<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { typeck_with_inspect(tcx, def_id, None) } @@ -95,6 +95,13 @@ pub fn inspect_typeck<'tcx>( def_id: LocalDefId, inspect: ObligationInspector<'tcx>, ) -> &'tcx ty::TypeckResults<'tcx> { + // Closures' typeck results come from their outermost function, + // as they are part of the same "inference environment". + let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id); + if typeck_root_def_id != def_id { + return tcx.typeck(typeck_root_def_id); + } + typeck_with_inspect(tcx, def_id, Some(inspect)) } @@ -104,12 +111,7 @@ fn typeck_with_inspect<'tcx>( def_id: LocalDefId, inspector: Option<ObligationInspector<'tcx>>, ) -> &'tcx ty::TypeckResults<'tcx> { - // Closures' typeck results come from their outermost function, - // as they are part of the same "inference environment". - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(); - if typeck_root_def_id != def_id { - return tcx.typeck(typeck_root_def_id); - } + assert!(!tcx.is_typeck_child(def_id.to_def_id())); let id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(id); @@ -660,7 +662,7 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { pub fn provide(providers: &mut Providers) { *providers = Providers { method_autoderef_steps: method::probe::method_autoderef_steps, - typeck, + typeck_root, used_trait_imports, check_transmutes: intrinsicck::check_transmutes, ..*providers
diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index e77c936..21b40806 100644 --- a/compiler/rustc_hir_typeck/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs
@@ -207,7 +207,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { }; // A `#[const_continue]` must break to a block in a `#[loop_match]`. - if find_attr!(self.tcx.hir_attrs(e.hir_id), ConstContinue(_)) { + if find_attr!(self.tcx, e.hir_id, ConstContinue(_)) { let Some(label) = break_destination.label else { let span = e.span; self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span }); @@ -420,7 +420,7 @@ fn is_loop_match( e: &'hir hir::Expr<'hir>, body: &'hir hir::Block<'hir>, ) -> Option<Destination> { - if !find_attr!(self.tcx.hir_attrs(e.hir_id), LoopMatch(_)) { + if !find_attr!(self.tcx, e.hir_id, LoopMatch(_)) { return None; }
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index b90d5b4..ed75609 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -18,7 +18,8 @@ }; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::{ - Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, + Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, DerefAdjustKind, + PointerCoercion, }; use rustc_middle::ty::{ self, AssocContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, @@ -243,12 +244,16 @@ fn adjust_self_ty( ty::Ref(_, ty, _) => *ty, _ => bug!("Expected a reference type for argument to Pin"), }; + adjustments.push(Adjustment { + kind: Adjust::Deref(DerefAdjustKind::Pin), + target: inner_ty, + }); Ty::new_pinned_ref(self.tcx, region, inner_ty, mutbl) } _ => bug!("Cannot adjust receiver type for reborrowing pin of {target:?}"), }; - - adjustments.push(Adjustment { kind: Adjust::ReborrowPin(mutbl), target }); + adjustments + .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Pin(mutbl)), target }); } None => {} }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 893cd02..c5b3d70 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1177,15 +1177,10 @@ fn report_no_match_method_error( let is_method = mode == Mode::MethodCall; let item_kind = if is_method { "method" - } else if rcvr_ty.is_enum() { - "variant or associated item" + } else if rcvr_ty.is_enum() || rcvr_ty.is_fresh_ty() { + "variant, associated function, or constant" } else { - match (item_ident.as_str().chars().next(), rcvr_ty.is_fresh_ty()) { - (Some(name), false) if name.is_lowercase() => "function or associated item", - (Some(_), false) => "associated item", - (Some(_), true) | (None, false) => "variant or associated item", - (None, true) => "variant", - } + "associated function or constant" }; if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( @@ -2291,8 +2286,11 @@ pub(crate) fn confusable_method_name( fn_sig, ); let name = inherent_method.name(); + let inputs = fn_sig.inputs(); + let expected_inputs = + if inherent_method.is_method() { &inputs[1..] } else { inputs }; if let Some(ref args) = call_args - && fn_sig.inputs()[1..] + && expected_inputs .iter() .eq_by(args, |expected, found| self.may_coerce(*expected, *found)) {
diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index 3354689..a1f4464 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs
@@ -192,7 +192,8 @@ pub(crate) struct DeleteFull<'a> { } #[derive(Diagnostic)] -#[diag("error finalizing incremental compilation session directory `{$path}`: {$err}")] +#[diag("did not finalize incremental compilation session directory `{$path}`: {$err}")] +#[help("the next build will not be able to reuse work from this compilation")] pub(crate) struct Finalize<'a> { pub path: &'a Path, pub err: std::io::Error,
diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index ab336a6..e999404 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs
@@ -49,7 +49,7 @@ label_strs::type_of, // And a big part of compilation (that we eventually want to cache) is type inference // information: - label_strs::typeck, + label_strs::typeck_root, ]; /// DepNodes for Hir, which is pretty much everything
diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 9cec270..c47540f 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs
@@ -12,7 +12,7 @@ use std::borrow::Cow; use std::io::{self, Read}; use std::path::{Path, PathBuf}; -use std::{env, fs}; +use std::{array, env, fs}; use rustc_data_structures::memmap::Mmap; use rustc_serialize::Encoder; @@ -30,12 +30,12 @@ pub(crate) fn write_file_header(stream: &mut FileEncoder, sess: &Session) { stream.emit_raw_bytes(FILE_MAGIC); - stream - .emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, (HEADER_FORMAT_VERSION >> 8) as u8]); + stream.emit_raw_bytes(&u16::to_le_bytes(HEADER_FORMAT_VERSION)); - let rustc_version = rustc_version(sess.is_nightly_build(), sess.cfg_version); - assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize); - stream.emit_raw_bytes(&[rustc_version.len() as u8]); + let rustc_version = rustc_version(sess); + let rustc_version_len = + u8::try_from(rustc_version.len()).expect("version string should not exceed 255 bytes"); + stream.emit_raw_bytes(&[rustc_version_len]); stream.emit_raw_bytes(rustc_version.as_bytes()); } @@ -80,26 +80,47 @@ pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: } } -/// Reads the contents of a file with a file header as defined in this module. -/// -/// - Returns `Ok(Some(data, pos))` if the file existed and was generated by a -/// compatible compiler version. `data` is the entire contents of the file -/// and `pos` points to the first byte after the header. -/// - Returns `Ok(None)` if the file did not exist or was generated by an -/// incompatible version of the compiler. -/// - Returns `Err(..)` if some kind of IO error occurred while reading the -/// file. -pub(crate) fn read_file( +pub(crate) struct OpenFile { + /// A read-only mmap view of the file contents. + pub(crate) mmap: Mmap, + /// File position to start reading normal data from, just after the end of the file header. + pub(crate) start_pos: usize, +} + +pub(crate) enum OpenFileError { + /// Either the file was not found, or one of the header checks failed. + /// + /// These conditions prevent us from reading the file contents, but should + /// not trigger an error or even a warning, because they routinely happen + /// during normal operation: + /// - File-not-found occurs in a fresh build, or after clearing the build directory. + /// - Header-mismatch occurs after upgrading or switching compiler versions. + NotFoundOrHeaderMismatch, + + /// An unexpected I/O error occurred while opening or checking the file. + IoError { err: io::Error }, +} + +impl From<io::Error> for OpenFileError { + fn from(err: io::Error) -> Self { + OpenFileError::IoError { err } + } +} + +/// Tries to open a file that was written by the previous incremental-compilation +/// session, and checks that it was produced by a matching compiler version. +pub(crate) fn open_incremental_file( + sess: &Session, path: &Path, - report_incremental_info: bool, - is_nightly_build: bool, - cfg_version: &'static str, -) -> io::Result<Option<(Mmap, usize)>> { - let file = match fs::File::open(path) { - Ok(file) => file, - Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None), - Err(err) => return Err(err), - }; +) -> Result<OpenFile, OpenFileError> { + let file = fs::File::open(path).map_err(|err| { + if err.kind() == io::ErrorKind::NotFound { + OpenFileError::NotFoundOrHeaderMismatch + } else { + OpenFileError::IoError { err } + } + })?; + // SAFETY: This process must not modify nor remove the backing file while the memory map lives. // For the dep-graph and the work product index, it is as soon as the decoding is done. // For the query result cache, the memory map is dropped in save_dep_graph before calling @@ -116,8 +137,8 @@ pub(crate) fn read_file( let mut file_magic = [0u8; 4]; file.read_exact(&mut file_magic)?; if file_magic != FILE_MAGIC { - report_format_mismatch(report_incremental_info, path, "Wrong FILE_MAGIC"); - return Ok(None); + report_format_mismatch(sess, path, "Wrong FILE_MAGIC"); + return Err(OpenFileError::NotFoundOrHeaderMismatch); } } @@ -126,37 +147,35 @@ pub(crate) fn read_file( debug_assert!(size_of_val(&HEADER_FORMAT_VERSION) == 2); let mut header_format_version = [0u8; 2]; file.read_exact(&mut header_format_version)?; - let header_format_version = - (header_format_version[0] as u16) | ((header_format_version[1] as u16) << 8); + let header_format_version = u16::from_le_bytes(header_format_version); if header_format_version != HEADER_FORMAT_VERSION { - report_format_mismatch(report_incremental_info, path, "Wrong HEADER_FORMAT_VERSION"); - return Ok(None); + report_format_mismatch(sess, path, "Wrong HEADER_FORMAT_VERSION"); + return Err(OpenFileError::NotFoundOrHeaderMismatch); } } // Check RUSTC_VERSION { - let mut rustc_version_str_len = [0u8; 1]; - file.read_exact(&mut rustc_version_str_len)?; - let rustc_version_str_len = rustc_version_str_len[0] as usize; - let mut buffer = vec![0; rustc_version_str_len]; + let mut rustc_version_str_len = 0u8; + file.read_exact(array::from_mut(&mut rustc_version_str_len))?; + let mut buffer = vec![0; usize::from(rustc_version_str_len)]; file.read_exact(&mut buffer)?; - if buffer != rustc_version(is_nightly_build, cfg_version).as_bytes() { - report_format_mismatch(report_incremental_info, path, "Different compiler version"); - return Ok(None); + if buffer != rustc_version(sess).as_bytes() { + report_format_mismatch(sess, path, "Different compiler version"); + return Err(OpenFileError::NotFoundOrHeaderMismatch); } } - let post_header_start_pos = file.position() as usize; - Ok(Some((mmap, post_header_start_pos))) + let start_pos = file.position() as usize; + Ok(OpenFile { mmap, start_pos }) } -fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: &str) { +fn report_format_mismatch(sess: &Session, file: &Path, message: &str) { debug!("read_file: {}", message); - if report_incremental_info { + if sess.opts.unstable_opts.incremental_info { eprintln!( "[incremental] ignoring cache artifact `{}`: {}", file.file_name().unwrap().to_string_lossy(), @@ -168,12 +187,13 @@ fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: & /// A version string that hopefully is always different for compiler versions /// with different encodings of incremental compilation artifacts. Contains /// the Git commit hash. -fn rustc_version(nightly_build: bool, cfg_version: &'static str) -> Cow<'static, str> { - if nightly_build { - if let Ok(val) = env::var("RUSTC_FORCE_RUSTC_VERSION") { - return val.into(); - } +fn rustc_version(sess: &Session) -> Cow<'static, str> { + // Allow version string overrides so that tests can produce a header-mismatch on demand. + if sess.is_nightly_build() + && let Ok(env_version) = env::var("RUSTC_FORCE_RUSTC_VERSION") + { + Cow::Owned(env_version) + } else { + Cow::Borrowed(sess.cfg_version) } - - cfg_version.into() }
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index f73cc4d..cf80a7a 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -366,7 +366,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) { } Err(e) => { // Warn about the error. However, no need to abort compilation now. - sess.dcx().emit_warn(errors::Finalize { path: &incr_comp_session_dir, err: e }); + sess.dcx().emit_note(errors::Finalize { path: &incr_comp_session_dir, err: e }); debug!("finalize_session_directory() - error, marking as invalid"); // Drop the file lock, so we can garage collect
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index f7182e3..c0466a4 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -1,9 +1,8 @@ //! Code to load the dep-graph from files. -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::Arc; -use rustc_data_structures::memmap::Mmap; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProductMap}; @@ -20,6 +19,7 @@ use super::save::build_dep_graph; use super::{file_format, work_product}; use crate::errors; +use crate::persist::file_format::{OpenFile, OpenFileError}; #[derive(Debug)] /// Represents the result of an attempt to load incremental compilation data. @@ -38,19 +38,8 @@ pub enum LoadResult<T> { impl<T: Default> LoadResult<T> { /// Accesses the data returned in [`LoadResult::Ok`]. pub fn open(self, sess: &Session) -> T { - // Check for errors when using `-Zassert-incremental-state` - match (sess.opts.assert_incr_state, &self) { - (Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => { - sess.dcx().emit_fatal(errors::AssertNotLoaded); - } - ( - Some(IncrementalStateAssertion::Loaded), - LoadResult::LoadDepGraph(..) | LoadResult::DataOutOfDate, - ) => { - sess.dcx().emit_fatal(errors::AssertLoaded); - } - _ => {} - }; + // Emit a fatal error if `-Zassert-incr-state` is present and unsatisfied. + maybe_assert_incr_state(sess, &self); match self { LoadResult::LoadDepGraph(path, err) => { @@ -69,23 +58,6 @@ pub fn open(self, sess: &Session) -> T { } } -fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> { - match file_format::read_file( - path, - sess.opts.unstable_opts.incremental_info, - sess.is_nightly_build(), - sess.cfg_version, - ) { - Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos }, - Ok(None) => { - // The file either didn't exist or was produced by an incompatible - // compiler version. Neither is an error. - LoadResult::DataOutOfDate - } - Err(err) => LoadResult::LoadDepGraph(path.to_path_buf(), err), - } -} - fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) { debug!("delete_dirty_work_product({:?})", swp); work_product::delete_workproduct_files(sess, &swp.work_product); @@ -113,12 +85,12 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr // when trying to load work products. if sess.incr_comp_session_dir_opt().is_some() { let work_products_path = work_products_path(sess); - let load_result = load_data(&work_products_path, sess); - if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result { + if let Ok(OpenFile { mmap, start_pos }) = + file_format::open_incremental_file(sess, &work_products_path) + { // Decode the list of work_products - let Ok(mut work_product_decoder) = MemDecoder::new(&work_products_data[..], start_pos) - else { + let Ok(mut work_product_decoder) = MemDecoder::new(&mmap[..], start_pos) else { sess.dcx().emit_warn(errors::CorruptFile { path: &work_products_path }); return LoadResult::DataOutOfDate; }; @@ -147,11 +119,11 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph"); - match load_data(&path, sess) { - LoadResult::DataOutOfDate => LoadResult::DataOutOfDate, - LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err), - LoadResult::Ok { data: (bytes, start_pos) } => { - let Ok(mut decoder) = MemDecoder::new(&bytes, start_pos) else { + match file_format::open_incremental_file(sess, &path) { + Err(OpenFileError::NotFoundOrHeaderMismatch) => LoadResult::DataOutOfDate, + Err(OpenFileError::IoError { err }) => LoadResult::LoadDepGraph(path.to_owned(), err), + Ok(OpenFile { mmap, start_pos }) => { + let Ok(mut decoder) = MemDecoder::new(&mmap, start_pos) else { sess.dcx().emit_warn(errors::CorruptFile { path: &path }); return LoadResult::DataOutOfDate; }; @@ -191,15 +163,43 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> { let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache"); let path = query_cache_path(sess); - match load_data(&path, sess) { - LoadResult::Ok { data: (bytes, start_pos) } => { - let cache = OnDiskCache::new(sess, bytes, start_pos).unwrap_or_else(|()| { + match file_format::open_incremental_file(sess, &path) { + Ok(OpenFile { mmap, start_pos }) => { + let cache = OnDiskCache::new(sess, mmap, start_pos).unwrap_or_else(|()| { sess.dcx().emit_warn(errors::CorruptFile { path: &path }); OnDiskCache::new_empty() }); Some(cache) } - _ => Some(OnDiskCache::new_empty()), + Err(OpenFileError::NotFoundOrHeaderMismatch | OpenFileError::IoError { .. }) => { + Some(OnDiskCache::new_empty()) + } + } +} + +/// Emits a fatal error if the assertion in `-Zassert-incr-state` doesn't match +/// the outcome of trying to load previous-session state. +fn maybe_assert_incr_state(sess: &Session, load_result: &LoadResult<impl Sized>) { + // Return immediately if there's nothing to assert. + let Some(assertion) = sess.opts.unstable_opts.assert_incr_state else { return }; + + // Match exhaustively to make sure we don't miss any cases. + let loaded = match load_result { + LoadResult::Ok { .. } => true, + LoadResult::DataOutOfDate | LoadResult::LoadDepGraph(..) => false, + }; + + match assertion { + IncrementalStateAssertion::Loaded => { + if !loaded { + sess.dcx().emit_fatal(errors::AssertLoaded); + } + } + IncrementalStateAssertion::NotLoaded => { + if loaded { + sess.dcx().emit_fatal(errors::AssertNotLoaded) + } + } } }
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 1de64bb..dc14a8c 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -6,6 +6,7 @@ use rustc_middle::dep_graph::{ DepGraph, SerializedDepGraph, WorkProduct, WorkProductId, WorkProductMap, }; +use rustc_middle::query::on_disk_cache; use rustc_middle::ty::TyCtxt; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::FileEncoder; @@ -82,7 +83,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { file_format::save_in(sess, query_cache_path, "query cache", |encoder| { tcx.sess.time("incr_comp_serialize_result_cache", || { - on_disk_cache.serialize(tcx, encoder) + on_disk_cache::OnDiskCache::serialize(tcx, encoder) }) }); });
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index f833acf..a2ab99f 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs
@@ -1323,6 +1323,12 @@ pub fn insert(&mut self, elem: T) -> bool { self.bit_set.insert(elem) } + #[inline] + pub fn insert_range(&mut self, elems: Range<T>) { + self.ensure(elems.end.index()); + self.bit_set.insert_range(elems); + } + /// Returns `true` if the set has changed. #[inline] pub fn remove(&mut self, elem: T) -> bool { @@ -1331,6 +1337,16 @@ pub fn remove(&mut self, elem: T) -> bool { } #[inline] + pub fn clear(&mut self) { + self.bit_set.clear(); + } + + #[inline] + pub fn count(&self) -> usize { + self.bit_set.count() + } + + #[inline] pub fn is_empty(&self) -> bool { self.bit_set.is_empty() } @@ -1342,6 +1358,14 @@ pub fn contains(&self, elem: T) -> bool { } #[inline] + pub fn contains_any(&self, elems: Range<T>) -> bool { + elems.start.index() < self.bit_set.domain_size + && self + .bit_set + .contains_any(elems.start..T::new(elems.end.index().min(self.bit_set.domain_size))) + } + + #[inline] pub fn iter(&self) -> BitIter<'_, T> { self.bit_set.iter() }
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index dc7fe03..1b8c8e3 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs
@@ -2,9 +2,13 @@ #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(all(feature = "nightly", test), feature(test))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait))] -#![cfg_attr(feature = "nightly", feature(new_range_api))] // tidy-alphabetical-end +// FIXME(#125687): new_range_api recently stabilized +// Remove this when it hits stable. cfg(bootstrap) +#![allow(stable_features)] +#![cfg_attr(feature = "nightly", feature(new_range_api))] + pub mod bit_set; #[cfg(feature = "nightly")] pub mod interval;
diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 2824032..b6ee283 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs
@@ -174,8 +174,8 @@ fn hash_stable(&self, hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx } else if stable_hash_generic || stable_hash_no_context { quote! { #gate_rustc_only - impl<CTX> ::rustc_data_structures::stable_hasher::HashStable<CTX> for #name { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + impl<Hcx> ::rustc_data_structures::stable_hasher::HashStable<Hcx> for #name { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { self.as_u32().hash_stable(hcx, hasher) } }
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 3487286..70e3d7d 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs
@@ -140,9 +140,6 @@ pub fn sup<T>( ty::Contravariant, actual, self.cause.span, - &mut |alias| { - self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias) - }, ) .map(|goals| self.goals_to_obligations(goals)) } else { @@ -176,9 +173,6 @@ pub fn sub<T>( ty::Covariant, actual, self.cause.span, - &mut |alias| { - self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias) - }, ) .map(|goals| self.goals_to_obligations(goals)) } else { @@ -231,9 +225,6 @@ pub fn eq_trace<T>( ty::Invariant, actual, self.cause.span, - &mut |alias| { - self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias) - }, ) .map(|goals| self.goals_to_obligations(goals)) } else {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e7082f9..e15b255 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1,5 +1,5 @@ use std::cell::{Cell, RefCell}; -use std::{fmt, mem}; +use std::fmt; pub use at::DefineOpaqueTypes; use free_regions::RegionRelations; @@ -21,7 +21,6 @@ use rustc_macros::extension; pub use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::bug; -use rustc_middle::hooks::TypeErasedInfcx; use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::select; @@ -1100,45 +1099,22 @@ pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { // // Note: if these two lines are combined into one we get // dynamic borrow errors on `self.inner`. - let (root_vid, value) = - self.inner.borrow_mut().type_variables().probe_with_root_vid(v); - value.known().map_or_else( - || if root_vid == v { ty } else { Ty::new_var(self.tcx, root_vid) }, - |t| self.shallow_resolve(t), - ) + let known = self.inner.borrow_mut().type_variables().probe(v).known(); + known.map_or(ty, |t| self.shallow_resolve(t)) } ty::IntVar(v) => { - let (root, value) = - self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v); - match value { + match self.inner.borrow_mut().int_unification_table().probe_value(v) { ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), - ty::IntVarValue::Unknown => { - if root == v { - ty - } else { - Ty::new_int_var(self.tcx, root) - } - } + ty::IntVarValue::Unknown => ty, } } ty::FloatVar(v) => { - let (root, value) = self - .inner - .borrow_mut() - .float_unification_table() - .inlined_probe_key_value(v); - match value { + match self.inner.borrow_mut().float_unification_table().probe_value(v) { ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), - ty::FloatVarValue::Unknown => { - if root == v { - ty - } else { - Ty::new_float_var(self.tcx, root) - } - } + ty::FloatVarValue::Unknown => ty, } } @@ -1152,16 +1128,13 @@ pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Infer(infer_ct) => match infer_ct { - InferConst::Var(vid) => { - let (root, value) = self - .inner - .borrow_mut() - .const_unification_table() - .inlined_probe_key_value(vid); - value.known().unwrap_or_else(|| { - if root.vid == vid { ct } else { ty::Const::new_var(self.tcx, root.vid) } - }) - } + InferConst::Var(vid) => self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .known() + .unwrap_or(ct), InferConst::Fresh(_) => ct, }, ty::ConstKind::Param(_) @@ -1185,13 +1158,6 @@ pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { self.inner.borrow_mut().type_variables().root_var(var) } - /// If `ty` is an unresolved type variable, returns its root vid. - pub fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> { - let (root, value) = - self.inner.borrow_mut().type_variables().inlined_probe_with_vid(ty.ty_vid()?); - value.is_unknown().then_some(root) - } - pub fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) { self.inner.borrow_mut().type_variables().sub_unify(a, b); } @@ -1251,36 +1217,6 @@ pub fn resolve_vars_if_possible<T>(&self, value: T) -> T value.fold_with(&mut r) } - /// Normally, we shallow-resolve unresolved type variables to their root - /// variables. This is mainly done for performance reasons, and in most - /// cases resolving to the root variable (instead of the variable itself) - /// does not affect type inference. - /// - /// However, there is an exceptional case: *fudging*. Fudging is intended - /// to guide inference rather than impose hard requirements. But our current - /// handling here is somewhat janky. - /// - /// In particular, inference variables that are considered equal within the - /// fudging scope may not remain equal outside of it. This makes it observable - /// which inference variable we resolve to. For backwards compatibility, we - /// avoid resolving to the root variable by using this function inside the - /// fudge instead of [`InferCtxt::resolve_vars_if_possible`]. - /// - /// See #153869 for more details. - pub fn resolve_vars_if_possible_for_fudging<T>(&self, value: T) -> T - where - T: TypeFoldable<TyCtxt<'tcx>>, - { - if let Err(guar) = value.error_reported() { - self.set_tainted_by_errors(guar); - } - if !value.has_non_region_infer() { - return value; - } - let mut r = resolve::OpportunisticVarResolver::new_for_fudging(self); - value.fold_with(&mut r) - } - pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T where T: TypeFoldable<TyCtxt<'tcx>>, @@ -1529,17 +1465,6 @@ pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar) -> boo } } - pub fn try_eagerly_normalize_alias<'a>( - &'a self, - param_env: ty::ParamEnv<'tcx>, - span: Span, - alias: ty::AliasTy<'tcx>, - ) -> Ty<'tcx> { - let erased = - unsafe { mem::transmute::<&'a InferCtxt<'tcx>, TypeErasedInfcx<'a, 'tcx>>(self) }; - self.tcx.try_eagerly_normalize_alias(erased, param_env, span, alias) - } - /// Attach a callback to be invoked on each root obligation evaluated in the new trait solver. pub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'tcx>) { debug_assert!(
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index b2d5913..3ab39e8 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -51,7 +51,7 @@ impl<'tcx> InferCtxt<'tcx> { /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all /// other usecases (i.e. setting the value of a type var). #[instrument(level = "debug", skip(self, relation))] - pub fn instantiate_ty_var<R: PredicateEmittingRelation<Self>>( + pub fn instantiate_ty_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>( &self, relation: &mut R, target_is_expected: bool, @@ -61,136 +61,13 @@ pub fn instantiate_ty_var<R: PredicateEmittingRelation<Self>>( ) -> RelateResult<'tcx, ()> { debug_assert!(self.inner.borrow_mut().type_variables().probe(target_vid).is_unknown()); - let generalized_ty = if self.next_trait_solver() - && matches!(relation.structurally_relate_aliases(), StructurallyRelateAliases::No) - && let ty::Alias(_, alias) = source_ty.kind() - { - let normalized_alias = relation.try_eagerly_normalize_alias(*alias); - - if normalized_alias.is_ty_var() { - normalized_alias - } else { - let Generalization { value_may_be_infer: generalized_ty } = self.generalize( - relation.span(), - GeneralizerState::ShallowStructurallyRelateAliases, - target_vid, - instantiation_variance, - normalized_alias, - &mut |alias| relation.try_eagerly_normalize_alias(alias), - )?; - - // The only way to get a tyvar back is if the outermost type is an alias. - // However, here, though we know it *is* an alias, we initialize the generalizer - // with `ShallowStructurallyRelateAliases` so we treat the outermost alias as rigid, - // ensuring this is never a tyvar. - assert!(!generalized_ty.is_ty_var()); - - generalized_ty - } - } else { - // Generalize `source_ty` depending on the current variance. As an example, assume - // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference - // variable. - // - // Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh - // region/type inference variables. - // - // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and - // `?1 <: ?3`. - let Generalization { value_may_be_infer: generalized_ty } = self.generalize( - relation.span(), - match relation.structurally_relate_aliases() { - StructurallyRelateAliases::No => GeneralizerState::Default, - StructurallyRelateAliases::Yes => GeneralizerState::StructurallyRelateAliases, - }, - target_vid, - instantiation_variance, - source_ty, - &mut |alias| relation.try_eagerly_normalize_alias(alias), - )?; - - generalized_ty - }; - - // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment. - // - // FIXME(#16847): This code is non-ideal because all these subtype - // relations wind up attributed to the same spans. We need - // to associate causes/spans with each of the relations in - // the stack to get this right. - if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() { - // Constrain `b_vid` to the generalized type variable. - self.inner.borrow_mut().type_variables().equate(target_vid, generalized_vid); - - // This happens for cases like `<?0 as Trait>::Assoc == ?0`. - // We can't instantiate `?0` here as that would result in a - // cyclic type. We instead delay the unification in case - // the alias can be normalized to something which does not - // mention `?0`. - if self.next_trait_solver() { - let (lhs, rhs, direction) = match instantiation_variance { - ty::Invariant => { - (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate) - } - ty::Covariant => { - (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype) - } - ty::Contravariant => { - (source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype) - } - ty::Bivariant => unreachable!("bivariant generalization"), - }; - - relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]); - } else { - match source_ty.kind() { - &ty::Alias(ty::Projection, data) => { - // FIXME: This does not handle subtyping correctly, we could - // instead create a new inference variable `?normalized_source`, emitting - // `Projection(normalized_source, ?ty_normalized)` and - // `?normalized_source <: generalized_ty`. - relation.register_predicates([ty::ProjectionPredicate { - projection_term: data.into(), - term: generalized_ty.into(), - }]); - } - // The old solver only accepts projection predicates for associated types. - ty::Alias(ty::Inherent | ty::Free | ty::Opaque, _) => { - return Err(TypeError::CyclicTy(source_ty)); - } - _ => bug!("generalized `{source_ty:?} to infer, not an alias"), - } - } - } else { - // Constrain `b_vid` to the generalized type `generalized_ty`. - self.inner.borrow_mut().type_variables().instantiate(target_vid, generalized_ty); - - // NOTE: The `instantiation_variance` is not the same variance as - // used by the relation. When instantiating `b`, `target_is_expected` - // is flipped and the `instantiation_variance` is also flipped. To - // constrain the `generalized_ty` while using the original relation, - // we therefore only have to flip the arguments. - // - // ```ignore (not code) - // ?a rel B - // instantiate_ty_var(?a, B) # expected and variance not flipped - // B' rel B - // ``` - // or - // ```ignore (not code) - // A rel ?b - // instantiate_ty_var(?b, A) # expected and variance flipped - // A rel A' - // ``` - if target_is_expected { - relation.relate(generalized_ty, source_ty)?; - } else { - debug!("flip relation"); - relation.relate(source_ty, generalized_ty)?; - } - } - - Ok(()) + self.instantiate_var( + relation, + target_is_expected, + target_vid.into(), + instantiation_variance, + source_ty.into(), + ) } /// Instantiates the const variable `target_vid` with the given constant. @@ -237,59 +114,191 @@ pub(crate) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'tcx> ) -> RelateResult<'tcx, ()> { // FIXME(generic_const_exprs): Occurs check failures for unevaluated // constants and generic expressions are not yet handled correctly. - let Generalization { value_may_be_infer: generalized_ct } = self.generalize( - relation.span(), - match relation.structurally_relate_aliases() { - StructurallyRelateAliases::No => GeneralizerState::Default, - StructurallyRelateAliases::Yes => GeneralizerState::StructurallyRelateAliases, - }, - target_vid, + debug_assert!( + self.inner.borrow_mut().const_unification_table().probe_value(target_vid).is_unknown() + ); + + self.instantiate_var( + relation, + target_is_expected, + target_vid.into(), ty::Invariant, - source_ct, - &mut |alias| relation.try_eagerly_normalize_alias(alias), + source_ct.into(), + ) + } + + #[instrument(level = "debug", skip(self, relation))] + fn instantiate_var<R: PredicateEmittingRelation<Self>>( + &self, + relation: &mut R, + target_is_expected: bool, + target_vid: TermVid, + instantiation_variance: ty::Variance, + source_term: Term<'tcx>, + ) -> RelateResult<'tcx, ()> { + // Generalize `source_term` depending on the current variance. As an example, assume + // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference + // variable. + // + // Then the `generalized_term` would be `&'?2 ?3`, where `'?2` and `?3` are fresh + // region/type inference variables. + // + // We then relate `generalized_term <: source_term`, adding constraints like `'x: '?2` and + // `?1 <: ?3`. + let Generalization { value_may_be_infer: generalized_term } = self.generalize( + relation.span(), + relation.structurally_relate_aliases(), + target_vid, + instantiation_variance, + source_term, )?; - debug_assert!(!generalized_ct.is_ct_infer()); + // Constrain `b_vid` to the generalized type `generalized_term`. + self.union_var_term(target_vid, generalized_term); - self.inner - .borrow_mut() - .const_unification_table() - .union_value(target_vid, ConstVariableValue::Known { value: generalized_ct }); + // Finally, relate `generalized_term` to `source_term`, as described in previous comment. + // + // FIXME(#16847): This code is non-ideal because all these subtype + // relations wind up attributed to the same spans. We need + // to associate causes/spans with each of the relations in + // the stack to get this right. + if generalized_term.is_infer() { + // This happens for cases like `<?0 as Trait>::Assoc == ?0`. + // We can't instantiate `?0` here as that would result in a + // cyclic type. We instead delay the unification in case + // the alias can be normalized to something which does not + // mention `?0`. + if self.next_trait_solver() { + let (lhs, rhs, direction) = match instantiation_variance { + ty::Invariant => { + (generalized_term, source_term, AliasRelationDirection::Equate) + } + ty::Covariant => { + (generalized_term, source_term, AliasRelationDirection::Subtype) + } + ty::Contravariant => { + (source_term, generalized_term, AliasRelationDirection::Subtype) + } + ty::Bivariant => unreachable!("bivariant generalization"), + }; - // Make sure that the order is correct when relating the - // generalized const and the source. - if target_is_expected { - relation.relate_with_variance( - ty::Invariant, - ty::VarianceDiagInfo::default(), - generalized_ct, - source_ct, - )?; + relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]); + } else { + let Some(source_alias) = source_term.to_alias_term() else { + bug!("generalized `{source_term:?} to infer, not an alias"); + }; + match source_alias.kind(self.tcx) { + ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { + // FIXME: This does not handle subtyping correctly, we could + // instead create a new inference variable `?normalized_source`, emitting + // `Projection(normalized_source, ?ty_normalized)` and + // `?normalized_source <: generalized_term`. + relation.register_predicates([ty::ProjectionPredicate { + projection_term: source_alias, + term: generalized_term, + }]); + } + // The old solver only accepts projection predicates for associated types. + ty::AliasTermKind::InherentTy + | ty::AliasTermKind::FreeTy + | ty::AliasTermKind::OpaqueTy => { + return Err(TypeError::CyclicTy(source_term.expect_type())); + } + ty::AliasTermKind::InherentConst + | ty::AliasTermKind::FreeConst + | ty::AliasTermKind::UnevaluatedConst => { + return Err(TypeError::CyclicConst(source_term.expect_const())); + } + } + } } else { - relation.relate_with_variance( - ty::Invariant, - ty::VarianceDiagInfo::default(), - source_ct, - generalized_ct, - )?; + // NOTE: The `instantiation_variance` is not the same variance as + // used by the relation. When instantiating `b`, `target_is_expected` + // is flipped and the `instantiation_variance` is also flipped. To + // constrain the `generalized_term` while using the original relation, + // we therefore only have to flip the arguments. + // + // ```ignore (not code) + // ?a rel B + // instantiate_ty_var(?a, B) # expected and variance not flipped + // B' rel B + // ``` + // or + // ```ignore (not code) + // A rel ?b + // instantiate_ty_var(?b, A) # expected and variance flipped + // A rel A' + // ``` + match generalized_term.kind() { + ty::TermKind::Ty(_) => { + if target_is_expected { + relation.relate(generalized_term, source_term)?; + } else { + debug!("flip relation"); + relation.relate(source_term, generalized_term)?; + } + } + ty::TermKind::Const(_) => { + // Override consts to always be invariant + if target_is_expected { + relation.relate_with_variance( + ty::Invariant, + ty::VarianceDiagInfo::default(), + generalized_term, + source_term, + )?; + } else { + relation.relate_with_variance( + ty::Invariant, + ty::VarianceDiagInfo::default(), + source_term, + generalized_term, + )?; + } + } + } } Ok(()) } + /// This is a thin wrapper around inserting into the var tables. You probably want + /// [`Self::instantiate_var`] instead, which calls this method. + fn union_var_term(&self, l: TermVid, r: ty::Term<'tcx>) { + match (l, r.kind()) { + (TermVid::Ty(l), ty::TermKind::Ty(r)) => { + if let Some(r) = r.ty_vid() { + self.inner.borrow_mut().type_variables().equate(l, r) + } else { + self.inner.borrow_mut().type_variables().instantiate(l, r) + } + } + (TermVid::Const(l), ty::TermKind::Const(r)) => { + if let Some(r) = r.ct_vid() { + self.inner.borrow_mut().const_unification_table().union(l, r) + } else { + self.inner + .borrow_mut() + .const_unification_table() + .union_value(l, ConstVariableValue::Known { value: r }) + } + } + _ => bug!("mismatched term kinds in generalize: {l:?}, {r:?}"), + } + } + /// Attempts to generalize `source_term` for the type variable `target_vid`. /// This checks for cycles -- that is, whether `source_term` references `target_vid`. - fn generalize<T: Into<Term<'tcx>> + Relate<TyCtxt<'tcx>>>( + fn generalize( &self, span: Span, - initial_state: GeneralizerState, - target_vid: impl Into<TermVid>, + structurally_relate_aliases: StructurallyRelateAliases, + target_vid: TermVid, ambient_variance: ty::Variance, - source_term: T, - normalize: &mut dyn FnMut(ty::AliasTy<'tcx>) -> Ty<'tcx>, - ) -> RelateResult<'tcx, Generalization<T>> { + source_term: Term<'tcx>, + ) -> RelateResult<'tcx, Generalization<Term<'tcx>>> { assert!(!source_term.has_escaping_bound_vars()); - let (for_universe, root_vid) = match target_vid.into() { + let (for_universe, root_vid) = match target_vid { TermVid::Ty(ty_vid) => { (self.probe_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid))) } @@ -302,13 +311,13 @@ fn generalize<T: Into<Term<'tcx>> + Relate<TyCtxt<'tcx>>>( let mut generalizer = Generalizer { infcx: self, span, + structurally_relate_aliases, root_vid, for_universe, - root_term: source_term.into(), + root_term: source_term, ambient_variance, - state: initial_state, + in_alias: false, cache: Default::default(), - normalize, }; let value_may_be_infer = generalizer.relate(source_term, source_term)?; @@ -355,54 +364,6 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) { } } -/// This state determines how generalization treats aliases. -/// -/// Based on which state we're in, we treat them either as rigid or normalizable, -/// which might change depending on what types the generalization visitor encounters. -/// See `handle_alias_ty` for the logic of how we change states. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -enum GeneralizerState { - /// Treat aliases as potentially normalizable. - /// - /// This is the default state that generalization starts in, unless we're - /// treating aliases as rigid. It also means we're not currently inside an - /// alias, since then we change the state to `IncompletelyRelateAliasArgs`. - Default, - /// We enter this state when we're generalizing the arguments of a - /// potentially normalizeable alias. - /// - /// The behavior here is different between the old and the new solver: - /// - /// In the old solver, the difference between this and `Default` is needed to - /// correctly handle `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. That - /// equality can hold by either normalizing the outer or the inner - /// associated type. In the old solver, we always structurally relate - /// aliases. If we we encounter an occurs check failure, we propagate the - /// failure to the outermost alias, for which we then emit a `Projection` - /// goal instead. - /// - /// In the new solver, we rarely get into this state. - /// When we encounter aliases we instead attempt to normalize them, and treat - /// them as rigid using `ShallowStructurallyRelate`. Only when an alias has - /// escaping bound variables do we continue with similar logic to the old - /// solver, except now we also explicitly relate the type and consts in the - /// arguments of aliases while in this mode. - /// - /// FIXME: Because we relate the type and consts in the arguments of aliases - /// while in this mode, this is incomplete. - IncompletelyRelateAliasArgs, - /// During generalization, when we encounter aliases, we will first attempt - /// to normalize them when we're using the next trait solver. We can now - /// treat the normalized alias as rigid, but only for "one layer", hence - /// shallow. New aliases encountered inside the arguments of the outer alias - /// should once again be related as normal. - ShallowStructurallyRelateAliases, - /// Treat aliases as rigid when relating them. - /// - /// This corresponds to `relation.structurally_relate_aliases()`. - StructurallyRelateAliases, -} - /// The "generalizer" is used when handling inference variables. /// /// The basic strategy for handling a constraint like `?A <: B` is to @@ -421,6 +382,10 @@ struct Generalizer<'me, 'tcx> { span: Span, + /// Whether aliases should be related structurally. If not, we have to + /// be careful when generalizing aliases. + structurally_relate_aliases: StructurallyRelateAliases, + /// The vid of the type variable that is in the process of being /// instantiated. If we find this within the value we are folding, /// that means we would have created a cyclic value. @@ -438,17 +403,14 @@ struct Generalizer<'me, 'tcx> { /// some other type. What will be the variance at this point? ambient_variance: ty::Variance, - /// This field keeps track of how we treat aliases during generalization. + /// This is set once we're generalizing the arguments of an alias. /// - /// Refer to [`GeneralizerState`]'s docs for more information about the - /// all the possible values this can have, and when we use which. - state: GeneralizerState, + /// This is necessary to correctly handle + /// `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. This equality can + /// hold by either normalizing the outer or the inner associated type. + in_alias: bool, - cache: SsoHashMap<(Ty<'tcx>, ty::Variance, GeneralizerState), Ty<'tcx>>, - - /// Normalize an alias in the trait solver. - /// If normalization fails, a fresh infer var is returned. - normalize: &'me mut dyn FnMut(ty::AliasTy<'tcx>) -> Ty<'tcx>, + cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>, } impl<'tcx> Generalizer<'_, 'tcx> { @@ -462,8 +424,12 @@ fn cyclic_term_error(&self) -> TypeError<'tcx> { /// Create a new type variable in the universe of the target when /// generalizing an alias. - fn next_ty_var_for_alias(&self) -> Ty<'tcx> { - self.infcx.next_ty_var_in_universe(self.span, self.for_universe) + fn next_var_for_alias_of_kind(&self, alias: ty::AliasTerm<'tcx>) -> ty::Term<'tcx> { + if alias.kind(self.cx()).is_type() { + self.infcx.next_ty_var_in_universe(self.span, self.for_universe).into() + } else { + self.infcx.next_const_var_in_universe(self.span, self.for_universe).into() + } } /// An occurs check failure inside of an alias does not mean @@ -484,51 +450,27 @@ fn next_ty_var_for_alias(&self) -> Ty<'tcx> { /// continue generalizing the alias. This ends up pulling down the universe of the /// inference variable and is incomplete in case the alias would normalize to a type /// which does not mention that inference variable. - fn handle_alias_ty( + fn generalize_alias_term( &mut self, - alias_ty: Ty<'tcx>, - alias: ty::AliasTy<'tcx>, - ) -> Result<Ty<'tcx>, TypeError<'tcx>> { - match self.state { - GeneralizerState::ShallowStructurallyRelateAliases => { - // We can switch back to default, we've treated one layer as rigid by doing this operation. - self.state = GeneralizerState::Default; - let res = relate::structurally_relate_tys(self, alias_ty, alias_ty); - self.state = GeneralizerState::ShallowStructurallyRelateAliases; - return res; - } - GeneralizerState::StructurallyRelateAliases => { - return relate::structurally_relate_tys(self, alias_ty, alias_ty); - } - GeneralizerState::Default - if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() => - { - // We do not eagerly replace aliases with inference variables if they have - // escaping bound vars, see the method comment for details. However, when we - // are inside of an alias with escaping bound vars replacing nested aliases - // with inference variables can cause incorrect ambiguity. - // - // cc trait-system-refactor-initiative#110 - let normalized_alias = (self.normalize)(alias); - - self.state = GeneralizerState::ShallowStructurallyRelateAliases; - // recursively generalize, treat the outer alias as rigid to avoid infinite recursion - let res = self.relate(normalized_alias, normalized_alias); - - // only one way to get here - self.state = GeneralizerState::Default; - - return res; - } - GeneralizerState::Default | GeneralizerState::IncompletelyRelateAliasArgs => {} + alias: ty::AliasTerm<'tcx>, + ) -> Result<Term<'tcx>, TypeError<'tcx>> { + // We do not eagerly replace aliases with inference variables if they have + // escaping bound vars, see the method comment for details. However, when we + // are inside of an alias with escaping bound vars replacing nested aliases + // with inference variables can cause incorrect ambiguity. + // + // cc trait-system-refactor-initiative#110 + if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias { + return Ok(self.next_var_for_alias_of_kind(alias)); } - let previous_state = - mem::replace(&mut self.state, GeneralizerState::IncompletelyRelateAliasArgs); + let is_nested_alias = mem::replace(&mut self.in_alias, true); let result = match self.relate(alias, alias) { - Ok(alias) => Ok(alias.to_ty(self.cx())), - Err(e) => match previous_state { - GeneralizerState::Default => { + Ok(alias) => Ok(alias.to_term(self.cx())), + Err(e) => { + if is_nested_alias { + return Err(e); + } else { let mut visitor = MaxUniverse::new(); alias.visit_with(&mut visitor); let infer_replacement_is_complete = @@ -539,16 +481,11 @@ fn handle_alias_ty( } debug!("generalization failure in alias"); - Ok(self.next_ty_var_for_alias()) + Ok(self.next_var_for_alias_of_kind(alias)) } - GeneralizerState::IncompletelyRelateAliasArgs => return Err(e), - - // Early return. - GeneralizerState::ShallowStructurallyRelateAliases - | GeneralizerState::StructurallyRelateAliases => unreachable!(), - }, + } }; - self.state = previous_state; + self.in_alias = is_nested_alias; result } } @@ -602,7 +539,7 @@ fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>( fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be == - if let Some(&result) = self.cache.get(&(t, self.ambient_variance, self.state)) { + if let Some(&result) = self.cache.get(&(t, self.ambient_variance, self.in_alias)) { return Ok(result); } @@ -650,7 +587,6 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { // of each other. This is currently only used for diagnostics. // To see why, see the docs in the `type_variables` module. inner.type_variables().sub_unify(vid, new_var_id); - // If we're in the new solver and create a new inference // variable inside of an alias we eagerly constrain that // inference variable to prevent unexpected ambiguity errors. @@ -668,15 +604,9 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { // cc trait-system-refactor-initiative#108 if self.infcx.next_trait_solver() && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) + && self.in_alias { - match self.state { - GeneralizerState::IncompletelyRelateAliasArgs => { - inner.type_variables().equate(vid, new_var_id); - } - GeneralizerState::Default - | GeneralizerState::ShallowStructurallyRelateAliases - | GeneralizerState::StructurallyRelateAliases => {} - } + inner.type_variables().equate(vid, new_var_id); } debug!("replacing original vid={:?} with new={:?}", vid, new_var_id); @@ -705,12 +635,17 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { } } - ty::Alias(_, data) => self.handle_alias_ty(t, data), + ty::Alias(_, data) => match self.structurally_relate_aliases { + StructurallyRelateAliases::No => { + self.generalize_alias_term(data.into()).map(|v| v.expect_type()) + } + StructurallyRelateAliases::Yes => relate::structurally_relate_tys(self, t, t), + }, _ => relate::structurally_relate_tys(self, t, t), }?; - self.cache.insert((t, self.ambient_variance, self.state), g); + self.cache.insert((t, self.ambient_variance, self.in_alias), g); Ok(g) } @@ -801,15 +736,9 @@ fn consts( // for more details. if self.infcx.next_trait_solver() && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) + && self.in_alias { - match self.state { - GeneralizerState::IncompletelyRelateAliasArgs => { - variable_table.union(vid, new_var_id); - } - GeneralizerState::Default - | GeneralizerState::ShallowStructurallyRelateAliases - | GeneralizerState::StructurallyRelateAliases => {} - } + variable_table.union(vid, new_var_id); } Ok(ty::Const::new_var(self.cx(), new_var_id)) } @@ -819,17 +748,26 @@ fn consts( // FIXME: Unevaluated constants are also not rigid, so the current // approach of always relating them structurally is incomplete. // - // FIXME: remove this branch once `structurally_relate_consts` is fully - // structural. - ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { - let args = self.relate_with_variance( - ty::Invariant, - ty::VarianceDiagInfo::default(), - args, - args, - )?; - Ok(ty::Const::new_unevaluated(self.cx(), ty::UnevaluatedConst { def, args })) - } + // FIXME: replace the StructurallyRelateAliases::Yes branch with + // `structurally_relate_consts` once it is fully structural. + ty::ConstKind::Unevaluated(uv) => match self.structurally_relate_aliases { + // Hack: Fall back to old behavior if GCE is enabled (it used to just be the Yes + // path), as doing this new No path breaks some GCE things. I expect GCE to be + // ripped out soon so this shouldn't matter soon. + StructurallyRelateAliases::No if !self.cx().features().generic_const_exprs() => { + self.generalize_alias_term(uv.into()).map(|v| v.expect_const()) + } + _ => { + let ty::UnevaluatedConst { def, args } = uv; + let args = self.relate_with_variance( + ty::Invariant, + ty::VarianceDiagInfo::default(), + args, + args, + )?; + Ok(ty::Const::new_unevaluated(self.cx(), ty::UnevaluatedConst { def, args })) + } + }, ty::ConstKind::Placeholder(placeholder) => { if self.for_universe.can_name(placeholder.universe) { Ok(c)
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 7e480df..a05e2d4 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -299,8 +299,4 @@ fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { ty::AliasRelationDirection::Equate, ))]); } - - fn try_eagerly_normalize_alias(&mut self, alias: ty::AliasTy<'tcx>) -> Ty<'tcx> { - self.infcx.try_eagerly_normalize_alias(self.param_env(), self.span(), alias) - } }
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 67f9dc6..96a0375 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -396,13 +396,4 @@ fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { } })]); } - - fn try_eagerly_normalize_alias( - &mut self, - _alias: rustc_type_ir::AliasTy<<InferCtxt<'tcx> as rustc_type_ir::InferCtxtLike>::Interner>, - ) -> <<InferCtxt<'tcx> as rustc_type_ir::InferCtxtLike>::Interner as rustc_type_ir::Interner>::Ty - { - // We only try to eagerly normalize aliases if we're using the new solver. - unreachable!() - } }
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 917d7b6..13df23a 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -17,9 +17,6 @@ /// points for correctness. pub struct OpportunisticVarResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, - /// If true, we don't resolve ty/const vars to their roots. - /// See comments on [`InferCtxt::resolve_vars_if_possible_for_fudging`] - for_fudging: bool, /// We're able to use a cache here as the folder does /// not have any mutable state. cache: DelayedMap<Ty<'tcx>, Ty<'tcx>>, @@ -28,12 +25,7 @@ pub struct OpportunisticVarResolver<'a, 'tcx> { impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { #[inline] pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticVarResolver { infcx, for_fudging: false, cache: Default::default() } - } - - #[inline] - pub fn new_for_fudging(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticVarResolver { infcx, for_fudging: true, cache: Default::default() } + OpportunisticVarResolver { infcx, cache: Default::default() } } } @@ -51,7 +43,6 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { } else { let shallow = self.infcx.shallow_resolve(t); let res = shallow.super_fold_with(self); - let res = if self.for_fudging && res.is_ty_var() { t } else { res }; assert!(self.cache.insert(t, res)); res } @@ -61,11 +52,8 @@ fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> { if !ct.has_non_region_infer() { ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { - let res = self.infcx.shallow_resolve_const(ct); - if self.for_fudging && res.is_ct_infer() { - return ct; - }; - res.super_fold_with(self) + let ct = self.infcx.shallow_resolve_const(ct); + ct.super_fold_with(self) } }
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 56cae2c..6709c82 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -101,7 +101,7 @@ pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E> // going to be popped, so we will have to // eliminate any references to them. let snapshot_vars = SnapshotVarData::new(self, variable_lengths); - Ok((snapshot_vars, self.resolve_vars_if_possible_for_fudging(value))) + Ok((snapshot_vars, self.resolve_vars_if_possible(value))) })?; // At this point, we need to replace any of the now-popped
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 9b928cc..65f77fe 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -258,25 +258,6 @@ pub(crate) fn inlined_probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx self.eq_relations().inlined_probe_value(vid) } - /// Retrieves the type to which `vid` has been instantiated, if - /// any, along with the root `vid`. - pub(crate) fn probe_with_root_vid( - &mut self, - vid: ty::TyVid, - ) -> (ty::TyVid, TypeVariableValue<'tcx>) { - self.inlined_probe_with_vid(vid) - } - - /// An always-inlined variant of `probe_with_root_vid`, for very hot call sites. - #[inline(always)] - pub(crate) fn inlined_probe_with_vid( - &mut self, - vid: ty::TyVid, - ) -> (ty::TyVid, TypeVariableValue<'tcx>) { - let (id, value) = self.eq_relations().inlined_probe_key_value(vid); - (id.vid, value) - } - #[inline] fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> { self.storage.eq_relations.with_log(self.undo_log)
diff --git a/compiler/rustc_infer/src/infer/unify_key.rs b/compiler/rustc_infer/src/infer/unify_key.rs index 5e5d0e0..4016054 100644 --- a/compiler/rustc_infer/src/infer/unify_key.rs +++ b/compiler/rustc_infer/src/infer/unify_key.rs
@@ -110,6 +110,13 @@ pub(crate) fn known(&self) -> Option<ty::Const<'tcx>> { ConstVariableValue::Known { value } => Some(value), } } + + pub(crate) fn is_unknown(&self) -> bool { + match *self { + ConstVariableValue::Unknown { .. } => true, + ConstVariableValue::Known { .. } => false, + } + } } #[derive(PartialEq, Copy, Clone, Debug)]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 28f5109..d7d4f00 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs
@@ -21,9 +21,12 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; use rustc_hir::limit::Limit; +use rustc_hir::lints::DelayedLint; use rustc_hir::{Attribute, MaybeOwner, find_attr}; use rustc_incremental::setup_dep_graph; -use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; +use rustc_lint::{ + BufferedEarlyLint, DecorateAttrLint, EarlyCheckNode, LintStore, unerased_lint_store, +}; use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; @@ -904,7 +907,7 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { rustc_hir_typeck::provide(&mut providers.queries); ty::provide(&mut providers.queries); traits::provide(&mut providers.queries); - solve::provide(providers); + solve::provide(&mut providers.queries); rustc_passes::provide(&mut providers.queries); rustc_traits::provide(&mut providers.queries); rustc_ty_utils::provide(&mut providers.queries); @@ -1025,6 +1028,29 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>( ) } +pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { + for owner_id in tcx.hir_crate_items(()).delayed_lint_items() { + if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { + for lint in &delayed_lints.lints { + match lint { + DelayedLint::AttributeParsing(attribute_lint) => { + tcx.emit_node_span_lint( + attribute_lint.lint_id.lint, + attribute_lint.id, + attribute_lint.span, + DecorateAttrLint { + sess: tcx.sess, + tcx: Some(tcx), + diagnostic: &attribute_lint.kind, + }, + ); + } + } + } + } + } +} + /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// This function never fails. fn run_required_analyses(tcx: TyCtxt<'_>) { @@ -1074,6 +1100,32 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { ]); }); + sess.time("emit_ast_lowering_delayed_lints", || { + // Sanity check in debug mode that all lints are really noticed and we really will emit + // them all in the loop right below. + // + // During ast lowering, when creating items, foreign items, trait items and impl items, + // we store in them whether they have any lints in their owner node that should be + // picked up by `hir_crate_items`. However, theoretically code can run between that + // boolean being inserted into the item and the owner node being created. We don't want + // any new lints to be emitted there (you have to really try to manage that but still), + // but this check is there to catch that. + #[cfg(debug_assertions)] + { + let hir_items = tcx.hir_crate_items(()); + for owner_id in hir_items.owners() { + if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { + if !delayed_lints.lints.is_empty() { + // Assert that delayed_lint_items also picked up this item to have lints. + assert!(hir_items.delayed_lint_items().any(|i| i == owner_id)); + } + } + } + } + + emit_delayed_lints(tcx); + }); + rustc_hir_analysis::check_crate(tcx); // Freeze definitions as we don't add new ones at this point. // We need to wait until now since we synthesize a by-move body
diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 63fed51..eb60c61 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs
@@ -7,7 +7,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> { let mut decls = None; for id in tcx.hir_free_items() { - if find_attr!(tcx.hir_attrs(id.hir_id()), RustcProcMacroDecls) { + if find_attr!(tcx, id.hir_id(), RustcProcMacroDecls) { decls = Some(id.owner_id.def_id); } }
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index f9d583b..417cde1 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs
@@ -12,12 +12,12 @@ use rustc_session::config::{ AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, - FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, - LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, - Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, - PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, - SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, - rustc_optgroups, + FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input, + InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, + MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, + PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, + SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, + build_session_options, rustc_optgroups, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -686,7 +686,7 @@ macro_rules! untracked { // Make sure that changing an [UNTRACKED] option leaves the hash unchanged. // tidy-alphabetical-start - untracked!(assert_incr_state, Some(String::from("loaded"))); + untracked!(assert_incr_state, Some(IncrementalStateAssertion::Loaded)); untracked!(codegen_source_order, true); untracked!(deduplicate_diagnostics, false); untracked!(dump_dep_graph, true);
diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index 910a291..9a37448 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs
@@ -172,7 +172,6 @@ fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Muta &Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some((mutbl.into(), false)), Adjust::NeverToAny | Adjust::Pointer(..) - | Adjust::ReborrowPin(..) | Adjust::Deref(DerefAdjustKind::Builtin | DerefAdjustKind::Pin) | Adjust::Borrow(AutoBorrow::RawPtr(..) | AutoBorrow::Pin(..)) => None, }
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index d5cd26d..1cb0f90 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -5,7 +5,6 @@ elided_lifetime_in_path_suggestion, }; use rustc_hir::lints::{AttributeLintKind, FormatWarning}; -use rustc_middle::middle::stability; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::lint::BuiltinLintDiag; @@ -88,63 +87,16 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } .into_diag(dcx, level) } - BuiltinLintDiag::RedundantImport(spans, ident) => { - let subs = spans - .into_iter() - .map(|(span, is_imported)| match (span.is_dummy(), is_imported) { - (false, true) => lints::RedundantImportSub::ImportedHere { span, ident }, - (false, false) => lints::RedundantImportSub::DefinedHere { span, ident }, - (true, true) => lints::RedundantImportSub::ImportedPrelude { span, ident }, - (true, false) => lints::RedundantImportSub::DefinedPrelude { span, ident }, - }) - .collect(); - lints::RedundantImport { subs, ident }.into_diag(dcx, level) - } - BuiltinLintDiag::DeprecatedMacro { - suggestion, - suggestion_span, - note, - path, - since_kind, - } => { - let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion { - span: suggestion_span, - kind: "macro".to_owned(), - suggestion, - }); - - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } - .into_diag(dcx, level) - } - BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { - let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - } - .into_diag(dcx, level) - } - BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { - let suggestion = match sugg { - Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { - left: left_sp, - right: right_sp, - sugg, - }, - None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, - }; - lints::DeprecatedWhereClauseLocation { suggestion }.into_diag(dcx, level) - } BuiltinLintDiag::SingleUseLifetime { param_span, - use_span: Some((use_span, elide)), + use_span, + elidable, deletion_span, ident, } => { debug!(?param_span, ?use_span, ?deletion_span); let suggestion = if let Some(deletion_span) = deletion_span { - let (use_span, replace_lt) = if elide { + let (use_span, replace_lt) = if elidable { let use_span = self.sess.source_map().span_extend_while_whitespace(use_span); (use_span, String::new()) @@ -165,9 +117,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { lints::SingleUseLifetime { suggestion, param_span, use_span, ident } .into_diag(dcx, level) } - BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { - lints::UnusedLifetime { deletion_span, ident }.into_diag(dcx, level) - } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, position_sp_for_msg, @@ -203,63 +152,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { } .into_diag(dcx, level) } - BuiltinLintDiag::AmbiguousGlobReexports { - name, - namespace, - first_reexport_span, - duplicate_reexport_span, - } => lints::AmbiguousGlobReexports { - first_reexport: first_reexport_span, - duplicate_reexport: duplicate_reexport_span, - name, - namespace, - } - .into_diag(dcx, level), - BuiltinLintDiag::HiddenGlobReexports { - name, - namespace, - glob_reexport_span, - private_item_span, - } => lints::HiddenGlobReexports { - glob_reexport: glob_reexport_span, - private_item: private_item_span, - name, - namespace, - } - .into_diag(dcx, level), - BuiltinLintDiag::UnusedQualifications { removal_span } => { - lints::UnusedQualifications { removal_span }.into_diag(dcx, level) - } - BuiltinLintDiag::AssociatedConstElidedLifetime { - elided, - span: lt_span, - lifetimes_in_scope, - } => { - let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; - let code = if elided { "'static " } else { "'static" }; - lints::AssociatedConstElidedLifetime { - span: lt_span, - code, - elided, - lifetimes_in_scope, - } - .into_diag(dcx, level) - } - BuiltinLintDiag::UnreachableCfg { span, wildcard_span } => match wildcard_span { - Some(wildcard_span) => { - lints::UnreachableCfgSelectPredicateWildcard { span, wildcard_span } - .into_diag(dcx, level) - } - None => lints::UnreachableCfgSelectPredicate { span }.into_diag(dcx, level), - }, - - BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { - lints::UnusedCrateDependency { extern_crate, local_crate }.into_diag(dcx, level) - } - BuiltinLintDiag::UnusedVisibility(span) => { - lints::UnusedVisibility { span }.into_diag(dcx, level) - } BuiltinLintDiag::AttributeLint(kind) => { DecorateAttrLint { sess: self.sess, tcx: self.tcx, diagnostic: &kind } .into_diag(dcx, level)
diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs index 0cac91c..6c65673 100644 --- a/compiler/rustc_lint/src/lifetime_syntax.rs +++ b/compiler/rustc_lint/src/lifetime_syntax.rs
@@ -387,9 +387,7 @@ fn emit_mismatch_diagnostic<'tcx>( build_mismatch_suggestion(info.lifetime.ident.as_str(), &suggest_change_to_explicit_bound) }); - let is_bound_static = bound_lifetime.is_some_and(|info| info.lifetime.is_static()); - - tracing::debug!(?bound_lifetime, ?explicit_bound_suggestion, ?is_bound_static); + tracing::debug!(?bound_lifetime, ?explicit_bound_suggestion); let should_suggest_mixed = // Do we have a mixed case? @@ -397,16 +395,16 @@ fn emit_mismatch_diagnostic<'tcx>( // Is there anything to change? (!suggest_change_to_mixed_implicit.is_empty() || !suggest_change_to_mixed_explicit_anonymous.is_empty()) && - // If we have `'static`, we don't want to remove it. - !is_bound_static; + // If we have a named lifetime, prefer consistent naming. + bound_lifetime.is_none(); let mixed_suggestion = should_suggest_mixed.then(|| { let implicit_suggestions = make_implicit_suggestions(&suggest_change_to_mixed_implicit); - let explicit_anonymous_suggestions = suggest_change_to_mixed_explicit_anonymous - .iter() - .map(|info| info.suggestion("'_")) - .collect(); + let explicit_anonymous_suggestions = build_mismatch_suggestions_for_lifetime( + "'_", + &suggest_change_to_mixed_explicit_anonymous, + ); lints::MismatchedLifetimeSyntaxesSuggestion::Mixed { implicit_suggestions, @@ -426,8 +424,8 @@ fn emit_mismatch_diagnostic<'tcx>( !suggest_change_to_implicit.is_empty() && // We never want to hide the lifetime in a path (or similar). allow_suggesting_implicit && - // If we have `'static`, we don't want to remove it. - !is_bound_static; + // If we have a named lifetime, prefer consistent naming. + bound_lifetime.is_none(); let implicit_suggestion = should_suggest_implicit.then(|| { let suggestions = make_implicit_suggestions(&suggest_change_to_implicit); @@ -448,8 +446,10 @@ fn emit_mismatch_diagnostic<'tcx>( let should_suggest_explicit_anonymous = // Is there anything to change? !suggest_change_to_explicit_anonymous.is_empty() && - // If we have `'static`, we don't want to remove it. - !is_bound_static; + // If we already have a mixed suggestion, avoid overlapping alternatives. + mixed_suggestion.is_none() && + // If we have a named lifetime, prefer consistent naming. + bound_lifetime.is_none(); let explicit_anonymous_suggestion = should_suggest_explicit_anonymous .then(|| build_mismatch_suggestion("'_", &suggest_change_to_explicit_anonymous)); @@ -483,7 +483,7 @@ fn build_mismatch_suggestion( ) -> lints::MismatchedLifetimeSyntaxesSuggestion { let lifetime_name = lifetime_name.to_owned(); - let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect(); + let suggestions = build_mismatch_suggestions_for_lifetime(&lifetime_name, infos); lints::MismatchedLifetimeSyntaxesSuggestion::Explicit { lifetime_name, @@ -492,6 +492,57 @@ fn build_mismatch_suggestion( } } +fn build_mismatch_suggestions_for_lifetime( + lifetime_name: &str, + infos: &[&Info<'_>], +) -> Vec<(Span, String)> { + use hir::{AngleBrackets, LifetimeSource, LifetimeSyntax}; + + #[derive(Clone, Copy, PartialEq, Eq, Hash)] + enum PathSuggestionKind { + Missing, + Empty, + Full, + } + + let mut suggestions = Vec::new(); + let mut path_counts: FxIndexMap<(hir::HirId, PathSuggestionKind), (Span, usize)> = + FxIndexMap::default(); + + for info in infos { + let lifetime = info.lifetime; + if matches!(lifetime.syntax, LifetimeSyntax::Implicit) { + if let LifetimeSource::Path { angle_brackets } = lifetime.source { + let (span, kind) = match angle_brackets { + AngleBrackets::Missing => { + (lifetime.ident.span.shrink_to_hi(), PathSuggestionKind::Missing) + } + AngleBrackets::Empty => (lifetime.ident.span, PathSuggestionKind::Empty), + AngleBrackets::Full => (lifetime.ident.span, PathSuggestionKind::Full), + }; + let entry = path_counts.entry((info.ty.hir_id, kind)).or_insert((span, 0)); + entry.1 += 1; + continue; + } + } + suggestions.push(info.suggestion(lifetime_name)); + } + + for ((_ty_hir_id, kind), (span, count)) in path_counts { + let repeated = std::iter::repeat(lifetime_name).take(count).collect::<Vec<_>>().join(", "); + + let suggestion = match kind { + PathSuggestionKind::Missing => format!("<{repeated}>"), + PathSuggestionKind::Empty => repeated, + PathSuggestionKind::Full => format!("{repeated}, "), + }; + + suggestions.push((span, suggestion)); + } + + suggestions +} + #[derive(Debug)] struct Info<'tcx> { lifetime: &'tcx hir::Lifetime,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index d5b5a50..f89d9e5 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs
@@ -2,12 +2,12 @@ use std::num::NonZero; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::codes::*; use rustc_errors::formatting::DiagMessageAddArg; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic, - ElidedLifetimeInPathSubdiag, EmissionGuarantee, Level, MultiSpan, Subdiagnostic, - SuggestionStyle, msg, + ElidedLifetimeInPathSubdiag, EmissionGuarantee, Level, Subdiagnostic, SuggestionStyle, msg, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -2995,14 +2995,6 @@ pub(crate) enum CargoHelp { } } -#[derive(Diagnostic)] -#[diag("extern crate `{$extern_crate}` is unused in crate `{$local_crate}`")] -#[help("remove the dependency or add `use {$extern_crate} as _;` to the crate root")] -pub(crate) struct UnusedCrateDependency { - pub extern_crate: Symbol, - pub local_crate: Symbol, -} - // FIXME(jdonszelmann): duplicated in rustc_attr_parsing, should be moved there completely. #[derive(Diagnostic)] #[diag( @@ -3090,98 +3082,6 @@ pub(crate) enum UnusedImportsSugg { } #[derive(Diagnostic)] -#[diag("the item `{$ident}` is imported redundantly")] -pub(crate) struct RedundantImport { - #[subdiagnostic] - pub subs: Vec<RedundantImportSub>, - pub ident: Ident, -} - -#[derive(Subdiagnostic)] -pub(crate) enum RedundantImportSub { - #[label("the item `{$ident}` is already imported here")] - ImportedHere { - #[primary_span] - span: Span, - ident: Ident, - }, - #[label("the item `{$ident}` is already defined here")] - DefinedHere { - #[primary_span] - span: Span, - ident: Ident, - }, - #[label("the item `{$ident}` is already imported by the extern prelude")] - ImportedPrelude { - #[primary_span] - span: Span, - ident: Ident, - }, - #[label("the item `{$ident}` is already defined by the extern prelude")] - DefinedPrelude { - #[primary_span] - span: Span, - ident: Ident, - }, -} - -#[derive(Diagnostic)] -pub(crate) enum PatternsInFnsWithoutBody { - #[diag("patterns aren't allowed in foreign function declarations")] - Foreign { - #[subdiagnostic] - sub: PatternsInFnsWithoutBodySub, - }, - #[diag("patterns aren't allowed in functions without bodies")] - Bodiless { - #[subdiagnostic] - sub: PatternsInFnsWithoutBodySub, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion( - "remove `mut` from the parameter", - code = "{ident}", - applicability = "machine-applicable" -)] -pub(crate) struct PatternsInFnsWithoutBodySub { - #[primary_span] - pub span: Span, - - pub ident: Ident, -} - -#[derive(Diagnostic)] -#[diag("where clause not allowed here")] -#[note("see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information")] -pub(crate) struct DeprecatedWhereClauseLocation { - #[subdiagnostic] - pub suggestion: DeprecatedWhereClauseLocationSugg, -} - -#[derive(Subdiagnostic)] -pub(crate) enum DeprecatedWhereClauseLocationSugg { - #[multipart_suggestion( - "move it to the end of the type declaration", - applicability = "machine-applicable" - )] - MoveToEnd { - #[suggestion_part(code = "")] - left: Span, - #[suggestion_part(code = "{sugg}")] - right: Span, - - sugg: String, - }, - #[suggestion("remove this `where`", code = "", applicability = "machine-applicable")] - RemoveWhere { - #[primary_span] - span: Span, - }, -} - -#[derive(Diagnostic)] #[diag("lifetime parameter `{$ident}` only used once")] pub(crate) struct SingleUseLifetime { #[label("this lifetime...")] @@ -3206,15 +3106,6 @@ pub(crate) struct SingleUseLifetimeSugg { } #[derive(Diagnostic)] -#[diag("lifetime parameter `{$ident}` never used")] -pub(crate) struct UnusedLifetime { - #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] - pub deletion_span: Option<Span>, - - pub ident: Ident, -} - -#[derive(Diagnostic)] #[diag("named argument `{$named_arg_name}` is not used by name")] pub(crate) struct NamedArgumentUsedPositionally { #[label("this named argument is referred to by position in formatting string")] @@ -3234,66 +3125,6 @@ pub(crate) struct NamedArgumentUsedPositionally { } #[derive(Diagnostic)] -#[diag("ambiguous glob re-exports")] -pub(crate) struct AmbiguousGlobReexports { - #[label("the name `{$name}` in the {$namespace} namespace is first re-exported here")] - pub first_reexport: Span, - #[label("but the name `{$name}` in the {$namespace} namespace is also re-exported here")] - pub duplicate_reexport: Span, - - pub name: String, - pub namespace: String, -} - -#[derive(Diagnostic)] -#[diag("private item shadows public glob re-export")] -pub(crate) struct HiddenGlobReexports { - #[note( - "the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here" - )] - pub glob_reexport: Span, - #[note("but the private item here shadows it")] - pub private_item: Span, - - pub name: String, - pub namespace: String, -} - -#[derive(Diagnostic)] -#[diag("unnecessary qualification")] -pub(crate) struct UnusedQualifications { - #[suggestion( - "remove the unnecessary path segments", - style = "verbose", - code = "", - applicability = "machine-applicable" - )] - pub removal_span: Span, -} - -#[derive(Diagnostic)] -#[diag( - "{$elided -> - [true] `&` without an explicit lifetime name cannot be used here - *[false] `'_` cannot be used here - }" -)] -pub(crate) struct AssociatedConstElidedLifetime { - #[suggestion( - "use the `'static` lifetime", - style = "verbose", - code = "{code}", - applicability = "machine-applicable" - )] - pub span: Span, - - pub code: &'static str, - pub elided: bool, - #[note("cannot automatically infer `'static` because of other lifetimes in scope")] - pub lifetimes_in_scope: MultiSpan, -} - -#[derive(Diagnostic)] #[diag("creating a {$shared_label}reference to mutable static")] pub(crate) struct RefOfMutStatic<'a> { #[label("{$shared_label}reference to mutable static")] @@ -3401,8 +3232,23 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { diag.span_label(s, msg!("the lifetime is named here")); } + let mut hidden_output_counts: FxIndexMap<Span, usize> = FxIndexMap::default(); for s in self.outputs.hidden { - diag.span_label(s, msg!("the same lifetime is hidden here")); + *hidden_output_counts.entry(s).or_insert(0) += 1; + } + for (span, count) in hidden_output_counts { + let label = msg!( + "the same {$count -> + [one] lifetime + *[other] lifetimes + } {$count -> + [one] is + *[other] are + } hidden here" + ) + .arg("count", count) + .format(); + diag.span_label(span, label); } for s in self.outputs.elided { diag.span_label(s, msg!("the same lifetime is elided here")); @@ -3645,19 +3491,6 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { } #[derive(Diagnostic)] -#[diag("visibility qualifiers have no effect on `const _` declarations")] -#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] -pub(crate) struct UnusedVisibility { - #[suggestion( - "remove the qualifier", - style = "short", - code = "", - applicability = "machine-applicable" - )] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag("doc alias is duplicated")] pub(crate) struct DocAliasDuplicated { #[label("first defined here")] @@ -3788,23 +3621,6 @@ pub(crate) struct UnknownCrateTypesSuggestion { } #[derive(Diagnostic)] -#[diag("unreachable configuration predicate")] -pub(crate) struct UnreachableCfgSelectPredicate { - #[label("this configuration predicate is never reached")] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag("unreachable configuration predicate")] -pub(crate) struct UnreachableCfgSelectPredicateWildcard { - #[label("this configuration predicate is never reached")] - pub span: Span, - - #[label("always matches")] - pub wildcard_span: Span, -} - -#[derive(Diagnostic)] #[diag("positional format arguments are not allowed here")] #[help( "only named format arguments with the name of one of the generic types are allowed in this context"
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e2e4ffc..af1d185 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -7,7 +7,7 @@ use rustc_data_structures::stable_hasher::{ HashStable, StableCompare, StableHasher, ToStableHashKey, }; -use rustc_error_messages::{DiagArgValue, IntoDiagArg, MultiSpan}; +use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_hir_id::{HashStableContext, HirId, ItemLocalId}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::def_id::DefPathHash; @@ -138,9 +138,9 @@ pub fn set_lint_index(&mut self, new_lint_index: Option<u16>) { } } -impl<HCX: HashStableContext> HashStable<HCX> for LintExpectationId { +impl<Hcx: HashStableContext> HashStable<Hcx> for LintExpectationId { #[inline] - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { match self { LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { hir_id.hash_stable(hcx, hasher); @@ -156,11 +156,11 @@ fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { } } -impl<HCX: HashStableContext> ToStableHashKey<HCX> for LintExpectationId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for LintExpectationId { type KeyType = (DefPathHash, ItemLocalId, u16, u16); #[inline] - fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType { + fn to_stable_hash_key(&self, hcx: &Hcx) -> Self::KeyType { match self { LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx); @@ -621,18 +621,18 @@ pub fn to_string(&self) -> String { } } -impl<HCX> HashStable<HCX> for LintId { +impl<Hcx> HashStable<Hcx> for LintId { #[inline] - fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.lint_name_raw().hash_stable(hcx, hasher); } } -impl<HCX> ToStableHashKey<HCX> for LintId { +impl<Hcx> ToStableHashKey<Hcx> for LintId { type KeyType = &'static str; #[inline] - fn to_stable_hash_key(&self, _: &HCX) -> &'static str { + fn to_stable_hash_key(&self, _: &Hcx) -> &'static str { self.lint_name_raw() } } @@ -665,21 +665,6 @@ pub enum BuiltinLintDiag { test_module_span: Option<Span>, span_snippets: Vec<String>, }, - RedundantImport(Vec<(Span, bool)>, Ident), - DeprecatedMacro { - suggestion: Option<Symbol>, - suggestion_span: Span, - note: Option<Symbol>, - path: String, - since_kind: DeprecatedSinceKind, - }, - PatternsInFnsWithoutBody { - span: Span, - ident: Ident, - is_foreign: bool, - }, - /// `##` or `#"` in edition < 2024. - DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), SingleUseLifetime { /// Span of the parameter which declares this lifetime. param_span: Span, @@ -688,7 +673,8 @@ pub enum BuiltinLintDiag { deletion_span: Option<Span>, /// Span of the single use, or None if the lifetime is never used. /// If true, the lifetime will be fully elided. - use_span: Option<(Span, bool)>, + use_span: Span, + elidable: bool, ident: Ident, }, NamedArgumentUsedPositionally { @@ -704,45 +690,7 @@ pub enum BuiltinLintDiag { /// Indicates if the named argument is used as a width/precision for formatting is_formatting_arg: bool, }, - AmbiguousGlobReexports { - /// The name for which collision(s) have occurred. - name: String, - /// The name space for which the collision(s) occurred in. - namespace: String, - /// Span where the name is first re-exported. - first_reexport_span: Span, - /// Span where the same name is also re-exported. - duplicate_reexport_span: Span, - }, - HiddenGlobReexports { - /// The name of the local binding which shadows the glob re-export. - name: String, - /// The namespace for which the shadowing occurred in. - namespace: String, - /// The glob reexport that is shadowed by the local binding. - glob_reexport_span: Span, - /// The local binding that shadows the glob reexport. - private_item_span: Span, - }, - UnusedQualifications { - /// The span of the unnecessarily-qualified path to remove. - removal_span: Span, - }, - AssociatedConstElidedLifetime { - elided: bool, - span: Span, - lifetimes_in_scope: MultiSpan, - }, - UnusedCrateDependency { - extern_crate: Symbol, - local_crate: Symbol, - }, - UnusedVisibility(Span), AttributeLint(AttributeLintKind), - UnreachableCfg { - span: Span, - wildcard_span: Option<Span>, - }, } #[derive(Debug, HashStable_Generic)]
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 00d03f0..b4f6bb4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -540,6 +540,8 @@ bool SanitizeHWAddressRecover; bool SanitizeKernelAddress; bool SanitizeKernelAddressRecover; + bool SanitizeKernelHWAddress; + bool SanitizeKernelHWAddressRecover; }; extern "C" typedef void (*registerEnzymeAndPassPipelineFn)( @@ -767,13 +769,15 @@ !TM->getTargetTriple().isOSWindows())); }); } - if (SanitizerOptions->SanitizeHWAddress) { + if (SanitizerOptions->SanitizeHWAddress || + SanitizerOptions->SanitizeKernelHWAddress) { OptimizerLastEPCallbacks.push_back( [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase phase) { HWAddressSanitizerOptions opts( - /*CompileKernel=*/false, - SanitizerOptions->SanitizeHWAddressRecover, + SanitizerOptions->SanitizeKernelHWAddress, + SanitizerOptions->SanitizeHWAddressRecover || + SanitizerOptions->SanitizeKernelHWAddressRecover, /*DisableOptimization=*/false); MPM.addPass(HWAddressSanitizerPass(opts)); });
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index b75236b..75be5a1 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs
@@ -5,8 +5,8 @@ use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{ - AttrStyle, Attribute, Block, Error, Expr, Ident, Pat, ReturnType, Token, Type, braced, - parenthesized, parse_macro_input, token, + AttrStyle, Attribute, Error, Expr, Ident, Pat, ReturnType, Token, Type, braced, parenthesized, + parse_macro_input, token, }; mod kw { @@ -132,16 +132,11 @@ struct Desc { expr_list: Punctuated<Expr, Token![,]>, } -struct CacheOnDiskIf { - modifier: Ident, - block: Block, -} - /// See `rustc_middle::query::modifiers` for documentation of each query modifier. struct QueryModifiers { // tidy-alphabetical-start arena_cache: Option<Ident>, - cache_on_disk_if: Option<CacheOnDiskIf>, + cache_on_disk: Option<Ident>, depth_limit: Option<Ident>, desc: Desc, eval_always: Option<Ident>, @@ -154,7 +149,7 @@ struct QueryModifiers { fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { let mut arena_cache = None; - let mut cache_on_disk_if = None; + let mut cache_on_disk = None; let mut desc = None; let mut no_force = None; let mut no_hash = None; @@ -182,11 +177,8 @@ macro_rules! try_insert { braced!(attr_content in input); let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?; try_insert!(desc = Desc { modifier, expr_list }); - } else if modifier == "cache_on_disk_if" { - // Parse a cache-on-disk modifier like: - // `cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) }` - let block = input.parse()?; - try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, block }); + } else if modifier == "cache_on_disk" { + try_insert!(cache_on_disk = modifier); } else if modifier == "arena_cache" { try_insert!(arena_cache = modifier); } else if modifier == "no_force" { @@ -210,7 +202,7 @@ macro_rules! try_insert { }; Ok(QueryModifiers { arena_cache, - cache_on_disk_if, + cache_on_disk, desc, no_force, no_hash, @@ -244,7 +236,7 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream { let QueryModifiers { // tidy-alphabetical-start arena_cache, - cache_on_disk_if, + cache_on_disk, depth_limit, desc: _, eval_always, @@ -256,7 +248,7 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream { } = &query.modifiers; let arena_cache = arena_cache.is_some(); - let cache_on_disk = cache_on_disk_if.is_some(); + let cache_on_disk = cache_on_disk.is_some(); let depth_limit = depth_limit.is_some(); let eval_always = eval_always.is_some(); let feedable = feedable.is_some(); @@ -321,7 +313,6 @@ fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attrib #[derive(Default)] struct HelperTokenStreams { description_fns_stream: proc_macro2::TokenStream, - cache_on_disk_if_fns_stream: proc_macro2::TokenStream, } fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) { @@ -331,16 +322,6 @@ fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) { let mut erased_name = name.clone(); erased_name.set_span(Span::call_site()); - // Generate a function to check whether we should cache the query to disk, for some key. - if let Some(CacheOnDiskIf { block, .. }) = modifiers.cache_on_disk_if.as_ref() { - streams.cache_on_disk_if_fns_stream.extend(quote! { - #[allow(unused_variables)] - #[inline] - pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> bool - #block - }); - } - let Desc { expr_list, .. } = &modifiers.desc; let desc = quote! { @@ -368,12 +349,6 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke crate::query::modifiers::#name; }); - if let Some(CacheOnDiskIf { modifier, .. }) = &modifiers.cache_on_disk_if { - modifiers_stream.extend(quote! { - crate::query::modifiers::#modifier; - }); - } - macro_rules! doc_link { ( $( $modifier:ident ),+ $(,)? ) => { $( @@ -389,6 +364,7 @@ macro_rules! doc_link { doc_link!( // tidy-alphabetical-start arena_cache, + cache_on_disk, depth_limit, eval_always, feedable, @@ -489,7 +465,7 @@ fn #name(#key_ty) #return_ty make_helpers_for_query(&query, &mut helpers); } - let HelperTokenStreams { description_fns_stream, cache_on_disk_if_fns_stream } = helpers; + let HelperTokenStreams { description_fns_stream } = helpers; TokenStream::from(quote! { /// Higher-order macro that invokes the specified macro with (a) a list of all query @@ -525,14 +501,6 @@ pub mod _description_fns { #description_fns_stream } - // FIXME(Zalathar): Instead of declaring these functions directly, can - // we put them in a macro and then expand that macro downstream in - // `rustc_query_impl`, where the functions are actually used? - pub mod _cache_on_disk_if_fns { - use super::*; - #cache_on_disk_if_fns_stream - } - #errors }) }
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 4000f12..345ee18 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs
@@ -23,15 +23,14 @@ use rustc_middle::ty::data_structures::IndexSet; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_proc_macro::bridge::client::ProcMacro; -use rustc_session::Session; use rustc_session::config::{ CrateType, ExtendedTargetModifierInfo, ExternLocation, Externs, OptionsTargetModifiers, TargetModifier, }; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; -use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; +use rustc_session::{Session, lint}; use rustc_span::def_id::DefId; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; @@ -1211,7 +1210,7 @@ fn report_unused_deps_in_crate(&mut self, tcx: TyCtxt<'_>, krate: &ast::Crate) { lint::builtin::UNUSED_CRATE_DEPENDENCIES, span, ast::CRATE_NODE_ID, - BuiltinLintDiag::UnusedCrateDependency { + errors::UnusedCrateDependency { extern_crate: name_interned, local_crate: tcx.crate_name(LOCAL_CRATE), },
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index d4c6144..8b2895d 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs
@@ -688,3 +688,11 @@ pub struct RawDylibMalformed { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("extern crate `{$extern_crate}` is unused in crate `{$local_crate}`")] +#[help("remove the dependency or add `use {$extern_crate} as _;` to the crate root")] +pub(crate) struct UnusedCrateDependency { + pub extern_crate: Symbol, + pub local_crate: Symbol, +}
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 17b16b3..a05366d 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -19,7 +19,7 @@ use rustc_session::search_paths::PathKind; use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_target::spec::{Abi, Arch, BinaryFormat, Env, LinkSelfContainedComponents, Os}; +use rustc_target::spec::{Arch, BinaryFormat, CfgAbi, Env, LinkSelfContainedComponents, Os}; use crate::errors; @@ -73,14 +73,14 @@ pub fn walk_native_lib_search_dirs<R>( // FIXME: On AIX this also has the side-effect of making the list of library search paths // non-empty, which is needed or the linker may decide to record the LIBPATH env, if // defined, as the search path instead of appending the default search paths. - if sess.target.abi == Abi::Fortanix + if sess.target.cfg_abi == CfgAbi::Fortanix || sess.target.os == Os::Linux || sess.target.os == Os::Fuchsia || sess.target.is_like_aix || sess.target.is_like_darwin && !sess.sanitizers().is_empty() || sess.target.os == Os::Windows && sess.target.env == Env::Gnu - && sess.target.abi == Abi::Llvm + && sess.target.cfg_abi == CfgAbi::Llvm { f(&sess.target_tlib_path.dir, false)?; }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e554da3..8bf919d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -727,7 +727,7 @@ macro_rules! stat { is_stub: false, }, extra_filename: tcx.sess.opts.cg.extra_filename.clone(), - stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), + stable_crate_id: tcx.stable_crate_id(LOCAL_CRATE), required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE), panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(),
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 81f3041..987aa3e 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -251,10 +251,10 @@ pub fn from_cgu_name(cgu_name: &str) -> WorkProductId { WorkProductId { hash: hasher.finish() } } } -impl<HCX> ToStableHashKey<HCX> for WorkProductId { +impl<Hcx> ToStableHashKey<Hcx> for WorkProductId { type KeyType = Fingerprint; #[inline] - fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { + fn to_stable_hash_key(&self, _: &Hcx) -> Self::KeyType { self.hash } } @@ -412,9 +412,6 @@ mod size_asserts { use super::*; // tidy-alphabetical-start static_assert_size!(DepKind, 2); - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] static_assert_size!(DepNode, 18); - #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] - static_assert_size!(DepNode, 24); // tidy-alphabetical-end }
diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index d0d7d58..4e789d7 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs
@@ -18,7 +18,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::Session; use rustc_span::Symbol; -use tracing::{debug, instrument}; +use tracing::instrument; #[cfg(debug_assertions)] use {super::debug::EdgeFilter, std::env}; @@ -164,9 +164,10 @@ pub fn new( ); assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE); if prev_graph_node_count > 0 { - colors.insert_red(SerializedDepNodeIndex::from_u32( - DepNodeIndex::FOREVER_RED_NODE.as_u32(), - )); + let prev_index = + const { SerializedDepNodeIndex::from_u32(DepNodeIndex::FOREVER_RED_NODE.as_u32()) }; + let result = colors.try_set_color(prev_index, DesiredColor::Red); + assert_matches!(result, TrySetColorResult::Success); } DepGraph { @@ -708,7 +709,7 @@ fn encode_side_effect<'tcx>( // side effect. std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(), ); - tcx.store_side_effect(dep_node_index, side_effect); + tcx.query_system.side_effects.borrow_mut().insert(dep_node_index, side_effect); dep_node_index } @@ -717,7 +718,13 @@ fn encode_side_effect<'tcx>( #[inline] fn force_side_effect<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) { with_deps(TaskDepsRef::Ignore, || { - let side_effect = tcx.load_side_effect(prev_index).unwrap(); + let side_effect = tcx + .query_system + .on_disk_cache + .as_ref() + .unwrap() + .load_side_effect(tcx, prev_index) + .unwrap(); // Use `send_and_color` as `promote_node_and_deps_to_current` expects all // green dependencies. `send_and_color` will also prevent multiple nodes @@ -744,7 +751,7 @@ fn force_side_effect<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNo } // This will just overwrite the same value for concurrent calls. - tcx.store_side_effect(dep_node_index, side_effect); + tcx.query_system.side_effects.borrow_mut().insert(dep_node_index, side_effect); }) } @@ -917,94 +924,6 @@ pub fn try_mark_green<'tcx>( } } - #[instrument(skip(self, tcx, parent_dep_node_index, frame), level = "debug")] - fn try_mark_parent_green<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - parent_dep_node_index: SerializedDepNodeIndex, - frame: &MarkFrame<'_>, - ) -> Option<()> { - let get_dep_dep_node = || self.previous.index_to_node(parent_dep_node_index); - - match self.colors.get(parent_dep_node_index) { - DepNodeColor::Green(_) => { - // This dependency has been marked as green before, we are - // still fine and can continue with checking the other - // dependencies. - // - // This path is extremely hot. We don't want to get the - // `dep_dep_node` unless it's necessary. Hence the - // `get_dep_dep_node` closure. - debug!("dependency {:?} was immediately green", get_dep_dep_node()); - return Some(()); - } - DepNodeColor::Red => { - // We found a dependency the value of which has changed - // compared to the previous compilation session. We cannot - // mark the DepNode as green and also don't need to bother - // with checking any of the other dependencies. - debug!("dependency {:?} was immediately red", get_dep_dep_node()); - return None; - } - DepNodeColor::Unknown => {} - } - - let dep_dep_node = get_dep_dep_node(); - - // We don't know the state of this dependency. If it isn't - // an eval_always node, let's try to mark it green recursively. - if !tcx.is_eval_always(dep_dep_node.kind) { - debug!( - "state of dependency {:?} ({}) is unknown, trying to mark it green", - dep_dep_node, dep_dep_node.key_fingerprint, - ); - - let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame)); - - if node_index.is_some() { - debug!("managed to MARK dependency {dep_dep_node:?} as green"); - return Some(()); - } - } - - // We failed to mark it green, so we try to force the query. - debug!("trying to force dependency {dep_dep_node:?}"); - if !tcx.try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) { - // The DepNode could not be forced. - debug!("dependency {dep_dep_node:?} could not be forced"); - return None; - } - - match self.colors.get(parent_dep_node_index) { - DepNodeColor::Green(_) => { - debug!("managed to FORCE dependency {dep_dep_node:?} to green"); - return Some(()); - } - DepNodeColor::Red => { - debug!("dependency {dep_dep_node:?} was red after forcing"); - return None; - } - DepNodeColor::Unknown => {} - } - - if let None = tcx.dcx().has_errors_or_delayed_bugs() { - panic!("try_mark_previous_green() - Forcing the DepNode should have set its color") - } - - // If the query we just forced has resulted in - // some kind of compilation error, we cannot rely on - // the dep-node color having been properly updated. - // This means that the query system has reached an - // invalid state. We let the compiler continue (by - // returning `None`) so it can emit error messages - // and wind down, but rely on the fact that this - // invalid state will not be persisted to the - // incremental compilation cache because of - // compilation errors being present. - debug!("dependency {dep_dep_node:?} resulted in compilation error"); - return None; - } - /// Try to mark a dep-node which existed in the previous compilation session as green. #[instrument(skip(self, tcx, prev_dep_node_index, frame), level = "debug")] fn try_mark_previous_green<'tcx>( @@ -1018,17 +937,58 @@ fn try_mark_previous_green<'tcx>( // We never try to mark eval_always nodes as green debug_assert!(!tcx.is_eval_always(self.previous.index_to_node(prev_dep_node_index).kind)); - let prev_deps = self.previous.edge_targets_from(prev_dep_node_index); + for parent_dep_node_index in self.previous.edge_targets_from(prev_dep_node_index) { + match self.colors.get(parent_dep_node_index) { + // This dependency has been marked as green before, we are still ok and can + // continue checking the remaining dependencies. + DepNodeColor::Green(_) => continue, - for dep_dep_node_index in prev_deps { - self.try_mark_parent_green(tcx, dep_dep_node_index, &frame)?; + // This dependency's result is different to the previous compilation session. We + // cannot mark this dep_node as green, so stop checking. + DepNodeColor::Red => return None, + + // We still need to determine this dependency's colour. + DepNodeColor::Unknown => {} + } + + let parent_dep_node = self.previous.index_to_node(parent_dep_node_index); + + // If this dependency isn't eval_always, try to mark it green recursively. + if !tcx.is_eval_always(parent_dep_node.kind) + && self.try_mark_previous_green(tcx, parent_dep_node_index, Some(&frame)).is_some() + { + continue; + } + + // We failed to mark it green, so we try to force the query. + if !tcx.try_force_from_dep_node(*parent_dep_node, parent_dep_node_index, &frame) { + return None; + } + + match self.colors.get(parent_dep_node_index) { + DepNodeColor::Green(_) => continue, + DepNodeColor::Red => return None, + DepNodeColor::Unknown => {} + } + + if tcx.dcx().has_errors_or_delayed_bugs().is_none() { + panic!("try_mark_previous_green() - forcing failed to set a color"); + } + + // If the query we just forced has resulted in some kind of compilation error, we + // cannot rely on the dep-node color having been properly updated. This means that the + // query system has reached an invalid state. We let the compiler continue (by + // returning `None`) so it can emit error messages and wind down, but rely on the fact + // that this invalid state will not be persisted to the incremental compilation cache + // because of compilation errors being present. + return None; } // If we got here without hitting a `return` that means that all // dependencies of this DepNode could be marked as green. Therefore we // can also mark this DepNode as green. - // There may be multiple threads trying to mark the same dep node green concurrently + // There may be multiple threads trying to mark the same dep node green concurrently. // We allocating an entry for the node in the current dependency graph and // adding all the appropriate edges imported from the previous graph. @@ -1037,12 +997,8 @@ fn try_mark_previous_green<'tcx>( let dep_node_index = self.promote_node_and_deps_to_current(prev_dep_node_index)?; // ... and finally storing a "Green" entry in the color map. - // Multiple threads can all write the same color here + // Multiple threads can all write the same color here. - debug!( - "successfully marked {:?} as green", - self.previous.index_to_node(prev_dep_node_index) - ); Some(dep_node_index) } } @@ -1415,28 +1371,29 @@ pub(super) fn current(&self, index: SerializedDepNodeIndex) -> Option<DepNodeInd if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None } } - /// This tries to atomically mark a node green and assign `index` as the new - /// index if `green` is true, otherwise it will try to atomicaly mark it red. + /// Atomically sets the color of a previous-session dep node to either green + /// or red, if it has not already been colored. /// - /// This returns `Ok` if `index` gets assigned or the node is marked red, otherwise it returns - /// the already allocated index in `Err` if it is green already. If it was already - /// red, `Err(None)` is returned. + /// If the node already has a color, the new color is ignored, and the + /// return value indicates the existing color. #[inline(always)] - pub(super) fn try_mark( + pub(super) fn try_set_color( &self, prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, - green: bool, - ) -> Result<(), Option<DepNodeIndex>> { - let value = &self.values[prev_index]; - match value.compare_exchange( + color: DesiredColor, + ) -> TrySetColorResult { + match self.values[prev_index].compare_exchange( COMPRESSED_UNKNOWN, - if green { index.as_u32() } else { COMPRESSED_RED }, + match color { + DesiredColor::Red => COMPRESSED_RED, + DesiredColor::Green { index } => index.as_u32(), + }, Ordering::Relaxed, Ordering::Relaxed, ) { - Ok(_) => Ok(()), - Err(v) => Err(if v == COMPRESSED_RED { None } else { Some(DepNodeIndex::from_u32(v)) }), + Ok(_) => TrySetColorResult::Success, + Err(COMPRESSED_RED) => TrySetColorResult::AlreadyRed, + Err(index) => TrySetColorResult::AlreadyGreen { index: DepNodeIndex::from_u32(index) }, } } @@ -1454,13 +1411,28 @@ pub(super) fn get(&self, index: SerializedDepNodeIndex) -> DepNodeColor { DepNodeColor::Unknown } } +} - #[inline] - pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) { - let value = self.values[index].swap(COMPRESSED_RED, Ordering::Release); - // Sanity check for duplicate nodes - assert_eq!(value, COMPRESSED_UNKNOWN, "tried to color an already colored node as red"); - } +/// The color that [`DepNodeColorMap::try_set_color`] should try to apply to a node. +#[derive(Clone, Copy, Debug)] +pub(super) enum DesiredColor { + /// Try to mark the node red. + Red, + /// Try to mark the node green, associating it with a current-session node index. + Green { index: DepNodeIndex }, +} + +/// Return value of [`DepNodeColorMap::try_set_color`], indicating success or failure, +/// and (on failure) what the existing color is. +#[derive(Clone, Copy, Debug)] +pub(super) enum TrySetColorResult { + /// The [`DesiredColor`] was freshly applied to the node. + Success, + /// Coloring failed because the node was already marked red. + AlreadyRed, + /// Coloring failed because the node was already marked green, + /// and corresponds to node `index` in the current-session dep graph. + AlreadyGreen { index: DepNodeIndex }, } #[inline(never)] @@ -1532,23 +1504,4 @@ impl<'tcx> TyCtxt<'tcx> { fn is_eval_always(self, kind: DepKind) -> bool { self.dep_kind_vtable(kind).is_eval_always } - - // Interactions with on_disk_cache - fn load_side_effect( - self, - prev_dep_node_index: SerializedDepNodeIndex, - ) -> Option<QuerySideEffect> { - self.query_system - .on_disk_cache - .as_ref() - .and_then(|c| c.load_side_effect(self, prev_dep_node_index)) - } - - #[inline(never)] - #[cold] - fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) { - if let Some(c) = self.query_system.on_disk_cache.as_ref() { - c.store_side_effect(dep_node_index, side_effect) - } - } }
diff --git a/compiler/rustc_middle/src/dep_graph/serialized.rs b/compiler/rustc_middle/src/dep_graph/serialized.rs index 8a4ac4b..ef5e3d9 100644 --- a/compiler/rustc_middle/src/dep_graph/serialized.rs +++ b/compiler/rustc_middle/src/dep_graph/serialized.rs
@@ -43,7 +43,7 @@ use std::cmp::max; use std::sync::Arc; use std::sync::atomic::Ordering; -use std::{iter, mem, u64}; +use std::{iter, mem}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::FxHashMap; @@ -58,7 +58,7 @@ use rustc_session::Session; use tracing::{debug, instrument}; -use super::graph::{CurrentDepGraph, DepNodeColorMap}; +use super::graph::{CurrentDepGraph, DepNodeColorMap, DesiredColor, TrySetColorResult}; use super::retained::RetainedDepGraph; use super::{DepKind, DepNode, DepNodeIndex}; use crate::dep_graph::edges::EdgesVec; @@ -72,6 +72,15 @@ pub struct SerializedDepNodeIndex {} } +impl SerializedDepNodeIndex { + /// Converts a current-session dep node index to a "serialized" index, + /// for the purpose of serializing data to be loaded by future sessions. + #[inline(always)] + pub fn from_curr_for_serialization(index: DepNodeIndex) -> Self { + SerializedDepNodeIndex::from_u32(index.as_u32()) + } +} + const DEP_NODE_SIZE: usize = size_of::<SerializedDepNodeIndex>(); /// Amount of padding we need to add to the edge list data so that we can retrieve every /// SerializedDepNodeIndex with a fixed-size read then mask. @@ -905,13 +914,14 @@ pub(crate) fn send_and_color( let mut local = self.status.local.borrow_mut(); let index = self.status.next_index(&mut *local); + let color = if is_green { DesiredColor::Green { index } } else { DesiredColor::Red }; - // Use `try_mark` to avoid racing when `send_promoted` is called concurrently + // Use `try_set_color` to avoid racing when `send_promoted` is called concurrently // on the same index. - match colors.try_mark(prev_index, index, is_green) { - Ok(()) => (), - Err(None) => panic!("dep node {:?} is unexpectedly red", prev_index), - Err(Some(dep_node_index)) => return dep_node_index, + match colors.try_set_color(prev_index, color) { + TrySetColorResult::Success => {} + TrySetColorResult::AlreadyRed => panic!("dep node {prev_index:?} is unexpectedly red"), + TrySetColorResult::AlreadyGreen { index } => return index, } self.status.bump_index(&mut *local); @@ -923,7 +933,8 @@ pub(crate) fn send_and_color( /// from the previous dep graph and expects all edges to already have a new dep node index /// assigned. /// - /// This will also ensure the dep node is marked green if `Some` is returned. + /// Tries to mark the dep node green, and returns Some if it is now green, + /// or None if had already been concurrently marked red. #[inline] pub(crate) fn send_promoted( &self, @@ -935,10 +946,10 @@ pub(crate) fn send_promoted( let mut local = self.status.local.borrow_mut(); let index = self.status.next_index(&mut *local); - // Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color` + // Use `try_set_color` to avoid racing when `send_promoted` or `send_and_color` // is called concurrently on the same index. - match colors.try_mark(prev_index, index, true) { - Ok(()) => { + match colors.try_set_color(prev_index, DesiredColor::Green { index }) { + TrySetColorResult::Success => { self.status.bump_index(&mut *local); self.status.encode_promoted_node( index, @@ -949,7 +960,8 @@ pub(crate) fn send_promoted( ); Some(index) } - Err(dep_node_index) => dep_node_index, + TrySetColorResult::AlreadyRed => None, + TrySetColorResult::AlreadyGreen { index } => Some(index), } }
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 1f339ea..c70ceef 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -3,16 +3,14 @@ //! similar to queries, but queries come with a lot of machinery for caching and incremental //! compilation, whereas hooks are just plain function pointers without any of the query magic. -use std::marker::PhantomData; - use rustc_hir::def_id::{DefId, DefPathHash}; use rustc_session::StableCrateId; use rustc_span::def_id::{CrateNum, LocalDefId}; -use rustc_span::{ExpnHash, ExpnId, Span}; +use rustc_span::{ExpnHash, ExpnId}; -use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex}; +use crate::mir; +use crate::query::on_disk_cache::CacheEncoder; use crate::ty::{Ty, TyCtxt}; -use crate::{mir, ty}; macro_rules! declare_hooks { ($($(#[$attr:meta])*hook $name:ident($($arg:ident: $K:ty),*) -> $V:ty;)*) => { @@ -113,33 +111,8 @@ fn clone(&self) -> Self { *self } /// Creates the MIR for a given `DefId`, including unreachable code. hook build_mir_inner_impl(def: LocalDefId) -> mir::Body<'tcx>; - hook encode_query_values( - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex - ) -> (); - - /// Tries to normalize an alias, ignoring any errors. - /// - /// Generalization with the new trait solver calls into this, - /// when generalizing outside of the trait solver in `hir_typeck`. - hook try_eagerly_normalize_alias( - type_erased_infcx: TypeErasedInfcx<'_, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - span: Span, - alias: ty::AliasTy<'tcx> - ) -> Ty<'tcx>; -} - -/// The `try_eagerly_normalize_alias` hook passes an `Infcx` from where it's called (in `rustc_infer`) -/// to where it's provided (in `rustc_trait_selection`). -/// Both of those crates have that type available, but `rustc_middle` does not. -/// Instead we pass this type-erased `Infcx` and transmute on both sides. -/// -/// Has to be `repr(transparent)` so we can transmute a `&'a Infcx<'tcx>` to this struct. -#[repr(transparent)] -pub struct TypeErasedInfcx<'a, 'tcx> { - _infcx: *const (), - phantom: PhantomData<&'a mut &'tcx ()>, + /// Serializes all eligible query return values into the on-disk cache. + hook encode_query_values(encoder: &mut CacheEncoder<'_, 'tcx>) -> (); } #[cold]
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index e76c9a8..f9821c9 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -4,7 +4,7 @@ use std::num::NonZero; use rustc_ast::NodeId; -use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer, msg}; +use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, LintBuffer, msg}; use rustc_feature::GateIssue; use rustc_hir::attrs::{DeprecatedSince, Deprecation}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -12,7 +12,7 @@ use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic}; use rustc_session::Session; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE}; -use rustc_session::lint::{BuiltinLintDiag, DeprecatedSinceKind, Level, Lint}; +use rustc_session::lint::{DeprecatedSinceKind, Level, Lint}; use rustc_session::parse::feature_err_issue; use rustc_span::{Span, Symbol, sym}; use tracing::debug; @@ -187,23 +187,33 @@ fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> Deprecat pub fn early_report_macro_deprecation( lint_buffer: &mut LintBuffer, depr: &Deprecation, - span: Span, + suggestion_span: Span, node_id: NodeId, path: String, ) { - if span.in_derive_expansion() { + if suggestion_span.in_derive_expansion() { return; } let is_in_effect = depr.is_in_effect(); - let diag = BuiltinLintDiag::DeprecatedMacro { - suggestion: depr.suggestion, - suggestion_span: span, - note: depr.note.map(|ident| ident.name), - path, - since_kind: deprecated_since_kind(is_in_effect, depr.since), - }; - lint_buffer.buffer_lint(deprecation_lint(is_in_effect), node_id, span, diag); + let suggestion = depr.suggestion; + let note = depr.note.map(|ident| ident.name); + let since_kind = deprecated_since_kind(is_in_effect, depr.since); + lint_buffer.dyn_buffer_lint( + deprecation_lint(is_in_effect), + node_id, + suggestion_span, + move |dcx, level| { + let sub = suggestion.map(|suggestion| DeprecationSuggestion { + span: suggestion_span, + kind: "macro".to_owned(), + suggestion, + }); + + Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } + .into_diag(dcx, level) + }, + ); } fn late_report_deprecation(
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index bd8c022..1d39452 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -171,7 +171,7 @@ fn decode(_: &mut D) -> Self { } } -impl<CTX> HashStable<CTX> for Cache { +impl<Hcx> HashStable<Hcx> for Cache { #[inline] - fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) {} + fn hash_stable(&self, _: &mut Hcx, _: &mut StableHasher) {} }
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2c3d114..6c7505a 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -318,7 +318,12 @@ pub enum UndefinedBehaviorInfo<'tcx> { /// Free-form case. Only for errors that are never caught! Used by miri Ub(String), /// Validation error. - ValidationError { path: Option<String>, msg: String, ptr_bytes_warning: bool }, + ValidationError { + orig_ty: Ty<'tcx>, + path: Option<String>, + msg: String, + ptr_bytes_warning: bool, + }, /// Unreachable code was executed. Unreachable, @@ -457,11 +462,11 @@ fn fmt_in_alloc_attempt( match self { Ub(msg) => write!(f, "{msg}"), - ValidationError { path: None, msg, .. } => { - write!(f, "constructing invalid value: {msg}") + ValidationError { orig_ty, path: None, msg, .. } => { + write!(f, "constructing invalid value of type {orig_ty}: {msg}") } - ValidationError { path: Some(path), msg, .. } => { - write!(f, "constructing invalid value at {path}: {msg}") + ValidationError { orig_ty, path: Some(path), msg, .. } => { + write!(f, "constructing invalid value of type {orig_ty}: at {path}, {msg}") } Unreachable => write!(f, "entering unreachable code"),
diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index c5dab80..35e33fd 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs
@@ -131,10 +131,10 @@ // `Providers` that the driver creates (using several `rustc_*` crates). // // The result type of each query must implement `Clone`. Additionally -// `ty::query::from_cycle_error::FromCycleError` can be implemented which produces an appropriate +// `QueryVTable::handle_cycle_error_fn` can be used to produce an appropriate // placeholder (error) value if the query resulted in a query cycle. -// Queries without a `FromCycleError` implementation will raise a fatal error on query -// cycles instead. +// Queries without a custom `handle_cycle_error_fn` implementation will raise a +// fatal error on query cycles instead. rustc_queries! { /// Caches the expansion of a derive proc macro, e.g. `#[derive(Serialize)]`. /// The key is: @@ -144,7 +144,7 @@ /// The output is the token stream generated by the proc macro. query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> { desc { "expanding a derive (proc) macro" } - cache_on_disk_if { true } + cache_on_disk } /// This exists purely for testing the interactions between delayed bugs and incremental. @@ -235,7 +235,7 @@ query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache desc { "getting HIR module items in `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } /// Returns HIR ID for the given `LocalDefId`. @@ -283,7 +283,7 @@ /// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { desc { "computing the default for const parameter `{}`", tcx.def_path_str(param) } - cache_on_disk_if { param.is_local() } + cache_on_disk separate_provide_extern } @@ -296,7 +296,7 @@ /// This query will ICE if given a const that is not marked with `type const`. query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { desc { "computing the type-level value for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -328,7 +328,7 @@ }, path = tcx.def_path_str(key), } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -376,7 +376,7 @@ -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> { desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -427,7 +427,7 @@ query generics_of(key: DefId) -> &'tcx ty::Generics { desc { "computing generics of `{}`", tcx.def_path_str(key) } arena_cache - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -483,7 +483,7 @@ /// ``` query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -496,7 +496,7 @@ /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -577,7 +577,7 @@ /// Checks whether a type is representable or infinitely sized // - // Infinitely sized types will cause a cycle. The `value_from_cycle_error` impl will print + // Infinitely sized types will cause a cycle. The query's `handle_cycle_error_fn` will print // a custom error about the infinite size and then abort compilation. (In the past we // recovered and continued, but in practice that leads to confusing subsequent error // messages about cycles that then abort.) @@ -625,7 +625,7 @@ /// the final value of a `const`. query mir_const_qualif(key: DefId) -> mir::ConstQualifs { desc { "const checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -658,7 +658,7 @@ key: DefId ) -> &'tcx mir::Body<'tcx> { desc { "caching mir of `{}` for CTFE", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -693,7 +693,7 @@ query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> { arena_cache desc { "coroutine witness types for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -721,7 +721,7 @@ /// for codegen. This is also the only query that can fetch non-local MIR, at present. query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { desc { "optimizing MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -759,7 +759,7 @@ /// need to use the `DefId` of the original body. query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { desc { "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -810,7 +810,7 @@ /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { "computing explicit predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -823,7 +823,7 @@ /// print the result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { desc { "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -837,7 +837,7 @@ /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "computing the super predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -849,7 +849,7 @@ /// predicates of the trait alias. query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { "computing the implied predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -908,22 +908,22 @@ query trait_def(key: DefId) -> &'tcx ty::TraitDef { desc { "computing trait definition for `{}`", tcx.def_path_str(key) } arena_cache - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_def(key: DefId) -> ty::AdtDef<'tcx> { desc { "computing ADT definition for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_destructor(key: DefId) -> Option<ty::Destructor> { desc { "computing `Drop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_async_destructor(key: DefId) -> Option<ty::AsyncDestructor> { desc { "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } query adt_sizedness_constraint( @@ -1031,7 +1031,7 @@ /// the result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { desc { "computing the variances of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1051,14 +1051,14 @@ /// to a list of the `DefId`s of its associated items or fields. query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { desc { "collecting associated items or fields of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } /// Maps from a trait/impl item to the trait/impl item "descriptor". query associated_item(key: DefId) -> ty::AssocItem { desc { "computing associated item data for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1106,7 +1106,7 @@ /// Given an `impl_id`, return the trait it implements along with some header information. query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { desc { "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } - cache_on_disk_if { impl_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1122,7 +1122,7 @@ /// Methods in these implementations don't need to be exported. query inherent_impls(key: DefId) -> &'tcx [DefId] { desc { "collecting inherent impls for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1163,7 +1163,7 @@ /// Computes the signature of the function. query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { desc { "computing function signature of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1193,7 +1193,6 @@ query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet<abi::FieldIdx> { arena_cache desc { "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } - cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) } } /// Return the live symbols in the crate for dead code check. @@ -1218,18 +1217,18 @@ /// Caches `CoerceUnsized` kinds for impls on custom types. query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> { desc { "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } - query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { + query typeck_root(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { !tcx.is_typeck_child(key.to_def_id()) } + cache_on_disk } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { desc { "finding used_trait_imports `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { @@ -1295,7 +1294,7 @@ "computing (transitive) callees of `{}` that may recurse", tcx.def_path_str(key), } - cache_on_disk_if { true } + cache_on_disk } /// Obtain all the calls into other local functions @@ -1333,7 +1332,7 @@ "const-evaluating + checking `{}`", key.value.display(tcx) } - cache_on_disk_if { true } + cache_on_disk } /// Evaluate a static's initializer, returning the allocation of the initializer's memory. @@ -1342,7 +1341,7 @@ "evaluating initializer of static `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1366,7 +1365,7 @@ key.value.display(tcx) } depth_limit - cache_on_disk_if { true } + cache_on_disk } /// Evaluate a constant and convert it to a type level constant or @@ -1408,12 +1407,12 @@ query reachable_set(_: ()) -> &'tcx LocalDefIdSet { arena_cache desc { "reachability" } - cache_on_disk_if { true } + cache_on_disk } /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. - query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { + query region_scope_tree(def_id: LocalDefId) -> &'tcx crate::middle::region::ScopeTree { desc { "computing drop scopes for `{}`", tcx.def_path_str(def_id) } } @@ -1432,20 +1431,22 @@ /// look up the correct symbol name of instances from upstream crates. query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName<'tcx> { desc { "computing the symbol for `{}`", key } - cache_on_disk_if { true } + cache_on_disk } query def_kind(def_id: DefId) -> DefKind { desc { "looking up definition kind of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } separate_provide_extern + // This query has no local provider. For defs in the current crate, + // its value is always set by feeding when the `DefId` is created, + // usually in `TyCtxt::create_def`. feedable } /// Gets the span for the definition. query def_span(def_id: DefId) -> Span { desc { "looking up span for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1453,7 +1454,7 @@ /// Gets the span for the identifier of the definition. query def_ident_span(def_id: DefId) -> Option<Span> { desc { "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1462,18 +1463,18 @@ /// Panics if it is not a definition that has a single type. query ty_span(def_id: LocalDefId) -> Span { desc { "looking up span for `{}`'s type", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } query lookup_stability(def_id: DefId) -> Option<hir::Stability> { desc { "looking up stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } query lookup_const_stability(def_id: DefId) -> Option<hir::ConstStability> { desc { "looking up const stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1492,7 +1493,7 @@ query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> { desc { "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -1527,7 +1528,7 @@ query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs { desc { "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } arena_cache - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern feedable } @@ -1562,7 +1563,7 @@ query is_mir_available(key: DefId) -> bool { desc { "checking if item has MIR available: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } + cache_on_disk separate_provide_extern } @@ -1596,7 +1597,7 @@ query codegen_select_candidate( key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { - cache_on_disk_if { true } + cache_on_disk desc { "computing candidate for `{}`", key.value } } @@ -1618,7 +1619,7 @@ query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { desc { "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } - cache_on_disk_if { true } + cache_on_disk } query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { desc { "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } @@ -1706,7 +1707,7 @@ /// then `Err(AlwaysRequiresDrop)` is returned. query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { desc { "computing when `{}` needs drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } /// A list of types where the ADT requires async drop if and only if any of @@ -1714,7 +1715,7 @@ /// then `Err(AlwaysRequiresDrop)` is returned. query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { desc { "computing when `{}` needs async drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } + cache_on_disk } /// A list of types where the ADT requires drop if and only if any of those types @@ -1841,7 +1842,7 @@ } query has_ffi_unwind_calls(key: LocalDefId) -> bool { desc { "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } - cache_on_disk_if { true } + cache_on_disk } query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> { desc { "getting a crate's required panic strategy" } @@ -1921,7 +1922,7 @@ } query is_reachable_non_generic(def_id: DefId) -> bool { desc { "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } query is_unreachable_local_definition(def_id: LocalDefId) -> bool { @@ -2368,7 +2369,7 @@ /// sets of different crates do not intersect. query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { desc { "collecting exported non-generic symbols for crate `{}`", cnum} - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern } @@ -2381,7 +2382,7 @@ /// sets of different crates do not intersect. query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { desc { "collecting exported generic symbols for crate `{}`", cnum} - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern } @@ -2711,12 +2712,12 @@ query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), NormalizationErrorInMono> { desc { "collecting items used by `{}`", key.0 } - cache_on_disk_if { true } + cache_on_disk } query size_estimate(key: ty::Instance<'tcx>) -> usize { desc { "estimating codegen size of `{}`", key } - cache_on_disk_if { true } + cache_on_disk } query anon_const_kind(def_id: DefId) -> ty::AnonConstKind { @@ -2726,7 +2727,7 @@ query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> { desc { "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } + cache_on_disk separate_provide_extern } @@ -2748,7 +2749,7 @@ query externally_implementable_items(cnum: CrateNum) -> &'tcx FxIndexMap<DefId, (EiiDecl, FxIndexMap<DefId, EiiImpl>)> { arena_cache desc { "looking up the externally implementable items of a crate" } - cache_on_disk_if { cnum == LOCAL_CRATE } + cache_on_disk separate_provide_extern }
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 036aa2e..7a31682 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs
@@ -7,16 +7,21 @@ use std::ffi::OsStr; use std::intrinsics::transmute_unchecked; +use std::marker::PhantomData; use std::mem::MaybeUninit; use rustc_ast::tokenstream::TokenStream; +use rustc_data_structures::steal::Steal; +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_span::{ErrorGuaranteed, Spanned}; -use crate::mir::interpret::EvalToValTreeResult; use crate::mir::mono::{MonoItem, NormalizationErrorInMono}; -use crate::traits::solve; use crate::ty::{self, Ty, TyCtxt}; -use crate::{mir, traits}; +use crate::{mir, thir, traits}; + +unsafe extern "C" { + type NoAutoTraits; +} /// Internal implementation detail of [`Erased`]. #[derive(Copy, Clone)] @@ -24,8 +29,15 @@ pub struct ErasedData<Storage: Copy> { /// We use `MaybeUninit` here to make sure it's legal to store a transmuted /// value that isn't actually of type `Storage`. data: MaybeUninit<Storage>, + /// `Storage` is an erased type, so we use an external type here to opt-out of auto traits + /// as those would be incorrect. + no_auto_traits: PhantomData<NoAutoTraits>, } +// SAFETY: The bounds on `erase_val` ensure the types we erase are `DynSync` and `DynSend` +unsafe impl<Storage: Copy> DynSync for ErasedData<Storage> {} +unsafe impl<Storage: Copy> DynSend for ErasedData<Storage> {} + /// Trait for types that can be erased into [`Erased<Self>`]. /// /// Erasing and unerasing values is performed by [`erase_val`] and [`restore_val`]. @@ -55,13 +67,11 @@ pub trait Erasable: Copy { /// /// `Erased<T>` and `Erased<U>` are type-checked as distinct types, but codegen /// can see whether they actually have the same storage type. -/// -/// FIXME: This might have soundness issues with erasable types that don't -/// implement the same auto-traits as `[u8; _]`; see -/// <https://github.com/rust-lang/rust/pull/151715#discussion_r2740113250> #[inline(always)] #[define_opaque(Erased)] -pub fn erase_val<T: Erasable>(value: T) -> Erased<T> { +// The `DynSend` and `DynSync` bounds on `T` are used to +// justify the safety of the implementations of these traits for `ErasedData`. +pub fn erase_val<T: Erasable + DynSend + DynSync>(value: T) -> Erased<T> { // Ensure the sizes match const { if size_of::<T>() != size_of::<T::Storage>() { @@ -79,6 +89,7 @@ pub fn erase_val<T: Erasable>(value: T) -> Erased<T> { // // SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes. data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Storage>>(value) }, + no_auto_traits: PhantomData, } } @@ -89,7 +100,7 @@ pub fn erase_val<T: Erasable>(value: T) -> Erased<T> { #[inline(always)] #[define_opaque(Erased)] pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T { - let ErasedData { data }: ErasedData<<T as Erasable>::Storage> = erased_value; + let ErasedData { data, .. }: ErasedData<<T as Erasable>::Storage> = erased_value; // See comment in `erase_val` for why we use `transmute_unchecked`. // // SAFETY: Due to the use of impl Trait in `Erased` the only way to safely create an instance @@ -98,195 +109,45 @@ pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T { unsafe { transmute_unchecked::<MaybeUninit<T::Storage>, T>(data) } } -// FIXME(#151565): Using `T: ?Sized` here should let us remove the separate -// impls for fat reference types. impl<T> Erasable for &'_ T { - type Storage = [u8; size_of::<&'static ()>()]; + type Storage = [u8; size_of::<&'_ ()>()]; } impl<T> Erasable for &'_ [T] { - type Storage = [u8; size_of::<&'static [()]>()]; + type Storage = [u8; size_of::<&'_ [()]>()]; } -impl Erasable for &'_ OsStr { - type Storage = [u8; size_of::<&'static OsStr>()]; -} - -impl<T> Erasable for &'_ ty::List<T> { - type Storage = [u8; size_of::<&'static ty::List<()>>()]; -} - -impl<T> Erasable for &'_ ty::ListWithCachedTypeInfo<T> { - type Storage = [u8; size_of::<&'static ty::ListWithCachedTypeInfo<()>>()]; -} - -impl<I: rustc_index::Idx, T> Erasable for &'_ rustc_index::IndexSlice<I, T> { - type Storage = [u8; size_of::<&'static rustc_index::IndexSlice<u32, ()>>()]; +// Note: this impl does not overlap with the impl for `&'_ T` above because `RawList` is unsized +// and does not satisfy the implicit `T: Sized` bound. +// +// Furthermore, even if that implicit bound was removed (by adding `T: ?Sized`) this impl still +// wouldn't overlap because `?Sized` is equivalent to `MetaSized` and `RawList` does not satisfy +// `MetaSized` because it contains an extern type. +impl<H, T> Erasable for &'_ ty::RawList<H, T> { + type Storage = [u8; size_of::<&'_ ty::RawList<(), ()>>()]; } impl<T> Erasable for Result<&'_ T, traits::query::NoSolution> { - type Storage = [u8; size_of::<Result<&'static (), traits::query::NoSolution>>()]; + type Storage = [u8; size_of::<Result<&'_ (), traits::query::NoSolution>>()]; } -impl<T> Erasable for Result<&'_ [T], traits::query::NoSolution> { - type Storage = [u8; size_of::<Result<&'static [()], traits::query::NoSolution>>()]; -} - -impl<T> Erasable for Result<&'_ T, rustc_errors::ErrorGuaranteed> { - type Storage = [u8; size_of::<Result<&'static (), rustc_errors::ErrorGuaranteed>>()]; -} - -impl<T> Erasable for Result<&'_ [T], rustc_errors::ErrorGuaranteed> { - type Storage = [u8; size_of::<Result<&'static [()], rustc_errors::ErrorGuaranteed>>()]; -} - -impl<T> Erasable for Result<&'_ T, traits::CodegenObligationError> { - type Storage = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()]; -} - -impl<T> Erasable for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> { - type Storage = [u8; size_of::<Result<&'static (), &'static ty::layout::FnAbiError<'static>>>()]; -} - -impl<T> Erasable for Result<(&'_ T, crate::thir::ExprId), rustc_errors::ErrorGuaranteed> { - type Storage = [u8; size_of::< - Result<(&'static (), crate::thir::ExprId), rustc_errors::ErrorGuaranteed>, - >()]; -} - -impl Erasable for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuaranteed> { - type Storage = - [u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()]; -} - -impl Erasable - for Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> -{ - type Storage = [u8; size_of::< - Result<Option<ty::EarlyBinder<'static, ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>, - >()]; -} - -impl Erasable for Result<ty::GenericArg<'_>, traits::query::NoSolution> { - type Storage = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()]; -} - -impl Erasable for Result<bool, &ty::layout::LayoutError<'_>> { - type Storage = [u8; size_of::<Result<bool, &'static ty::layout::LayoutError<'static>>>()]; -} - -impl Erasable for Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>> { - type Storage = [u8; size_of::< - Result< - rustc_abi::TyAndLayout<'static, Ty<'static>>, - &'static ty::layout::LayoutError<'static>, - >, - >()]; -} - -impl Erasable for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> { - type Storage = - [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()]; -} - -impl Erasable for Option<(mir::ConstValue, Ty<'_>)> { - type Storage = [u8; size_of::<Option<(mir::ConstValue, Ty<'_>)>>()]; -} - -impl Erasable for EvalToValTreeResult<'_> { - type Storage = [u8; size_of::<EvalToValTreeResult<'static>>()]; -} - -impl Erasable for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> { - type Storage = - [u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()]; -} - -impl Erasable - for Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono> -{ - type Storage = [u8; size_of::< - Result< - (&'static [Spanned<MonoItem<'static>>], &'static [Spanned<MonoItem<'static>>]), - NormalizationErrorInMono, - >, - >()]; -} - -impl Erasable for Result<&'_ TokenStream, ()> { - type Storage = [u8; size_of::<Result<&'static TokenStream, ()>>()]; +impl<T> Erasable for Result<&'_ T, ErrorGuaranteed> { + type Storage = [u8; size_of::<Result<&'_ (), ErrorGuaranteed>>()]; } impl<T> Erasable for Option<&'_ T> { - type Storage = [u8; size_of::<Option<&'static ()>>()]; -} - -impl<T> Erasable for Option<&'_ [T]> { - type Storage = [u8; size_of::<Option<&'static [()]>>()]; -} - -impl Erasable for Option<&'_ OsStr> { - type Storage = [u8; size_of::<Option<&'static OsStr>>()]; -} - -impl Erasable for Option<mir::DestructuredConstant<'_>> { - type Storage = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()]; -} - -impl Erasable for ty::ImplTraitHeader<'_> { - type Storage = [u8; size_of::<ty::ImplTraitHeader<'static>>()]; -} - -impl Erasable for Option<ty::EarlyBinder<'_, Ty<'_>>> { - type Storage = [u8; size_of::<Option<ty::EarlyBinder<'static, Ty<'static>>>>()]; -} - -impl Erasable for Option<ty::Value<'_>> { - type Storage = [u8; size_of::<Option<ty::Value<'static>>>()]; -} - -impl Erasable for rustc_hir::MaybeOwner<'_> { - type Storage = [u8; size_of::<rustc_hir::MaybeOwner<'static>>()]; + type Storage = [u8; size_of::<Option<&'_ ()>>()]; } impl<T: Erasable> Erasable for ty::EarlyBinder<'_, T> { type Storage = T::Storage; } -impl Erasable for ty::Binder<'_, ty::FnSig<'_>> { - type Storage = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()]; -} - -impl Erasable for ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>> { - type Storage = - [u8; size_of::<ty::Binder<'static, ty::CoroutineWitnessTypes<TyCtxt<'static>>>>()]; -} - -impl Erasable for ty::Binder<'_, &'_ ty::List<Ty<'_>>> { - type Storage = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()]; -} - impl<T0, T1> Erasable for (&'_ T0, &'_ T1) { - type Storage = [u8; size_of::<(&'static (), &'static ())>()]; + type Storage = [u8; size_of::<(&'_ (), &'_ ())>()]; } -impl<T0> Erasable for (solve::QueryResult<'_>, &'_ T0) { - type Storage = [u8; size_of::<(solve::QueryResult<'static>, &'static ())>()]; -} - -impl<T0, T1> Erasable for (&'_ T0, &'_ [T1]) { - type Storage = [u8; size_of::<(&'static (), &'static [()])>()]; -} - -impl<T0, T1> Erasable for (&'_ [T0], &'_ [T1]) { - type Storage = [u8; size_of::<(&'static [()], &'static [()])>()]; -} - -impl<T0> Erasable for (&'_ T0, Result<(), ErrorGuaranteed>) { - type Storage = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()]; -} - -macro_rules! impl_erasable_for_simple_types { +macro_rules! impl_erasable_for_types_with_no_type_params { ($($ty:ty),+ $(,)?) => { $( impl Erasable for $ty { @@ -296,171 +157,96 @@ impl Erasable for $ty { } } -// For concrete types with no lifetimes, the erased storage for `Foo` is -// `[u8; size_of::<Foo>()]`. -impl_erasable_for_simple_types! { - // FIXME(#151565): Add `tidy-alphabetical-{start,end}` and sort this. +// For types with no type parameters the erased storage for `Foo` is +// `[u8; size_of::<Foo>()]`. ('_ lifetimes are allowed.) +impl_erasable_for_types_with_no_type_params! { + // tidy-alphabetical-start + (&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>), (), - bool, + (traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe<TyCtxt<'_>>), + Option<&'_ OsStr>, + Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol, rustc_span::Symbol>]>, + Option<(mir::ConstValue, Ty<'_>)>, Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>, + Option<rustc_abi::Align>, Option<rustc_ast::expand::allocator::AllocatorKind>, + Option<rustc_data_structures::svh::Svh>, Option<rustc_hir::ConstStability>, + Option<rustc_hir::CoroutineKind>, Option<rustc_hir::DefaultBodyStability>, Option<rustc_hir::Stability>, - Option<rustc_data_structures::svh::Svh>, - Option<rustc_hir::def::DefKind>, - Option<rustc_hir::CoroutineKind>, - Option<rustc_hir::HirId>, Option<rustc_middle::middle::stability::DeprecationEntry>, Option<rustc_middle::ty::AsyncDestructor>, Option<rustc_middle::ty::Destructor>, - Option<rustc_middle::ty::ImplTraitInTraitData>, + Option<rustc_middle::ty::IntrinsicDef>, Option<rustc_middle::ty::ScalarInt>, + Option<rustc_span::Span>, Option<rustc_span::def_id::CrateNum>, Option<rustc_span::def_id::DefId>, Option<rustc_span::def_id::LocalDefId>, - Option<rustc_span::Span>, - Option<rustc_abi::FieldIdx>, Option<rustc_target::spec::PanicStrategy>, + Option<ty::EarlyBinder<'_, Ty<'_>>>, + Option<ty::Value<'_>>, Option<usize>, - Option<rustc_middle::ty::IntrinsicDef>, - Option<rustc_abi::Align>, - Result<(), rustc_errors::ErrorGuaranteed>, - Result<(), rustc_middle::traits::query::NoSolution>, - Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>, - Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed>, + Result<&'_ TokenStream, ()>, + Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>, + Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>, + Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop>, + Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed>, + Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>, + Result<(), ErrorGuaranteed>, + Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed>, + Result<Option<ty::Instance<'_>>, ErrorGuaranteed>, + Result<bool, &ty::layout::LayoutError<'_>>, + Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled>, Result<mir::ConstValue, mir::interpret::ErrorHandled>, - rustc_abi::ReprOptions, - rustc_ast::expand::allocator::AllocatorKind, - rustc_hir::DefaultBodyStability, - rustc_hir::attrs::Deprecation, - rustc_hir::attrs::EiiDecl, - rustc_hir::attrs::EiiImpl, + Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>, + Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>, + Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>, + Result<ty::GenericArg<'_>, traits::query::NoSolution>, + Ty<'_>, + bool, rustc_data_structures::svh::Svh, - rustc_errors::ErrorGuaranteed, rustc_hir::Constness, - rustc_hir::ConstStability, - rustc_hir::def_id::DefId, - rustc_hir::def_id::DefIndex, - rustc_hir::def_id::LocalDefId, - rustc_hir::def_id::LocalModDefId, - rustc_hir::def::DefKind, rustc_hir::Defaultness, - rustc_hir::definitions::DefKey, - rustc_hir::CoroutineKind, rustc_hir::HirId, - rustc_hir::IsAsync, - rustc_hir::ItemLocalId, - rustc_hir::LangItem, + rustc_hir::MaybeOwner<'_>, rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>, - rustc_hir::OwnerId, - rustc_hir::Stability, - rustc_hir::Upvar, - rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, - rustc_middle::middle::dependency_format::Linkage, - rustc_middle::middle::exported_symbols::SymbolExportInfo, + rustc_hir::def::DefKind, + rustc_hir::def_id::DefId, + rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, - rustc_middle::middle::resolve_bound_vars::ResolvedArg, - rustc_middle::middle::stability::DeprecationEntry, rustc_middle::mir::ConstQualifs, rustc_middle::mir::ConstValue, rustc_middle::mir::interpret::AllocId, - rustc_middle::mir::interpret::CtfeProvenance, - rustc_middle::mir::interpret::ErrorHandled, - rustc_middle::thir::ExprId, - rustc_middle::traits::CodegenObligationError, - rustc_middle::traits::EvaluationResult, - rustc_middle::traits::OverflowError, - rustc_middle::traits::query::NoSolution, - rustc_middle::traits::WellFormedLoc, - rustc_middle::ty::adjustment::CoerceUnsizedInfo, - rustc_middle::ty::AssocItem, - rustc_middle::ty::AssocContainer, - rustc_middle::ty::Asyncness, - rustc_middle::ty::AsyncDestructor, + rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>, + rustc_middle::mir::interpret::EvalToValTreeResult<'_>, + rustc_middle::mir::mono::MonoItemPartitions<'_>, + rustc_middle::traits::query::MethodAutoderefStepsResult<'_>, + rustc_middle::ty::AdtDef<'_>, rustc_middle::ty::AnonConstKind, - rustc_middle::ty::Destructor, - rustc_middle::ty::fast_reject::SimplifiedType, - rustc_middle::ty::ImplPolarity, - rustc_middle::ty::util::AlwaysRequiresDrop, + rustc_middle::ty::AssocItem, + rustc_middle::ty::Asyncness, + rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>, + rustc_middle::ty::Binder<'_, ty::FnSig<'_>>, + rustc_middle::ty::ClosureTypeInfo<'_>, + rustc_middle::ty::Const<'_>, + rustc_middle::ty::ConstConditions<'_>, + rustc_middle::ty::GenericPredicates<'_>, + rustc_middle::ty::ImplTraitHeader<'_>, + rustc_middle::ty::ParamEnv<'_>, + rustc_middle::ty::SymbolName<'_>, + rustc_middle::ty::TypingEnv<'_>, rustc_middle::ty::Visibility<rustc_span::def_id::DefId>, - rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, - rustc_session::config::CrateType, - rustc_session::config::EntryFnType, + rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>, + rustc_session::Limits, rustc_session::config::OptLevel, rustc_session::config::SymbolManglingVersion, rustc_session::cstore::CrateDepKind, - rustc_session::cstore::ExternCrate, - rustc_session::cstore::LinkagePreference, - rustc_session::Limits, - rustc_session::lint::LintExpectationId, - rustc_span::def_id::CrateNum, - rustc_span::def_id::DefPathHash, - rustc_span::ExpnHash, rustc_span::ExpnId, rustc_span::Span, rustc_span::Symbol, - rustc_span::Ident, rustc_target::spec::PanicStrategy, - rustc_type_ir::Variance, - u32, usize, -} - -macro_rules! impl_erasable_for_single_lifetime_types { - ($($($fake_path:ident)::+),+ $(,)?) => { - $( - impl<'tcx> Erasable for $($fake_path)::+<'tcx> { - type Storage = [u8; size_of::<$($fake_path)::+<'static>>()]; - } - )* - } -} - -// For types containing a single lifetime and no other generics, e.g. -// `Foo<'tcx>`, the erased storage is `[u8; size_of::<Foo<'static>>()]`. -// -// FIXME(#151565): Some of the hand-written impls above that only use one -// lifetime can probably be migrated here. -impl_erasable_for_single_lifetime_types! { - // FIXME(#151565): Add `tidy-alphabetical-{start,end}` and sort this. - rustc_middle::middle::exported_symbols::ExportedSymbol, - rustc_middle::mir::Const, - rustc_middle::mir::DestructuredConstant, - rustc_middle::mir::ConstAlloc, - rustc_middle::mir::interpret::GlobalId, - rustc_middle::mir::interpret::EvalStaticInitializerRawResult, - rustc_middle::mir::mono::MonoItemPartitions, - rustc_middle::traits::query::MethodAutoderefStepsResult, - rustc_middle::traits::query::type_op::AscribeUserType, - rustc_middle::traits::query::type_op::Eq, - rustc_middle::traits::query::type_op::ProvePredicate, - rustc_middle::traits::query::type_op::Subtype, - rustc_middle::ty::AdtDef, - rustc_middle::ty::AliasTy, - rustc_middle::ty::ClauseKind, - rustc_middle::ty::ClosureTypeInfo, - rustc_middle::ty::Const, - rustc_middle::ty::DestructuredAdtConst, - rustc_middle::ty::ExistentialTraitRef, - rustc_middle::ty::FnSig, - rustc_middle::ty::GenericArg, - rustc_middle::ty::GenericPredicates, - rustc_middle::ty::ConstConditions, - rustc_middle::ty::inhabitedness::InhabitedPredicate, - rustc_middle::ty::Instance, - rustc_middle::ty::BoundVariableKind, - rustc_middle::ty::InstanceKind, - rustc_middle::ty::layout::FnAbiError, - rustc_middle::ty::layout::LayoutError, - rustc_middle::ty::LitToConstInput, - rustc_middle::ty::ParamEnv, - rustc_middle::ty::TypingEnv, - rustc_middle::ty::Predicate, - rustc_middle::ty::SymbolName, - rustc_middle::ty::TraitRef, - rustc_middle::ty::Ty, - rustc_middle::ty::UnevaluatedConst, - rustc_middle::ty::ValTree, - rustc_middle::ty::VtblEntry, + // tidy-alphabetical-end }
diff --git a/compiler/rustc_middle/src/query/job.rs b/compiler/rustc_middle/src/query/job.rs index 3bf37a7..24c4daf 100644 --- a/compiler/rustc_middle/src/query/job.rs +++ b/compiler/rustc_middle/src/query/job.rs
@@ -6,7 +6,7 @@ use parking_lot::{Condvar, Mutex}; use rustc_span::Span; -use crate::query::CycleError; +use crate::query::Cycle; use crate::ty::TyCtxt; /// A value uniquely identifying an active query job. @@ -59,7 +59,7 @@ pub struct QueryWaiter<'tcx> { pub parent: Option<QueryJobId>, pub condvar: Condvar, pub span: Span, - pub cycle: Mutex<Option<CycleError<'tcx>>>, + pub cycle: Mutex<Option<Cycle<'tcx>>>, } #[derive(Clone, Debug)] @@ -79,7 +79,7 @@ pub fn wait_on( tcx: TyCtxt<'tcx>, query: Option<QueryJobId>, span: Span, - ) -> Result<(), CycleError<'tcx>> { + ) -> Result<(), Cycle<'tcx>> { let mut waiters_guard = self.waiters.lock(); let Some(waiters) = &mut *waiters_guard else { return Ok(()); // already complete
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9c012f2..b7e5e9b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs
@@ -5,8 +5,8 @@ pub use self::job::{QueryJob, QueryJobId, QueryLatch, QueryWaiter}; pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey}; pub use self::plumbing::{ - ActiveKeyStatus, CycleError, EnsureMode, QueryMode, QueryState, QuerySystem, QueryVTable, - TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult, + ActiveKeyStatus, Cycle, EnsureMode, QueryMode, QueryState, QuerySystem, QueryVTable, TyCtxtAt, + TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult, }; pub use self::stack::QueryStackFrame; pub use crate::queries::Providers;
diff --git a/compiler/rustc_middle/src/query/modifiers.rs b/compiler/rustc_middle/src/query/modifiers.rs index 50c9136..2d22a54 100644 --- a/compiler/rustc_middle/src/query/modifiers.rs +++ b/compiler/rustc_middle/src/query/modifiers.rs
@@ -18,11 +18,15 @@ /// The query plumbing takes care of the arenas and the type manipulations. pub(crate) struct arena_cache; -/// # `cache_on_disk_if { ... }` query modifier +/// # `cache_on_disk` query modifier /// -/// Cache the query result to disk if the provided block evaluates to true. The query key -/// identifier is available for use within the block, as is `tcx`. -pub(crate) struct cache_on_disk_if; +/// The query's return values are cached to disk, and can be loaded by subsequent +/// sessions if the corresponding dep node is green. +/// +/// If the [`separate_provide_extern`] modifier is also present, values will only +/// be cached to disk for "local" keys, because values for external crates should +/// be loadable from crate metadata instead. +pub(crate) struct cache_on_disk; /// # `depth_limit` query modifier /// @@ -73,6 +77,8 @@ /// # `separate_provide_extern` query modifier /// /// Use separate query provider functions for local and extern crates. +/// +/// Also affects the [`cache_on_disk`] modifier. pub(crate) struct separate_provide_extern; // tidy-alphabetical-end
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 607891d..4dbceba 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -2,14 +2,14 @@ use std::sync::Arc; use std::{fmt, mem}; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::sync::{HashMapExt, Lock, RwLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, StableCrateId}; use rustc_hir::definitions::DefPathHash; -use rustc_index::{Idx, IndexVec}; +use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -53,22 +53,18 @@ pub struct OnDiskCache { // The complete cache data in serialized form. serialized_data: RwLock<Option<Mmap>>, - // Collects all `QuerySideEffect` created during the current compilation - // session. - current_side_effects: Lock<FxIndexMap<DepNodeIndex, QuerySideEffect>>, - file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>, // Caches that are populated lazily during decoding. file_index_to_file: Lock<FxHashMap<SourceFileIndex, Arc<SourceFile>>>, - // A map from dep-node to the position of the cached query result in - // `serialized_data`. - query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, + /// For query dep nodes that have a disk-cached return value, maps the node + /// index to the position of its serialized value in `serialized_data`. + query_values_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, - // A map from dep-node to the position of any associated `QuerySideEffect` in - // `serialized_data`. - prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, + /// For `DepKind::SideEffect` dep nodes, maps the node index to the position + /// of its serialized [`QuerySideEffect`] in `serialized_data`. + side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, alloc_decoding_state: AllocDecodingState, @@ -101,8 +97,8 @@ pub struct OnDiskCache { #[derive(Encodable, Decodable)] struct Footer { file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>, - query_result_index: EncodedDepNodeIndex, - side_effects_index: EncodedDepNodeIndex, + query_values_index: Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>, + side_effects_index: Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>, // The location of all allocations. // Most uses only need values up to u32::MAX, but benchmarking indicates that we can use a u64 // without measurable overhead. This permits larger const allocations without ICEing. @@ -114,8 +110,6 @@ struct Footer { foreign_expn_data: UnhashMap<ExpnHash, u32>, } -pub type EncodedDepNodeIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable)] struct SourceFileIndex(u32); @@ -174,9 +168,8 @@ pub fn new(sess: &Session, data: Mmap, start_pos: usize) -> Result<Self, ()> { serialized_data: RwLock::new(Some(data)), file_index_to_stable_id: footer.file_index_to_stable_id, file_index_to_file: Default::default(), - current_side_effects: Default::default(), - query_result_index: footer.query_result_index.into_iter().collect(), - prev_side_effects_index: footer.side_effects_index.into_iter().collect(), + query_values_index: footer.query_values_index.into_iter().collect(), + side_effects_index: footer.side_effects_index.into_iter().collect(), alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index), syntax_contexts: footer.syntax_contexts, expn_data: footer.expn_data, @@ -190,9 +183,8 @@ pub fn new_empty() -> Self { serialized_data: RwLock::new(None), file_index_to_stable_id: Default::default(), file_index_to_file: Default::default(), - current_side_effects: Default::default(), - query_result_index: Default::default(), - prev_side_effects_index: Default::default(), + query_values_index: Default::default(), + side_effects_index: Default::default(), alloc_decoding_state: AllocDecodingState::new(Vec::new()), syntax_contexts: FxHashMap::default(), expn_data: UnhashMap::default(), @@ -207,7 +199,9 @@ pub fn close_serialized_data_mmap(&self) { *self.serialized_data.write() = None; } - pub fn serialize(&self, tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult { + /// Serialize the current-session data that will be loaded by [`OnDiskCache`] + /// in a subsequent incremental compilation session. + pub fn serialize(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult { // Serializing the `DepGraph` should not modify it. tcx.dep_graph.with_ignore(|| { // Allocate `SourceFileIndex`es. @@ -237,34 +231,23 @@ pub fn serialize(&self, tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResu type_shorthands: Default::default(), predicate_shorthands: Default::default(), interpret_allocs: Default::default(), - source_map: CachingSourceMapView::new(tcx.sess.source_map()), + caching_source_map_view: CachingSourceMapView::new(tcx.sess.source_map()), file_to_file_index, hygiene_context: &hygiene_encode_context, symbol_index_table: Default::default(), + query_values_index: Default::default(), + side_effects_index: Default::default(), }; - // Encode query results. - let mut query_result_index = EncodedDepNodeIndex::new(); - + // Encode query return values. tcx.sess.time("encode_query_values", || { - let enc = &mut encoder; - let qri = &mut query_result_index; - tcx.encode_query_values(enc, qri); + tcx.encode_query_values(&mut encoder); }); // Encode side effects. - let side_effects_index: EncodedDepNodeIndex = self - .current_side_effects - .borrow() - .iter() - .map(|(dep_node_index, side_effect)| { - let pos = AbsoluteBytePos::new(encoder.position()); - let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index()); - encoder.encode_tagged(dep_node_index, side_effect); - - (dep_node_index, pos) - }) - .collect(); + for (&dep_node_index, side_effect) in tcx.query_system.side_effects.borrow().iter() { + encoder.encode_side_effect(dep_node_index, side_effect); + } let interpret_alloc_index = { let mut interpret_alloc_index = Vec::new(); @@ -315,11 +298,13 @@ pub fn serialize(&self, tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResu // Encode the file footer. let footer_pos = encoder.position() as u64; + let query_values_index = mem::take(&mut encoder.query_values_index); + let side_effects_index = mem::take(&mut encoder.side_effects_index); encoder.encode_tagged( TAG_FILE_FOOTER, &Footer { file_index_to_stable_id, - query_result_index, + query_values_index, side_effects_index, interpret_alloc_index, syntax_contexts, @@ -340,35 +325,25 @@ pub fn serialize(&self, tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResu } /// Loads a `QuerySideEffect` created during the previous compilation session. - pub fn load_side_effect( + pub(crate) fn load_side_effect( &self, tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Option<QuerySideEffect> { let side_effect: Option<QuerySideEffect> = - self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index); + self.load_indexed(tcx, dep_node_index, &self.side_effects_index); side_effect } - /// Stores a `QuerySideEffect` emitted during the current compilation session. - /// Anything stored like this will be available via `load_side_effect` in - /// the next compilation session. - pub fn store_side_effect(&self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) { - let mut current_side_effects = self.current_side_effects.borrow_mut(); - let prev = current_side_effects.insert(dep_node_index, side_effect); - debug_assert!(prev.is_none()); - } - - /// Return whether the cached query result can be decoded. + /// Returns true if there is a disk-cached query return value for the given node. #[inline] pub fn loadable_from_disk(&self, dep_node_index: SerializedDepNodeIndex) -> bool { - self.query_result_index.contains_key(&dep_node_index) + self.query_values_index.contains_key(&dep_node_index) // with_decoder is infallible, so we can stop here } - /// Returns the cached query result if there is something in the cache for - /// the given `SerializedDepNodeIndex`; otherwise returns `None`. - pub fn try_load_query_result<'tcx, T>( + /// Returns the disk-cached query return value for the given node, if there is one. + pub fn try_load_query_value<'tcx, T>( &self, tcx: TyCtxt<'tcx>, dep_node_index: SerializedDepNodeIndex, @@ -376,9 +351,7 @@ pub fn try_load_query_result<'tcx, T>( where T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>, { - let opt_value = self.load_indexed(tcx, dep_node_index, &self.query_result_index); - debug_assert_eq!(opt_value.is_some(), self.loadable_from_disk(dep_node_index)); - opt_value + self.load_indexed(tcx, dep_node_index, &self.query_values_index) } fn load_indexed<'tcx, T>( @@ -810,11 +783,14 @@ pub struct CacheEncoder<'a, 'tcx> { type_shorthands: FxHashMap<Ty<'tcx>, usize>, predicate_shorthands: FxHashMap<ty::PredicateKind<'tcx>, usize>, interpret_allocs: FxIndexSet<interpret::AllocId>, - source_map: CachingSourceMapView<'tcx>, + caching_source_map_view: CachingSourceMapView<'tcx>, file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>, hygiene_context: &'a HygieneEncodeContext, // Used for both `Symbol`s and `ByteSymbol`s. symbol_index_table: FxHashMap<u32, usize>, + + query_values_index: Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>, + side_effects_index: Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>, } impl<'a, 'tcx> fmt::Debug for CacheEncoder<'a, 'tcx> { @@ -835,7 +811,7 @@ fn source_file_index(&mut self, source_file: Arc<SourceFile>) -> SourceFileIndex /// encode the specified tag, then the given value, then the number of /// bytes taken up by tag and value. On decoding, we can then verify that /// we get the expected tag and read the expected number of bytes. - pub fn encode_tagged<T: Encodable<Self>, V: Encodable<Self>>(&mut self, tag: T, value: &V) { + fn encode_tagged<T: Encodable<Self>, V: Encodable<Self>>(&mut self, tag: T, value: &V) { let start_pos = self.position(); tag.encode(self); @@ -845,6 +821,20 @@ pub fn encode_tagged<T: Encodable<Self>, V: Encodable<Self>>(&mut self, tag: T, ((end_pos - start_pos) as u64).encode(self); } + pub fn encode_query_value<V: Encodable<Self>>(&mut self, index: DepNodeIndex, value: &V) { + let index = SerializedDepNodeIndex::from_curr_for_serialization(index); + + self.query_values_index.push((index, AbsoluteBytePos::new(self.position()))); + self.encode_tagged(index, value); + } + + fn encode_side_effect(&mut self, index: DepNodeIndex, side_effect: &QuerySideEffect) { + let index = SerializedDepNodeIndex::from_curr_for_serialization(index); + + self.side_effects_index.push((index, AbsoluteBytePos::new(self.position()))); + self.encode_tagged(index, side_effect); + } + // copy&paste impl from rustc_metadata fn encode_symbol_or_byte_symbol( &mut self, @@ -910,7 +900,7 @@ fn encode_span(&mut self, span: Span) { } let Some((file_lo, line_lo, col_lo)) = - self.source_map.byte_pos_to_line_and_col(span_data.lo) + self.caching_source_map_view.byte_pos_to_line_and_col(span_data.lo) else { return TAG_PARTIAL_SPAN.encode(self); };
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index dcf7a95..2e1e614 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -2,18 +2,20 @@ use std::ops::Deref; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::hash_table::HashTable; use rustc_data_structures::sharded::Sharded; -use rustc_data_structures::sync::{AtomicU64, WorkerLocal}; +use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal}; use rustc_errors::Diag; +use rustc_hir::def_id::LocalDefId; use rustc_span::Span; -use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepNodeIndex, QuerySideEffect, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey}; use crate::query::on_disk_cache::OnDiskCache; -use crate::query::{QueryCache, QueryJob, QueryStackFrame}; -use crate::ty::TyCtxt; +use crate::query::{IntoQueryKey, QueryCache, QueryJob, QueryStackFrame}; +use crate::ty::{self, TyCtxt}; /// For a particular query, keeps track of "active" keys, i.e. keys whose /// evaluation has started but has not yet finished successfully. @@ -47,12 +49,12 @@ pub enum ActiveKeyStatus<'tcx> { } #[derive(Debug)] -pub struct CycleError<'tcx> { +pub struct Cycle<'tcx> { /// The query and related span that uses the cycle. pub usage: Option<QueryStackFrame<'tcx>>, /// The span here corresponds to the reason for which this query was required. - pub cycle: Vec<QueryStackFrame<'tcx>>, + pub frames: Vec<QueryStackFrame<'tcx>>, } #[derive(Debug)] @@ -95,7 +97,7 @@ pub struct QueryVTable<'tcx, C: QueryCache> { /// This should be the only code that calls the provider function. pub invoke_provider_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, - pub will_cache_on_disk_for_key_fn: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> bool, + pub will_cache_on_disk_for_key_fn: fn(key: C::Key) -> bool, pub try_load_from_disk_fn: fn( tcx: TyCtxt<'tcx>, @@ -104,9 +106,6 @@ pub struct QueryVTable<'tcx, C: QueryCache> { index: DepNodeIndex, ) -> Option<C::Value>, - pub is_loadable_from_disk_fn: - fn(tcx: TyCtxt<'tcx>, key: C::Key, index: SerializedDepNodeIndex) -> bool, - /// Function pointer that hashes this query's result values. /// /// For `no_hash` queries, this function pointer is None. @@ -114,13 +113,10 @@ pub struct QueryVTable<'tcx, C: QueryCache> { /// Function pointer that handles a cycle error. `error` must be consumed, e.g. with `emit` (if /// it should be emitted) or `delay_as_bug` (if it need not be emitted because an alternative - /// error is created and emitted). - pub value_from_cycle_error: fn( - tcx: TyCtxt<'tcx>, - key: C::Key, - cycle_error: CycleError<'tcx>, - error: Diag<'_>, - ) -> C::Value, + /// error is created and emitted). A value may be returned, or (more commonly) the function may + /// just abort after emitting the error. + pub handle_cycle_error_fn: + fn(tcx: TyCtxt<'tcx>, key: C::Key, cycle: Cycle<'tcx>, error: Diag<'_>) -> C::Value, pub format_value: fn(&C::Value) -> String, @@ -154,6 +150,13 @@ pub struct QuerySystem<'tcx> { pub arenas: WorkerLocal<QueryArenas<'tcx>>, pub query_vtables: QueryVTables<'tcx>, + /// Side-effect associated with each [`DepKind::SideEffect`] node in the + /// current incremental-compilation session. Side effects will be written + /// to disk, and loaded by [`OnDiskCache`] in the next session. + /// + /// Always empty if incremental compilation is off. + pub side_effects: Lock<FxIndexMap<DepNodeIndex, QuerySideEffect>>, + /// This provides access to the incremental compilation on-disk cache for query results. /// Do not access this directly. It is only meant to be used by /// `DepGraph::try_mark_green()` and the query infrastructure. @@ -198,7 +201,21 @@ pub struct TyCtxtEnsureDone<'tcx> { pub tcx: TyCtxt<'tcx>, } +impl<'tcx> TyCtxtEnsureOk<'tcx> { + pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) { + self.typeck_root( + self.tcx.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(), + ) + } +} + impl<'tcx> TyCtxt<'tcx> { + pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) -> &'tcx ty::TypeckResults<'tcx> { + self.typeck_root( + self.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(), + ) + } + /// Returns a transparent wrapper for `TyCtxt` which uses /// `span` as the location of queries performed through it. #[inline(always)]
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 58687be..3802bde 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -103,10 +103,6 @@ pub enum Adjust { Borrow(AutoBorrow), Pointer(PointerCoercion), - - /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. - // FIXME(pin_ergonomics): This can be replaced with a `Deref(Pin)` followed by a `Borrow(Pin)` - ReborrowPin(hir::Mutability), } #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index aade274..d342e4b 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -323,6 +323,13 @@ pub fn is_ct_infer(self) -> bool { matches!(self.kind(), ty::ConstKind::Infer(_)) } + pub fn ct_vid(self) -> Option<ty::ConstVid> { + match self.kind() { + ConstKind::Infer(ty::InferConst::Var(vid)) => Some(vid), + _ => None, + } + } + /// Iterator that walks `self` and any types reachable from /// `self`, in depth-first order. Note that just walks the types /// that appear in `self`, it does not descend into the fields of
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 180ccd9..25ad8a5 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -151,8 +151,8 @@ pub struct ScalarInt { // Cannot derive these, as the derives take references to the fields, and we // can't take references to fields of packed structs. -impl<CTX> crate::ty::HashStable<CTX> for ScalarInt { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut crate::ty::StableHasher) { +impl<Hcx> crate::ty::HashStable<Hcx> for ScalarInt { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut crate::ty::StableHasher) { // Using a block `{self.data}` here to force a copy instead of using `self.data` // directly, because `hash_stable` takes `&self` and would thus borrow `self.data`. // Since `Self` is a packed struct, that would create a possibly unaligned reference,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 58a2edc..a81697c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs
@@ -607,7 +607,7 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> { /// Never return a `Feed` from a query. Only queries that create a `DefId` are /// allowed to feed queries for that `DefId`. -impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {} +impl<KEY: Copy, Hcx> !HashStable<Hcx> for TyCtxtFeed<'_, KEY> {} /// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`. /// Use this to pass around when you have a `TyCtxt` elsewhere. @@ -622,7 +622,7 @@ pub struct Feed<'tcx, KEY: Copy> { /// Never return a `Feed` from a query. Only queries that create a `DefId` are /// allowed to feed queries for that `DefId`. -impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {} +impl<KEY: Copy, Hcx> !HashStable<Hcx> for Feed<'_, KEY> {} impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -899,12 +899,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn has_typeck_results(self, def_id: LocalDefId) -> bool { // Closures' typeck results come from their outermost function, // as they are part of the same "inference environment". - let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id()); - if typeck_root_def_id != def_id.to_def_id() { - return self.has_typeck_results(typeck_root_def_id.expect_local()); - } - - self.hir_node_by_def_id(def_id).body_id().is_some() + let root = self.typeck_root_def_id_local(def_id); + self.hir_node_by_def_id(root).body_id().is_some() } /// Expects a body and returns its codegen attributes.
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 0cf58209..a2bbc1e 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs
@@ -37,7 +37,18 @@ #[repr(C)] pub struct RawList<H, T> { skel: ListSkeleton<H, T>, - opaque: OpaqueListContents, + + // `List`/`RawList` is variable-sized. So we want it to be an unsized + // type because calling `size_of::<List<Foo>>` would be dangerous. + // + // We also want `&List`/`&RawList` to be thin pointers. + // + // A field with an extern type is a hacky way to achieve this. (See + // https://github.com/rust-lang/rust/pull/154399#issuecomment-4157036415 + // for some discussion.) This field is never directly manipulated because + // `RawList` instances are created with manual memory layout in + // `from_arena`. + _extern_ty: ExternTy, } /// A [`RawList`] without the unsized tail. This type is used for layout computation @@ -47,7 +58,8 @@ struct ListSkeleton<H, T> { header: H, len: usize, /// Although this claims to be a zero-length array, in practice `len` - /// elements are actually present. + /// elements are actually present. This is achieved with manual memory + /// layout in `from_arena`. See also the comment on `RawList::_extern_ty`. data: [T; 0], } @@ -58,9 +70,7 @@ fn default() -> Self { } unsafe extern "C" { - /// A dummy type used to force `List` to be unsized while not requiring - /// references to it be wide pointers. - type OpaqueListContents; + type ExternTy; } impl<H, T> RawList<H, T> { @@ -257,14 +267,18 @@ fn into_iter(self) -> Self::IntoIter { unsafe impl<H: Sync, T: Sync> Sync for RawList<H, T> {} -// We need this since `List` uses extern type `OpaqueListContents`. +// We need this because `List` uses the extern type `ExternTy`. unsafe impl<H: DynSync, T: DynSync> DynSync for RawList<H, T> {} // Safety: -// Layouts of `ListSkeleton<H, T>` and `RawList<H, T>` are the same, modulo opaque tail, -// thus aligns of `ListSkeleton<H, T>` and `RawList<H, T>` must be the same. +// Layouts of `ListSkeleton<H, T>` and `RawList<H, T>` are the same, modulo the +// `_extern_ty` field (which is never instantiated in practice). Therefore, +// aligns of `ListSkeleton<H, T>` and `RawList<H, T>` must be the same. unsafe impl<H, T> Aligned for RawList<H, T> { + #[cfg(bootstrap)] const ALIGN: ptr::Alignment = align_of::<ListSkeleton<H, T>>(); + #[cfg(not(bootstrap))] + const ALIGN: mem::Alignment = align_of::<ListSkeleton<H, T>>(); } /// A [`List`] that additionally stores type information inline to speed up @@ -307,3 +321,14 @@ fn from(computation: FlagComputation<TyCtxt<'tcx>>) -> TypeInfo { } } } + +#[cfg(target_pointer_width = "64")] +mod size_asserts { + use rustc_data_structures::static_assert_size; + + use super::*; + // tidy-alphabetical-start + static_assert_size!(&List<u32>, 8); // thin pointer + static_assert_size!(&RawList<u8, u32>, 8); // thin pointer + // tidy-alphabetical-end +}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f072b26..822bbe0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -85,6 +85,7 @@ }; pub use self::fold::*; pub use self::instance::{Instance, InstanceKind, ReifyReason}; +pub(crate) use self::list::RawList; pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::opaque_types::OpaqueTypeKey; pub use self::pattern::{Pattern, PatternKind}; @@ -2172,6 +2173,36 @@ pub fn fn_abi_of_instance( } } +// `HasAttrs` impls: allow `find_attr!(tcx, id, ...)` to work with both DefId-like types and HirId. + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for DefId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + if let Some(did) = self.as_local() { + tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)) + } else { + tcx.attrs_for_def(self) + } + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for LocalDefId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + tcx.hir_attrs(tcx.local_def_id_to_hir_id(self)) + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::OwnerId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + hir::attrs::HasAttrs::get_attrs(self.def_id, tcx) + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::HirId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + tcx.hir_attrs(self) + } +} + pub fn provide(providers: &mut Providers) { closure::provide(providers); context::provide(providers);
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 0fd68e7..20e40dd 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -133,8 +133,15 @@ fn print_coroutine_with_kind( self.print_path_with_generic_args(|p| p.print_def_path(def_id, parent_args), &[kind.into()]) } - // Defaults (should not be overridden): + fn reset_path(&mut self) -> Result<(), PrintError> { + Ok(()) + } + fn should_omit_parent_def_path(&self, _parent_def_id: DefId) -> bool { + false + } + + // Defaults (should not be overridden): #[instrument(skip(self), level = "debug")] fn default_print_def_path( &mut self, @@ -210,9 +217,15 @@ fn default_print_def_path( && self.tcx().generics_of(parent_def_id).parent_count == 0; } + let omit_parent = matches!(key.disambiguated_data.data, DefPathData::TypeNs(..)) + && self.should_omit_parent_def_path(parent_def_id); + self.print_path_with_simple( |p: &mut Self| { - if trait_qualify_parent { + if omit_parent { + p.reset_path()?; + Ok(()) + } else if trait_qualify_parent { let trait_ref = ty::TraitRef::new( p.tcx(), parent_def_id,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2c14c37..4146ee2 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2224,6 +2224,19 @@ fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } + fn reset_path(&mut self) -> Result<(), PrintError> { + self.empty_path = true; + Ok(()) + } + + fn should_omit_parent_def_path(&self, parent_def_id: DefId) -> bool { + RTN_MODE.with(|mode| mode.get()) == RtnMode::ForSuggestion + && matches!( + self.tcx().def_key(parent_def_id).disambiguated_data.data, + DefPathData::ValueNs(..) | DefPathData::Closure | DefPathData::AnonConst + ) + } + fn print_def_path( &mut self, def_id: DefId, @@ -3314,7 +3327,8 @@ macro_rules! define_print_and_forward_display { TraitRefPrintSugared<'tcx> { if !with_reduced_queries() && p.tcx().trait_def(self.0.def_id).paren_sugar - && let ty::Tuple(args) = self.0.args.type_at(1).kind() + && let Some(args_ty) = self.0.args.get(1).and_then(|arg| arg.as_type()) + && let ty::Tuple(args) = args_ty.kind() { write!(p, "{}(", p.tcx().item_name(self.0.def_id))?; for (i, arg) in args.iter().enumerate() {
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index a497501..798b98c 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs
@@ -291,7 +291,7 @@ pub fn type_flags(self) -> TypeFlags { } ty::ReError(_) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_ERROR; + flags = flags | TypeFlags::HAS_RE_ERROR; } }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e7c7d59..d0cbdff 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs
@@ -650,6 +650,20 @@ pub fn typeck_root_def_id(self, def_id: DefId) -> DefId { def_id } + /// Given the `LocalDefId`, returns the `LocalDefId` of the innermost item that + /// has its own type-checking context or "inference environment". + /// + /// For example, a closure has its own `LocalDefId`, but it is type-checked + /// with the containing item. Therefore, when we fetch the `typeck` of the closure, + /// for example, we really wind up fetching the `typeck` of the enclosing fn item. + pub fn typeck_root_def_id_local(self, def_id: LocalDefId) -> LocalDefId { + let mut def_id = def_id; + while self.is_typeck_child(def_id.to_def_id()) { + def_id = self.local_parent(def_id); + } + def_id + } + /// Given the `DefId` and args a closure, creates the type of /// `self` argument that the closure expects. For example, for a /// `Fn` closure, this would return a reference type `&T` where
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index bcac451..01c1e2e 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -491,7 +491,7 @@ fn construct_fn<'tcx>( }; if let Some((dialect, phase)) = - find_attr!(tcx.hir_attrs(fn_id), CustomMir(dialect, phase, _) => (dialect, phase)) + find_attr!(tcx, fn_id, CustomMir(dialect, phase, _) => (dialect, phase)) { return custom::build_custom_mir( tcx,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index c362bad..793d9ef 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1053,17 +1053,115 @@ pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] #[label("constant of non-structural type")] pub(crate) span: Span, - #[label("`{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns")] + #[label( + "{$is_local -> + *[true] `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + [false] `{$ty}` is not usable in patterns + }" + )] pub(crate) ty_def_span: Span, pub(crate) ty: Ty<'tcx>, #[note( - "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" + "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see \ + https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" )] pub(crate) manual_partialeq_impl_span: Option<Span>, #[note( "see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" )] pub(crate) manual_partialeq_impl_note: bool, + #[subdiagnostic] + pub(crate) suggestion: Option<SuggestEq<'tcx>>, + pub(crate) is_local: bool, +} + +#[derive(Subdiagnostic)] +pub(crate) enum SuggestEq<'tcx> { + #[multipart_suggestion( + "{$manual_partialeq_impl -> + [false] if `{$ty}` manually implemented `PartialEq`, you could add + *[true] add + } a condition to the match arm checking for equality", + applicability = "maybe-incorrect", + style = "verbose" + )] + AddIf { + #[suggestion_part(code = "binding")] + pat_span: Span, + #[suggestion_part(code = " if binding == {name}")] + if_span: Span, + name: String, + ty: Ty<'tcx>, + manual_partialeq_impl: bool, + }, + #[multipart_suggestion( + "{$manual_partialeq_impl -> + [false] if `{$ty}` manually implemented `PartialEq`, you could add + *[true] add + } a check for equality to the condition of the match arm", + applicability = "maybe-incorrect", + style = "verbose" + )] + AddToIf { + #[suggestion_part(code = "binding")] + pat_span: Span, + #[suggestion_part(code = " && binding == {name}")] + span: Span, + name: String, + ty: Ty<'tcx>, + manual_partialeq_impl: bool, + }, + #[multipart_suggestion( + "{$manual_partialeq_impl -> + [false] if `{$ty}` manually implemented `PartialEq`, you could check + *[true] check + } for equality instead of pattern matching", + applicability = "maybe-incorrect", + style = "verbose" + )] + AddToLetChain { + #[suggestion_part(code = "binding")] + pat_span: Span, + #[suggestion_part(code = " && binding == {name}")] + span: Span, + name: String, + ty: Ty<'tcx>, + manual_partialeq_impl: bool, + }, + #[multipart_suggestion( + "{$manual_partialeq_impl -> + [false] if `{$ty}` manually implemented `PartialEq`, you could check + *[true] check + } for equality instead of pattern matching", + applicability = "maybe-incorrect", + style = "verbose" + )] + ReplaceWithEq { + #[suggestion_part(code = "")] + removal: Span, + #[suggestion_part(code = " == ")] + eq: Span, + ty: Ty<'tcx>, + manual_partialeq_impl: bool, + }, + #[multipart_suggestion( + "{$manual_partialeq_impl -> + [false] if `{$ty}` manually implemented `PartialEq`, you could check + *[true] check + } for equality instead of pattern matching", + applicability = "maybe-incorrect", + style = "verbose" + )] + ReplaceLetElseWithIf { + #[suggestion_part(code = "if ")] + if_span: Span, + #[suggestion_part(code = " == ")] + eq: Span, + #[suggestion_part(code = " ")] + else_span: Span, + ty: Ty<'tcx>, + manual_partialeq_impl: bool, + }, } #[derive(Diagnostic)]
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index b79bda2..6926079 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -221,68 +221,6 @@ fn apply_adjustment( debug!(?kind); kind } - Adjust::ReborrowPin(mutbl) => { - debug!("apply ReborrowPin adjustment"); - // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` - - // We'll need these types later on - let pin_ty_args = match expr.ty.kind() { - ty::Adt(_, args) => args, - _ => bug!("ReborrowPin with non-Pin type"), - }; - let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty(); - let ptr_target_ty = match pin_ty.kind() { - ty::Ref(_, ty, _) => *ty, - _ => bug!("ReborrowPin with non-Ref type"), - }; - - // pointer = ($expr).__pointer - let pointer_target = ExprKind::Field { - lhs: self.thir.exprs.push(expr), - variant_index: FIRST_VARIANT, - name: FieldIdx::ZERO, - }; - let arg = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target }; - let arg = self.thir.exprs.push(arg); - - // arg = *pointer - let expr = ExprKind::Deref { arg }; - let arg = self.thir.exprs.push(Expr { - temp_scope_id, - ty: ptr_target_ty, - span, - kind: expr, - }); - - // expr = &mut target - let borrow_kind = match mutbl { - hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default }, - hir::Mutability::Not => BorrowKind::Shared, - }; - let new_pin_target = - Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, ptr_target_ty, mutbl); - let expr = self.thir.exprs.push(Expr { - temp_scope_id, - ty: new_pin_target, - span, - kind: ExprKind::Borrow { borrow_kind, arg }, - }); - - // kind = Pin { __pointer: pointer } - let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span); - let args = self.tcx.mk_args(&[new_pin_target.into()]); - let kind = ExprKind::Adt(Box::new(AdtExpr { - adt_def: self.tcx.adt_def(pin_did), - variant_index: FIRST_VARIANT, - args, - fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]), - user_ty: None, - base: AdtExprBase::None, - })); - - debug!(?kind); - kind - } }; Expr { temp_scope_id, ty: adjustment.target, span, kind } @@ -816,8 +754,8 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> } hir::InlineAsmOperand::Const { ref anon_const } => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions( GenericArgs::identity_for_item(tcx, typeck_root_def_id), ); @@ -825,7 +763,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }) .args; - let uneval = mir::UnevaluatedConst::new(did, args); + let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args); let value = mir::Const::Unevaluated(uneval, ty); InlineAsmOperand::Const { value, span: tcx.def_span(did) } } @@ -895,15 +833,15 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item( tcx, typeck_root_def_id, )); let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args; - ExprKind::ConstBlock { did, args } + ExprKind::ConstBlock { did: did.to_def_id(), args } } // Now comes the rote stuff: hir::ExprKind::Repeat(v, _) => { @@ -917,7 +855,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) }, hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) }, hir::ExprKind::Break(dest, ref value) => { - if find_attr!(self.tcx.hir_attrs(expr.hir_id), ConstContinue(_)) { + if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) { match dest.target_id { Ok(target_id) => { let (Some(value), Some(_)) = (value, dest.label) else { @@ -982,7 +920,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> match_source, }, hir::ExprKind::Loop(body, ..) => { - if find_attr!(self.tcx.hir_attrs(expr.hir_id), LoopMatch(_)) { + if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) { let dcx = self.tcx.dcx(); // Accept either `state = expr` or `state = expr;`.
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 7f4b70b..f22ff92 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -104,7 +104,7 @@ fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { typing_env: ty::TypingEnv::non_body_analysis(tcx, def), typeck_results, body_owner: def.to_def_id(), - apply_adjustments: !find_attr!(tcx.hir_attrs(hir_id), CustomMir(..) => ()).is_some(), + apply_adjustments: !find_attr!(tcx, hir_id, CustomMir(..)), } }
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 ff4778d..6307701 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
@@ -22,7 +22,7 @@ use super::PatCtxt; use crate::errors::{ ConstPatternDependsOnGenericParameter, CouldNotEvalConstPattern, InvalidPattern, NaNPattern, - PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern, + PointerPattern, SuggestEq, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern, }; impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> { @@ -224,13 +224,93 @@ fn valtree_to_pat(&self, value: ty::Value<'tcx>) -> Box<Pat<'tcx>> { } _ => (None, true), }; + let manual_partialeq_impl = + manual_partialeq_impl_note || manual_partialeq_impl_span.is_some(); + let is_local = adt_def.did().is_local(); let ty_def_span = tcx.def_span(adt_def.did()); + let suggestion = if let Ok(name) = tcx.sess.source_map().span_to_snippet(self.span) + && (is_local || manual_partialeq_impl) + { + let mut hir_id = self.id; + while let hir::Node::Pat(pat) = tcx.parent_hir_node(hir_id) { + hir_id = pat.hir_id; + } + match tcx.parent_hir_node(hir_id) { + hir::Node::Arm(hir::Arm { pat, guard: None, .. }) => { + // Add an if condition to the match arm. + Some(SuggestEq::AddIf { + if_span: pat.span.shrink_to_hi(), + pat_span: self.span, + name, + ty, + manual_partialeq_impl, + }) + } + hir::Node::Arm(hir::Arm { guard: Some(guard), .. }) => { + // Modify the the match arm if condition and add a check for equality. + Some(SuggestEq::AddToIf { + span: guard.span.shrink_to_hi(), + pat_span: self.span, + name, + ty, + manual_partialeq_impl, + }) + } + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Let(let_expr), + span, + .. + }) => { + if let_expr.pat.span == self.span { + // `if let CONST = expr` -> `if CONST == expr`. + Some(SuggestEq::ReplaceWithEq { + removal: span.until(self.span), + eq: self.span.between(let_expr.init.span), + ty, + manual_partialeq_impl, + }) + } else if tcx.sess.edition().at_least_rust_2024() { + // `if let Some(CONST) = expr` -> + // `if let Some(binding) = expr && binding == CONST`. + Some(SuggestEq::AddToLetChain { + span: span.shrink_to_hi(), + pat_span: self.span, + name, + ty, + manual_partialeq_impl, + }) + } else { + None + } + } + hir::Node::LetStmt(let_stmt) + if let Some(init) = let_stmt.init + && let Some(els) = let_stmt.els + && init.span.ctxt().is_root() + && els.span.ctxt().is_root() => + { + // `let PAT = expr else {` -> `if PAT == expr {`. + Some(SuggestEq::ReplaceLetElseWithIf { + if_span: let_stmt.span.until(let_stmt.pat.span), + eq: let_stmt.pat.span.between(init.span), + else_span: init.span.between(els.span), + ty, + manual_partialeq_impl, + }) + } + _ => None, + } + } else { + None + }; let err = TypeNotStructural { span, ty, ty_def_span, manual_partialeq_impl_span, manual_partialeq_impl_note, + is_local, + suggestion, }; return self.mk_err(tcx.dcx().create_err(err), ty); }
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 89ee963..e04cb26 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -58,7 +58,8 @@ fn is_required(&self) -> bool { } } -/// Utility to help performing substitution of `*pattern` by `target`. +/// Utility to help performing substitution: for all key-value pairs in `copy_classes`, +/// all occurrences of the key get replaced by the value. struct Replacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, unified: DenseBitSet<Local>,
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index daee8de..77dea3a 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -218,11 +218,29 @@ pub(crate) struct UnusedVarAssignedOnly { pub(crate) struct UnusedAssign { pub name: Symbol, #[subdiagnostic] + pub overwrite: Option<UnusedAssignOverwrite>, + #[subdiagnostic] pub suggestion: Option<UnusedAssignSuggestion>, #[help("maybe it is overwritten before being read?")] pub help: bool, } +pub(crate) struct UnusedAssignOverwrite { + pub assigned_span: Span, + pub overwrite_span: Span, + pub name: Symbol, +} + +impl Subdiagnostic for UnusedAssignOverwrite { + fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { + diag.span_label(self.assigned_span, "this value is reassigned later and never used"); + diag.span_label( + self.overwrite_span, + format!("`{}` is overwritten here before the previous value is read", self.name), + ); + } +} + #[derive(Subdiagnostic)] #[multipart_suggestion( "you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding",
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 245ee6e..e9a20aa 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -48,8 +48,15 @@ //! # Handling of references //! //! We handle references by assigning a different "provenance" index to each Ref/RawPtr rvalue. -//! This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we -//! consider all the derefs of an immutable reference to a freeze type to give the same value: +//! This ensure that we do not spuriously merge borrows that should not be merged. For instance: +//! ```ignore (MIR) +//! _x = &_a; +//! _a = 0; +//! _y = &_a; // cannot be turned into `_y = _x`! +//! ``` +//! +//! On top of that, we consider all the derefs of an immutable reference to a freeze type to give +//! the same value: //! ```ignore (MIR) //! _a = *_b // _b is &Freeze //! _c = *_b // replaced by _c = _a
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 89bd91e..2f81235 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -1,4 +1,5 @@ use rustc_abi::{HasDataLayout, Size, TagEncoding, Variants}; +use rustc_const_eval::interpret::{Scalar, alloc_range}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; @@ -23,7 +24,8 @@ /// /// In summary, what this does is at runtime determine which enum variant is active, /// and instead of copying all the bytes of the largest possible variant, -/// copy only the bytes for the currently active variant. +/// copy only the bytes for the currently active variant. The number of bytes to copy is determined +/// by a lookup table: a discriminant-indexed array indicating the size of each variant. pub(super) struct EnumSizeOpt { pub(crate) discrepancy: u64, } @@ -32,8 +34,8 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { fn is_enabled(&self, sess: &Session) -> bool { // There are some differences in behavior on wasm and ARM that are not properly // understood, so we conservatively treat this optimization as unsound: - // https://github.com/rust-lang/rust/pull/85158#issuecomment-1101836457 - sess.opts.unstable_opts.unsound_mir_opts || sess.mir_opt_level() >= 3 + // https://github.com/rust-lang/rust/issues/154413 + sess.opts.unstable_opts.unsound_mir_opts && sess.mir_opt_level() >= 3 } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { @@ -202,45 +204,23 @@ fn candidate<'tcx>( return Some((*adt_def, num_discrs, *alloc_id)); } + // Construct an in-memory array mapping discriminant idx to variant size. let data_layout = tcx.data_layout(); - let ptr_sized_int = data_layout.ptr_sized_integer(); - let target_bytes = ptr_sized_int.size().bytes() as usize; - let mut data = vec![0; target_bytes * num_discrs]; - - // We use a macro because `$bytes` can be u32 or u64. - macro_rules! encode_store { - ($curr_idx: expr, $endian: expr, $bytes: expr) => { - let bytes = match $endian { - rustc_abi::Endian::Little => $bytes.to_le_bytes(), - rustc_abi::Endian::Big => $bytes.to_be_bytes(), - }; - for (i, b) in bytes.into_iter().enumerate() { - data[$curr_idx + i] = b; - } - }; - } - - for (var_idx, layout) in variants.iter_enumerated() { - let curr_idx = - target_bytes * adt_def.discriminant_for_variant(tcx, var_idx).val as usize; - let sz = layout.size; - match ptr_sized_int { - rustc_abi::Integer::I32 => { - encode_store!(curr_idx, data_layout.endian, sz.bytes() as u32); - } - rustc_abi::Integer::I64 => { - encode_store!(curr_idx, data_layout.endian, sz.bytes()); - } - _ => unreachable!(), - }; - } - let alloc = interpret::Allocation::from_bytes( - data, + let ptr_size = data_layout.pointer_size(); + let mut alloc = interpret::Allocation::from_bytes( + vec![0; ptr_size.bytes_usize() * num_discrs], tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, - Mutability::Not, + Mutability::Mut, (), ); + for (var_idx, layout) in variants.iter_enumerated() { + let curr_idx = ptr_size * adt_def.discriminant_for_variant(tcx, var_idx).val as u64; + let val = Scalar::from_target_usize(layout.size.bytes(), &tcx); + alloc.write_scalar(&tcx, alloc_range(curr_idx, val.size()), val).unwrap(); + } + alloc.mutability = Mutability::Not; let alloc = tcx.reserve_and_set_memory_alloc(tcx.mk_const_alloc(alloc)); + Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc))) } }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 094aae4..9273c21 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -526,7 +526,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // We only need to borrowck non-synthetic MIR. let tainted_by_errors = if !tcx.is_synthetic_mir(def) { - tcx.mir_borrowck(tcx.typeck_root_def_id(def.to_def_id()).expect_local()).err() + tcx.mir_borrowck(tcx.typeck_root_def_id_local(def)).err() } else { None }; @@ -554,14 +554,14 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // // We do this check here and not during `mir_promoted` because that may result // in borrowck cycles if WF requires looking into an opaque hidden type. - let root = tcx.typeck_root_def_id(def.to_def_id()); + let root = tcx.typeck_root_def_id_local(def); match tcx.def_kind(root) { DefKind::Fn | DefKind::AssocFn | DefKind::Static { .. } | DefKind::Const { .. } | DefKind::AssocConst { .. } => { - if let Err(guar) = tcx.ensure_result().check_well_formed(root.expect_local()) { + if let Err(guar) = tcx.ensure_result().check_well_formed(root) { body.tainted_by_errors = Some(guar); } } @@ -840,7 +840,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_ } if !tcx.is_synthetic_mir(def) { - tcx.ensure_done().mir_borrowck(tcx.typeck_root_def_id(def.to_def_id()).expect_local()); + tcx.ensure_done().mir_borrowck(tcx.typeck_root_def_id_local(def)); } let mut promoted = tcx.mir_promoted(def).1.steal();
diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index af24673..c3fa88d 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs
@@ -67,7 +67,7 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den } // Don't run unused pass for #[derive] - let parent = tcx.parent(tcx.typeck_root_def_id(def_id.to_def_id())); + let parent = tcx.local_parent(tcx.typeck_root_def_id_local(def_id)); if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent) && find_attr!(tcx, parent, AutomaticallyDerived(..)) { @@ -1094,29 +1094,49 @@ fn report_unused_assignments(self) { self.body, ); - // We probed MIR in reverse order for dataflow. - // We revert the vector to give a consistent order to the user. - for (source_info, Access { live, kind, is_direct }) in statements.into_iter().rev() { + // By convention, underscore-prefixed bindings are allowed to be unused explicitly. + if name.as_str().starts_with('_') { + continue; + } + + let mut next_direct_assign = None; + let mut dead_statements = Vec::with_capacity(statements.len()); + + for (source_info, Access { live, kind, is_direct }) in statements.into_iter() { + let overwrite = match (kind, is_direct, next_direct_assign) { + (AccessKind::Assign, true, Some(overwrite_span)) => { + Some(errors::UnusedAssignOverwrite { + assigned_span: source_info.span, + overwrite_span, + name, + }) + } + _ => None, + }; + + if kind == AccessKind::Assign && is_direct { + next_direct_assign = Some(source_info.span); + } + if live { continue; } - // If this place was dropped and has non-trivial drop, // skip reporting field assignments. if !is_direct && is_maybe_drop_guard { continue; } + dead_statements.push((source_info, kind, is_direct, overwrite)); + } + // We probed MIR in reverse order for dataflow. + // Emit diagnostics in source order instead. + for (source_info, kind, is_direct, overwrite) in dead_statements.into_iter().rev() { // Report the dead assignment. let Some(hir_id) = source_info.scope.lint_root(&self.body.source_scopes) else { continue; }; - // By convention, underscore-prefixed bindings are allowed to be unused explicitly - if name.as_str().starts_with('_') { - break; - } - match kind { AccessKind::Assign => { let suggestion = annotate_mut_binding_to_immutable_binding( @@ -1126,11 +1146,14 @@ fn report_unused_assignments(self) { source_info.span, self.body, ); + let overwrite = + if suggestion.is_none() && is_direct { overwrite } else { None }; + let help = suggestion.is_none() && overwrite.is_none(); tcx.emit_node_span_lint( lint::builtin::UNUSED_ASSIGNMENTS, hir_id, source_info.span, - errors::UnusedAssign { name, help: suggestion.is_none(), suggestion }, + errors::UnusedAssign { name, overwrite, help, suggestion }, ) } AccessKind::Param => tcx.emit_node_span_lint(
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8bd6730..4698e05 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1615,7 +1615,7 @@ fn process_nested_body(&mut self, def_id: LocalDefId) { if (self.strategy == MonoItemCollectionStrategy::Eager || is_pub_fn_coroutine) && !self .tcx - .generics_of(self.tcx.typeck_root_def_id(def_id.to_def_id())) + .generics_of(self.tcx.typeck_root_def_id_local(def_id)) .requires_monomorphization(self.tcx) { let instance = match *self.tcx.type_of(def_id).instantiate_identity().kind() {
diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index e469451..5a0f149 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs
@@ -78,7 +78,7 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner /// We can simply cache based on the ty itself, because we use /// `ty::BoundVarIndexKind::Canonical`. - cache: HashMap<I::Ty, I::Ty>, + cache: HashMap<ty::Ty<I>, ty::Ty<I>>, } impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> { @@ -177,11 +177,7 @@ fn canonicalize_param_env( cache: Default::default(), }; let param_env = param_env.fold_with(&mut env_canonicalizer); - debug_assert!( - env_canonicalizer.sub_root_lookup_table.is_empty(), - "{:?}", - env_canonicalizer.sub_root_lookup_table - ); + debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty()); ( param_env, env_canonicalizer.variables, @@ -320,7 +316,7 @@ fn finalize(self) -> (ty::UniverseIndex, Vec<I::GenericArg>, I::CanonicalVarKind (max_universe, self.variables, var_kinds) } - fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn inner_fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { let kind = match t.kind() { ty::Infer(i) => match i { ty::TyVar(vid) => { @@ -479,7 +475,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region { Region::new_canonical_bound(self.cx(), var) } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { if !t.flags().intersects(NEEDS_CANONICAL) { t } else if let Some(&ty) = self.cache.get(&t) {
diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 1f64f09..cd42bf8 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs
@@ -16,7 +16,7 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::{ - self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, + self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Ty, TypeFoldable, }; use tracing::instrument; @@ -53,7 +53,7 @@ fn var_values(&self) -> CanonicalVarValues<I> { pub(super) fn canonicalize_goal<D, I>( delegate: &D, goal: Goal<I, I::Predicate>, - opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)], + opaque_types: &[(ty::OpaqueTypeKey<I>, Ty<I>)], ) -> (Vec<I::GenericArg>, CanonicalInput<I, I::Predicate>) where D: SolverDelegate<Interner = I>, @@ -264,7 +264,7 @@ fn register_region_constraints<D, I>( fn register_new_opaque_types<D, I>( delegate: &D, - opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)], + opaque_types: &[(ty::OpaqueTypeKey<I>, Ty<I>)], span: I::Span, ) where D: SolverDelegate<Interner = I>,
diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index c370fd2..69cebb0 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs
@@ -47,7 +47,7 @@ pub enum Conflict { pub fn trait_ref_is_knowable<Infcx, I, E>( infcx: &Infcx, trait_ref: ty::TraitRef<I>, - mut lazily_normalize_ty: impl FnMut(I::Ty) -> Result<I::Ty, E>, + mut lazily_normalize_ty: impl FnMut(ty::Ty<I>) -> Result<ty::Ty<I>, E>, ) -> Result<Result<(), Conflict>, E> where Infcx: InferCtxtLike<Interner = I>, @@ -115,14 +115,14 @@ fn from(b: bool) -> IsFirstInputType { #[derive_where(Debug; I: Interner, T: Debug)] pub enum OrphanCheckErr<I: Interner, T> { - NonLocalInputType(Vec<(I::Ty, IsFirstInputType)>), + NonLocalInputType(Vec<(ty::Ty<I>, IsFirstInputType)>), UncoveredTyParams(UncoveredTyParams<I, T>), } #[derive_where(Debug; I: Interner, T: Debug)] pub struct UncoveredTyParams<I: Interner, T> { pub uncovered: T, - pub local_ty: Option<I::Ty>, + pub local_ty: Option<ty::Ty<I>>, } /// Checks whether a trait-ref is potentially implementable by a crate. @@ -222,8 +222,8 @@ pub fn orphan_check_trait_ref<Infcx, I, E: Debug>( infcx: &Infcx, trait_ref: ty::TraitRef<I>, in_crate: InCrate, - lazily_normalize_ty: impl FnMut(I::Ty) -> Result<I::Ty, E>, -) -> Result<Result<(), OrphanCheckErr<I, I::Ty>>, E> + lazily_normalize_ty: impl FnMut(ty::Ty<I>) -> Result<ty::Ty<I>, E>, +) -> Result<Result<(), OrphanCheckErr<I, ty::Ty<I>>>, E> where Infcx: InferCtxtLike<Interner = I>, I: Interner, @@ -262,14 +262,14 @@ struct OrphanChecker<'a, Infcx, I: Interner, F> { lazily_normalize_ty: F, /// Ignore orphan check failures and exclusively search for the first local type. search_first_local_ty: bool, - non_local_tys: Vec<(I::Ty, IsFirstInputType)>, + non_local_tys: Vec<(ty::Ty<I>, IsFirstInputType)>, } impl<'a, Infcx, I, F, E> OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike<Interner = I>, I: Interner, - F: FnOnce(I::Ty) -> Result<I::Ty, E>, + F: FnOnce(ty::Ty<I>) -> Result<ty::Ty<I>, E>, { fn new(infcx: &'a Infcx, in_crate: InCrate, lazily_normalize_ty: F) -> Self { OrphanChecker { @@ -282,12 +282,15 @@ fn new(infcx: &'a Infcx, in_crate: InCrate, lazily_normalize_ty: F) -> Self { } } - fn found_non_local_ty(&mut self, t: I::Ty) -> ControlFlow<OrphanCheckEarlyExit<I, E>> { + fn found_non_local_ty(&mut self, t: ty::Ty<I>) -> ControlFlow<OrphanCheckEarlyExit<I, E>> { self.non_local_tys.push((t, self.in_self_ty.into())); ControlFlow::Continue(()) } - fn found_uncovered_ty_param(&mut self, ty: I::Ty) -> ControlFlow<OrphanCheckEarlyExit<I, E>> { + fn found_uncovered_ty_param( + &mut self, + ty: ty::Ty<I>, + ) -> ControlFlow<OrphanCheckEarlyExit<I, E>> { if self.search_first_local_ty { return ControlFlow::Continue(()); } @@ -305,15 +308,15 @@ fn def_id_is_local(&mut self, def_id: impl DefId<I>) -> bool { enum OrphanCheckEarlyExit<I: Interner, E> { NormalizationFailure(E), - UncoveredTyParam(I::Ty), - LocalTy(I::Ty), + UncoveredTyParam(ty::Ty<I>), + LocalTy(ty::Ty<I>), } impl<'a, Infcx, I, F, E> TypeVisitor<I> for OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike<Interner = I>, I: Interner, - F: FnMut(I::Ty) -> Result<I::Ty, E>, + F: FnMut(ty::Ty<I>) -> Result<ty::Ty<I>, E>, { type Result = ControlFlow<OrphanCheckEarlyExit<I, E>>; @@ -321,7 +324,7 @@ fn visit_region(&mut self, _r: I::Region) -> Self::Result { ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: ty::Ty<I>) -> Self::Result { let ty = self.infcx.shallow_resolve(ty); let ty = match (self.lazily_normalize_ty)(ty) { Ok(norm_ty) if norm_ty.is_ty_var() => ty,
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 9d5aa8b..1714ae3 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -1,7 +1,7 @@ use std::ops::Deref; use rustc_type_ir::solve::{Certainty, Goal, NoSolution}; -use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner, Ty, TypeFoldable}; pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized { type Infcx: InferCtxtLike<Interner = Self::Interner>; @@ -70,7 +70,7 @@ fn add_item_bounds_for_hidden_type( def_id: <Self::Interner as Interner>::DefId, args: <Self::Interner as Interner>::GenericArgs, param_env: <Self::Interner as Interner>::ParamEnv, - hidden_ty: <Self::Interner as Interner>::Ty, + hidden_ty: Ty<Self::Interner>, goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, ); @@ -86,8 +86,8 @@ fn fetch_eligible_assoc_item( fn is_transmutable( &self, - src: <Self::Interner as Interner>::Ty, - dst: <Self::Interner as Interner>::Ty, + src: Ty<Self::Interner>, + dst: Ty<Self::Interner>, assume: <Self::Interner as Interner>::Const, ) -> Result<Certainty, NoSolution>; }
diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index 83f3bdf..fe7521c 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs
@@ -113,7 +113,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region { } } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { match t.kind() { ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) if debruijn.as_usize() + 1
diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index c3c57ec..86bf05b 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs
@@ -1,7 +1,7 @@ use rustc_type_ir::data_structures::DelayedMap; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, + self as ty, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -19,7 +19,7 @@ struct EagerResolver<'a, D, I = <D as SolverDelegate>::Interner> delegate: &'a D, /// We're able to use a cache here as the folder does not have any /// mutable state. - cache: DelayedMap<I::Ty, I::Ty>, + cache: DelayedMap<Ty<I>, Ty<I>>, } pub fn eager_resolve_vars<D: SolverDelegate, T: TypeFoldable<D::Interner>>( @@ -45,7 +45,7 @@ fn cx(&self) -> I { self.delegate.cx() } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: Ty<I>) -> Ty<I> { match t.kind() { ty::Infer(ty::TyVar(vid)) => { let resolved = self.delegate.opportunistic_resolve_ty_var(vid);
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 32b1e93..f58318b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -46,11 +46,11 @@ pub(super) trait GoalKind<D, I = <D as SolverDelegate>::Interner>: D: SolverDelegate<Interner = I>, I: Interner, { - fn self_ty(self) -> I::Ty; + fn self_ty(self) -> ty::Ty<I>; fn trait_ref(self, cx: I) -> ty::TraitRef<I>; - fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self; + fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty<I>) -> Self; fn trait_def_id(self, cx: I) -> I::TraitId; @@ -683,7 +683,7 @@ fn assemble_alias_bound_candidates<G: GoalKind<D>>( // hitting another overflow error something. Add a depth parameter needed later. fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>( &mut self, - self_ty: I::Ty, + self_ty: ty::Ty<I>, goal: Goal<I, G>, candidates: &mut Vec<Candidate<I>>, consider_self_bounds: AliasBoundKind, @@ -1017,13 +1017,13 @@ fn try_assemble_bounds_via_registered_opaques<G: GoalKind<D>>( struct ReplaceOpaque<I: Interner> { cx: I, alias_ty: ty::AliasTy<I>, - self_ty: I::Ty, + self_ty: ty::Ty<I>, } impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> { fn cx(&self) -> I { self.cx } - fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { + fn fold_ty(&mut self, ty: ty::Ty<I>) -> ty::Ty<I> { if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() { if alias_ty == self.alias_ty { return self.self_ty; @@ -1280,7 +1280,7 @@ fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::R ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: ty::Ty<I>) -> Self::Result { let ty = self.ecx.replace_bound_vars(ty, &mut self.universes); let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else { return ControlFlow::Break(Err(NoSolution));
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 456fe52..cbdf0b0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -21,8 +21,8 @@ #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>( ecx: &EvalCtxt<'_, D>, - ty: I::Ty, -) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution> + ty: ty::Ty<I>, +) -> Result<ty::Binder<I, Vec<ty::Ty<I>>>, NoSolution> where D: SolverDelegate<Interner = I>, I: Interner, @@ -108,8 +108,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>( pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait<D, I>( ecx: &EvalCtxt<'_, D>, sizedness: SizedTraitKind, - ty: I::Ty, -) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution> + ty: ty::Ty<I>, +) -> Result<ty::Binder<I, Vec<ty::Ty<I>>>, NoSolution> where D: SolverDelegate<Interner = I>, I: Interner, @@ -186,8 +186,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait<D, I>( #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>( ecx: &EvalCtxt<'_, D>, - ty: I::Ty, -) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution> + ty: ty::Ty<I>, +) -> Result<ty::Binder<I, Vec<ty::Ty<I>>>, NoSolution> where D: SolverDelegate<Interner = I>, I: Interner, @@ -268,9 +268,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>( // Returns a binder of the tupled inputs types and output type from a builtin callable type. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Interner>( cx: I, - self_ty: I::Ty, + self_ty: ty::Ty<I>, goal_kind: ty::ClosureKind, -) -> Result<Option<ty::Binder<I, (I::Ty, I::Ty)>>, NoSolution> { +) -> Result<Option<ty::Binder<I, (ty::Ty<I>, ty::Ty<I>)>>, NoSolution> { match self_ty.kind() { // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. ty::FnDef(def_id, args) => { @@ -408,13 +408,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern #[derive_where(Clone, Copy, Debug; I: Interner)] #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] pub(in crate::solve) struct AsyncCallableRelevantTypes<I: Interner> { - pub tupled_inputs_ty: I::Ty, + pub tupled_inputs_ty: ty::Ty<I>, /// Type returned by calling the closure /// i.e. `f()`. - pub output_coroutine_ty: I::Ty, + pub output_coroutine_ty: ty::Ty<I>, /// Type returned by `await`ing the output /// i.e. `f().await`. - pub coroutine_return_ty: I::Ty, + pub coroutine_return_ty: ty::Ty<I>, } // Returns a binder of the tupled inputs types, output type, and coroutine type @@ -424,7 +424,7 @@ pub(in crate::solve) struct AsyncCallableRelevantTypes<I: Interner> { // know the kind already, we can short-circuit this check. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: Interner>( cx: I, - self_ty: I::Ty, + self_ty: ty::Ty<I>, goal_kind: ty::ClosureKind, env_region: I::Region, ) -> Result<(ty::Binder<I, AsyncCallableRelevantTypes<I>>, Vec<I::Predicate>), NoSolution> { @@ -608,7 +608,7 @@ fn coroutine_closure_to_certain_coroutine<I: Interner>( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs<I>, sig: ty::CoroutineClosureSignature<I>, -) -> I::Ty { +) -> ty::Ty<I> { sig.to_coroutine_given_kind_and_upvars( cx, args.parent_args(), @@ -632,7 +632,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs<I>, sig: ty::CoroutineClosureSignature<I>, -) -> I::Ty { +) -> ty::Ty<I> { let upvars_projection_def_id = cx.require_lang_item(SolverLangItem::AsyncFnKindUpvars); let tupled_upvars_ty = Ty::new_projection( cx, @@ -664,8 +664,8 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>( #[instrument(level = "trace", skip(cx), ret)] pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>( cx: I, - self_ty: I::Ty, -) -> Result<(ty::Binder<I, (I::Ty, I::Ty)>, I::DefId, I::GenericArgs), NoSolution> { + self_ty: ty::Ty<I>, +) -> Result<(ty::Binder<I, (ty::Ty<I>, ty::Ty<I>)>, I::DefId, I::GenericArgs), NoSolution> { match self_ty.kind() { ty::FnDef(def_id, args) => { let sig = cx.fn_sig(def_id); @@ -742,7 +742,7 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>( // the old solver, for as long as that exists. pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>( cx: I, - self_ty: I::Ty, + self_ty: ty::Ty<I>, ) -> Result<Vec<ty::TraitRef<I>>, NoSolution> { let destruct_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Destruct); @@ -797,12 +797,16 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>( | ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) | ty::Error(_) => Ok(vec![]), - // Coroutines and closures could implement `[const] Drop`, + // Closures are [const] Destruct when all of their upvars (captures) are [const] Destruct. + ty::Closure(_, args) => { + let closure_args = args.as_closure(); + Ok(vec![ty::TraitRef::new(cx, destruct_def_id, [closure_args.tupled_upvars_ty()])]) + } + // Coroutines could implement `[const] Drop`, // but they don't really need to right now. - ty::Closure(_, _) - | ty::CoroutineClosure(_, _) - | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) => Err(NoSolution), + ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) | ty::CoroutineWitness(_, _) => { + Err(NoSolution) + } // FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop` // if their inner type implements it. @@ -923,7 +927,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<D, I>( struct ReplaceProjectionWith<'a, 'b, I: Interner, D: SolverDelegate<Interner = I>> { ecx: &'a mut EvalCtxt<'b, D>, param_env: I::ParamEnv, - self_ty: I::Ty, + self_ty: ty::Ty<I>, mapping: &'a HashMap<I::DefId, Vec<ty::Binder<I, ty::ProjectionPredicate<I>>>>, nested: Vec<Goal<I, I::Predicate>>, } @@ -987,12 +991,7 @@ fn try_eagerly_replace_alias( let replacement = self.ecx.instantiate_binder_with_infer(*replacement); self.nested.extend( self.ecx - .relate_and_get_goals( - self.param_env, - alias_term, - ty::Invariant, - replacement.projection_term, - ) + .eq_and_get_goals(self.param_env, alias_term, replacement.projection_term) .expect("expected to be able to unify goal projection with dyn's projection"), ); @@ -1014,7 +1013,7 @@ fn cx(&self) -> I { self.ecx.cx() } - fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> { + fn try_fold_ty(&mut self, ty: ty::Ty<I>) -> Result<ty::Ty<I>, Ambiguous> { if let ty::Alias(ty::Projection, alias_ty) = ty.kind() && let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? {
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 4b1e4b2..9a0a82a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -13,7 +13,7 @@ use crate::delegate::SolverDelegate; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, - QueryResult, assembly, + QueryResult, Ty, assembly, }; impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I> @@ -21,7 +21,7 @@ impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I> D: SolverDelegate<Interner = I>, I: Interner, { - fn self_ty(self) -> I::Ty { + fn self_ty(self) -> Ty<I> { self.self_ty() } @@ -29,7 +29,7 @@ fn trait_ref(self, _: I) -> ty::TraitRef<I> { self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: Ty<I>) -> Self { self.with_replaced_self_ty(cx, self_ty) }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index fedb639..d6ed220 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -10,7 +10,7 @@ use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind}; use rustc_type_ir::solve::OpaqueTypesJank; use rustc_type_ir::{ - self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder, + self as ty, CanonicalVarValues, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; @@ -408,7 +408,7 @@ pub(super) fn ignore_candidate_head_usages(&mut self, usages: CandidateHeadUsage /// Recursively evaluates `goal`, returning whether any inference vars have /// been constrained and the certainty of the result. - pub(super) fn evaluate_goal( + fn evaluate_goal( &mut self, source: GoalSource, goal: Goal<I, I::Predicate>, @@ -781,7 +781,7 @@ pub(super) fn next_region_var(&mut self) -> I::Region { region } - pub(super) fn next_ty_infer(&mut self) -> I::Ty { + pub(super) fn next_ty_infer(&mut self) -> Ty<I> { let ty = self.delegate.next_ty_infer(); self.inspect.add_var_value(ty); ty @@ -829,7 +829,7 @@ struct ContainsTermOrNotNameable<'a, D: SolverDelegate<Interner = I>, I: Interne term: I::Term, universe_of_term: ty::UniverseIndex, delegate: &'a D, - cache: HashSet<I::Ty>, + cache: HashSet<Ty<I>>, } impl<D: SolverDelegate<Interner = I>, I: Interner> ContainsTermOrNotNameable<'_, D, I> { @@ -846,7 +846,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeVisitor<I> for ContainsTermOrNotNameable<'_, D, I> { type Result = ControlFlow<()>; - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + fn visit_ty(&mut self, t: Ty<I>) -> Self::Result { if self.cache.contains(&t) { return ControlFlow::Continue(()); } @@ -1018,8 +1018,7 @@ pub(super) fn relate<T: Relate<I>>( variance: ty::Variance, rhs: T, ) -> Result<(), NoSolution> { - let goals = self.relate_and_get_goals(param_env, lhs, variance, rhs)?; - + let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; for &goal in goals.iter() { let source = match goal.predicate.kind().skip_binder() { ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => { @@ -1040,37 +1039,13 @@ pub(super) fn relate<T: Relate<I>>( /// If possible, try using `eq` instead which automatically handles nested /// goals correctly. #[instrument(level = "trace", skip(self, param_env), ret)] - pub(super) fn relate_and_get_goals<T: Relate<I>>( - &mut self, + pub(super) fn eq_and_get_goals<T: Relate<I>>( + &self, param_env: I::ParamEnv, lhs: T, - variance: ty::Variance, rhs: T, ) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> { - let cx = self.cx(); - let delegate = self.delegate; - let origin_span = self.origin_span; - - let mut normalize = |alias: ty::AliasTy<I>| { - let inference_var = self.next_ty_infer(); - - let goal = Goal::new( - cx, - param_env, - ty::PredicateKind::AliasRelate( - alias.to_ty(cx).into(), - inference_var.into(), - ty::AliasRelationDirection::Equate, - ), - ); - - // Ignore the result. If we can't eagerly normalize, returning the inference variable is enough. - let _ = self.evaluate_goal(GoalSource::TypeRelating, goal, None); - - self.resolve_vars_if_possible(inference_var) - }; - - Ok(delegate.relate(param_env, lhs, variance, rhs, origin_span, &mut normalize)?) + Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs, self.origin_span)?) } pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>( @@ -1097,7 +1072,7 @@ pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T self.delegate.resolve_vars_if_possible(value) } - pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty { + pub(super) fn shallow_resolve(&self, ty: Ty<I>) -> Ty<I> { self.delegate.shallow_resolve(ty) } @@ -1117,7 +1092,7 @@ pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs args } - pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) { + pub(super) fn register_ty_outlives(&self, ty: Ty<I>, lt: I::Region) { self.delegate.register_ty_outlives(ty, lt, self.origin_span); } @@ -1159,8 +1134,8 @@ pub(super) fn fetch_eligible_assoc_item( pub(super) fn register_hidden_type_in_storage( &mut self, opaque_type_key: ty::OpaqueTypeKey<I>, - hidden_ty: I::Ty, - ) -> Option<I::Ty> { + hidden_ty: Ty<I>, + ) -> Option<Ty<I>> { self.delegate.register_hidden_type_in_storage(opaque_type_key, hidden_ty, self.origin_span) } @@ -1169,7 +1144,7 @@ pub(super) fn add_item_bounds_for_hidden_type( opaque_def_id: I::DefId, opaque_args: I::GenericArgs, param_env: I::ParamEnv, - hidden_ty: I::Ty, + hidden_ty: Ty<I>, ) { let mut goals = Vec::new(); self.delegate.add_item_bounds_for_hidden_type( @@ -1195,8 +1170,8 @@ pub(super) fn evaluate_const( pub(super) fn is_transmutable( &mut self, - src: I::Ty, - dst: I::Ty, + src: Ty<I>, + dst: Ty<I>, assume: I::Const, ) -> Result<Certainty, NoSolution> { self.delegate.is_transmutable(dst, src, assume) @@ -1220,7 +1195,7 @@ pub(super) fn may_use_unstable_feature( pub(crate) fn opaques_with_sub_unified_hidden_type( &self, - self_ty: I::Ty, + self_ty: Ty<I>, ) -> Vec<ty::AliasTy<I>> { if let ty::Infer(ty::TyVar(vid)) = self_ty.kind() { self.delegate.opaques_with_sub_unified_hidden_type(vid) @@ -1414,7 +1389,7 @@ struct ReplaceAliasWithInfer<'me, 'a, D, I> ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv, normalization_goal_source: GoalSource, - cache: HashMap<I::Ty, I::Ty>, + cache: HashMap<Ty<I>, Ty<I>>, } impl<'me, 'a, D, I> ReplaceAliasWithInfer<'me, 'a, D, I> @@ -1446,7 +1421,7 @@ fn cx(&self) -> I { self.ecx.cx() } - fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { + fn fold_ty(&mut self, ty: Ty<I>) -> Ty<I> { match ty.kind() { ty::Alias(..) if !ty.has_escaping_bound_vars() => { let infer_ty = self.ecx.next_ty_infer();
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 58bd7cf..71b28cf 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -24,7 +24,7 @@ use derive_where::derive_where; use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode}; +use rustc_type_ir::{self as ty, Interner, Ty, TyVid, TypingMode}; use tracing::instrument; pub use self::eval_ctxt::{ @@ -88,7 +88,7 @@ impl<'a, D, I> EvalCtxt<'a, D> #[instrument(level = "trace", skip(self))] fn compute_type_outlives_goal( &mut self, - goal: Goal<I, ty::OutlivesPredicate<I, I::Ty>>, + goal: Goal<I, ty::OutlivesPredicate<I, Ty<I>>>, ) -> QueryResult<I> { let ty::OutlivesPredicate(ty, lt) = goal.predicate; self.register_ty_outlives(ty, lt); @@ -205,7 +205,7 @@ fn compute_const_evaluatable_goal( #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, - goal: Goal<I, (I::Const, I::Ty)>, + goal: Goal<I, (I::Const, Ty<I>)>, ) -> QueryResult<I> { let (ct, ty) = goal.predicate; let ct = self.structurally_normalize_const(goal.param_env, ct)?; @@ -315,8 +315,8 @@ fn flounder(&mut self, candidates: &[Candidate<I>]) -> QueryResult<I> { fn structurally_normalize_ty( &mut self, param_env: I::ParamEnv, - ty: I::Ty, - ) -> Result<I::Ty, NoSolution> { + ty: Ty<I>, + ) -> Result<Ty<I>, NoSolution> { self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty()) }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 13f2ad8..13ed945 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -125,7 +125,7 @@ impl<D, I> assembly::GoalKind<D> for NormalizesTo<I> D: SolverDelegate<Interner = I>, I: Interner, { - fn self_ty(self) -> I::Ty { + fn self_ty(self) -> ty::Ty<I> { self.self_ty() } @@ -133,7 +133,7 @@ fn trait_ref(self, cx: I) -> ty::TraitRef<I> { self.alias.trait_ref(cx) } - fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty<I>) -> Self { self.with_replaced_self_ty(cx, self_ty) }
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 6589a12..82051b2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -29,7 +29,7 @@ impl<D, I> assembly::GoalKind<D> for TraitPredicate<I> D: SolverDelegate<Interner = I>, I: Interner, { - fn self_ty(self) -> I::Ty { + fn self_ty(self) -> ty::Ty<I> { self.self_ty() } @@ -37,7 +37,7 @@ fn trait_ref(self, _: I) -> ty::TraitRef<I> { self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty<I>) -> Self { self.with_replaced_self_ty(cx, self_ty) } @@ -929,7 +929,7 @@ impl<D, I> EvalCtxt<'_, D> /// ``` fn consider_builtin_dyn_upcast_candidates( &mut self, - goal: Goal<I, (I::Ty, I::Ty)>, + goal: Goal<I, (ty::Ty<I>, ty::Ty<I>)>, a_data: I::BoundExistentialPredicates, a_region: I::Region, b_data: I::BoundExistentialPredicates, @@ -977,7 +977,7 @@ fn consider_builtin_dyn_upcast_candidates( fn consider_builtin_unsize_to_dyn_candidate( &mut self, - goal: Goal<I, (I::Ty, I::Ty)>, + goal: Goal<I, (ty::Ty<I>, ty::Ty<I>)>, b_data: I::BoundExistentialPredicates, b_region: I::Region, ) -> Result<Candidate<I>, NoSolution> { @@ -1018,7 +1018,7 @@ fn consider_builtin_unsize_to_dyn_candidate( fn consider_builtin_upcast_to_principal( &mut self, - goal: Goal<I, (I::Ty, I::Ty)>, + goal: Goal<I, (ty::Ty<I>, ty::Ty<I>)>, source: CandidateSource<I>, a_data: I::BoundExistentialPredicates, a_region: I::Region, @@ -1132,9 +1132,9 @@ fn consider_builtin_upcast_to_principal( /// `#[rustc_deny_explicit_impl]` in this case. fn consider_builtin_array_unsize( &mut self, - goal: Goal<I, (I::Ty, I::Ty)>, - a_elem_ty: I::Ty, - b_elem_ty: I::Ty, + goal: Goal<I, (ty::Ty<I>, ty::Ty<I>)>, + a_elem_ty: ty::Ty<I>, + b_elem_ty: ty::Ty<I>, ) -> Result<Candidate<I>, NoSolution> { self.eq(goal.param_env, a_elem_ty, b_elem_ty)?; self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) @@ -1156,7 +1156,7 @@ fn consider_builtin_array_unsize( /// ``` fn consider_builtin_struct_unsize( &mut self, - goal: Goal<I, (I::Ty, I::Ty)>, + goal: Goal<I, (ty::Ty<I>, ty::Ty<I>)>, def: I::AdtDef, a_args: I::GenericArgs, b_args: I::GenericArgs, @@ -1319,8 +1319,8 @@ fn probe_and_evaluate_goal_for_constituent_tys( goal: Goal<I, TraitPredicate<I>>, constituent_tys: impl Fn( &EvalCtxt<'_, D>, - I::Ty, - ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>, + ty::Ty<I>, + ) -> Result<ty::Binder<I, Vec<ty::Ty<I>>>, NoSolution>, ) -> Result<Candidate<I>, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { let goals = @@ -1542,7 +1542,10 @@ pub(super) fn compute_trait_goal( self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info) } - fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> { + fn try_stall_coroutine( + &mut self, + self_ty: ty::Ty<I>, + ) -> Option<Result<Candidate<I>, NoSolution>> { if let ty::Coroutine(def_id, _) = self_ty.kind() { match self.typing_mode() { TypingMode::Analysis {
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 0e852d2..6faaafc 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs
@@ -4344,7 +4344,7 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { pub(crate) enum HiddenUnicodeCodepointsDiagSub { Escape { spans: Vec<(char, Span)> }, - NoEscape { spans: Vec<(char, Span)> }, + NoEscape { spans: Vec<(char, Span)>, is_doc_comment: bool }, } // Used because of multiple multipart_suggestion and note @@ -4370,7 +4370,7 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { Applicability::MachineApplicable, ); } - HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => { + HiddenUnicodeCodepointsDiagSub::NoEscape { spans, is_doc_comment } => { // FIXME: in other suggestions we've reversed the inner spans of doc comments. We // should do the same here to provide the same good suggestions as we do for // literals above. @@ -4383,7 +4383,11 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { .join(", "), ); diag.note(msg!("if their presence wasn't intentional, you can remove them")); - diag.note(msg!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); + if is_doc_comment { + diag.note(msg!(r#"if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as {$escaped}"#)); + } else { + diag.note(msg!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); + } } } }
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 2223e6a..5766d25 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -546,6 +546,7 @@ fn lint_doc_comment_unicode_text_flow(&mut self, start: BytePos, content: &str) self.mk_sp(start, self.pos), 0, false, + true, "doc comment", ); } @@ -580,6 +581,7 @@ fn lint_literal_unicode_text_flow( span, padding, point_at_inner_spans, + false, label, ); } @@ -590,6 +592,7 @@ fn report_text_direction_codepoint( span: Span, padding: u32, point_at_inner_spans: bool, + is_doc_comment: bool, label: &str, ) { // Obtain the `Span`s for each of the forbidden chars. @@ -610,7 +613,7 @@ fn report_text_direction_codepoint( let sub = if point_at_inner_spans && !spans.is_empty() { errors::HiddenUnicodeCodepointsDiagSub::Escape { spans } } else { - errors::HiddenUnicodeCodepointsDiagSub::NoEscape { spans } + errors::HiddenUnicodeCodepointsDiagSub::NoEscape { spans, is_doc_comment } }; self.psess.buffer_lint(
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7d1a066..c18e8c6 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -15,8 +15,8 @@ use rustc_ast::{ self as ast, AnonConst, Arm, AssignOp, AssignOpKind, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy, ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, - FnRetTy, Label, MacCall, MetaItemLit, MgcaDisambiguation, Movability, Param, RangeLimits, - StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind, YieldKind, + FnRetTy, Guard, Label, MacCall, MetaItemLit, MgcaDisambiguation, Movability, Param, + RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind, YieldKind, }; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic}; @@ -2767,7 +2767,7 @@ pub fn parse_expr_cond( /// Parses a `let $pat = $expr` pseudo-expression. fn parse_expr_let(&mut self, restrictions: Restrictions) -> PResult<'a, Box<Expr>> { - let recovered = if !restrictions.contains(Restrictions::ALLOW_LET) { + let recovered: Recovered = if !restrictions.contains(Restrictions::ALLOW_LET) { let err = errors::ExpectedExpressionFoundLet { span: self.token.span, reason: errors::ForbiddenLetReason::OtherForbidden, @@ -3463,20 +3463,54 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> { }) } - fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<Box<Expr>>> { + pub(crate) fn eat_metavar_guard(&mut self) -> Option<Box<Guard>> { + self.eat_metavar_seq_with_matcher( + |mv_kind| matches!(mv_kind, MetaVarKind::Guard), + |this| this.parse_match_arm_guard(), + ) + .flatten() + } + + fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<Box<Guard>>> { + if let Some(guard) = self.eat_metavar_guard() { + return Ok(Some(guard)); + } + if !self.eat_keyword(exp!(If)) { // No match arm guard present. return Ok(None); } + self.expect_match_arm_guard_cond(ForceCollect::No).map(Some) + } - let mut cond = self.parse_match_guard_condition()?; + pub(crate) fn expect_match_arm_guard( + &mut self, + force_collect: ForceCollect, + ) -> PResult<'a, Box<Guard>> { + if let Some(guard) = self.eat_metavar_guard() { + return Ok(guard); + } + + self.expect_keyword(exp!(If))?; + self.expect_match_arm_guard_cond(force_collect) + } + + fn expect_match_arm_guard_cond( + &mut self, + force_collect: ForceCollect, + ) -> PResult<'a, Box<Guard>> { + let leading_if_span = self.prev_token.span; + + let mut cond = self.parse_match_guard_condition(force_collect)?; + let cond_span = cond.span; CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond); - Ok(Some(cond)) + let guard = Guard { cond: *cond, span_with_leading_if: leading_if_span.to(cond_span) }; + Ok(Box::new(guard)) } - fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Expr>>)> { + fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Guard>>)> { if self.token == token::OpenParen { let left = self.token.span; let pat = self.parse_pat_no_top_guard( @@ -3492,10 +3526,10 @@ fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Expr // FIXME(guard_patterns): convert this to a normal guard instead let span = pat.span; let ast::PatKind::Paren(subpat) = pat.kind else { unreachable!() }; - let ast::PatKind::Guard(_, mut cond) = subpat.kind else { unreachable!() }; - self.psess.gated_spans.ungate_last(sym::guard_patterns, cond.span); + let ast::PatKind::Guard(_, mut guard) = subpat.kind else { unreachable!() }; + self.psess.gated_spans.ungate_last(sym::guard_patterns, guard.span()); let mut checker = CondChecker::new(self, LetChainsPolicy::AlwaysAllowed); - checker.visit_expr(&mut cond); + checker.visit_expr(&mut guard.cond); let right = self.prev_token.span; self.dcx().emit_err(errors::ParenthesesInMatchPat { @@ -3503,14 +3537,10 @@ fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Expr sugg: errors::ParenthesesInMatchPatSugg { left, right }, }); - Ok(( - self.mk_pat(span, ast::PatKind::Wild), - (if let Some(guar) = checker.found_incorrect_let_chain { - Some(self.mk_expr_err(cond.span, guar)) - } else { - Some(cond) - }), - )) + if let Some(guar) = checker.found_incorrect_let_chain { + guard.cond = *self.mk_expr_err(guard.span(), guar); + } + Ok((self.mk_pat(span, ast::PatKind::Wild), Some(guard))) } else { Ok((pat, self.parse_match_arm_guard()?)) } @@ -3526,33 +3556,47 @@ fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Expr } } - fn parse_match_guard_condition(&mut self) -> PResult<'a, Box<Expr>> { + fn parse_match_guard_condition( + &mut self, + force_collect: ForceCollect, + ) -> PResult<'a, Box<Expr>> { let attrs = self.parse_outer_attributes()?; - match self.parse_expr_res(Restrictions::ALLOW_LET | Restrictions::IN_IF_GUARD, attrs) { - Ok((expr, _)) => Ok(expr), - Err(mut err) => { - if self.prev_token == token::OpenBrace { - let sugg_sp = self.prev_token.span.shrink_to_lo(); - // Consume everything within the braces, let's avoid further parse - // errors. - self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); - let msg = "you might have meant to start a match arm after the match guard"; - if self.eat(exp!(CloseBrace)) { - let applicability = if self.token != token::FatArrow { - // We have high confidence that we indeed didn't have a struct - // literal in the match guard, but rather we had some operation - // that ended in a path, immediately followed by a block that was - // meant to be the match arm. - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - err.span_suggestion_verbose(sugg_sp, msg, "=> ", applicability); + let expr = self.collect_tokens( + None, + AttrWrapper::empty(), + force_collect, + |this, _empty_attrs| { + match this + .parse_expr_res(Restrictions::ALLOW_LET | Restrictions::IN_IF_GUARD, attrs) + { + Ok((expr, _)) => Ok((expr, Trailing::No, UsePreAttrPos::No)), + Err(mut err) => { + if this.prev_token == token::OpenBrace { + let sugg_sp = this.prev_token.span.shrink_to_lo(); + // Consume everything within the braces, let's avoid further parse + // errors. + this.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); + let msg = + "you might have meant to start a match arm after the match guard"; + if this.eat(exp!(CloseBrace)) { + let applicability = if this.token != token::FatArrow { + // We have high confidence that we indeed didn't have a struct + // literal in the match guard, but rather we had some operation + // that ended in a path, immediately followed by a block that was + // meant to be the match arm. + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + err.span_suggestion_verbose(sugg_sp, msg, "=> ", applicability); + } + } + Err(err) } } - Err(err) - } - } + }, + )?; + Ok(expr) } pub(crate) fn is_builtin(&self) -> bool {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 36ca8a7..8c1c3c7 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1788,4 +1788,5 @@ pub enum ParseNtResult { Meta(Box<ast::AttrItem>), Path(Box<ast::Path>), Vis(Box<ast::Visibility>), + Guard(Box<ast::Guard>), }
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 706b454..ddf1b10 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -31,7 +31,8 @@ fn may_be_ident(kind: MetaVarKind) -> bool { MetaVarKind::Item | MetaVarKind::Block - | MetaVarKind::Vis => false, + | MetaVarKind::Vis + | MetaVarKind::Guard => false, MetaVarKind::Ident | MetaVarKind::Lifetime @@ -86,7 +87,8 @@ fn may_be_ident(kind: MetaVarKind) -> bool { | MetaVarKind::Ty { .. } | MetaVarKind::Meta { .. } | MetaVarKind::Path - | MetaVarKind::Vis => false, + | MetaVarKind::Vis + | MetaVarKind::Guard => false, MetaVarKind::Lifetime | MetaVarKind::Ident | MetaVarKind::TT => { unreachable!() } @@ -103,6 +105,7 @@ fn may_be_ident(kind: MetaVarKind) -> bool { token::Lifetime(..) | token::NtLifetime(..) => true, _ => false, }, + NonterminalKind::Guard => token.is_keyword(kw::If), NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => { token.kind.close_delim().is_none() } @@ -196,6 +199,9 @@ pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseN })) } } + NonterminalKind::Guard => { + Ok(ParseNtResult::Guard(self.expect_match_arm_guard(ForceCollect::Yes)?)) + } } } }
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 7ee7781..bdcbb1e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -6,8 +6,9 @@ use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ - self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, Mutability, - Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, StmtKind, + self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, Guard, LocalKind, MacCall, + Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, + StmtKind, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey}; @@ -110,11 +111,19 @@ pub fn parse_pat_allow_top_guard( let pat = self.parse_pat_no_top_guard(expected, rc, ra, rt)?; if self.eat_keyword(exp!(If)) { - let cond = self.parse_expr()?; + let guard = if let Some(guard) = self.eat_metavar_guard() { + guard + } else { + let leading_if_span = self.prev_token.span; + let cond = self.parse_expr()?; + let cond_span = cond.span; + Box::new(Guard { cond: *cond, span_with_leading_if: leading_if_span.to(cond_span) }) + }; + // Feature-gate guard patterns - self.psess.gated_spans.gate(sym::guard_patterns, cond.span); - let span = pat.span.to(cond.span); - Ok(self.mk_pat(span, PatKind::Guard(Box::new(pat), cond))) + self.psess.gated_spans.gate(sym::guard_patterns, guard.span()); + let span = pat.span.to(guard.span()); + Ok(self.mk_pat(span, PatKind::Guard(Box::new(pat), guard))) } else { Ok(pat) } @@ -601,17 +610,18 @@ fn maybe_add_suggestions_then_emit( } Some(guard) => { // Are parentheses required around the old guard? - let wrap_guard = guard.precedence() <= ExprPrecedence::LAnd; + let wrap_guard = + guard.cond.precedence() <= ExprPrecedence::LAnd; err.subdiagnostic( UnexpectedExpressionInPatternSugg::UpdateGuard { ident_span, guard_lo: if wrap_guard { - Some(guard.span.shrink_to_lo()) + Some(guard.span().shrink_to_lo()) } else { None }, - guard_hi: guard.span.shrink_to_hi(), + guard_hi: guard.span().shrink_to_hi(), guard_hi_paren: if wrap_guard { ")" } else { "" }, ident, expr, @@ -1739,6 +1749,9 @@ fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> } else { // Parsing a pattern of the form `(box) (ref) (mut) fieldname`. let is_box = self.eat_keyword(exp!(Box)); + if is_box { + self.psess.gated_spans.gate(sym::box_patterns, self.prev_token.span); + } let boxed_span = self.token.span; let mutability = self.parse_mutability(); let by_ref = self.parse_byref();
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a8ca801..6aeb0ae 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey, msg}; +use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, msg}; use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; use rustc_hir::attrs::diagnostic::Directive; use rustc_hir::attrs::{ @@ -45,7 +45,7 @@ }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; -use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; @@ -1188,7 +1188,8 @@ fn check_doc_attrs(&self, attr: &DocAttribute, hir_id: HirId, target: Target) { html_no_source: _, // already checked in attr_parsing issue_tracker_base_url: _, - rust_logo, + // already checked in attr_parsing + rust_logo: _, // allowed anywhere test_attrs: _, // already checked in attr_parsing @@ -1217,18 +1218,6 @@ fn check_doc_attrs(&self, attr: &DocAttribute, hir_id: HirId, target: Target) { self.check_doc_inline(hir_id, target, inline); - if let Some(span) = rust_logo - && !self.tcx.features().rustdoc_internals() - { - feature_err( - &self.tcx.sess, - sym::rustdoc_internals, - *span, - msg!("the `#[doc(rust_logo)]` attribute is used for Rust branding"), - ) - .emit(); - } - if let Some(span) = masked { self.check_doc_masked(*span, hir_id, target); } @@ -1907,27 +1896,6 @@ fn visit_item(&mut self, item: &'tcx Item<'tcx>) { } fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) { - // FIXME(where_clause_attrs): Currently, as the following check shows, - // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed - // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`) - // in where clauses. After that, only `self.check_attributes` should be enough. - let spans = self - .tcx - .hir_attrs(where_predicate.hir_id) - .iter() - // FIXME: We shouldn't need to special-case `doc`! - .filter(|attr| { - matches!( - attr, - Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_)) - | Attribute::Unparsed(_) - ) - }) - .map(|attr| attr.span()) - .collect::<Vec<_>>(); - if !spans.is_empty() { - self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() }); - } self.check_attributes( where_predicate.hir_id, where_predicate.span, @@ -2025,64 +1993,6 @@ fn is_c_like_enum(item: &Item<'_>) -> bool { } } -// FIXME: Fix "Cannot determine resolution" error and remove built-in macros -// from this check. -fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { - // Check for builtin attributes at the crate level - // which were unsuccessfully resolved due to cannot determine - // resolution for the attribute macro error. - const ATTRS_TO_CHECK: &[Symbol] = - &[sym::derive, sym::test, sym::test_case, sym::global_allocator, sym::bench]; - - for attr in attrs { - // FIXME(jdonszelmann): all attrs should be combined here cleaning this up some day. - let (span, name) = if let Some(a) = - ATTRS_TO_CHECK.iter().find(|attr_to_check| attr.has_name(**attr_to_check)) - { - (attr.span(), *a) - } else if let Attribute::Parsed(AttributeKind::Repr { - reprs: _, - first_span: first_attr_span, - }) = attr - { - (*first_attr_span, sym::repr) - } else { - continue; - }; - - let item = tcx - .hir_free_items() - .map(|id| tcx.hir_item(id)) - .find(|item| !item.span.is_dummy()) // Skip prelude `use`s - .map(|item| errors::ItemFollowingInnerAttr { - span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span }, - kind: tcx.def_descr(item.owner_id.to_def_id()), - }); - let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { - span, - sugg_span: tcx - .sess - .source_map() - .span_to_snippet(span) - .ok() - .filter(|src| src.starts_with("#![")) - .map(|_| span.with_lo(span.lo() + BytePos(1)).with_hi(span.lo() + BytePos(2))), - name, - item, - }); - - if let Attribute::Unparsed(p) = attr { - tcx.dcx().try_steal_replace_and_emit_err( - p.path.span, - StashKey::UndeterminedMacroResolution, - err, - ); - } else { - err.emit(); - } - } -} - fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { let attrs = tcx.hir_attrs(item.hir_id()); @@ -2098,7 +2008,6 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { tcx.hir_visit_item_likes_in_module(module_def_id, check_attr_visitor); if module_def_id.to_local_def_id().is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); - check_invalid_crate_level_attr(tcx, tcx.hir_krate_attrs()); } if check_attr_visitor.abort.get() { tcx.dcx().abort_if_errors()
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 15c91de..d5ef9ee 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs
@@ -157,7 +157,7 @@ fn handle_res(&mut self, res: Res) { Res::Def(_, def_id) => self.check_def_id(def_id), Res::SelfTyParam { trait_: t } => self.check_def_id(t), Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i), - Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {} + Res::ToolMod | Res::NonMacroAttr(..) | Res::OpenMod(..) | Res::Err => {} } } @@ -380,8 +380,8 @@ fn mark_live_symbols(&mut self) -> <MarkSymbolVisitor<'tcx> as Visitor<'tcx>>::R /// for discussion). fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool { if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind - && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) - && self.tcx.is_automatically_derived(impl_of) + && let impl_of = self.tcx.local_parent(impl_item.owner_id.def_id) + && self.tcx.is_automatically_derived(impl_of.to_def_id()) && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() && find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads) {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 5e84122..f9dc696 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs
@@ -3,8 +3,7 @@ use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, - MultiSpan, msg, + Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, msg, }; use rustc_hir::Target; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -447,44 +446,6 @@ pub(crate) struct LangItemOnIncorrectTarget { pub actual_target: Target, } -pub(crate) struct InvalidAttrAtCrateLevel { - pub span: Span, - pub sugg_span: Option<Span>, - pub name: Symbol, - pub item: Option<ItemFollowingInnerAttr>, -} - -#[derive(Clone, Copy)] -pub(crate) struct ItemFollowingInnerAttr { - pub span: Span, - pub kind: &'static str, -} - -impl<G: EmissionGuarantee> Diagnostic<'_, G> for InvalidAttrAtCrateLevel { - #[track_caller] - fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = - Diag::new(dcx, level, msg!("`{$name}` attribute cannot be used at crate level")); - diag.span(self.span); - diag.arg("name", self.name); - // Only emit an error with a suggestion if we can create a string out - // of the attribute span - if let Some(span) = self.sugg_span { - diag.span_suggestion_verbose( - span, - msg!("perhaps you meant to use an outer attribute"), - String::new(), - Applicability::MachineApplicable, - ); - } - if let Some(item) = self.item { - diag.arg("kind", item.kind); - diag.span_label(item.span, msg!("the inner attribute doesn't annotate this {$kind}")); - } - diag - } -} - #[derive(Diagnostic)] #[diag("duplicate diagnostic item in crate `{$crate_name}`: `{$name}`")] pub(crate) struct DuplicateDiagnosticItemInCrate { @@ -1190,14 +1151,6 @@ pub(crate) struct RustcConstStableIndirectPairing { } #[derive(Diagnostic)] -#[diag("most attributes are not supported in `where` clauses")] -#[help("only `#[cfg]` and `#[cfg_attr]` are supported")] -pub(crate) struct UnsupportedAttributesInWhere { - #[primary_span] - pub span: MultiSpan, -} - -#[derive(Diagnostic)] pub(crate) enum UnexportableItem<'a> { #[diag("{$descr}'s are not exportable")] Item {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 63860df..663f872 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs
@@ -1595,13 +1595,14 @@ fn check_assoc_item( let mut check = self.check(item.def_id.expect_local(), vis, effective_vis); let is_assoc_ty = item.is_type(); - check.hard_error = is_assoc_ty && !item.is_impl_trait_in_trait(); + check.hard_error = is_assoc_ty; check.generics().predicates(); if assoc_has_type_of(self.tcx, item) { - check.hard_error = check.hard_error && item.defaultness(self.tcx).has_value(); check.ty(); } if is_assoc_ty && item.container == AssocContainer::Trait { + // FIXME: too much breakage from reporting hard errors here, better wait for a fix + // from proper associated type normalization. check.hard_error = false; check.bounds(); }
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 1c3f0f9..02d3b01 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml
@@ -10,7 +10,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } -rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_serialize = { path = "../rustc_serialize" }
diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index 44b92dc..b70fe30 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs
@@ -4,7 +4,7 @@ use rustc_middle::query::QueryCache; use crate::GetQueryVTable; -use crate::plumbing::{force_from_dep_node_inner, promote_from_disk_inner}; +use crate::plumbing::promote_from_disk_inner; /// [`DepKindVTable`] constructors for special dep kinds that aren't queries. #[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")] @@ -111,10 +111,16 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>( DepKindVTable { is_eval_always, key_fingerprint_style, - force_from_dep_node_fn: (can_recover && !is_no_force) - .then_some(force_from_dep_node_inner::<Q>), - promote_from_disk_fn: (can_recover && is_cache_on_disk) - .then_some(promote_from_disk_inner::<Q>), + force_from_dep_node_fn: (can_recover && !is_no_force).then_some( + |tcx, dep_node, _prev_index| { + let query = Q::query_vtable(tcx); + crate::execution::force_query_dep_node(tcx, query, dep_node) + }, + ), + promote_from_disk_fn: (can_recover && is_cache_on_disk).then_some(|tcx, dep_node| { + let query = Q::query_vtable(tcx); + promote_from_disk_inner(tcx, query, dep_node) + }), } }
diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index bbd55e9..44995f3 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs
@@ -8,8 +8,8 @@ use rustc_errors::FatalError; use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex}; use rustc_middle::query::{ - ActiveKeyStatus, CycleError, EnsureMode, QueryCache, QueryJob, QueryJobId, QueryKey, - QueryLatch, QueryMode, QueryState, QueryVTable, + ActiveKeyStatus, Cycle, EnsureMode, QueryCache, QueryJob, QueryJobId, QueryKey, QueryLatch, + QueryMode, QueryState, QueryVTable, }; use rustc_middle::ty::TyCtxt; use rustc_middle::verify_ich::incremental_verify_ich; @@ -17,8 +17,8 @@ use tracing::warn; use crate::dep_graph::{DepNode, DepNodeIndex}; -use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle}; -use crate::plumbing::{current_query_job, next_job_id, start_query}; +use crate::job::{QueryJobInfo, QueryJobMap, create_cycle_error, find_cycle_in_stack}; +use crate::plumbing::{current_query_job, loadable_from_disk, next_job_id, start_query}; use crate::query_impl::for_each_query_vtable; #[inline] @@ -108,14 +108,14 @@ fn collect_active_query_jobs_inner<'tcx, C>( #[cold] #[inline(never)] -fn mk_cycle<'tcx, C: QueryCache>( +fn handle_cycle<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, - cycle_error: CycleError<'tcx>, + cycle: Cycle<'tcx>, ) -> C::Value { - let error = report_cycle(tcx, &cycle_error); - (query.value_from_cycle_error)(tcx, key, cycle_error, error) + let error = create_cycle_error(tcx, &cycle); + (query.handle_cycle_error_fn)(tcx, key, cycle, error) } /// Guard object representing the responsibility to execute a query job and @@ -194,7 +194,7 @@ fn drop(&mut self) { #[cold] #[inline(never)] -fn cycle_error<'tcx, C: QueryCache>( +fn find_and_handle_cycle<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, @@ -205,8 +205,8 @@ fn cycle_error<'tcx, C: QueryCache>( // We need the complete map to ensure we find a cycle to break. let job_map = collect_active_query_jobs(tcx, CollectActiveJobsKind::FullNoContention); - let error = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(), span); - (mk_cycle(query, tcx, key, error), None) + let cycle = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(), span); + (handle_cycle(query, tcx, key, cycle), None) } #[inline(always)] @@ -250,7 +250,7 @@ fn wait_for_query<'tcx, C: QueryCache>( (v, Some(index)) } - Err(cycle) => (mk_cycle(query, tcx, key, cycle), None), + Err(cycle) => (handle_cycle(query, tcx, key, cycle), None), } } @@ -261,9 +261,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( tcx: TyCtxt<'tcx>, span: Span, key: C::Key, - // If present, some previous step has already created a `DepNode` for this - // query+key, which we should reuse instead of creating a new one. - dep_node: Option<DepNode>, + dep_node: Option<DepNode>, // `None` for non-incremental, `Some` for incremental ) -> (C::Value, Option<DepNodeIndex>) { let key_hash = sharded::make_hash(&key); let mut state_lock = query.state.active.lock_shard_by_hash(key_hash); @@ -298,11 +296,9 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( // panic occurs while executing the query (or any intermediate plumbing). let job_guard = ActiveJobGuard { state: &query.state, key, key_hash }; - debug_assert_eq!(tcx.dep_graph.is_fully_enabled(), INCR); - // Delegate to another function to actually execute the query job. let (value, dep_node_index) = if INCR { - execute_job_incr(query, tcx, key, dep_node, id) + execute_job_incr(query, tcx, key, dep_node.unwrap(), id) } else { execute_job_non_incr(query, tcx, key, id) }; @@ -334,7 +330,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( // If we are single-threaded we know that we have cycle error, // so we just return the error. - cycle_error(query, tcx, key, id, span) + find_and_handle_cycle(query, tcx, key, id, span) } } ActiveKeyStatus::Poisoned => FatalError.raise(), @@ -418,27 +414,23 @@ fn execute_job_incr<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, - mut dep_node_opt: Option<DepNode>, + dep_node: DepNode, job_id: QueryJobId, ) -> (C::Value, DepNodeIndex) { let dep_graph_data = tcx.dep_graph.data().expect("should always be present in incremental mode"); if !query.eval_always { - // `to_dep_node` is expensive for some `DepKind`s. - let dep_node = - dep_node_opt.get_or_insert_with(|| DepNode::construct(tcx, query.dep_kind, &key)); - // The diagnostics for this query will be promoted to the current session during // `try_mark_green()`, so we can ignore them here. if let Some(ret) = start_query(job_id, false, || try { - let (prev_index, dep_node_index) = dep_graph_data.try_mark_green(tcx, dep_node)?; + let (prev_index, dep_node_index) = dep_graph_data.try_mark_green(tcx, &dep_node)?; let value = load_from_disk_or_invoke_provider_green( tcx, dep_graph_data, query, key, - dep_node, + &dep_node, prev_index, dep_node_index, ); @@ -451,10 +443,6 @@ fn execute_job_incr<'tcx, C: QueryCache>( let prof_timer = tcx.prof.query_provider(); let (result, dep_node_index) = start_query(job_id, query.depth_limit, || { - // `to_dep_node` is expensive for some `DepKind`s. - let dep_node = - dep_node_opt.unwrap_or_else(|| DepNode::construct(tcx, query.dep_kind, &key)); - // Call the query provider. dep_graph_data.with_task( dep_node, @@ -488,94 +476,62 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>( debug_assert!(dep_graph_data.is_index_green(prev_index)); - // First we try to load the result from the on-disk cache. - // Some things are never cached on disk. - if let Some(value) = (query.try_load_from_disk_fn)(tcx, key, prev_index, dep_node_index) { - if std::intrinsics::unlikely(tcx.sess.opts.unstable_opts.query_dep_graph) { - dep_graph_data.mark_debug_loaded_from_disk(*dep_node) - } + // First try to load the result from the on-disk cache. Some things are never cached on disk. + let value; + let verify; + match (query.try_load_from_disk_fn)(tcx, key, prev_index, dep_node_index) { + Some(loaded_value) => { + if std::intrinsics::unlikely(tcx.sess.opts.unstable_opts.query_dep_graph) { + dep_graph_data.mark_debug_loaded_from_disk(*dep_node) + } - let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_index); - // If `-Zincremental-verify-ich` is specified, re-hash results from - // the cache and make sure that they have the expected fingerprint. + value = loaded_value; + + let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_index); + // If `-Zincremental-verify-ich` is specified, re-hash results from + // the cache and make sure that they have the expected fingerprint. + // + // If not, we still seek to verify a subset of fingerprints loaded + // from disk. Re-hashing results is fairly expensive, so we can't + // currently afford to verify every hash. This subset should still + // give us some coverage of potential bugs. + verify = prev_fingerprint.split().1.as_u64().is_multiple_of(32) + || tcx.sess.opts.unstable_opts.incremental_verify_ich; + } + None => { + // We could not load a result from the on-disk cache, so recompute. The dep-graph for + // this computation is already in-place, so we can just call the query provider. + let prof_timer = tcx.prof.query_provider(); + value = tcx.dep_graph.with_ignore(|| (query.invoke_provider_fn)(tcx, key)); + prof_timer.finish_with_query_invocation_id(dep_node_index.into()); + + verify = true; + } + }; + + if verify { + // Verify that re-running the query produced a result with the expected hash. + // This catches bugs in query implementations, turning them into ICEs. + // For example, a query might sort its result by `DefId` - since `DefId`s are + // not stable across compilation sessions, the result could get up getting sorted + // in a different order when the query is re-run, even though all of the inputs + // (e.g. `DefPathHash` values) were green. // - // If not, we still seek to verify a subset of fingerprints loaded - // from disk. Re-hashing results is fairly expensive, so we can't - // currently afford to verify every hash. This subset should still - // give us some coverage of potential bugs though. - let try_verify = prev_fingerprint.split().1.as_u64().is_multiple_of(32); - if std::intrinsics::unlikely( - try_verify || tcx.sess.opts.unstable_opts.incremental_verify_ich, - ) { - incremental_verify_ich( - tcx, - dep_graph_data, - &value, - prev_index, - query.hash_value_fn, - query.format_value, - ); - } - - return value; + // See issue #82920 for an example of a miscompilation that would get turned into + // an ICE by this check + incremental_verify_ich( + tcx, + dep_graph_data, + &value, + prev_index, + query.hash_value_fn, + query.format_value, + ); } - // We always expect to find a cached result for things that - // can be forced from `DepNode`. - debug_assert!( - !(query.will_cache_on_disk_for_key_fn)(tcx, key) - || !tcx.key_fingerprint_style(dep_node.kind).is_maybe_recoverable(), - "missing on-disk cache entry for {dep_node:?}" - ); - - // Sanity check for the logic in `ensure`: if the node is green and the result loadable, - // we should actually be able to load it. - debug_assert!( - !(query.is_loadable_from_disk_fn)(tcx, key, prev_index), - "missing on-disk cache entry for loadable {dep_node:?}" - ); - - // We could not load a result from the on-disk cache, so - // recompute. - let prof_timer = tcx.prof.query_provider(); - - // The dep-graph for this computation is already in-place. - // Call the query provider. - let value = tcx.dep_graph.with_ignore(|| (query.invoke_provider_fn)(tcx, key)); - - prof_timer.finish_with_query_invocation_id(dep_node_index.into()); - - // Verify that re-running the query produced a result with the expected hash - // This catches bugs in query implementations, turning them into ICEs. - // For example, a query might sort its result by `DefId` - since `DefId`s are - // not stable across compilation sessions, the result could get up getting sorted - // in a different order when the query is re-run, even though all of the inputs - // (e.g. `DefPathHash` values) were green. - // - // See issue #82920 for an example of a miscompilation that would get turned into - // an ICE by this check - incremental_verify_ich( - tcx, - dep_graph_data, - &value, - prev_index, - query.hash_value_fn, - query.format_value, - ); - value } -/// Return value struct for [`check_if_ensure_can_skip_execution`]. -struct EnsureCanSkip { - /// If true, the current `tcx.ensure_ok()` or `tcx.ensure_done()` query - /// can return early without actually trying to execute. - skip_execution: bool, - /// A dep node that was prepared while checking whether execution can be - /// skipped, to be reused by execution itself if _not_ skipped. - dep_node: Option<DepNode>, -} - /// Checks whether a `tcx.ensure_ok()` or `tcx.ensure_done()` query call can /// return early without actually trying to execute. /// @@ -583,20 +539,19 @@ struct EnsureCanSkip { /// on having the dependency graph (and in some cases a disk-cached value) /// from the previous incr-comp session. #[inline(never)] -fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>( +fn ensure_can_skip_execution<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, + dep_node: DepNode, ensure_mode: EnsureMode, -) -> EnsureCanSkip { +) -> bool { // Queries with `eval_always` should never skip execution. if query.eval_always { - return EnsureCanSkip { skip_execution: false, dep_node: None }; + return false; } - let dep_node = DepNode::construct(tcx, query.dep_kind, &key); - - let serialized_dep_node_index = match tcx.dep_graph.try_mark_green(tcx, &dep_node) { + match tcx.dep_graph.try_mark_green(tcx, &dep_node) { None => { // A None return from `try_mark_green` means that this is either // a new dep node or that the dep node has already been marked red. @@ -604,28 +559,27 @@ fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>( // DepNodeIndex. We must invoke the query itself. The performance cost // this introduces should be negligible as we'll immediately hit the // in-memory cache, or another query down the line will. - return EnsureCanSkip { skip_execution: false, dep_node: Some(dep_node) }; + false } Some((serialized_dep_node_index, dep_node_index)) => { tcx.dep_graph.read_index(dep_node_index); tcx.prof.query_cache_hit(dep_node_index.into()); - serialized_dep_node_index - } - }; + match ensure_mode { + // In ensure-ok mode, we can skip execution for this key if the + // node is green. It must have succeeded in the previous + // session, and therefore would succeed in the current session + // if executed. + EnsureMode::Ok => true, - match ensure_mode { - EnsureMode::Ok => { - // In ensure-ok mode, we can skip execution for this key if the node - // is green. It must have succeeded in the previous session, and - // therefore would succeed in the current session if executed. - EnsureCanSkip { skip_execution: true, dep_node: None } - } - EnsureMode::Done => { - // In ensure-done mode, we can only skip execution for this key if - // there's a disk-cached value available to load later if needed, - // which guarantees the query provider will never run for this key. - let is_loadable = (query.is_loadable_from_disk_fn)(tcx, key, serialized_dep_node_index); - EnsureCanSkip { skip_execution: is_loadable, dep_node: Some(dep_node) } + // In ensure-done mode, we can only skip execution for this key + // if there's a disk-cached value available to load later if + // needed, which guarantees the query provider will never run + // for this key. + EnsureMode::Done => { + (query.will_cache_on_disk_for_key_fn)(key) + && loadable_from_disk(tcx, serialized_dep_node_index) + } + } } } } @@ -639,8 +593,6 @@ pub(super) fn execute_query_non_incr_inner<'tcx, C: QueryCache>( span: Span, key: C::Key, ) -> C::Value { - debug_assert!(!tcx.dep_graph.is_fully_enabled()); - ensure_sufficient_stack(|| try_execute_query::<C, false>(query, tcx, span, key, None).0) } @@ -654,46 +606,44 @@ pub(super) fn execute_query_incr_inner<'tcx, C: QueryCache>( key: C::Key, mode: QueryMode, ) -> Option<C::Value> { - debug_assert!(tcx.dep_graph.is_fully_enabled()); + let dep_node = DepNode::construct(tcx, query.dep_kind, &key); // Check if query execution can be skipped, for `ensure_ok` or `ensure_done`. - // This might have the side-effect of creating a suitable DepNode, which - // we should reuse for execution instead of creating a new one. - let dep_node: Option<DepNode> = match mode { - QueryMode::Ensure { ensure_mode } => { - let EnsureCanSkip { skip_execution, dep_node } = - check_if_ensure_can_skip_execution(query, tcx, key, ensure_mode); - if skip_execution { - // Return early to skip execution. - return None; - } - dep_node - } - QueryMode::Get => None, - }; + if let QueryMode::Ensure { ensure_mode } = mode + && ensure_can_skip_execution(query, tcx, key, dep_node, ensure_mode) + { + return None; + } - let (result, dep_node_index) = - ensure_sufficient_stack(|| try_execute_query::<C, true>(query, tcx, span, key, dep_node)); + let (result, dep_node_index) = ensure_sufficient_stack(|| { + try_execute_query::<C, true>(query, tcx, span, key, Some(dep_node)) + }); if let Some(dep_node_index) = dep_node_index { tcx.dep_graph.read_index(dep_node_index) } Some(result) } -pub(crate) fn force_query<'tcx, C: QueryCache>( - query: &'tcx QueryVTable<'tcx, C>, +/// Inner implementation of [`DepKindVTable::force_from_dep_node_fn`][force_fn] +/// for query nodes. +/// +/// [force_fn]: rustc_middle::dep_graph::DepKindVTable::force_from_dep_node_fn +pub(crate) fn force_query_dep_node<'tcx, C: QueryCache>( tcx: TyCtxt<'tcx>, - key: C::Key, + query: &'tcx QueryVTable<'tcx, C>, dep_node: DepNode, -) { - // We may be concurrently trying both execute and force a query. - // Ensure that only one of them runs the query. - if let Some((_, index)) = query.cache.lookup(&key) { - tcx.prof.query_cache_hit(index.into()); - return; - } +) -> bool { + let Some(key) = C::Key::try_recover_key(tcx, &dep_node) else { + // We couldn't recover a key from the node's key fingerprint. + // Tell the caller that we couldn't force the node. + return false; + }; ensure_sufficient_stack(|| { try_execute_query::<C, true>(query, tcx, DUMMY_SP, key, Some(dep_node)) }); + + // We did manage to recover a key and force the node, though it's up to + // the caller to check whether the node ended up marked red or green. + true }
diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/handle_cycle_error.rs similarity index 92% rename from compiler/rustc_query_impl/src/from_cycle_error.rs rename to compiler/rustc_query_impl/src/handle_cycle_error.rs index 0c6082e..5676669 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/handle_cycle_error.rs
@@ -10,33 +10,33 @@ use rustc_hir::def::{DefKind, Res}; use rustc_middle::bug; use rustc_middle::queries::{QueryVTables, TaggedQueryKey}; -use rustc_middle::query::CycleError; +use rustc_middle::query::Cycle; use rustc_middle::query::erase::erase_val; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; -use crate::job::report_cycle; +use crate::job::create_cycle_error; pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) { - vtables.fn_sig.value_from_cycle_error = |tcx, key, _, err| { + vtables.fn_sig.handle_cycle_error_fn = |tcx, key, _, err| { let guar = err.delay_as_bug(); erase_val(fn_sig(tcx, key, guar)) }; - vtables.check_representability.value_from_cycle_error = + vtables.check_representability.handle_cycle_error_fn = |tcx, _, cycle, _err| check_representability(tcx, cycle); - vtables.check_representability_adt_ty.value_from_cycle_error = + vtables.check_representability_adt_ty.handle_cycle_error_fn = |tcx, _, cycle, _err| check_representability(tcx, cycle); - vtables.variances_of.value_from_cycle_error = |tcx, key, _, err| { + vtables.variances_of.handle_cycle_error_fn = |tcx, key, _, err| { let _guar = err.delay_as_bug(); erase_val(variances_of(tcx, key)) }; - vtables.layout_of.value_from_cycle_error = |tcx, _, cycle, err| { + vtables.layout_of.handle_cycle_error_fn = |tcx, _, cycle, err| { let _guar = err.delay_as_bug(); erase_val(Err(layout_of(tcx, cycle))) } @@ -72,10 +72,10 @@ fn fn_sig<'tcx>( ))) } -fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx>) -> ! { +fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> ! { let mut item_and_field_ids = Vec::new(); let mut representable_ids = FxHashSet::default(); - for frame in &cycle_error.cycle { + for frame in &cycle.frames { if let TaggedQueryKey::check_representability(def_id) = frame.tagged_key && tcx.def_kind(def_id) == DefKind::Field { @@ -88,7 +88,7 @@ fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx> item_and_field_ids.push((item_id.expect_local(), field_id)); } } - for frame in &cycle_error.cycle { + for frame in &cycle.frames { if let TaggedQueryKey::check_representability_adt_ty(key) = frame.tagged_key && let Some(adt) = key.ty_adt_def() && let Some(def_id) = adt.did().as_local() @@ -127,14 +127,11 @@ fn search_for_cycle_permutation<Q, T>( otherwise() } -fn layout_of<'tcx>( - tcx: TyCtxt<'tcx>, - cycle_error: CycleError<'tcx>, -) -> &'tcx ty::layout::LayoutError<'tcx> { +fn layout_of<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> &'tcx ty::layout::LayoutError<'tcx> { let diag = search_for_cycle_permutation( - &cycle_error.cycle, - |cycle| { - if let TaggedQueryKey::layout_of(key) = cycle[0].tagged_key + &cycle.frames, + |frames| { + if let TaggedQueryKey::layout_of(key) = frames[0].tagged_key && let ty::Coroutine(def_id, _) = key.value.kind() && let Some(def_id) = def_id.as_local() && let def_kind = tcx.def_kind(def_id) @@ -158,7 +155,7 @@ fn layout_of<'tcx>( tcx.def_kind_descr_article(def_kind, def_id.to_def_id()), tcx.def_kind_descr(def_kind, def_id.to_def_id()), ); - for (i, frame) in cycle.iter().enumerate() { + for (i, frame) in frames.iter().enumerate() { let TaggedQueryKey::layout_of(frame_key) = frame.tagged_key else { continue; }; @@ -169,7 +166,7 @@ fn layout_of<'tcx>( continue; }; let frame_span = - frame.tagged_key.default_span(tcx, cycle[(i + 1) % cycle.len()].span); + frame.tagged_key.default_span(tcx, frames[(i + 1) % frames.len()].span); if frame_span.is_dummy() { continue; } @@ -203,7 +200,7 @@ fn layout_of<'tcx>( ControlFlow::Continue(()) } }, - || report_cycle(tcx, &cycle_error), + || create_cycle_error(tcx, &cycle), ); let guar = diag.emit();
diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index 213fc79..a27a6f4 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs
@@ -7,9 +7,7 @@ use rustc_errors::{Diag, DiagCtxtHandle}; use rustc_hir::def::DefKind; use rustc_middle::queries::TaggedQueryKey; -use rustc_middle::query::{ - CycleError, QueryJob, QueryJobId, QueryLatch, QueryStackFrame, QueryWaiter, -}; +use rustc_middle::query::{Cycle, QueryJob, QueryJobId, QueryLatch, QueryStackFrame, QueryWaiter}; use rustc_middle::ty::TyCtxt; use rustc_span::{DUMMY_SP, Span}; @@ -58,29 +56,28 @@ pub(crate) fn find_cycle_in_stack<'tcx>( job_map: QueryJobMap<'tcx>, current_job: &Option<QueryJobId>, span: Span, -) -> CycleError<'tcx> { - // Find the waitee amongst `current_job` parents - let mut cycle = Vec::new(); +) -> Cycle<'tcx> { + // Find the waitee amongst `current_job` parents. + let mut frames = Vec::new(); let mut current_job = Option::clone(current_job); while let Some(job) = current_job { let info = &job_map.map[&job]; - cycle.push(QueryStackFrame { span: info.job.span, tagged_key: info.tagged_key }); + frames.push(QueryStackFrame { span: info.job.span, tagged_key: info.tagged_key }); if job == id { - cycle.reverse(); + frames.reverse(); - // This is the end of the cycle - // The span entry we included was for the usage - // of the cycle itself, and not part of the cycle - // Replace it with the span which caused the cycle to form - cycle[0].span = span; - // Find out why the cycle itself was used + // This is the end of the cycle. The span entry we included was for + // the usage of the cycle itself, and not part of the cycle. + // Replace it with the span which caused the cycle to form. + frames[0].span = span; + // Find out why the cycle itself was used. let usage = try { let parent = info.job.parent?; QueryStackFrame { span: info.job.span, tagged_key: job_map.tagged_key_of(parent) } }; - return CycleError { usage, cycle }; + return Cycle { usage, frames }; } current_job = info.job.parent; @@ -319,9 +316,9 @@ struct EntryPoint { .map(|(span, job)| QueryStackFrame { span, tagged_key: job_map.tagged_key_of(job) }); // Create the cycle error - let error = CycleError { + let error = Cycle { usage, - cycle: stack + frames: stack .iter() .map(|&(span, job)| QueryStackFrame { span, @@ -454,27 +451,27 @@ pub fn print_query_stack<'tcx>( #[inline(never)] #[cold] -pub(crate) fn report_cycle<'tcx>( +pub(crate) fn create_cycle_error<'tcx>( tcx: TyCtxt<'tcx>, - CycleError { usage, cycle: stack }: &CycleError<'tcx>, + Cycle { usage, frames }: &Cycle<'tcx>, ) -> Diag<'tcx> { - assert!(!stack.is_empty()); + assert!(!frames.is_empty()); - let span = stack[0].tagged_key.default_span(tcx, stack[1 % stack.len()].span); + let span = frames[0].tagged_key.default_span(tcx, frames[1 % frames.len()].span); let mut cycle_stack = Vec::new(); use crate::error::StackCount; - let stack_bottom = stack[0].tagged_key.description(tcx); - let stack_count = if stack.len() == 1 { + let stack_bottom = frames[0].tagged_key.description(tcx); + let stack_count = if frames.len() == 1 { StackCount::Single { stack_bottom: stack_bottom.clone() } } else { StackCount::Multiple { stack_bottom: stack_bottom.clone() } }; - for i in 1..stack.len() { - let frame = &stack[i]; - let span = frame.tagged_key.default_span(tcx, stack[(i + 1) % stack.len()].span); + for i in 1..frames.len() { + let frame = &frames[i]; + let span = frame.tagged_key.default_span(tcx, frames[(i + 1) % frames.len()].span); cycle_stack .push(crate::error::CycleStack { span, desc: frame.tagged_key.description(tcx) }); } @@ -484,12 +481,12 @@ pub(crate) fn report_cycle<'tcx>( usage: usage.tagged_key.description(tcx), }); - let alias = if stack + let alias = if frames .iter() .all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TyAlias)) { Some(crate::error::Alias::Ty) - } else if stack.iter().all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) + } else if frames.iter().all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) { Some(crate::error::Alias::Trait) } else {
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 2f69082..de03b48 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs
@@ -22,7 +22,7 @@ mod dep_kind_vtables; mod error; mod execution; -mod from_cycle_error; +mod handle_cycle_error; mod job; mod plumbing; mod profiling_support; @@ -49,10 +49,11 @@ pub fn query_system<'tcx>( incremental: bool, ) -> QuerySystem<'tcx> { let mut query_vtables = query_impl::make_query_vtables(incremental); - from_cycle_error::specialize_query_vtables(&mut query_vtables); + handle_cycle_error::specialize_query_vtables(&mut query_vtables); QuerySystem { arenas: Default::default(), query_vtables, + side_effects: Default::default(), on_disk_cache, local_providers, extern_providers,
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b8aa125..dfc66a2 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -2,28 +2,24 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir::limit::Limit; -use rustc_index::Idx; use rustc_middle::bug; #[expect(unused_imports, reason = "used by doc comments")] use rustc_middle::dep_graph::DepKindVTable; -use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeIndex, DepNodeKey, SerializedDepNodeIndex}; +use rustc_middle::dep_graph::{DepNode, DepNodeIndex, DepNodeKey, SerializedDepNodeIndex}; use rustc_middle::query::erase::{Erasable, Erased}; -use rustc_middle::query::on_disk_cache::{ - AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex, -}; +use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder}; use rustc_middle::query::{QueryCache, QueryJobId, QueryMode, QueryVTable, erase}; use rustc_middle::ty::TyCtxt; -use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::DUMMY_SP; use rustc_span::def_id::LOCAL_CRATE; use crate::error::{QueryOverflow, QueryOverflowNote}; -use crate::execution::{all_inactive, force_query}; +use crate::execution::all_inactive; use crate::job::find_dep_kind_root; use crate::query_impl::for_each_query_vtable; -use crate::{CollectActiveJobsKind, GetQueryVTable, collect_active_query_jobs}; +use crate::{CollectActiveJobsKind, collect_active_query_jobs}; fn depth_limit_error<'tcx>(tcx: TyCtxt<'tcx>, job: QueryJobId) { let job_map = collect_active_query_jobs(tcx, CollectActiveJobsKind::Full); @@ -79,13 +75,9 @@ pub(crate) fn start_query<R>( }) } -pub(crate) fn encode_query_values<'tcx>( - tcx: TyCtxt<'tcx>, - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, -) { +pub(crate) fn encode_query_values<'tcx>(tcx: TyCtxt<'tcx>, encoder: &mut CacheEncoder<'_, 'tcx>) { for_each_query_vtable!(CACHE_ON_DISK, tcx, |query| { - encode_query_values_inner(tcx, query, encoder, query_result_index) + encode_query_values_inner(tcx, query, encoder) }); } @@ -93,7 +85,6 @@ fn encode_query_values_inner<'a, 'tcx, C, V>( tcx: TyCtxt<'tcx>, query: &'tcx QueryVTable<'tcx, C>, encoder: &mut CacheEncoder<'a, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, ) where C: QueryCache<Value = Erased<V>>, V: Erasable + Encodable<CacheEncoder<'a, 'tcx>>, @@ -102,15 +93,8 @@ fn encode_query_values_inner<'a, 'tcx, C, V>( assert!(all_inactive(&query.state)); query.cache.for_each(&mut |key, value, dep_node| { - if (query.will_cache_on_disk_for_key_fn)(tcx, *key) { - let dep_node = SerializedDepNodeIndex::new(dep_node.index()); - - // Record position of the cache entry. - query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position()))); - - // Encode the type check tables with the `SerializedDepNodeIndex` - // as tag. - encoder.encode_tagged(dep_node, &erase::restore_val::<V>(*value)); + if (query.will_cache_on_disk_for_key_fn)(*key) { + encoder.encode_query_value::<V>(dep_node, &erase::restore_val::<V>(*value)); } }); } @@ -151,15 +135,15 @@ fn verify_query_key_hashes_inner<'tcx, C: QueryCache>( }); } -/// Implementation of [`DepKindVTable::promote_from_disk_fn`] for queries. -pub(crate) fn promote_from_disk_inner<'tcx, Q: GetQueryVTable<'tcx>>( +/// Inner implementation of [`DepKindVTable::promote_from_disk_fn`] for queries. +pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>( tcx: TyCtxt<'tcx>, + query: &'tcx QueryVTable<'tcx, C>, dep_node: DepNode, ) { - let query = Q::query_vtable(tcx); debug_assert!(tcx.dep_graph.is_green(&dep_node)); - let key = <Q::Cache as QueryCache>::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| { + let key = C::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| { panic!( "Failed to recover key for {dep_node:?} with key fingerprint {}", dep_node.key_fingerprint @@ -168,7 +152,7 @@ pub(crate) fn promote_from_disk_inner<'tcx, Q: GetQueryVTable<'tcx>>( // If the recovered key isn't eligible for cache-on-disk, then there's no // value on disk to promote. - if !(query.will_cache_on_disk_for_key_fn)(tcx, key) { + if !(query.will_cache_on_disk_for_key_fn)(key) { return; } @@ -214,44 +198,9 @@ pub(crate) fn try_load_from_disk<'tcx, V>( // details. let value = tcx .dep_graph - .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index)); + .with_query_deserialization(|| on_disk_cache.try_load_query_value(tcx, prev_index)); prof_timer.finish_with_query_invocation_id(index.into()); value } - -/// Implementation of [`DepKindVTable::force_from_dep_node_fn`] for queries. -pub(crate) fn force_from_dep_node_inner<'tcx, Q: GetQueryVTable<'tcx>>( - tcx: TyCtxt<'tcx>, - dep_node: DepNode, - // Needed by the vtable function signature, but not used when forcing queries. - _prev_index: SerializedDepNodeIndex, -) -> bool { - let query = Q::query_vtable(tcx); - - // We must avoid ever having to call `force_from_dep_node()` for a - // `DepNode::codegen_unit`: - // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we - // would always end up having to evaluate the first caller of the - // `codegen_unit` query that *is* reconstructible. This might very well be - // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just - // to re-trigger calling the `codegen_unit` query with the right key. At - // that point we would already have re-done all the work we are trying to - // avoid doing in the first place. - // The solution is simple: Just explicitly call the `codegen_unit` query for - // each CGU, right after partitioning. This way `try_mark_green` will always - // hit the cache instead of having to go through `force_from_dep_node`. - // This assertion makes sure, we actually keep applying the solution above. - debug_assert!( - dep_node.kind != DepKind::codegen_unit, - "calling force_from_dep_node() on dep_kinds::codegen_unit" - ); - - if let Some(key) = <Q::Cache as QueryCache>::Key::try_recover_key(tcx, &dep_node) { - force_query(query, tcx, key, dep_node); - true - } else { - false - } -}
diff --git a/compiler/rustc_query_impl/src/query_impl.rs b/compiler/rustc_query_impl/src/query_impl.rs index 56b7534..2d3dae0 100644 --- a/compiler/rustc_query_impl/src/query_impl.rs +++ b/compiler/rustc_query_impl/src/query_impl.rs
@@ -125,6 +125,20 @@ pub(crate) fn __rust_begin_short_backtrace<'tcx>( } } + fn will_cache_on_disk_for_key<'tcx>( + _key: rustc_middle::queries::$name::Key<'tcx>, + ) -> bool { + cfg_select! { + // If a query has both `cache_on_disk` and `separate_provide_extern`, only + // disk-cache values for "local" keys, i.e. things in the current crate. + all($cache_on_disk, $separate_provide_extern) => { + AsLocalQueryKey::as_local_key(&_key).is_some() + } + all($cache_on_disk, not($separate_provide_extern)) => true, + not($cache_on_disk) => false, + } + } + pub(crate) fn make_query_vtable<'tcx>(incremental: bool) -> QueryVTable<'tcx, rustc_middle::queries::$name::Cache<'tcx>> { @@ -141,18 +155,15 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool) invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace, - #[cfg($cache_on_disk)] will_cache_on_disk_for_key_fn: - rustc_middle::queries::_cache_on_disk_if_fns::$name, - #[cfg(not($cache_on_disk))] - will_cache_on_disk_for_key_fn: |_, _| false, + $crate::query_impl::$name::will_cache_on_disk_for_key, #[cfg($cache_on_disk)] try_load_from_disk_fn: |tcx, key, prev_index, index| { use rustc_middle::queries::$name::{ProvidedValue, provided_to_erased}; - // Check the `cache_on_disk_if` condition for this key. - if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { + // Check the cache-on-disk condition for this key. + if !$crate::query_impl::$name::will_cache_on_disk_for_key(key) { return None; } @@ -165,19 +176,11 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool) #[cfg(not($cache_on_disk))] try_load_from_disk_fn: |_tcx, _key, _prev_index, _index| None, - #[cfg($cache_on_disk)] - is_loadable_from_disk_fn: |tcx, key, index| -> bool { - rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) && - $crate::plumbing::loadable_from_disk(tcx, index) - }, - #[cfg(not($cache_on_disk))] - is_loadable_from_disk_fn: |_tcx, _key, _index| false, - // The default just emits `err` and then aborts. - // `from_cycle_error::specialize_query_vtables` overwrites this default for - // certain queries. - value_from_cycle_error: |_tcx, _key, _cycle, err| { - $crate::from_cycle_error::default(err) + // `handle_cycle_error::specialize_query_vtables` overwrites this default + // for certain queries. + handle_cycle_error_fn: |_tcx, _key, _cycle, err| { + $crate::handle_cycle_error::default(err) }, #[cfg($no_hash)]
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d9d42cf..29b5cdb2c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -357,6 +357,7 @@ fn build_reduced_graph_for_external_crate_res( | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::SelfCtor(..) + | Res::OpenMod(..) | Res::Err => bug!("unexpected resolution: {:?}", res), } }
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 45fdea8..8e150b7 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -36,7 +36,7 @@ use rustc_span::{DUMMY_SP, Ident, Span, kw}; use crate::imports::{Import, ImportKind}; -use crate::{DeclKind, IdentKey, LateDecl, Resolver, module_to_string}; +use crate::{DeclKind, IdentKey, LateDecl, Resolver, errors, module_to_string}; struct UnusedImport { use_tree: ast::UseTree, @@ -554,7 +554,7 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) { UNUSED_QUALIFICATIONS, unn_qua.node_id, unn_qua.path_span, - BuiltinLintDiag::UnusedQualifications { removal_span: unn_qua.removal_span }, + errors::UnusedQualifications { removal_span: unn_qua.removal_span }, ); }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f114682..97c88064 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1740,8 +1740,8 @@ pub(crate) fn unresolved_macro_suggestions( Res::Def(DefKind::Macro(kinds), _) => { format!("{} {}", kinds.article(), kinds.descr()) } - Res::ToolMod => { - // Don't confuse the user with tool modules. + Res::ToolMod | Res::OpenMod(..) => { + // Don't confuse the user with tool modules or open modules. continue; } Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => { @@ -1978,7 +1978,8 @@ fn decl_description(&self, b: Decl<'_>, ident: Ident, scope: Scope<'_>) -> Strin let (built_in, from) = match scope { Scope::StdLibPrelude | Scope::MacroUsePrelude => ("", " from prelude"), Scope::ExternPreludeFlags - if self.tcx.sess.opts.externs.get(ident.as_str()).is_some() => + if self.tcx.sess.opts.externs.get(ident.as_str()).is_some() + || matches!(res, Res::OpenMod(..)) => { ("", " passed with `--extern`") }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 4bbb7d8..9684d3a 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs
@@ -1592,3 +1592,108 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { diag } } + +#[derive(Diagnostic)] +#[diag("lifetime parameter `{$ident}` never used")] +pub(crate) struct UnusedLifetime { + #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] + pub deletion_span: Option<Span>, + + pub ident: Ident, +} + +#[derive(Diagnostic)] +#[diag("ambiguous glob re-exports")] +pub(crate) struct AmbiguousGlobReexports { + #[label("the name `{$name}` in the {$namespace} namespace is first re-exported here")] + pub first_reexport: Span, + #[label("but the name `{$name}` in the {$namespace} namespace is also re-exported here")] + pub duplicate_reexport: Span, + + pub name: String, + pub namespace: String, +} + +#[derive(Diagnostic)] +#[diag("private item shadows public glob re-export")] +pub(crate) struct HiddenGlobReexports { + #[note( + "the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here" + )] + pub glob_reexport: Span, + #[note("but the private item here shadows it")] + pub private_item: Span, + + pub name: String, + pub namespace: String, +} + +#[derive(Diagnostic)] +#[diag("the item `{$ident}` is imported redundantly")] +pub(crate) struct RedundantImport { + #[subdiagnostic] + pub subs: Vec<RedundantImportSub>, + pub ident: Ident, +} + +#[derive(Subdiagnostic)] +pub(crate) enum RedundantImportSub { + #[label("the item `{$ident}` is already imported here")] + ImportedHere { + #[primary_span] + span: Span, + ident: Ident, + }, + #[label("the item `{$ident}` is already defined here")] + DefinedHere { + #[primary_span] + span: Span, + ident: Ident, + }, + #[label("the item `{$ident}` is already imported by the extern prelude")] + ImportedPrelude { + #[primary_span] + span: Span, + ident: Ident, + }, + #[label("the item `{$ident}` is already defined by the extern prelude")] + DefinedPrelude { + #[primary_span] + span: Span, + ident: Ident, + }, +} + +#[derive(Diagnostic)] +#[diag("unnecessary qualification")] +pub(crate) struct UnusedQualifications { + #[suggestion( + "remove the unnecessary path segments", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] + pub removal_span: Span, +} + +#[derive(Diagnostic)] +#[diag( + "{$elided -> + [true] `&` without an explicit lifetime name cannot be used here + *[false] `'_` cannot be used here + }" +)] +pub(crate) struct AssociatedConstElidedLifetime { + #[suggestion( + "use the `'static` lifetime", + style = "verbose", + code = "{code}", + applicability = "machine-applicable" + )] + pub span: Span, + + pub code: &'static str, + pub elided: bool, + #[note("cannot automatically infer `'static` because of other lifetimes in scope")] + pub lifetimes_in_scope: MultiSpan, +}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7cfd5b5..0690181 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs
@@ -26,7 +26,7 @@ AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize, IdentKey, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, - Segment, Stage, Used, errors, + Segment, Stage, Symbol, Used, errors, }; #[derive(Copy, Clone)] @@ -386,7 +386,6 @@ pub(crate) fn resolve_ident_in_lexical_scope( } /// Resolve an identifier in the specified set of scopes. - #[instrument(level = "debug", skip(self))] pub(crate) fn resolve_ident_in_scope_set<'r>( self: CmResolver<'r, 'ra, 'tcx>, orig_ident: Ident, @@ -639,6 +638,13 @@ fn resolve_ident_in_scope<'r>( Err(ControlFlow::Break(..)) => return decl, } } + Scope::ModuleGlobs(module, _) + if let ModuleKind::Def(_, def_id, _) = module.kind + && !def_id.is_local() => + { + // Fast path: external module decoding only creates non-glob declarations. + Err(Determined) + } Scope::ModuleGlobs(module, derive_fallback_lint_id) => { let (adjusted_parent_scope, adjusted_finalize) = if matches!( scope_set, @@ -976,6 +982,14 @@ pub(crate) fn resolve_ident_in_module<'r>( ignore_import, ) } + ModuleOrUniformRoot::OpenModule(sym) => { + let open_ns_name = format!("{}::{}", sym.as_str(), ident.name); + let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(&open_ns_name)); + match self.extern_prelude_get_flag(ns_ident, ident.span, finalize.is_some()) { + Some(decl) => Ok(decl), + None => Err(Determinacy::Determined), + } + } ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set( ident, ScopeSet::ModuleAndExternPrelude(ns, module), @@ -1366,7 +1380,7 @@ fn single_import_can_define_name<'r>( &single_import.parent_scope, None, ignore_decl, - ignore_import, + None, ) { Err(Determined) => continue, Ok(binding) @@ -1962,7 +1976,10 @@ fn record_segment_res<'r, 'ra, 'tcx>( } let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res); - if let Some(def_id) = binding.res().module_like_def_id() { + if let Res::OpenMod(sym) = binding.res() { + module = Some(ModuleOrUniformRoot::OpenModule(sym)); + record_segment_res(self.reborrow(), finalize, res, id); + } else if let Some(def_id) = binding.res().module_like_def_id() { if self.mods_with_parse_errors.contains(&def_id) { module_had_parse_errors = true; }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7696b4b..6507ee3 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs
@@ -6,13 +6,12 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::codes::*; -use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; +use rustc_errors::{Applicability, Diagnostic, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir::def::{self, DefKind, PartialRes}; use rustc_hir::def_id::{DefId, LocalDefIdMap}; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty::Visibility; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, @@ -26,9 +25,10 @@ use crate::Namespace::{self, *}; use crate::diagnostics::{DiagMode, Suggestion, import_candidates}; use crate::errors::{ - CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, - CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, - ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate, + self, CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, + CannotBeReexportedPrivate, CannotBeReexportedPrivateNS, CannotDetermineImportResolution, + CannotGlobImportAllCrates, ConsiderAddingMacroExport, ConsiderMarkingAsPub, + ConsiderMarkingAsPubCrate, }; use crate::ref_mut::CmCell; use crate::{ @@ -41,7 +41,7 @@ /// A potential import declaration in the process of being planted into a module. /// Also used for lazily planting names from `--extern` flags to extern prelude. -#[derive(Clone, Copy, Default, PartialEq)] +#[derive(Clone, Copy, Default, PartialEq, Debug)] pub(crate) enum PendingDecl<'ra> { Ready(Option<Decl<'ra>>), #[default] @@ -721,11 +721,11 @@ pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<Decl<'ra AMBIGUOUS_GLOB_REEXPORTS, import.root_id, import.root_span, - BuiltinLintDiag::AmbiguousGlobReexports { + errors::AmbiguousGlobReexports { name: key.ident.name.to_string(), namespace: key.ns.descr().to_string(), - first_reexport_span: import.root_span, - duplicate_reexport_span: amb_binding.span, + first_reexport: import.root_span, + duplicate_reexport: amb_binding.span, }, ); } @@ -753,11 +753,11 @@ pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<Decl<'ra HIDDEN_GLOB_REEXPORTS, binding_id, binding.span, - BuiltinLintDiag::HiddenGlobReexports { + errors::HiddenGlobReexports { name: key.ident.name.to_string(), namespace: key.ns.descr().to_owned(), - glob_reexport_span: glob_decl.span, - private_item_span: binding.span, + glob_reexport: glob_decl.span, + private_item: binding.span, }, ); } @@ -1535,11 +1535,31 @@ pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> boo let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); redundant_spans.sort(); redundant_spans.dedup(); - self.lint_buffer.buffer_lint( + self.lint_buffer.dyn_buffer_lint( REDUNDANT_IMPORTS, id, import.span, - BuiltinLintDiag::RedundantImport(redundant_spans, source), + move |dcx, level| { + let ident = source; + let subs = redundant_spans + .into_iter() + .map(|(span, is_imported)| match (span.is_dummy(), is_imported) { + (false, true) => { + errors::RedundantImportSub::ImportedHere { span, ident } + } + (false, false) => { + errors::RedundantImportSub::DefinedHere { span, ident } + } + (true, true) => { + errors::RedundantImportSub::ImportedPrelude { span, ident } + } + (true, false) => { + errors::RedundantImportSub::DefinedPrelude { span, ident } + } + }) + .collect(); + errors::RedundantImport { subs, ident }.into_diag(dcx, level) + }, ); return true; }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index a484a51..b3a6fe9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs
@@ -1882,13 +1882,21 @@ fn resolve_anonymous_lifetime( ); return; } else if emit_lint { + let lt_span = if elided { + lifetime.ident.span.shrink_to_hi() + } else { + lifetime.ident.span + }; + let code = if elided { "'static " } else { "'static" }; + self.r.lint_buffer.buffer_lint( lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, node_id, lifetime.ident.span, - lint::BuiltinLintDiag::AssociatedConstElidedLifetime { + crate::errors::AssociatedConstElidedLifetime { elided, - span: lifetime.ident.span, + code, + span: lt_span, lifetimes_in_scope: lifetimes_in_scope.into(), }, ); @@ -4065,7 +4073,7 @@ fn check_consistent_bindings(&mut self, pat: &'ast Pat) { fn resolve_arm(&mut self, arm: &'ast Arm) { self.with_rib(ValueNS, RibKind::Normal, |this| { this.resolve_pattern_top(&arm.pat, PatternSource::Match); - visit_opt!(this, visit_expr, &arm.guard); + visit_opt!(this, visit_expr, arm.guard.as_ref().map(|g| &g.cond)); visit_opt!(this, visit_expr, &arm.body); }); } @@ -4207,7 +4215,7 @@ fn resolve_pattern_inner( let subpat_bindings = bindings.pop().unwrap().1; self.with_rib(ValueNS, RibKind::Normal, |this| { *this.innermost_rib_bindings(ValueNS) = subpat_bindings.clone(); - this.resolve_expr(guard, None); + this.resolve_expr(&guard.cond, None); }); // Propagate the subpattern's bindings upwards. // FIXME(guard_patterns): For `if let` guards, we'll also need to get the
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a8ca4fa..cf04823 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -3381,7 +3381,7 @@ pub(crate) fn detect_and_suggest_const_parameter_error( && def_id.is_local() && let Some(local_def_id) = def_id.as_local() && let Some(struct_generics) = self.r.struct_generics.get(&local_def_id) - && let target_param = &struct_generics.params[idx] + && let Some(target_param) = &struct_generics.params.get(idx) && let GenericParamKind::Const { ty, .. } = &target_param.kind && let TyKind::Path(_, path) = &ty.kind { @@ -3653,7 +3653,8 @@ pub(crate) fn maybe_report_lifetime_uses( param.ident.span, lint::BuiltinLintDiag::SingleUseLifetime { param_span: param.ident.span, - use_span: Some((use_span, elidable)), + use_span, + elidable, deletion_span, ident: param.ident, }, @@ -3669,12 +3670,7 @@ pub(crate) fn maybe_report_lifetime_uses( lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, - lint::BuiltinLintDiag::SingleUseLifetime { - param_span: param.ident.span, - use_span: None, - deletion_span, - ident: param.ident, - }, + errors::UnusedLifetime { deletion_span, ident: param.ident }, ); } }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 27d4182..72d5cdc 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs
@@ -61,6 +61,7 @@ use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; +use rustc_middle::bug; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; @@ -445,6 +446,11 @@ enum ModuleOrUniformRoot<'ra> { /// Used only for resolving single-segment imports. The reason it exists is that import paths /// are always split into two parts, the first of which should be some kind of module. CurrentScope, + + /// Virtual module for the resolution of base names of namespaced crates, + /// where the base name doesn't correspond to a module in the extern prelude. + /// E.g. `my_api::utils` is in the prelude, but `my_api` is not. + OpenModule(Symbol), } #[derive(Debug)] @@ -541,6 +547,13 @@ fn name(&self) -> Option<Symbol> { ModuleKind::Def(.., name) => name, } } + + fn opt_def_id(&self) -> Option<DefId> { + match self { + ModuleKind::Def(_, def_id, _) => Some(*def_id), + _ => None, + } + } } /// Combination of a symbol and its macros 2.0 normalized hygiene context. @@ -778,10 +791,7 @@ fn def_id(self) -> DefId { } fn opt_def_id(self) -> Option<DefId> { - match self.kind { - ModuleKind::Def(_, def_id, _) => Some(def_id), - _ => None, - } + self.kind.opt_def_id() } // `self` resolves to the first module ancestor that `is_normal`. @@ -1105,13 +1115,20 @@ fn determined(&self) -> bool { } } +#[derive(Debug)] struct ExternPreludeEntry<'ra> { /// Name declaration from an `extern crate` item. /// The boolean flag is true is `item_decl` is non-redundant, happens either when /// `flag_decl` is `None`, or when `extern crate` introducing `item_decl` used renaming. item_decl: Option<(Decl<'ra>, Span, /* introduced by item */ bool)>, /// Name declaration from an `--extern` flag, lazily populated on first use. - flag_decl: Option<CacheCell<(PendingDecl<'ra>, /* finalized */ bool)>>, + flag_decl: Option< + CacheCell<( + PendingDecl<'ra>, + /* finalized */ bool, + /* open flag (namespaced crate) */ bool, + )>, + >, } impl ExternPreludeEntry<'_> { @@ -1122,7 +1139,14 @@ fn introduced_by_item(&self) -> bool { fn flag() -> Self { ExternPreludeEntry { item_decl: None, - flag_decl: Some(CacheCell::new((PendingDecl::Pending, false))), + flag_decl: Some(CacheCell::new((PendingDecl::Pending, false, false))), + } + } + + fn open_flag() -> Self { + ExternPreludeEntry { + item_decl: None, + flag_decl: Some(CacheCell::new((PendingDecl::Pending, false, true))), } } @@ -1430,14 +1454,19 @@ fn new_module( &'ra self, parent: Option<Module<'ra>>, kind: ModuleKind, + vis: Visibility<DefId>, expn_id: ExpnId, span: Span, no_implicit_prelude: bool, ) -> Module<'ra> { let self_decl = match kind { - ModuleKind::Def(def_kind, def_id, _) => { - Some(self.new_pub_def_decl(Res::Def(def_kind, def_id), span, LocalExpnId::ROOT)) - } + ModuleKind::Def(def_kind, def_id, _) => Some(self.new_def_decl( + Res::Def(def_kind, def_id), + vis, + span, + LocalExpnId::ROOT, + None, + )), ModuleKind::Block => None, }; Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( @@ -1619,6 +1648,7 @@ pub fn new( let graph_root = arenas.new_module( None, ModuleKind::Def(DefKind::Mod, root_def_id, None), + Visibility::Public, ExpnId::root(), crate_span, attr::contains_name(attrs, sym::no_implicit_prelude), @@ -1628,6 +1658,7 @@ pub fn new( let empty_module = arenas.new_module( None, ModuleKind::Def(DefKind::Mod, root_def_id, None), + Visibility::Public, ExpnId::root(), DUMMY_SP, true, @@ -1643,35 +1674,7 @@ pub fn new( let mut invocation_parents = FxHashMap::default(); invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT); - let mut extern_prelude: FxIndexMap<_, _> = tcx - .sess - .opts - .externs - .iter() - .filter_map(|(name, entry)| { - // Make sure `self`, `super`, `_` etc do not get into extern prelude. - // FIXME: reject `--extern self` and similar in option parsing instead. - if entry.add_prelude - && let name = Symbol::intern(name) - && name.can_be_raw() - { - let ident = IdentKey::with_root_ctxt(name); - Some((ident, ExternPreludeEntry::flag())) - } else { - None - } - }) - .collect(); - - if !attr::contains_name(attrs, sym::no_core) { - let ident = IdentKey::with_root_ctxt(sym::core); - extern_prelude.insert(ident, ExternPreludeEntry::flag()); - if !attr::contains_name(attrs, sym::no_std) { - let ident = IdentKey::with_root_ctxt(sym::std); - extern_prelude.insert(ident, ExternPreludeEntry::flag()); - } - } - + let extern_prelude = build_extern_prelude(tcx, attrs); let registered_tools = tcx.registered_tools(()); let edition = tcx.sess.edition(); @@ -1757,7 +1760,9 @@ fn new_local_module( span: Span, no_implicit_prelude: bool, ) -> Module<'ra> { - let module = self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude); + let vis = + kind.opt_def_id().map_or(Visibility::Public, |def_id| self.tcx.visibility(def_id)); + let module = self.arenas.new_module(parent, kind, vis, expn_id, span, no_implicit_prelude); self.local_modules.push(module); if let Some(def_id) = module.opt_def_id() { self.local_module_map.insert(def_id.expect_local(), module); @@ -1773,7 +1778,9 @@ fn new_extern_module( span: Span, no_implicit_prelude: bool, ) -> Module<'ra> { - let module = self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude); + let vis = + kind.opt_def_id().map_or(Visibility::Public, |def_id| self.tcx.visibility(def_id)); + let module = self.arenas.new_module(parent, kind, vis, expn_id, span, no_implicit_prelude); self.extern_module_map.borrow_mut().insert(module.def_id(), module); module } @@ -2326,10 +2333,10 @@ fn extern_prelude_get_flag( ) -> Option<Decl<'ra>> { let entry = self.extern_prelude.get(&ident); entry.and_then(|entry| entry.flag_decl.as_ref()).and_then(|flag_decl| { - let (pending_decl, finalized) = flag_decl.get(); + let (pending_decl, finalized, is_open) = flag_decl.get(); let decl = match pending_decl { PendingDecl::Ready(decl) => { - if finalize && !finalized { + if finalize && !finalized && !is_open { self.cstore_mut().process_path_extern( self.tcx, ident.name, @@ -2340,18 +2347,28 @@ fn extern_prelude_get_flag( } PendingDecl::Pending => { debug_assert!(!finalized); - let crate_id = if finalize { - self.cstore_mut().process_path_extern(self.tcx, ident.name, orig_ident_span) + if is_open { + let res = Res::OpenMod(ident.name); + Some(self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT)) } else { - self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name) - }; - crate_id.map(|crate_id| { - let res = Res::Def(DefKind::Mod, crate_id.as_def_id()); - self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT) - }) + let crate_id = if finalize { + self.cstore_mut().process_path_extern( + self.tcx, + ident.name, + orig_ident_span, + ) + } else { + self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name) + }; + crate_id.map(|crate_id| { + let def_id = crate_id.as_def_id(); + let res = Res::Def(DefKind::Mod, def_id); + self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT) + }) + } } }; - flag_decl.set((PendingDecl::Ready(decl), finalize || finalized)); + flag_decl.set((PendingDecl::Ready(decl), finalize || finalized, is_open)); decl.or_else(|| finalize.then_some(self.dummy_decl)) }) } @@ -2393,7 +2410,9 @@ fn resolve_rustdoc_path( PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => { None } - PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), + path_result @ (PathResult::Module(..) | PathResult::Indeterminate) => { + bug!("got invalid path_result: {path_result:?}") + } } } @@ -2511,6 +2530,60 @@ fn resolve_main(&mut self) { } } +fn build_extern_prelude<'tcx, 'ra>( + tcx: TyCtxt<'tcx>, + attrs: &[ast::Attribute], +) -> FxIndexMap<IdentKey, ExternPreludeEntry<'ra>> { + let mut extern_prelude: FxIndexMap<IdentKey, ExternPreludeEntry<'ra>> = tcx + .sess + .opts + .externs + .iter() + .filter_map(|(name, entry)| { + // Make sure `self`, `super`, `_` etc do not get into extern prelude. + // FIXME: reject `--extern self` and similar in option parsing instead. + if entry.add_prelude + && let sym = Symbol::intern(name) + && sym.can_be_raw() + { + Some((IdentKey::with_root_ctxt(sym), ExternPreludeEntry::flag())) + } else { + None + } + }) + .collect(); + + // Add open base entries for namespaced crates whose base segment + // is missing from the prelude (e.g. `foo::bar` without `foo`). + // These are necessary in order to resolve the open modules, whereas + // the namespaced names are necessary in `extern_prelude` for actually + // resolving the namespaced crates. + let missing_open_bases: Vec<IdentKey> = extern_prelude + .keys() + .filter_map(|ident| { + let (base, _) = ident.name.as_str().split_once("::")?; + let base_sym = Symbol::intern(base); + base_sym.can_be_raw().then(|| IdentKey::with_root_ctxt(base_sym)) + }) + .filter(|base_ident| !extern_prelude.contains_key(base_ident)) + .collect(); + + extern_prelude.extend( + missing_open_bases.into_iter().map(|ident| (ident, ExternPreludeEntry::open_flag())), + ); + + // Inject `core` / `std` unless suppressed by attributes. + if !attr::contains_name(attrs, sym::no_core) { + extern_prelude.insert(IdentKey::with_root_ctxt(sym::core), ExternPreludeEntry::flag()); + + if !attr::contains_name(attrs, sym::no_std) { + extern_prelude.insert(IdentKey::with_root_ctxt(sym::std), ExternPreludeEntry::flag()); + } + } + + extern_prelude +} + fn names_to_string(names: impl Iterator<Item = Symbol>) -> String { let mut result = String::new(); for (i, name) in names.enumerate().filter(|(_, name)| *name != kw::PathRoot) {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0677ca0..e37247d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs
@@ -636,10 +636,10 @@ impl StableOrd for OutputType { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } - impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType { + impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for OutputType { type KeyType = Self; - fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { + fn to_stable_hash_key(&self, _: &Hcx) -> Self::KeyType { *self } } @@ -1405,7 +1405,6 @@ fn default() -> Options { }; Options { - assert_incr_state: None, crate_types: Vec::new(), optimize: OptLevel::No, debuginfo: DebugInfo::None, @@ -2287,20 +2286,6 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf if max_g > max_c { DebugInfo::Full } else { cg.debuginfo } } -fn parse_assert_incr_state( - early_dcx: &EarlyDiagCtxt, - opt_assertion: &Option<String>, -) -> Option<IncrementalStateAssertion> { - match opt_assertion { - Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded), - Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded), - Some(s) => { - early_dcx.early_fatal(format!("unexpected incremental state assertion value: {s}")) - } - None => None, - } -} - pub fn parse_externs( early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches, @@ -2506,8 +2491,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let incremental = cg.incremental.as_ref().map(PathBuf::from); - let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); - if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive"); } @@ -2759,7 +2742,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals; Options { - assert_incr_state, crate_types, optimize: opt_level, debuginfo,
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index ebbbe36..a7b54e6 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs
@@ -229,6 +229,10 @@ macro_rules! ins_sym { if s == SanitizerSet::KERNELADDRESS { s = SanitizerSet::ADDRESS; } + // KHWASAN is still HWASAN under the hood, so it uses the same attribute. + if s == SanitizerSet::KERNELHWADDRESS { + s = SanitizerSet::HWADDRESS; + } ins_str!(sym::sanitize, &s.to_string()); } @@ -239,7 +243,7 @@ macro_rules! ins_sym { ins_none!(sym::sanitizer_cfi_normalize_integers); } - ins_sym!(sym::target_abi, sess.target.abi.desc_symbol()); + ins_sym!(sym::target_abi, sess.target.cfg_abi.desc_symbol()); ins_sym!(sym::target_arch, sess.target.arch.desc_symbol()); ins_str!(sym::target_endian, sess.target.endian.as_str()); ins_sym!(sym::target_env, sess.target.env.desc_symbol()); @@ -447,7 +451,7 @@ macro_rules! ins { }; for target in Target::builtins().chain(iter::once(current_target.clone())) { - values_target_abi.insert(target.options.abi.desc_symbol()); + values_target_abi.insert(target.options.cfg_abi.desc_symbol()); values_target_arch.insert(target.arch.desc_symbol()); values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); values_target_env.insert(target.options.env.desc_symbol());
diff --git a/compiler/rustc_session/src/config/externs.rs b/compiler/rustc_session/src/config/externs.rs index d668d8b..ff76eaa 100644 --- a/compiler/rustc_session/src/config/externs.rs +++ b/compiler/rustc_session/src/config/externs.rs
@@ -43,6 +43,13 @@ pub(crate) fn split_extern_opt<'a>( } }; + // Reject paths with more than two segments. + if unstable_opts.namespaced_crates && crate_name.split("::").count() > 2 { + return Err(early_dcx.early_struct_fatal(format!( + "crate name `{crate_name}` passed to `--extern` can have at most two segments." + ))); + } + if !valid_crate_name(&crate_name, unstable_opts) { let mut error = early_dcx.early_struct_fatal(format!( "crate name `{crate_name}` passed to `--extern` is not a valid ASCII identifier"
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index d1899de..295d9c3 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs
@@ -530,3 +530,7 @@ pub(crate) struct UnexpectedBuiltinCfg { #[derive(Diagnostic)] #[diag("ThinLTO is not supported by the codegen backend, using fat LTO instead")] pub(crate) struct ThinLtoNotSupportedByBackend; + +#[derive(Diagnostic)] +#[diag("`-Zpacked-stack` is only supported on s390x")] +pub(crate) struct UnsupportedPackedStack;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index fb1b3c8..027a704 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs
@@ -106,6 +106,7 @@ pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool | SanitizerSet::SHADOWCALLSTACK | SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS | SanitizerSet::SAFESTACK | SanitizerSet::DATAFLOW; @@ -418,7 +419,6 @@ pub struct Options { /// If `Some`, enable incremental compilation, using the given /// directory to store intermediate results. incremental: Option<PathBuf> [UNTRACKED], - assert_incr_state: Option<IncrementalStateAssertion> [UNTRACKED], /// Set based on the result of the `Config::track_state` callback /// for custom drivers to invalidate the incremental cache. #[rustc_lint_opt_deny_field_access("should only be used via `Config::track_state`")] @@ -817,7 +817,7 @@ mod desc { pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy; pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; - pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'"; + pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `kernel-hwaddress`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'"; pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; pub(crate) const parse_cfguard: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; @@ -888,6 +888,7 @@ mod desc { pub(crate) const parse_mir_include_spans: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)"; pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29"; + pub(crate) const parse_assert_incr_state: &str = "one of: `loaded`, `not-loaded`"; } pub mod parse { @@ -1265,6 +1266,7 @@ pub(crate) fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool "dataflow" => SanitizerSet::DATAFLOW, "kcfi" => SanitizerSet::KCFI, "kernel-address" => SanitizerSet::KERNELADDRESS, + "kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS, "leak" => SanitizerSet::LEAK, "memory" => SanitizerSet::MEMORY, "memtag" => SanitizerSet::MEMTAG, @@ -2059,6 +2061,18 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool { true } + + pub(crate) fn parse_assert_incr_state( + slot: &mut Option<IncrementalStateAssertion>, + v: Option<&str>, + ) -> bool { + *slot = match v { + Some("loaded") => Some(IncrementalStateAssertion::Loaded), + Some("not-loaded") => Some(IncrementalStateAssertion::NotLoaded), + _ => return false, + }; + true + } } options! { @@ -2228,7 +2242,7 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool { annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], "emit debug info for compiler-generated move and copy operations \ to make them visible in profilers. Can be a boolean or a size limit in bytes (default: disabled)"), - assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED], + assert_incr_state: Option<IncrementalStateAssertion> = (None, parse_assert_incr_state, [UNTRACKED], "assert that the incremental cache is in given state: \ either `loaded` or `not-loaded`."), assume_incomplete_release: bool = (false, parse_bool, [TRACKED], @@ -2543,6 +2557,8 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool { "pass `-install_name @rpath/...` to the macOS linker (default: no)"), packed_bundled_libs: bool = (false, parse_bool, [TRACKED], "change rlib format to store native libraries as archives"), + packed_stack: bool = (false, parse_bool, [TRACKED], + "use packed stack frames (s390x only) (default: no)"), panic_abort_tests: bool = (false, parse_bool, [TRACKED], "support compiling tests with panic=abort (default: no)"), panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index a8210f2..65a15db 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs
@@ -7,7 +7,7 @@ use rustc_ast::attr::AttrIdGenerator; use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_data_structures::sync::{AppendOnlyVec, DynSend, Lock}; +use rustc_data_structures::sync::{AppendOnlyVec, DynSend, DynSync, Lock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{EmitterWithNote, stderr_destination}; use rustc_errors::{ @@ -332,7 +332,7 @@ pub fn buffer_lint( } pub fn dyn_buffer_lint< - F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static, + F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSync + DynSend + 'static, >( &self, lint: &'static Lint,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fece46d..a9e7f15 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs
@@ -533,9 +533,12 @@ pub fn needs_plt(&self) -> bool { pub fn emit_lifetime_markers(&self) -> bool { self.opts.optimize != config::OptLevel::No // AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs. + // // MemorySanitizer uses lifetimes to detect use of uninitialized stack variables. - // HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future. - || self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS) + // + // HWAddressSanitizer and KernelHWAddressSanitizer will use lifetimes to detect use after + // scope bugs in the future. + || self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS) } pub fn diagnostic_width(&self) -> usize { @@ -1360,6 +1363,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } } + + if sess.opts.unstable_opts.packed_stack { + if sess.target.arch != Arch::S390x { + sess.dcx().emit_err(errors::UnsupportedPackedStack); + } + } } /// Holds data on the current incremental compilation session, if there is one.
diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 11507a3..d9aa73c 100644 --- a/compiler/rustc_span/src/caching_source_map_view.rs +++ b/compiler/rustc_span/src/caching_source_map_view.rs
@@ -4,10 +4,15 @@ use crate::source_map::SourceMap; use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData}; +/// A `SourceMap` wrapper that caches info about a single recent code position. This gives a good +/// speedup when hashing spans, because often multiple spans within a single line are hashed in +/// succession, and this avoids expensive `SourceMap` lookups each time the cache is hit. We used +/// to cache multiple code positions, but caching a single position ended up being simpler and +/// faster. #[derive(Clone)] -struct CacheEntry { - time_stamp: usize, - line_number: usize, +pub struct CachingSourceMapView<'sm> { + source_map: &'sm SourceMap, + file: Arc<SourceFile>, // The line's byte position range in the `SourceMap`. This range will fail to contain a valid // position in certain edge cases. Spans often start/end one past something, and when that // something is the last character of a file (this can happen when a file doesn't end in a @@ -20,261 +25,134 @@ struct CacheEntry { // entry contains a position, the only ramification of the above is that we will get cache // misses for these rare positions. A line lookup for the position via `SourceMap::lookup_line` // after a cache miss will produce the last line number, as desired. - line: Range<BytePos>, - file: Arc<SourceFile>, - file_index: usize, -} - -impl CacheEntry { - #[inline] - fn update( - &mut self, - new_file_and_idx: Option<(Arc<SourceFile>, usize)>, - pos: BytePos, - time_stamp: usize, - ) { - if let Some((file, file_idx)) = new_file_and_idx { - self.file = file; - self.file_index = file_idx; - } - - let pos = self.file.relative_position(pos); - let line_index = self.file.lookup_line(pos).unwrap(); - let line_bounds = self.file.line_bounds(line_index); - self.line_number = line_index + 1; - self.line = line_bounds; - self.touch(time_stamp); - } - - #[inline] - fn touch(&mut self, time_stamp: usize) { - self.time_stamp = time_stamp; - } -} - -#[derive(Clone)] -pub struct CachingSourceMapView<'sm> { - source_map: &'sm SourceMap, - line_cache: [CacheEntry; 3], - time_stamp: usize, + line_bounds: Range<BytePos>, + line_number: usize, } impl<'sm> CachingSourceMapView<'sm> { pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> { let files = source_map.files(); let first_file = Arc::clone(&files[0]); - let entry = CacheEntry { - time_stamp: 0, - line_number: 0, - line: BytePos(0)..BytePos(0), - file: first_file, - file_index: 0, - }; - CachingSourceMapView { source_map, - line_cache: [entry.clone(), entry.clone(), entry], - time_stamp: 0, + file: first_file, + line_bounds: BytePos(0)..BytePos(0), + line_number: 0, } } + #[inline] + fn pos_to_line(&self, pos: BytePos) -> (Range<BytePos>, usize) { + let pos = self.file.relative_position(pos); + let line_index = self.file.lookup_line(pos).unwrap(); + let line_bounds = self.file.line_bounds(line_index); + let line_number = line_index + 1; + (line_bounds, line_number) + } + + #[inline] + fn update(&mut self, new_file: Option<Arc<SourceFile>>, pos: BytePos) { + if let Some(file) = new_file { + self.file = file; + } + (self.line_bounds, self.line_number) = self.pos_to_line(pos); + } + pub fn byte_pos_to_line_and_col( &mut self, pos: BytePos, ) -> Option<(Arc<SourceFile>, usize, RelativeBytePos)> { - self.time_stamp += 1; - - // Check if the position is in one of the cached lines - let cache_idx = self.cache_entry_index(pos); - if cache_idx != -1 { - let cache_entry = &mut self.line_cache[cache_idx as usize]; - cache_entry.touch(self.time_stamp); - - let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32()); - return Some((Arc::clone(&cache_entry.file), cache_entry.line_number, col)); - } - - // No cache hit ... - let oldest = self.oldest_cache_entry_index(); - - // If the entry doesn't point to the correct file, get the new file and index. - let new_file_and_idx = if !file_contains(&self.line_cache[oldest].file, pos) { - Some(self.file_for_position(pos)?) + if self.line_bounds.contains(&pos) { + // Cache hit: do nothing. } else { - None + // Cache miss. If the entry doesn't point to the correct file, get the new file and + // index. + let new_file = if !file_contains(&self.file, pos) { + Some(self.file_for_position(pos)?) + } else { + None + }; + self.update(new_file, pos); }; - let cache_entry = &mut self.line_cache[oldest]; - cache_entry.update(new_file_and_idx, pos, self.time_stamp); - - let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32()); - Some((Arc::clone(&cache_entry.file), cache_entry.line_number, col)) + let col = RelativeBytePos(pos.to_u32() - self.line_bounds.start.to_u32()); + Some((Arc::clone(&self.file), self.line_number, col)) } pub fn span_data_to_lines_and_cols( &mut self, span_data: &SpanData, ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> { - self.time_stamp += 1; - - // Check if lo and hi are in the cached lines. - let lo_cache_idx: isize = self.cache_entry_index(span_data.lo); - let hi_cache_idx = self.cache_entry_index(span_data.hi); - - if lo_cache_idx != -1 && hi_cache_idx != -1 { - // Cache hit for span lo and hi. Check if they belong to the same file. - let lo_file_index = self.line_cache[lo_cache_idx as usize].file_index; - let hi_file_index = self.line_cache[hi_cache_idx as usize].file_index; - - if lo_file_index != hi_file_index { - return None; - } - - self.line_cache[lo_cache_idx as usize].touch(self.time_stamp); - self.line_cache[hi_cache_idx as usize].touch(self.time_stamp); - - let lo = &self.line_cache[lo_cache_idx as usize]; - let hi = &self.line_cache[hi_cache_idx as usize]; + let lo_hit = self.line_bounds.contains(&span_data.lo); + let hi_hit = self.line_bounds.contains(&span_data.hi); + if lo_hit && hi_hit { + // span_data.lo and span_data.hi are cached (i.e. both in the same line). return Some(( - &lo.file, - lo.line_number, - span_data.lo - lo.line.start, - hi.line_number, - span_data.hi - hi.line.start, + &self.file, + self.line_number, + span_data.lo - self.line_bounds.start, + self.line_number, + span_data.hi - self.line_bounds.start, )); } - // No cache hit or cache hit for only one of span lo and hi. - let oldest = if lo_cache_idx != -1 || hi_cache_idx != -1 { - let avoid_idx = if lo_cache_idx != -1 { lo_cache_idx } else { hi_cache_idx }; - self.oldest_cache_entry_index_avoid(avoid_idx as usize) - } else { - self.oldest_cache_entry_index() - }; - - // If the entry doesn't point to the correct file, get the new file and index. - // Return early if the file containing beginning of span doesn't contain end of span. - let new_file_and_idx = if !file_contains(&self.line_cache[oldest].file, span_data.lo) { - let new_file_and_idx = self.file_for_position(span_data.lo)?; - if !file_contains(&new_file_and_idx.0, span_data.hi) { + // If the cached file is wrong, update it. Return early if the span lo and hi are in + // different files. + let new_file = if !file_contains(&self.file, span_data.lo) { + let new_file = self.file_for_position(span_data.lo)?; + if !file_contains(&new_file, span_data.hi) { return None; } - - Some(new_file_and_idx) + Some(new_file) } else { - let file = &self.line_cache[oldest].file; - if !file_contains(file, span_data.hi) { + if !file_contains(&self.file, span_data.hi) { return None; } - None }; - // Update the cache entries. - let (lo_idx, hi_idx) = match (lo_cache_idx, hi_cache_idx) { - // Oldest cache entry is for span_data.lo line. - (-1, -1) => { - let lo = &mut self.line_cache[oldest]; - lo.update(new_file_and_idx, span_data.lo, self.time_stamp); + // If we reach here, lo and hi are in the same file. - if !lo.line.contains(&span_data.hi) { - let new_file_and_idx = Some((Arc::clone(&lo.file), lo.file_index)); - let next_oldest = self.oldest_cache_entry_index_avoid(oldest); - let hi = &mut self.line_cache[next_oldest]; - hi.update(new_file_and_idx, span_data.hi, self.time_stamp); - (oldest, next_oldest) - } else { - (oldest, oldest) - } - } - // Oldest cache entry is for span_data.lo line. - (-1, _) => { - let lo = &mut self.line_cache[oldest]; - lo.update(new_file_and_idx, span_data.lo, self.time_stamp); - let hi = &mut self.line_cache[hi_cache_idx as usize]; - hi.touch(self.time_stamp); - (oldest, hi_cache_idx as usize) - } - // Oldest cache entry is for span_data.hi line. - (_, -1) => { - let hi = &mut self.line_cache[oldest]; - hi.update(new_file_and_idx, span_data.hi, self.time_stamp); - let lo = &mut self.line_cache[lo_cache_idx as usize]; - lo.touch(self.time_stamp); - (lo_cache_idx as usize, oldest) - } - _ => { - panic!( - "the case of neither value being equal to -1 was handled above and the function returns." - ); - } + if !lo_hit { + // We cache the lo information. + self.update(new_file, span_data.lo); + } + let lo_line_bounds = &self.line_bounds; + let lo_line_number = self.line_number.clone(); + + let (hi_line_bounds, hi_line_number) = if !self.line_bounds.contains(&span_data.hi) { + // hi and lo are in different lines. We compute but don't cache the hi information. + self.pos_to_line(span_data.hi) + } else { + // hi and lo are in the same line. + (self.line_bounds.clone(), self.line_number) }; - let lo = &self.line_cache[lo_idx]; - let hi = &self.line_cache[hi_idx]; - // Span lo and hi may equal line end when last line doesn't // end in newline, hence the inclusive upper bounds below. - assert!(span_data.lo >= lo.line.start); - assert!(span_data.lo <= lo.line.end); - assert!(span_data.hi >= hi.line.start); - assert!(span_data.hi <= hi.line.end); - assert!(lo.file.contains(span_data.lo)); - assert!(lo.file.contains(span_data.hi)); - assert_eq!(lo.file_index, hi.file_index); + assert!(span_data.lo >= lo_line_bounds.start); + assert!(span_data.lo <= lo_line_bounds.end); + assert!(span_data.hi >= hi_line_bounds.start); + assert!(span_data.hi <= hi_line_bounds.end); + assert!(self.file.contains(span_data.lo)); + assert!(self.file.contains(span_data.hi)); Some(( - &lo.file, - lo.line_number, - span_data.lo - lo.line.start, - hi.line_number, - span_data.hi - hi.line.start, + &self.file, + lo_line_number, + span_data.lo - lo_line_bounds.start, + hi_line_number, + span_data.hi - hi_line_bounds.start, )) } - fn cache_entry_index(&self, pos: BytePos) -> isize { - for (idx, cache_entry) in self.line_cache.iter().enumerate() { - if cache_entry.line.contains(&pos) { - return idx as isize; - } - } - - -1 - } - - fn oldest_cache_entry_index(&self) -> usize { - let mut oldest = 0; - - for idx in 1..self.line_cache.len() { - if self.line_cache[idx].time_stamp < self.line_cache[oldest].time_stamp { - oldest = idx; - } - } - - oldest - } - - fn oldest_cache_entry_index_avoid(&self, avoid_idx: usize) -> usize { - let mut oldest = if avoid_idx != 0 { 0 } else { 1 }; - - for idx in 0..self.line_cache.len() { - if idx != avoid_idx - && self.line_cache[idx].time_stamp < self.line_cache[oldest].time_stamp - { - oldest = idx; - } - } - - oldest - } - - fn file_for_position(&self, pos: BytePos) -> Option<(Arc<SourceFile>, usize)> { + fn file_for_position(&self, pos: BytePos) -> Option<Arc<SourceFile>> { if !self.source_map.files().is_empty() { let file_idx = self.source_map.lookup_source_file_idx(pos); let file = &self.source_map.files()[file_idx]; if file_contains(file, pos) { - return Some((Arc::clone(file), file_idx)); + return Some(Arc::clone(file)); } }
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 82d455a..8c313c7 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs
@@ -402,59 +402,59 @@ fn decode(d: &mut D) -> LocalDefId { LocalDefId ); -impl<CTX: HashStableContext> HashStable<CTX> for DefId { +impl<Hcx: HashStableContext> HashStable<Hcx> for DefId { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { hcx.def_path_hash(*self).hash_stable(hcx, hasher); } } -impl<CTX: HashStableContext> HashStable<CTX> for LocalDefId { +impl<Hcx: HashStableContext> HashStable<Hcx> for LocalDefId { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { hcx.def_path_hash(self.to_def_id()).local_hash().hash_stable(hcx, hasher); } } -impl<CTX: HashStableContext> HashStable<CTX> for CrateNum { +impl<Hcx: HashStableContext> HashStable<Hcx> for CrateNum { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.as_def_id().to_stable_hash_key(hcx).stable_crate_id().hash_stable(hcx, hasher); } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for DefId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for DefId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { hcx.def_path_hash(*self) } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for LocalDefId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for LocalDefId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { hcx.def_path_hash(self.to_def_id()) } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for CrateNum { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for CrateNum { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { self.as_def_id().to_stable_hash_key(hcx) } } -impl<CTX: HashStableContext> ToStableHashKey<CTX> for DefPathHash { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for DefPathHash { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, _: &CTX) -> DefPathHash { + fn to_stable_hash_key(&self, _: &Hcx) -> DefPathHash { *self } }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 25834f0..e7b98cc 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs
@@ -207,9 +207,9 @@ pub fn fresh_empty() -> LocalExpnId { }) } - pub fn fresh(mut expn_data: ExpnData, ctx: impl HashStableContext) -> LocalExpnId { + pub fn fresh(mut expn_data: ExpnData, hcx: impl HashStableContext) -> LocalExpnId { debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE); - let expn_hash = update_disambiguator(&mut expn_data, ctx); + let expn_hash = update_disambiguator(&mut expn_data, hcx); HygieneData::with(|data| { let expn_id = data.local_expn_data.push(Some(expn_data)); let _eid = data.local_expn_hashes.push(expn_hash); @@ -231,9 +231,9 @@ pub fn to_expn_id(self) -> ExpnId { } #[inline] - pub fn set_expn_data(self, mut expn_data: ExpnData, ctx: impl HashStableContext) { + pub fn set_expn_data(self, mut expn_data: ExpnData, hcx: impl HashStableContext) { debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE); - let expn_hash = update_disambiguator(&mut expn_data, ctx); + let expn_hash = update_disambiguator(&mut expn_data, hcx); HygieneData::with(|data| { let old_expn_data = &mut data.local_expn_data[self]; assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID"); @@ -950,13 +950,13 @@ pub fn mark_with_reason( allow_internal_unstable: Option<Arc<[Symbol]>>, reason: DesugaringKind, edition: Edition, - ctx: impl HashStableContext, + hcx: impl HashStableContext, ) -> Span { let expn_data = ExpnData { allow_internal_unstable, ..ExpnData::default(ExpnKind::Desugaring(reason), self, edition, None, None) }; - let expn_id = LocalExpnId::fresh(expn_data, ctx); + let expn_id = LocalExpnId::fresh(expn_data, hcx); self.apply_mark(expn_id.to_expn_id(), Transparency::Transparent) } } @@ -1102,9 +1102,9 @@ pub fn is_root(&self) -> bool { } #[inline] - fn hash_expn(&self, ctx: &mut impl HashStableContext) -> Hash64 { + fn hash_expn(&self, hcx: &mut impl HashStableContext) -> Hash64 { let mut hasher = StableHasher::new(); - self.hash_stable(ctx, &mut hasher); + self.hash_stable(hcx, &mut hasher); hasher.finish() } } @@ -1482,11 +1482,11 @@ pub fn raw_encode_syntax_context( /// `set_expn_data`). It is *not* called for foreign `ExpnId`s deserialized /// from another crate's metadata - since `ExpnHash` includes the stable crate id, /// collisions are only possible between `ExpnId`s within the same crate. -fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContext) -> ExpnHash { +fn update_disambiguator(expn_data: &mut ExpnData, mut hcx: impl HashStableContext) -> ExpnHash { // This disambiguator should not have been set yet. assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}"); - ctx.assert_default_hashing_controls("ExpnData (disambiguator)"); - let mut expn_hash = expn_data.hash_expn(&mut ctx); + hcx.assert_default_hashing_controls("ExpnData (disambiguator)"); + let mut expn_hash = expn_data.hash_expn(&mut hcx); let disambiguator = HygieneData::with(|data| { // If this is the first ExpnData with a given hash, then keep our @@ -1501,7 +1501,7 @@ fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContex debug!("Set disambiguator for expn_data={:?} expn_hash={:?}", expn_data, expn_hash); expn_data.disambiguator = disambiguator; - expn_hash = expn_data.hash_expn(&mut ctx); + expn_hash = expn_data.hash_expn(&mut hcx); // Verify that the new disambiguator makes the hash unique #[cfg(debug_assertions)] @@ -1514,28 +1514,28 @@ fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContex }); } - ExpnHash::new(ctx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), expn_hash) + ExpnHash::new(hcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), expn_hash) } -impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx: HashStableContext> HashStable<Hcx> for SyntaxContext { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { const TAG_EXPANSION: u8 = 0; const TAG_NO_EXPANSION: u8 = 1; if self.is_root() { - TAG_NO_EXPANSION.hash_stable(ctx, hasher); + TAG_NO_EXPANSION.hash_stable(hcx, hasher); } else { - TAG_EXPANSION.hash_stable(ctx, hasher); + TAG_EXPANSION.hash_stable(hcx, hasher); let (expn_id, transparency) = self.outer_mark(); - expn_id.hash_stable(ctx, hasher); - transparency.hash_stable(ctx, hasher); + expn_id.hash_stable(hcx, hasher); + transparency.hash_stable(hcx, hasher); } } } -impl<CTX: HashStableContext> HashStable<CTX> for ExpnId { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - ctx.assert_default_hashing_controls("ExpnId"); +impl<Hcx: HashStableContext> HashStable<Hcx> for ExpnId { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + hcx.assert_default_hashing_controls("ExpnId"); let hash = if *self == ExpnId::root() { // Avoid fetching TLS storage for a trivial often-used value. Fingerprint::ZERO @@ -1543,12 +1543,12 @@ fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.expn_hash().0 }; - hash.hash_stable(ctx, hasher); + hash.hash_stable(hcx, hasher); } } -impl<CTX: HashStableContext> HashStable<CTX> for LocalExpnId { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx: HashStableContext> HashStable<Hcx> for LocalExpnId { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.to_expn_id().hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d7d2ecb..6794ffb 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs
@@ -2812,13 +2812,13 @@ pub trait HashStableContext { fn assert_default_hashing_controls(&self, msg: &str); } -impl<CTX> HashStable<CTX> for Span +impl<Hcx> HashStable<Hcx> for Span where - CTX: HashStableContext, + Hcx: HashStableContext, { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { // `span_hash_stable` does all the work. - ctx.span_hash_stable(*self, hasher) + hcx.span_hash_stable(*self, hasher) } }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 738c9b9..30bf8dd 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs
@@ -505,6 +505,7 @@ avx512bw, avx512f, await_macro, + backchain, bang, begin_panic, bench, @@ -746,6 +747,7 @@ custom_mir, custom_test_frameworks, d32, + dbg_macro, dead_code, dealloc, debug, @@ -915,10 +917,7 @@ f64_nan, f128, f128_nan, - fabsf16, - fabsf32, - fabsf64, - fabsf128, + fabs, fadd_algebraic, fadd_fast, fake_variadic, @@ -1028,6 +1027,7 @@ global_registration, globs, gt, + guard, guard_patterns, half_open_range_patterns, half_open_range_patterns_in_slices, @@ -1116,6 +1116,7 @@ iterator_collect_fn, kcfi, kernel_address, + kernel_hwaddress, keylocker_x86, keyword, kind, @@ -1192,6 +1193,7 @@ macro_derive, macro_escape, macro_export, + macro_guard_matcher, macro_lifetime_matcher, macro_literal_matcher, macro_metavar_expr, @@ -1224,6 +1226,7 @@ maybe_uninit, maybe_uninit_uninit, maybe_uninit_zeroed, + mem, mem_align_const, mem_discriminant, mem_drop, @@ -1852,8 +1855,6 @@ simd_flog10, simd_floor, simd_fma, - simd_fmax, - simd_fmin, simd_fsin, simd_fsqrt, simd_funnel_shl, @@ -1867,6 +1868,8 @@ simd_lt, simd_masked_load, simd_masked_store, + simd_maximum_number_nsz, + simd_minimum_number_nsz, simd_mul, simd_ne, simd_neg, @@ -1917,6 +1920,7 @@ slice_len_fn, slice_patterns, slicing_syntax, + soft_float: "soft-float", sparc, sparc64, sparc_target_feature, @@ -2597,17 +2601,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl<CTX> HashStable<CTX> for Symbol { +impl<Hcx> HashStable<Hcx> for Symbol { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.as_str().hash_stable(hcx, hasher); } } -impl<CTX> ToStableHashKey<CTX> for Symbol { +impl<Hcx> ToStableHashKey<Hcx> for Symbol { type KeyType = String; #[inline] - fn to_stable_hash_key(&self, _: &CTX) -> String { + fn to_stable_hash_key(&self, _: &Hcx) -> String { self.as_str().to_string() } } @@ -2657,9 +2661,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl<CTX> HashStable<CTX> for ByteSymbol { +impl<Hcx> HashStable<Hcx> for ByteSymbol { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { self.as_byte_str().hash_stable(hcx, hasher); } }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index ea16231..54ecf27 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -155,9 +155,7 @@ fn get_symbol_hash<'tcx>( args.hash_stable(hcx, &mut hasher); if let Some(instantiating_crate) = instantiating_crate { - tcx.def_path_hash(instantiating_crate.as_def_id()) - .stable_crate_id() - .hash_stable(hcx, &mut hasher); + tcx.stable_crate_id(instantiating_crate).hash_stable(hcx, &mut hasher); } // We want to avoid accidental collision between different types of instances.
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 95cbb9e..eff8cbe 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -841,7 +841,7 @@ fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> { fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> { self.push("C"); if !self.is_exportable { - let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); + let stable_crate_id = self.tcx.stable_crate_id(cnum); self.push_disambiguator(stable_crate_id.as_u64()); } let name = self.tcx.crate_name(cnum);
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 27dd0b7..643eeaa 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs
@@ -5,7 +5,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::Symbol; -use crate::spec::{Abi, Arch, RelocModel, Target}; +use crate::spec::{Arch, CfgAbi, RelocModel, Target}; pub struct ModifierInfo { pub modifier: char, @@ -1001,7 +1001,7 @@ pub fn parse( _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name { - "C" | "system" => Ok(if target.abi == Abi::Spe { + "C" | "system" => Ok(if target.cfg_abi == CfgAbi::Spe { InlineAsmClobberAbi::PowerPCSPE } else { InlineAsmClobberAbi::PowerPC
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index fd0e118..a09b93c 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -4,7 +4,7 @@ use rustc_span::Symbol; use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use crate::spec::{Abi, RelocModel, Target}; +use crate::spec::{CfgAbi, RelocModel, Target}; def_reg_class! { PowerPC PowerPCInlineAsmRegClass { @@ -105,9 +105,9 @@ fn reserved_v20to31( _is_clobber: bool, ) -> Result<(), &'static str> { if target.is_like_aix { - match &target.options.abi { - Abi::VecDefault => Err("v20-v31 (vs52-vs63) are reserved on vec-default ABI"), - Abi::VecExtAbi => Ok(()), + match &target.options.cfg_abi { + CfgAbi::VecDefault => Err("v20-v31 (vs52-vs63) are reserved on vec-default ABI"), + CfgAbi::VecExtAbi => Ok(()), abi => unreachable!("unrecognized AIX ABI: {abi}"), } } else { @@ -122,7 +122,11 @@ fn spe_acc_target_check( target: &Target, _is_clobber: bool, ) -> Result<(), &'static str> { - if target.abi == Abi::Spe { Ok(()) } else { Err("spe_acc is only available on spe targets") } + if target.cfg_abi == CfgAbi::Spe { + Ok(()) + } else { + Err("spe_acc is only available on spe targets") + } } def_regs! {
diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index 054e9a0..6d3826a 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs
@@ -4,7 +4,7 @@ }; use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform}; -use crate::spec::HasTargetSpec; +use crate::spec::{HasTargetSpec, LlvmAbi}; #[derive(Copy, Clone)] enum RegPassKind { @@ -415,9 +415,9 @@ pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) C: HasDataLayout + HasTargetSpec, { let xlen = cx.data_layout().pointer_size().bits(); - let flen = match &cx.target_spec().llvm_abiname[..] { - "ilp32f" | "lp64f" => 32, - "ilp32d" | "lp64d" => 64, + let flen = match &cx.target_spec().llvm_abiname { + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => 32, + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => 64, _ => 0, };
diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index 683b615..d807617 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs
@@ -5,7 +5,7 @@ use rustc_abi::{Endian, HasDataLayout, TyAbiInterface}; use crate::callconv::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::spec::{HasTargetSpec, Os}; +use crate::spec::{HasTargetSpec, LlvmAbi, Os}; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { @@ -106,9 +106,9 @@ pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - let abi = if cx.target_spec().options.llvm_abiname == "elfv2" { + let abi = if cx.target_spec().options.llvm_abiname == LlvmAbi::ElfV2 { ELFv2 - } else if cx.target_spec().options.llvm_abiname == "elfv1" { + } else if cx.target_spec().options.llvm_abiname == LlvmAbi::ElfV1 { ELFv1 } else if cx.target_spec().os == Os::Aix { AIX
diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 18efdc5..bc81ec9 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs
@@ -10,7 +10,7 @@ }; use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform}; -use crate::spec::HasTargetSpec; +use crate::spec::{HasTargetSpec, LlvmAbi}; #[derive(Copy, Clone)] enum RegPassKind { @@ -419,9 +419,9 @@ pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - let flen = match &cx.target_spec().llvm_abiname[..] { - "ilp32f" | "lp64f" => 32, - "ilp32d" | "lp64d" => 64, + let flen = match &cx.target_spec().llvm_abiname { + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => 32, + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => 64, _ => 0, }; let xlen = cx.data_layout().pointer_size().bits();
diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs index 76e8fb7..41cf3e0 100644 --- a/compiler/rustc_target/src/spec/base/aix.rs +++ b/compiler/rustc_target/src/spec/base/aix.rs
@@ -1,13 +1,13 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, Os, TargetOptions, crt_objects, - cvs, + BinaryFormat, Cc, CfgAbi, CodeModel, LinkOutputKind, LinkerFlavor, Os, TargetOptions, + crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { TargetOptions { - abi: Abi::VecExtAbi, + cfg_abi: CfgAbi::VecExtAbi, code_model: Some(CodeModel::Large), cpu: "pwr7".into(), os: Os::Aix,
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 18b41d1..d1d91cb 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -4,7 +4,7 @@ use std::str::FromStr; use crate::spec::{ - Abi, BinaryFormat, Cc, DebuginfoKind, Env, FloatAbi, FramePointer, LinkerFlavor, Lld, Os, + BinaryFormat, Cc, CfgAbi, DebuginfoKind, Env, FloatAbi, FramePointer, LinkerFlavor, Lld, Os, RustcAbi, SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs, }; @@ -108,11 +108,11 @@ fn target_env(self) -> Env { // // But let's continue setting them for backwards compatibility. // FIXME(madsmtm): Warn about using these in the future. - fn target_abi(self) -> Abi { + fn target_abi(self) -> CfgAbi { match self { - Self::Normal => Abi::Unspecified, - Self::MacCatalyst => Abi::MacAbi, - Self::Simulator => Abi::Sim, + Self::Normal => CfgAbi::Unspecified, + Self::MacCatalyst => CfgAbi::MacAbi, + Self::Simulator => CfgAbi::Sim, } } } @@ -135,7 +135,7 @@ pub(crate) fn base( }, os, env: env.target_env(), - abi: env.target_abi(), + cfg_abi: env.target_abi(), cpu: arch.target_cpu(env).into(), link_env_remove, vendor: "apple".into(),
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs index fd3fd6d..f178698 100644 --- a/compiler/rustc_target/src/spec/base/apple/tests.rs +++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -4,7 +4,7 @@ aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios, x86_64_apple_tvos, x86_64_apple_watchos_sim, }; -use crate::spec::{Abi, Env}; +use crate::spec::{CfgAbi, Env}; #[test] fn simulator_targets_set_env() { @@ -21,7 +21,7 @@ fn simulator_targets_set_env() { for target in &all_sim_targets { assert_eq!(target.env, Env::Sim); // Ensure backwards compat - assert_eq!(target.abi, Abi::Sim); + assert_eq!(target.cfg_abi, CfgAbi::Sim); } }
diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index d2fe42b..cee3f91 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs
@@ -106,6 +106,7 @@ pub(crate) fn opts() -> TargetOptions { // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to // output DWO, despite using DWARF, doesn't use ELF.. supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), + mcount: "_mcount".into(), ..Default::default() } }
diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 3bd8ebd..c1b4eec 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
@@ -2,7 +2,7 @@ use crate::spec::crt_objects::pre_mingw_self_contained; use crate::spec::{ - Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os, + BinaryFormat, Cc, CfgAbi, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os, SplitDebuginfo, TargetOptions, add_link_args, cvs, }; @@ -26,7 +26,7 @@ pub(crate) fn opts() -> TargetOptions { os: Os::Windows, env: Env::Gnu, vendor: "pc".into(), - abi: Abi::Llvm, + cfg_abi: CfgAbi::Llvm, linker: Some("clang".into()), dynamic_linking: true, dll_tls_export: false, @@ -53,6 +53,7 @@ pub(crate) fn opts() -> TargetOptions { // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to // output DWO, despite using DWARF, doesn't use ELF.. supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), + mcount: "_mcount".into(), ..Default::default() } }
diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs index 0f009ff..d1adc89 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions, add_link_args, base}; +use crate::spec::{Cc, CfgAbi, LinkArgs, LinkerFlavor, Lld, TargetOptions, add_link_args, base}; pub(crate) fn opts() -> TargetOptions { let base = base::windows_gnu::opts(); @@ -23,7 +23,7 @@ pub(crate) fn opts() -> TargetOptions { let late_link_args_static = LinkArgs::new(); TargetOptions { - abi: Abi::Uwp, + cfg_abi: CfgAbi::Uwp, vendor: "uwp".into(), limit_rdylib_exports: false, late_link_args,
diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs index 1583298..b9b2f42 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs
@@ -1,8 +1,8 @@ -use crate::spec::{Abi, LinkerFlavor, Lld, TargetOptions, base}; +use crate::spec::{CfgAbi, LinkerFlavor, Lld, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { let mut opts = - TargetOptions { abi: Abi::Uwp, vendor: "uwp".into(), ..base::windows_msvc::opts() }; + TargetOptions { cfg_abi: CfgAbi::Uwp, vendor: "uwp".into(), ..base::windows_msvc::opts() }; opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]);
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index d8ef248..5507af0 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs
@@ -5,14 +5,14 @@ use super::crt_objects::CrtObjects; use super::{ - Abi, Arch, BinaryFormat, CodeModel, DebuginfoKind, Env, FloatAbi, FramePointer, LinkArgsCli, + Arch, BinaryFormat, CfgAbi, CodeModel, DebuginfoKind, Env, FloatAbi, FramePointer, LinkArgsCli, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor, MergeFunctions, Os, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target, TargetKind, TargetOptions, TargetWarnings, TlsModel, }; use crate::json::{Json, ToJson}; -use crate::spec::AbiMap; +use crate::spec::{AbiMap, LlvmAbi}; impl Target { /// Loads a target descriptor from a JSON object. @@ -69,7 +69,9 @@ macro_rules! forward_opt { forward_opt!(c_enum_min_bits); // if None, matches c_int_width forward!(os); forward!(env); - forward!(abi); + if let Some(abi) = json.abi { + base.cfg_abi = abi; + } forward!(vendor); forward_opt!(linker); forward!(linker_flavor_json); @@ -297,7 +299,7 @@ macro_rules! target_option_val { target_option_val!(c_int_width, "target-c-int-width"); target_option_val!(os); target_option_val!(env); - target_option_val!(abi); + target_option_val!(cfg_abi, "abi"); target_option_val!(vendor); target_option_val!(linker); target_option_val!(linker_flavor_json, "linker-flavor"); @@ -505,7 +507,7 @@ struct TargetSpecJson { c_enum_min_bits: Option<u64>, os: Option<Os>, env: Option<Env>, - abi: Option<Abi>, + abi: Option<CfgAbi>, vendor: Option<StaticCow<str>>, linker: Option<StaticCow<str>>, #[serde(rename = "linker-flavor")] @@ -609,7 +611,7 @@ struct TargetSpecJson { #[serde(rename = "target-mcount")] mcount: Option<StaticCow<str>>, llvm_mcount_intrinsic: Option<StaticCow<str>>, - llvm_abiname: Option<StaticCow<str>>, + llvm_abiname: Option<LlvmAbi>, llvm_floatabi: Option<FloatAbi>, rustc_abi: Option<RustcAbi>, relax_elf_relocations: Option<bool>,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8683e4f..68d6162 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1175,9 +1175,10 @@ impl SanitizerSet: u16 { const SHADOWCALLSTACK = 1 << 7; const KCFI = 1 << 8; const KERNELADDRESS = 1 << 9; - const SAFESTACK = 1 << 10; - const DATAFLOW = 1 << 11; - const REALTIME = 1 << 12; + const KERNELHWADDRESS = 1 << 10; + const SAFESTACK = 1 << 11; + const DATAFLOW = 1 << 12; + const REALTIME = 1 << 13; } } rustc_data_structures::external_bitflags_debug! { SanitizerSet } @@ -1191,24 +1192,32 @@ impl SanitizerSet { (SanitizerSet::ADDRESS, SanitizerSet::HWADDRESS), (SanitizerSet::ADDRESS, SanitizerSet::MEMTAG), (SanitizerSet::ADDRESS, SanitizerSet::KERNELADDRESS), + (SanitizerSet::ADDRESS, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::ADDRESS, SanitizerSet::SAFESTACK), (SanitizerSet::LEAK, SanitizerSet::MEMORY), (SanitizerSet::LEAK, SanitizerSet::THREAD), (SanitizerSet::LEAK, SanitizerSet::KERNELADDRESS), + (SanitizerSet::LEAK, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::LEAK, SanitizerSet::SAFESTACK), (SanitizerSet::MEMORY, SanitizerSet::THREAD), (SanitizerSet::MEMORY, SanitizerSet::HWADDRESS), (SanitizerSet::MEMORY, SanitizerSet::KERNELADDRESS), + (SanitizerSet::MEMORY, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::MEMORY, SanitizerSet::SAFESTACK), (SanitizerSet::THREAD, SanitizerSet::HWADDRESS), (SanitizerSet::THREAD, SanitizerSet::KERNELADDRESS), + (SanitizerSet::THREAD, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::THREAD, SanitizerSet::SAFESTACK), (SanitizerSet::HWADDRESS, SanitizerSet::MEMTAG), (SanitizerSet::HWADDRESS, SanitizerSet::KERNELADDRESS), + (SanitizerSet::HWADDRESS, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::HWADDRESS, SanitizerSet::SAFESTACK), (SanitizerSet::CFI, SanitizerSet::KCFI), (SanitizerSet::MEMTAG, SanitizerSet::KERNELADDRESS), + (SanitizerSet::MEMTAG, SanitizerSet::KERNELHWADDRESS), + (SanitizerSet::KERNELADDRESS, SanitizerSet::KERNELHWADDRESS), (SanitizerSet::KERNELADDRESS, SanitizerSet::SAFESTACK), + (SanitizerSet::KERNELHWADDRESS, SanitizerSet::SAFESTACK), ]; /// Return sanitizer's name @@ -1221,6 +1230,7 @@ pub fn as_str(self) -> Option<&'static str> { SanitizerSet::DATAFLOW => "dataflow", SanitizerSet::KCFI => "kcfi", SanitizerSet::KERNELADDRESS => "kernel-address", + SanitizerSet::KERNELHWADDRESS => "kernel-hwaddress", SanitizerSet::LEAK => "leak", SanitizerSet::MEMORY => "memory", SanitizerSet::MEMTAG => "memtag", @@ -1266,6 +1276,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> { "dataflow" => SanitizerSet::DATAFLOW, "kcfi" => SanitizerSet::KCFI, "kernel-address" => SanitizerSet::KERNELADDRESS, + "kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS, "leak" => SanitizerSet::LEAK, "memory" => SanitizerSet::MEMORY, "memtag" => SanitizerSet::MEMTAG, @@ -1815,6 +1826,8 @@ fn $module() { ("x86_64-pc-cygwin", x86_64_pc_cygwin), ("x86_64-unknown-linux-gnuasan", x86_64_unknown_linux_gnuasan), + ("x86_64-unknown-linux-gnumsan", x86_64_unknown_linux_gnumsan), + ("x86_64-unknown-linux-gnutsan", x86_64_unknown_linux_gnutsan), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> @@ -1939,24 +1952,6 @@ pub fn desc_symbol(&self) -> Symbol { } } - pub fn supports_c_variadic_definitions(&self) -> bool { - use Arch::*; - - match self { - // These targets just do not support c-variadic definitions. - Bpf | SpirV => false, - - // We don't know if the target supports c-variadic definitions, but we don't want - // to needlessly restrict custom target.json configurations. - Other(_) => true, - - AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64 - | M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC - | PowerPC64 | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 | Wasm64 | X86 - | X86_64 | Xtensa => true, - } - } - /// Whether `#[rustc_scalable_vector]` is supported for a target architecture pub fn supports_scalable_vectors(&self) -> bool { use Arch::*; @@ -2065,7 +2060,10 @@ pub fn desc_symbol(&self) -> Symbol { } crate::target_spec_enum! { - pub enum Abi { + /// An enum representing possible values for `cfg(target_abi)`. + /// This field is not forwarded to LLVM so it does not by itself affect codegen. + /// See the `cfg_abi` field of [`TargetOptions`] for more details. + pub enum CfgAbi { Abi64 = "abi64", AbiV2 = "abiv2", AbiV2Hf = "abiv2hf", @@ -2090,12 +2088,40 @@ pub enum Abi { other_variant = Other; } -impl Abi { +impl CfgAbi { pub fn desc_symbol(&self) -> Symbol { Symbol::intern(self.desc()) } } +crate::target_spec_enum! { + /// An enum representing possible values for the `llvm_abiname` field of [`TargetOptions`]. + /// This field is used by LLVM on some targets to control which ABI to use. + pub enum LlvmAbi { + // RISC-V and LoongArch + Ilp32 = "ilp32", + Ilp32f = "ilp32f", + Ilp32d = "ilp32d", + Ilp32e = "ilp32e", + Ilp32s = "ilp32s", + Lp64 = "lp64", + Lp64f = "lp64f", + Lp64d = "lp64d", + Lp64e = "lp64e", + Lp64s = "lp64s", + // MIPS + O32 = "o32", + N32 = "n32", + N64 = "n64", + // PowerPC + ElfV1 = "elfv1", + ElfV2 = "elfv2", + + Unspecified = "", + } + other_variant = Other; +} + /// Everything `rustc` knows about how to compile for a specific target. /// /// Every field here must be specified, and has no default value. @@ -2170,6 +2196,33 @@ pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErro Ok(dl) } + + pub fn supports_c_variadic_definitions(&self) -> bool { + use Arch::*; + + match self.arch { + // The c-variadic ABI for this target may change in the future, per this comment in + // clang: + // + // > To be compatible with GCC's behaviors, we force arguments with + // > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, + // > `unsigned long long` and `double` to have 4-byte alignment. This + // > behavior may be changed when RV32E/ILP32E is ratified. + RiscV32 if self.llvm_abiname == LlvmAbi::Ilp32e => false, + + // These targets just do not support c-variadic definitions. + Bpf | SpirV => false, + + // We don't know how c-variadics work for this target. Using the default LLVM + // fallback implementation may work, but just to be safe we disallow this. + Other(_) => false, + + AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64 + | M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC + | PowerPC64 | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 | Wasm64 | X86 + | X86_64 | Xtensa => true, + } + } } pub trait HasTargetSpec { @@ -2221,13 +2274,18 @@ pub struct TargetOptions { pub os: Os, /// Environment name to use for conditional compilation (`target_env`). Defaults to [`Env::Unspecified`]. pub env: Env, - /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"` - /// or `"eabihf"`. Defaults to [`Abi::Unspecified`]. - /// This field is *not* forwarded directly to LLVM and therefore does not control which ABI (in - /// the sense of function calling convention) is actually used; its primary purpose is - /// `cfg(target_abi)`. The actual calling convention is controlled by `llvm_abiname`, - /// `llvm_floatabi`, and `rustc_abi`. - pub abi: Abi, + /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, + /// `"eabi"` or `"eabihf"`. Defaults to [`CfgAbi::Unspecified`]. + /// The only purpose of this field is to control `cfg(target_abi)`. This does not control the + /// calling convention used by this target! The actual calling convention is controlled by + /// `llvm_abiname`, `llvm_floatabi`, and `rustc_abi`. + /// + /// In a target spec, this field generally *informs* the user about what the ABI is, but you + /// have to also set up other parts of the target spec to ensure that this information is + /// correct. In the rest of the compiler, do not check this field if what you actually need to + /// know about is the calling convention. Most targets have an open-ended set of values for this + /// field. + pub cfg_abi: CfgAbi, /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown". #[rustc_lint_opt_deny_field_access( "use `Target::is_like_*` instead of this field; see https://github.com/rust-lang/rust/issues/100343 for rationale" @@ -2537,7 +2595,7 @@ pub struct TargetOptions { /// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers /// and the `-target-abi` flag in llc. In the LLVM API this is `MCOptions.ABIName`. - pub llvm_abiname: StaticCow<str>, + pub llvm_abiname: LlvmAbi, /// Control the float ABI to use, for architectures that support it. The only architecture we /// currently use this for is ARM. Corresponds to the `-float-abi` flag in llc. In the LLVM API @@ -2550,7 +2608,6 @@ pub struct TargetOptions { /// Picks a specific ABI for this target. This is *not* just for "Rust" ABI functions, /// it can also affect "C" ABI functions; the point is that this flag is interpreted by /// rustc and not forwarded to LLVM. - /// So far, this is only used on x86. pub rustc_abi: Option<RustcAbi>, /// Whether or not RelaxElfRelocation flag will be passed to the linker @@ -2739,7 +2796,7 @@ fn default() -> TargetOptions { c_int_width: 32, os: Os::None, env: Env::Unspecified, - abi: Abi::Unspecified, + cfg_abi: CfgAbi::Unspecified, vendor: "unknown".into(), linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), @@ -2835,7 +2892,7 @@ fn default() -> TargetOptions { merge_functions: MergeFunctions::Aliases, mcount: "mcount".into(), llvm_mcount_intrinsic: None, - llvm_abiname: "".into(), + llvm_abiname: LlvmAbi::Unspecified, llvm_floatabi: None, rustc_abi: None, relax_elf_relocations: false, @@ -3183,71 +3240,106 @@ macro_rules! check_matches { ); } + // Ensure built-in targets don't use the `Other` variants. + if kind == TargetKind::Builtin { + check!( + !matches!(self.arch, Arch::Other(_)), + "`Arch::Other` is only meant for JSON targets" + ); + check!(!matches!(self.os, Os::Other(_)), "`Os::Other` is only meant for JSON targets"); + check!( + !matches!(self.env, Env::Other(_)), + "`Env::Other` is only meant for JSON targets" + ); + check!( + !matches!(self.cfg_abi, CfgAbi::Other(_)), + "`CfgAbi::Other` is only meant for JSON targets" + ); + check!( + !matches!(self.llvm_abiname, LlvmAbi::Other(_)), + "`LlvmAbi::Other` is only meant for JSON targets" + ); + } + // Check ABI flag consistency, for the architectures where we have proper ABI treatment. // To ensure targets are trated consistently, please consult with the team before allowing // new cases. match self.arch { Arch::X86 => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on x86-32"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on x86-32" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on x86-32"); check_matches!( - (&self.rustc_abi, &self.abi), + (&self.rustc_abi, &self.cfg_abi), // FIXME: we do not currently set a target_abi for softfloat targets here, // but we probably should, so we already allow it. - (Some(RustcAbi::Softfloat), Abi::SoftFloat | Abi::Unspecified | Abi::Other(_)) - | ( - Some(RustcAbi::X86Sse2) | None, - Abi::Uwp | Abi::Llvm | Abi::Sim | Abi::Unspecified | Abi::Other(_) - ), + ( + Some(RustcAbi::Softfloat), + CfgAbi::SoftFloat | CfgAbi::Unspecified | CfgAbi::Other(_) + ) | ( + Some(RustcAbi::X86Sse2) | None, + CfgAbi::Uwp + | CfgAbi::Llvm + | CfgAbi::Sim + | CfgAbi::Unspecified + | CfgAbi::Other(_) + ), "invalid x86-32 Rust-specific ABI and `cfg(target_abi)` combination:\n\ Rust-specific ABI: {:?}\n\ cfg(target_abi): {}", self.rustc_abi, - self.abi, + self.cfg_abi, ); } Arch::X86_64 => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on x86-64"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on x86-64" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on x86-64"); // FIXME: we do not currently set a target_abi for softfloat targets here, but we // probably should, so we already allow it. // FIXME: Ensure that target_abi = "x32" correlates with actually using that ABI. // Do any of the others need a similar check? check_matches!( - (&self.rustc_abi, &self.abi), - (Some(RustcAbi::Softfloat), Abi::SoftFloat | Abi::Unspecified | Abi::Other(_)) - | ( - None, - Abi::X32 - | Abi::Llvm - | Abi::Fortanix - | Abi::Uwp - | Abi::MacAbi - | Abi::Sim - | Abi::Unspecified - | Abi::Other(_) - ), + (&self.rustc_abi, &self.cfg_abi), + ( + Some(RustcAbi::Softfloat), + CfgAbi::SoftFloat | CfgAbi::Unspecified | CfgAbi::Other(_) + ) | ( + None, + CfgAbi::X32 + | CfgAbi::Llvm + | CfgAbi::Fortanix + | CfgAbi::Uwp + | CfgAbi::MacAbi + | CfgAbi::Sim + | CfgAbi::Unspecified + | CfgAbi::Other(_) + ), "invalid x86-64 Rust-specific ABI and `cfg(target_abi)` combination:\n\ Rust-specific ABI: {:?}\n\ cfg(target_abi): {}", self.rustc_abi, - self.abi, + self.cfg_abi, ); } Arch::RiscV32 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on RISC-V"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on RISC-V"); check_matches!( - (&*self.llvm_abiname, &self.abi), - ("ilp32", Abi::Unspecified | Abi::Other(_)) - | ("ilp32f", Abi::Unspecified | Abi::Other(_)) - | ("ilp32d", Abi::Unspecified | Abi::Other(_)) - | ("ilp32e", Abi::Ilp32e), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::Ilp32, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Ilp32f, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Ilp32d, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Ilp32e, CfgAbi::Ilp32e), "invalid RISC-V ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::RiscV64 => { @@ -3255,68 +3347,77 @@ macro_rules! check_matches { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on RISC-V"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on RISC-V"); check_matches!( - (&*self.llvm_abiname, &self.abi), - ("lp64", Abi::Unspecified | Abi::Other(_)) - | ("lp64f", Abi::Unspecified | Abi::Other(_)) - | ("lp64d", Abi::Unspecified | Abi::Other(_)) - | ("lp64e", Abi::Unspecified | Abi::Other(_)), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::Lp64, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Lp64f, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Lp64d, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Lp64e, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid RISC-V ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::Arm => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on ARM"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on ARM" + ); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on ARM"); check_matches!( - (&self.llvm_floatabi, &self.abi), + (&self.llvm_floatabi, &self.cfg_abi), ( Some(FloatAbi::Hard), - Abi::EabiHf | Abi::Uwp | Abi::Unspecified | Abi::Other(_) - ) | (Some(FloatAbi::Soft), Abi::Eabi), + CfgAbi::EabiHf | CfgAbi::Uwp | CfgAbi::Unspecified | CfgAbi::Other(_) + ) | (Some(FloatAbi::Soft), CfgAbi::Eabi), "Invalid combination of float ABI and `cfg(target_abi)` for ARM target\n\ float ABI: {:?}\n\ cfg(target_abi): {}", self.llvm_floatabi, - self.abi, + self.cfg_abi, ) } Arch::AArch64 => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on aarch64"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on aarch64" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on aarch64"); // FIXME: Ensure that target_abi = "ilp32" correlates with actually using that ABI. // Do any of the others need a similar check? check_matches!( - (&self.rustc_abi, &self.abi), - (Some(RustcAbi::Softfloat), Abi::SoftFloat) + (&self.rustc_abi, &self.cfg_abi), + (Some(RustcAbi::Softfloat), CfgAbi::SoftFloat) | ( None, - Abi::Ilp32 - | Abi::Llvm - | Abi::MacAbi - | Abi::Sim - | Abi::Uwp - | Abi::Unspecified - | Abi::Other(_) + CfgAbi::Ilp32 + | CfgAbi::Llvm + | CfgAbi::MacAbi + | CfgAbi::Sim + | CfgAbi::Uwp + | CfgAbi::Unspecified + | CfgAbi::Other(_) ), "invalid aarch64 Rust-specific ABI and `cfg(target_abi)` combination:\n\ Rust-specific ABI: {:?}\n\ cfg(target_abi): {}", self.rustc_abi, - self.abi, + self.cfg_abi, ); } Arch::PowerPC => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on PowerPC"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on PowerPC" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on PowerPC"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on PowerPC"); // FIXME: Check that `target_abi` matches the actually configured ABI (with or // without SPE). check_matches!( - self.abi, - Abi::Spe | Abi::Unspecified | Abi::Other(_), + self.cfg_abi, + CfgAbi::Spe | CfgAbi::Unspecified | CfgAbi::Other(_), "invalid `target_abi` for PowerPC" ); } @@ -3328,116 +3429,123 @@ macro_rules! check_matches { // FIXME: Check that `target_abi` matches the actually configured ABI // (vec-default vs vec-ext). check_matches!( - (&*self.llvm_abiname, &self.abi), - ("", Abi::VecDefault | Abi::VecExtAbi), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::Unspecified, CfgAbi::VecDefault | CfgAbi::VecExtAbi), "invalid PowerPC64 AIX ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } else if self.endian == Endian::Big { check_matches!( - (&*self.llvm_abiname, &self.abi), - ("elfv1", Abi::ElfV1) | ("elfv2", Abi::ElfV2), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::ElfV1, CfgAbi::ElfV1) | (LlvmAbi::ElfV2, CfgAbi::ElfV2), "invalid PowerPC64 big-endian ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } else { check_matches!( - (&*self.llvm_abiname, &self.abi), - ("elfv2", Abi::ElfV2), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::ElfV2, CfgAbi::ElfV2), "invalid PowerPC64 little-endian ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } } Arch::S390x => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on s390x"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on s390x" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on s390x"); check_matches!( - (&self.rustc_abi, &self.abi), - (Some(RustcAbi::Softfloat), Abi::SoftFloat) - | (None, Abi::Unspecified | Abi::Other(_)), + (&self.rustc_abi, &self.cfg_abi), + (Some(RustcAbi::Softfloat), CfgAbi::SoftFloat) + | (None, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid s390x Rust-specific ABI and `cfg(target_abi)` combination:\n\ Rust-specific ABI: {:?}\n\ cfg(target_abi): {}", self.rustc_abi, - self.abi, + self.cfg_abi, ); } Arch::LoongArch32 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on LoongArch"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on LoongArch"); check_matches!( - (&*self.llvm_abiname, &self.abi), - ("ilp32s", Abi::SoftFloat) - | ("ilp32f", Abi::Unspecified | Abi::Other(_)) - | ("ilp32d", Abi::Unspecified | Abi::Other(_)), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::Ilp32s, CfgAbi::SoftFloat) + | (LlvmAbi::Ilp32f, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Ilp32d, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid LoongArch ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::LoongArch64 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on LoongArch"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on LoongArch"); check_matches!( - (&*self.llvm_abiname, &self.abi), - ("lp64s", Abi::SoftFloat) - | ("lp64f", Abi::Unspecified | Abi::Other(_)) - | ("lp64d", Abi::Unspecified | Abi::Other(_)), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::Lp64s, CfgAbi::SoftFloat) + | (LlvmAbi::Lp64f, CfgAbi::Unspecified | CfgAbi::Other(_)) + | (LlvmAbi::Lp64d, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid LoongArch ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::Mips | Arch::Mips32r6 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on MIPS"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); check_matches!( - (&*self.llvm_abiname, &self.abi), - ("o32", Abi::Unspecified | Abi::Other(_)), + (&self.llvm_abiname, &self.cfg_abi), + (LlvmAbi::O32, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::Mips64 | Arch::Mips64r6 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on MIPS"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); check_matches!( - (&*self.llvm_abiname, &self.abi), + (&self.llvm_abiname, &self.cfg_abi), // No in-tree targets use "n32" but at least for now we let out-of-tree targets // experiment with that. - ("n64", Abi::Abi64) | ("n32", Abi::Unspecified | Abi::Other(_)), + (LlvmAbi::N64, CfgAbi::Abi64) + | (LlvmAbi::N32, CfgAbi::Unspecified | CfgAbi::Other(_)), "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", self.llvm_abiname, - self.abi, + self.cfg_abi, ); } Arch::CSky => { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on CSky"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on CSky" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on CSky"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on CSky"); // FIXME: Check that `target_abi` matches the actually configured ABI (v2 vs v2hf). check_matches!( - self.abi, - Abi::AbiV2 | Abi::AbiV2Hf, + self.cfg_abi, + CfgAbi::AbiV2 | CfgAbi::AbiV2Hf, "invalid `target_abi` for CSky" ); } @@ -3446,11 +3554,14 @@ macro_rules! check_matches { // Ensure consistency among built-in targets, but give JSON targets the opportunity // to experiment with these. if kind == TargetKind::Builtin { - check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on {arch}"); + check!( + self.llvm_abiname == LlvmAbi::Unspecified, + "`llvm_abiname` is unused on {arch}" + ); check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on {arch}"); check_matches!( - self.abi, - Abi::Unspecified | Abi::Other(_), + self.cfg_abi, + CfgAbi::Unspecified | CfgAbi::Other(_), "`target_abi` is unused on {arch}" ); } @@ -3665,7 +3776,7 @@ pub fn object_architecture( // it using a custom target specification. N32 // is an ILP32 ABI like the Aarch64_Ilp32 // and X86_64_X32 cases above and below this one. - if self.options.llvm_abiname.as_ref() == "n32" { + if self.options.llvm_abiname == LlvmAbi::N32 { Architecture::Mips64_N32 } else { Architecture::Mips64
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs index 4abd555..8a432ca 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, CfgAbi, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - abi: Abi::Ilp32, + cfg_abi: CfgAbi::Ilp32, features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs index e204c64..77a57f9 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs
@@ -8,13 +8,13 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, rustc_abi: Some(RustcAbi::Softfloat), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), @@ -22,7 +22,9 @@ pub(crate) fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, endian: Endian::Big,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs index 22f2717..e8e7b84 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, CfgAbi, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - abi: Abi::Ilp32, + cfg_abi: CfgAbi::Ilp32, features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs index 1c16603..13d3b77 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
@@ -21,7 +21,9 @@ pub(crate) fn target() -> Target { &["--fix-cortex-a53-843419"], ), features: "+v8a,+strict-align,+neon".into(), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index ed2e2fb..0587689 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
@@ -7,13 +7,13 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, rustc_abi: Some(RustcAbi::Softfloat), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), @@ -21,7 +21,9 @@ pub(crate) fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, default_uwtable: true,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs index 19b7ebe..1e06d3a 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs
@@ -21,7 +21,9 @@ pub(crate) fn target() -> Target { &["--fix-cortex-a53-843419"], ), features: "+v8a,+strict-align,+neon".into(), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none.rs index 8f8bbb4..680d896 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none.rs
@@ -8,7 +8,9 @@ pub(crate) fn target() -> Target { // based off the aarch64-unknown-none target at time of addition linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs index 6f11f97..ee9a6b8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs
@@ -1,18 +1,20 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, rustc_abi: Some(RustcAbi::Softfloat), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), - supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KCFI + | SanitizerSet::KERNELADDRESS + | SanitizerSet::KERNELHWADDRESS, stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, default_uwtable: true,
diff --git a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs index 7dc6509..5b0951b 100644 --- a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Abi, Arch, FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CfgAbi, FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -13,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // https://developer.android.com/ndk/guides/abis.html#armeabi features: "+strict-align,+v5te".into(),
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs index cc63ffa..5275113 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+strict-align,+v6".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs index 1cae42c..7dd36d6 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+strict-align,+v6,+vfp2".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs index 25ef767..5dce420 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // Most of these settings are copied from the arm_unknown_linux_gnueabi // target.
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs index 99995e2..5b1d1e2 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target.
diff --git a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs index 73374bc..df9ecd6 100644 --- a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+strict-align,+v8,+crc".into(), endian: Endian::Big,
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs index 7a62464..a460852 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
@@ -3,8 +3,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), endian: Endian::Big, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs index 33147c5..4452b3b 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
@@ -3,8 +3,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), endian: Endian::Big, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs index c917531..176bdec 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs
@@ -9,7 +9,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",], features: "+soft-float,+strict-align".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs index 8c38601..9d95a2b 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs index b8ae881..17065c8 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs
@@ -1,6 +1,6 @@ //! Targets the ARMv5TE architecture, with `a32` code by default. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv5te", "-mlittle-endian",], features: "+soft-float,+strict-align".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs index d1fded2..17ad14c 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs index 2daf2ab..b5a31a9 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs index b05df3a..ac07c87 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins
diff --git a/compiler/rustc_target/src/spec/targets/armv6_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv6_none_eabi.rs index 48a196b..c2c6ec4 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_none_eabi.rs
@@ -1,6 +1,6 @@ //! Targets the ARMv6K architecture, with `a32` code by default. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv6", "-mlittle-endian",], features: "+soft-float,+strict-align,+v6k".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv6_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_none_eabihf.rs index 8bc6b06..d4886ee 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_none_eabihf.rs
@@ -1,6 +1,6 @@ //! Targets the ARMv6K architecture, with `a32` code by default, and hard-float ABI -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), asm_args: cvs!["-mthumb-interwork", "-march=armv6", "-mlittle-endian",], features: "+strict-align,+v6k,+vfp2,-d32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs index 6d6dfee..bd71c83 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v6,+vfp2".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs index cb931e6..5e5468d 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v6,+vfp2".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs index ed2ab47..d2bdf74 100644 --- a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs +++ b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, + Arch, Cc, CfgAbi, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -29,7 +29,7 @@ pub(crate) fn target() -> Target { env: Env::Newlib, vendor: "nintendo".into(), cpu: "mpcore".into(), - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), families: cvs!["unix"], linker: Some("arm-none-eabi-gcc".into()),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs index 3ccb99c..99adc85 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, TargetOptions, base, }; @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb-mode,+thumb2,+vfp3d16,-neon".into(), supported_sanitizers: SanitizerSet::ADDRESS,
diff --git a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs index 382658a..90daac1 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + Arch, Cc, CfgAbi, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { os: Os::Rtems, families: cvs!["unix"], - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), linker: None,
diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs index 20e5c0ac..56d129d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
@@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, + Arch, Cc, CfgAbi, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -34,7 +34,7 @@ pub(crate) fn target() -> Target { c_int_width: 32, env: Env::Newlib, vendor: "sony".into(), - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), no_default_libraries: false,
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs index c358b53..cd6d8b7 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs index 8fad2ce..88f9b9e 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs index 639a9d2..a1f90b3 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+vfp3d16,+thumb2,-neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs index 9bf0b4f..66e1eb1 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs index fb7bd12..6ce45de 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode or NEON. @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs index 318170f..1709bef 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or // hardfloat. @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs index 37a70da..979a02b 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON, // thumb-mode or hardfloat. @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), cpu: "generic".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs index 8fb38d3..63845a1 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { cpu: "generic".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), ..base },
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs index 8869210..4000e39 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs index fb3954a..e561af2 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, FloatAbi, LinkSelfContainedDefault, Os, PanicStrategy, RelroLevel, Target, + Arch, CfgAbi, FloatAbi, LinkSelfContainedDefault, Os, PanicStrategy, RelroLevel, Target, TargetMetadata, TargetOptions, }; @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs index 27e81c5..63f82a0 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+vfp3d16,+thumb2,-neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs index bd18d6d..8723dc0 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Abi, Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CfgAbi, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { let base = base::solid::opts(); @@ -14,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker: Some("arm-kmc-eabi-gcc".into()), features: "+v7,+soft-float,+thumb2,-neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs index cb652e6..b59ce32 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Abi, Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CfgAbi, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { let base = base::solid::opts(); @@ -14,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker: Some("arm-kmc-eabi-gcc".into()), features: "+v7,+vfp3d16,+thumb2,-neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index e8c5c16..01d55ce 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,-neon,+strict-align".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index 32a79e3..cbeb409 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3d16,-neon,+strict-align".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs index 5ab74e05..9af6bac 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs
@@ -5,13 +5,13 @@ // configuration without hardware floating point support. use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs index 4ac07e2..5008f38 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs
@@ -5,13 +5,13 @@ // configuration with hardware floating point support. use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index b83d7b0..cf4ea3c 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + Arch, Cc, CfgAbi, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { env: Env::V5, os: Os::VexOs, cpu: "cortex-a9".into(), - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, is_like_vexos: true, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index 114b079..382f862 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(64), has_thumb_interworking: true,
diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 1c6114f..b8d0ea2 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3d16".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index 16006e4..a488637f 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Armv8-R requires a minimum set of floating-point features equivalent to: // fp-armv8, SP-only, with 16 DP (32 SP) registers
diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs index 176b853..72193fc 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, Cc, CfgAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, +}; // This target is for glibc Linux on Csky @@ -16,7 +18,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), arch: Arch::CSky, options: TargetOptions { - abi: Abi::AbiV2, + cfg_abi: CfgAbi::AbiV2, features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a"]), max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs index 5af5449..cf44932 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, Cc, CfgAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, +}; // This target is for glibc Linux on Csky @@ -16,7 +18,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), arch: Arch::CSky, options: TargetOptions { - abi: Abi::AbiV2Hf, + cfg_abi: CfgAbi::AbiV2Hf, cpu: "ck860fv".into(), features: "+hard-float,+hard-float-abi,+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a", "-mhard-float"]),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs index d9a4708..7e074b7 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,8 +20,9 @@ pub(crate) fn target() -> Target { features: "+f,+d".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "ilp32d".into(), + llvm_abiname: LlvmAbi::Ilp32d, max_atomic_width: Some(32), + mcount: "_mcount".into(), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs index 896cf0f..4e68070 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -18,11 +18,12 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "ilp32s".into(), + llvm_abiname: LlvmAbi::Ilp32s, max_atomic_width: Some(32), + mcount: "_mcount".into(), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs index 5936ea5..8dad88b 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -16,8 +18,9 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic".into(), features: "+f,+d,+lsx,+relax".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), + mcount: "_mcount".into(), supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs index 2951b34..91a0289 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -16,8 +18,9 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic".into(), features: "+f,+d,+lsx,+relax".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), + mcount: "_mcount".into(), crt_static_default: false, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs index 1dab4fe..6792356 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
@@ -1,4 +1,6 @@ -use crate::spec::{Arch, CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -16,8 +18,9 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic".into(), features: "+f,+d,+lsx,+relax".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), + mcount: "_mcount".into(), supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs index d8b5095..2d3b217 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -20,8 +20,9 @@ pub(crate) fn target() -> Target { features: "+f,+d,-lsx".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), + mcount: "_mcount".into(), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index efeb864..f5e2fb4 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, CodeModel, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -18,11 +18,12 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "lp64s".into(), + llvm_abiname: LlvmAbi::Lp64s, max_atomic_width: Some(64), + mcount: "_mcount".into(), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs index f90e689..8b02e12 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -2,7 +2,7 @@ use rustc_abi::Endian; -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -24,10 +24,10 @@ pub(crate) fn target() -> Target { arch: Arch::Mips64, options: TargetOptions { vendor: "openwrt".into(), - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, endian: Endian::Big, mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base }, }
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs index ecb66b4..1494288 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,14 +15,14 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, endian: Endian::Big, // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".into(), features: "+mips64r2,+xgot".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base::linux_gnu::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs index ccb13fe..c5336fd 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -20,10 +20,10 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, endian: Endian::Big, mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base }, }
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs index 2457bd8..665cf1d 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,13 +13,13 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".into(), features: "+mips64r2,+xgot".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base::linux_gnu::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs index 4135372..bd237ea 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -18,9 +18,9 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base }, }
diff --git a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs index ed024c6..32440cd 100644 --- a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -24,7 +25,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), features: "+mips32r2,+soft-float,+noabicalls".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs index 9eb3173..8bfa8ec 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), features: "+mips32r2,+fpxx,+nooddspreg".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs index 5737e42..316e59d 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { arch: Arch::Mips, options: TargetOptions { endian: Endian::Big, - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, mcount: "_mcount".into(), ..base },
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs index d9bfa12..b03dec5 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), features: "+mips32r2,+soft-float".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs index 767c57e..ce50ced 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -24,7 +25,7 @@ pub(crate) fn target() -> Target { endian: Endian::Little, cpu: "mips32r2".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), features: "+mips32r2,+soft-float,+noabicalls".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs index bc8f29c..2fde3e9 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, RelocModel, Target, TargetMetadata, TargetOptions, + cvs, }; // The PSP has custom linker requirements. @@ -36,7 +37,7 @@ pub(crate) fn target() -> Target { // PSP does not support trap-on-condition instructions. llvm_args: cvs!["-mno-check-zero-division"], - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, pre_link_args, link_script: Some(LINKER_SCRIPT.into()), ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index 06631fd..cb88c71 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -41,7 +41,7 @@ pub(crate) fn target() -> Target { // PSX does not support trap-on-condition instructions. llvm_args: cvs!["-mno-check-zero-division"], - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, panic_strategy: PanicStrategy::Abort, ..Default::default() },
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs index 752de46..0541e0e 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r2".into(), features: "+mips32r2,+fpxx,+nooddspreg".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs index fb33752..5d0136a 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -16,6 +16,6 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), arch: Arch::Mips, - options: TargetOptions { llvm_abiname: "o32".into(), mcount: "_mcount".into(), ..base }, + options: TargetOptions { llvm_abiname: LlvmAbi::O32, mcount: "_mcount".into(), ..base }, } }
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs index 830cdd1..0add21b 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r2".into(), features: "+mips32r2,+soft-float".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs index 2620629..5395c15 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::netbsd::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { arch: Arch::Mips, options: TargetOptions { features: "+soft-float".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, mcount: "__mcount".into(), endian: Endian::Little, ..base
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs index b66be0b..0e184c8 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs
@@ -3,7 +3,8 @@ //! Can be used for MIPS M4K core (e.g. on PIC32MX devices) use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -23,7 +24,7 @@ pub(crate) fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips32r2".into(), features: "+mips32r2,+soft-float,+noabicalls".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), linker: Some("rust-lld".into()), panic_strategy: PanicStrategy::Abort,
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs index 9b06336..8091650 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r6".into(), features: "+mips32r6".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs index a5a05d5..87db5a2 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r6".into(), features: "+mips32r6".into(), - llvm_abiname: "o32".into(), + llvm_abiname: LlvmAbi::O32, max_atomic_width: Some(32), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs index fb97a2e..8e66407 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,14 +15,14 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64r6, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, endian: Endian::Big, // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".into(), features: "+mips64r6".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base::linux_gnu::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs index 5569624..5523f44 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,13 +13,13 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64r6, options: TargetOptions { - abi: Abi::Abi64, + cfg_abi: CfgAbi::Abi64, // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".into(), features: "+mips64r6".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - llvm_abiname: "n64".into(), + llvm_abiname: LlvmAbi::N64, ..base::linux_gnu::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs index f5d5698..537b21c 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64-unknown-freebsd".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs index e2dada2..df7f115 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV1; - base.llvm_abiname = "elfv1".into(); + base.cfg_abi = CfgAbi::ElfV1; + base.llvm_abiname = LlvmAbi::ElfV1; Target { llvm_target: "powerpc64-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index 130bcac..474d20d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs index 082358e..052dbf5 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64-unknown-openbsd".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs index f576d23..4a684fe 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV1; - base.llvm_abiname = "elfv1".into(); + base.cfg_abi = CfgAbi::ElfV1; + base.llvm_abiname = LlvmAbi::ElfV1; Target { llvm_target: "powerpc64-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs index b2713af..35c477d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -8,8 +9,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64le-unknown-freebsd".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs index 550ad56..ae2c871 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -8,8 +9,8 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64le-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs index 38e3d09..0060a41 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, + TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,8 +11,8 @@ pub(crate) fn target() -> Target { base.stack_probes = StackProbeType::Inline; // FIXME(compiler-team#422): musl targets should be dynamically linked by default. base.crt_static_default = true; - base.abi = Abi::ElfV2; - base.llvm_abiname = "elfv2".into(); + base.cfg_abi = CfgAbi::ElfV2; + base.llvm_abiname = LlvmAbi::ElfV2; Target { llvm_target: "powerpc64le-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs index 4962030..88655c9 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: Abi::Spe, + cfg_abi: CfgAbi::Spe, endian: Endian::Big, features: "+secure-plt,+msync".into(), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs index 210a80f..c61ceab 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: Abi::Spe, + cfg_abi: CfgAbi::Spe, endian: Endian::Big, features: "+msync".into(), mcount: "_mcount".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs index 041580f..8f7aaa0 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
@@ -1,7 +1,8 @@ use rustc_abi::Endian; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: Abi::Spe, + cfg_abi: CfgAbi::Spe, endian: Endian::Big, // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2 features: "+secure-plt,+msync".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs index 3ec8891..2e0a13f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { cpu: "generic-rv32".into(), - llvm_abiname: "ilp32d".into(), + llvm_abiname: LlvmAbi::Ilp32d, max_atomic_width: Some(32), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), stack_probes: StackProbeType::Inline,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs index 65dbd39..90dcf17 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: Abi::Ilp32e, + cfg_abi: CfgAbi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: LlvmAbi::Ilp32e, max_atomic_width: Some(32), atomic_cas: false, features: "+e,+forced-atomics".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs index 0826326..cba1809 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: Abi::Ilp32e, + cfg_abi: CfgAbi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: LlvmAbi::Ilp32e, max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+forced-atomics".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs index e37a44e..9de6ef9 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: Abi::Ilp32e, + cfg_abi: CfgAbi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: LlvmAbi::Ilp32e, max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+c,+forced-atomics".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs index 29b0f35..c11edf7 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
@@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -18,7 +20,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv32".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "ilp32d".into(), + llvm_abiname: LlvmAbi::Ilp32d, max_atomic_width: Some(32), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..base::linux_gnu::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs index 2811605..e5618ea 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -18,7 +20,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv32".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "ilp32d".into(), + llvm_abiname: LlvmAbi::Ilp32d, max_atomic_width: Some(32), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..base::linux_musl::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs index bd6375f..2e4d83b 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(32), atomic_cas: false, features: "+forced-atomics".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs index af25334..82cc02aa 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { atomic_cas: true, features: "+m".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, executables: true, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs index 5aef58b..f47102c 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(32), atomic_cas: false, features: "+m,+forced-atomics".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs index c455f65..a963674 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -21,7 +22,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv32".into(), max_atomic_width: Some(32), features: "+m,+a".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs index 11a5626..8891527 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Env, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -29,7 +29,7 @@ pub(crate) fn target() -> Target { atomic_cas: true, features: "+m,+a,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs index deca348..c27e7aa 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -21,7 +22,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv32".into(), max_atomic_width: Some(32), features: "+m,+a,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs index 7205fb6..3a5a942 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv32".into(), max_atomic_width: Some(32), features: "+m,+a,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Unwind, relocation_model: RelocModel::Static, ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs index 363e465..6d8bf30 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv32".into(), max_atomic_width: Some(32), features: "+m,+a,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Unwind, relocation_model: RelocModel::Static, ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs index b3a3ab9..614d81f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Env, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(32), atomic_cas: true, - llvm_abiname: "ilp32f".into(), + llvm_abiname: LlvmAbi::Ilp32f, features: "+m,+a,+c,+f".into(), panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs index 21f6835..bf519fb 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -20,7 +21,7 @@ pub(crate) fn target() -> Target { linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(32), - llvm_abiname: "ilp32f".into(), + llvm_abiname: LlvmAbi::Ilp32f, features: "+m,+a,+c,+f".into(), panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs index 0bba2e4..045845a 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(32), - llvm_abiname: "ilp32f".into(), + llvm_abiname: LlvmAbi::Ilp32f, features: "+m,+a,+c,+f".into(), panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs index f903bbd..cfec1b5 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Env, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { atomic_cas: true, features: "+m,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs index 0b8e447..1010039 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
@@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -22,7 +23,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(32), atomic_cas: false, features: "+m,+c,+forced-atomics".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false,
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs index d1d7384..6143080 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + Arch, Cc, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv32".into(), max_atomic_width: Some(32), features: "+m,+c".into(), - llvm_abiname: "ilp32".into(), + llvm_abiname: LlvmAbi::Ilp32, panic_strategy: PanicStrategy::Unwind, relocation_model: RelocModel::Static, ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs index 404f414..9842b9f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
@@ -1,7 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - Arch, CodeModel, SanitizerSet, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, + Arch, CodeModel, LlvmAbi, SanitizerSet, SplitDebuginfo, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { @@ -20,7 +21,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+b,+v,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, supported_sanitizers: SanitizerSet::ADDRESS, max_atomic_width: Some(64), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs index c6fffc25..f3389b8 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, StackProbeType, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, LlvmAbi, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV64, options: TargetOptions { cpu: "generic-rv64".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), stack_probes: StackProbeType::Inline,
diff --git a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs index bbcf31f..f9a7d30 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64a23_unknown_linux_gnu.rs
@@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -18,7 +20,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+rva23u64".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..base::linux_gnu::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs index dbcfbc3..d59d026 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), ..base::freebsd::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs index 2127048..3944c4c 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
@@ -1,11 +1,13 @@ -use crate::spec::{Arch, CodeModel, SanitizerSet, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); base.code_model = Some(CodeModel::Medium); base.cpu = "generic-rv64".into(); base.features = "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(); - base.llvm_abiname = "lp64d".into(); + base.llvm_abiname = LlvmAbi::Lp64d; base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::SHADOWCALLSTACK;
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs index 68f6904..516610d 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Arch, CodeModel, RelocModel, Target, TargetMetadata, TargetOptions, TlsModel, base, + Arch, CodeModel, LlvmAbi, RelocModel, Target, TargetMetadata, TargetOptions, TlsModel, base, }; pub(crate) fn target() -> Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), tls_model: TlsModel::LocalExec, max_atomic_width: Some(64), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, ..base::hermit::opts() }, }
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs index 333a63a..76c9ad6 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
@@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -18,7 +20,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..base::linux_gnu::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 6eba099..8ed4e09 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
@@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, CodeModel, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{ + Arch, CodeModel, LlvmAbi, SplitDebuginfo, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { Target { @@ -18,7 +20,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..base::linux_musl::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs index a9ecf27..f837daf 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, CodeModel, Target, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, LlvmAbi, Target, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), ..base::managarm_mlibc::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs index bc929a0..564d9b2 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), mcount: "__mcount".into(), ..base::netbsd::opts()
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs index b06727e..f79cd50 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, - TargetMetadata, TargetOptions, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, SanitizerSet, + Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, cpu: "generic-rv64".into(), max_atomic_width: Some(64), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs index 7850cc8..9fde109 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, SanitizerSet, Target, - TargetMetadata, TargetOptions, cvs, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, SanitizerSet, + Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, cpu: "generic-rv64".into(), max_atomic_width: Some(64), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs index fb7b077..b937007 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Arch, CodeModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CodeModel, LlvmAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(), - llvm_abiname: "lp64d".into(), + llvm_abiname: LlvmAbi::Lp64d, max_atomic_width: Some(64), ..base::openbsd::opts() },
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs index b6e8864..4213221 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_redox.rs
@@ -1,11 +1,11 @@ -use crate::spec::{Arch, CodeModel, Target, TargetMetadata, base}; +use crate::spec::{Arch, CodeModel, LlvmAbi, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::redox::opts(); base.code_model = Some(CodeModel::Medium); base.cpu = "generic-rv64".into(); base.features = "+m,+a,+f,+d,+c".into(); - base.llvm_abiname = "lp64d".into(); + base.llvm_abiname = LlvmAbi::Lp64d; base.plt_by_default = false; base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs index 6aae40a..fb36efb 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(64), atomic_cas: false, features: "+m,+forced-atomics".into(), - llvm_abiname: "lp64".into(), + llvm_abiname: LlvmAbi::Lp64, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs index 60ee41b..65c3f1a 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, - TargetMetadata, TargetOptions, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, SanitizerSet, + Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv64".into(), max_atomic_width: Some(64), features: "+m,+a,+c".into(), - llvm_abiname: "lp64".into(), + llvm_abiname: LlvmAbi::Lp64, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs index b1a1817..469c0d1 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
@@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, SanitizerSet, Target, - TargetMetadata, TargetOptions, cvs, + Arch, Cc, CodeModel, LinkerFlavor, Lld, LlvmAbi, Os, PanicStrategy, RelocModel, SanitizerSet, + Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { cpu: "generic-rv64".into(), max_atomic_width: Some(64), features: "+m,+a,+c".into(), - llvm_abiname: "lp64".into(), + llvm_abiname: LlvmAbi::Lp64, panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, code_model: Some(CodeModel::Medium),
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs index 7d42c1f..8c41109 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs
@@ -1,13 +1,13 @@ use rustc_abi::{Align, Endian}; use crate::spec::{ - Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, + Arch, Cc, CfgAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: Abi::SoftFloat, + cfg_abi: CfgAbi::SoftFloat, cpu: "z10".into(), endian: Endian::Big, features: "+soft-float,-vector".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs index dfb8ccb..83bbfff 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs
@@ -9,7 +9,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",], features: "+soft-float,+strict-align".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs index 3b41208..7d2f910 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs
@@ -1,6 +1,6 @@ //! Targets the ARMv5TE architecture, with `t32` code by default. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv5te", "-mlittle-endian",], features: "+soft-float,+strict-align".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv6_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6_none_eabi.rs index 077f028..45a1221 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6_none_eabi.rs
@@ -1,6 +1,6 @@ //! Targets the ARMv6K architecture, with `t32` code by default. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), asm_args: cvs!["-mthumb-interwork", "-march=armv6", "-mlittle-endian",], features: "+soft-float,+strict-align,+v6k".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs index cc81cb9..19b5919 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align.
diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs index 8b58d2e..2536152 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align.
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs index ce11e3f..011307a 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,-neon,+strict-align".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs index 12210e9..4baa73c 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3d16,-neon,+strict-align".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs index 17d25a6..8eaebe7 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs
@@ -4,7 +4,7 @@ // and will use software floating point operations. This matches the NuttX EABI // configuration without hardware floating point support. -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // Cortex-A7/A8/A9 with software floating point features: "+soft-float,-neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs index a4e1700..ea070f0 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs
@@ -7,7 +7,7 @@ // This target uses the "hard" floating convention (ABI) where floating point values // are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.). -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Cortex-A7/A8/A9 support VFPv3-D32/VFPv4-D32 with optional double-precision // and NEON SIMD instructions
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs index 6e6975c..a9d7660 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs
@@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs index 6a7fe14..6af82f8 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
@@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // vfp4 is the lowest common denominator between the Cortex-M4F (vfp4) and the // Cortex-M7 (vfp5).
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs index 1017327..3166a01 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs
@@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -27,7 +27,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs index 1f24155..3e5e7da 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs
@@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // vfp4 is the lowest common denominator between the Cortex-M4F (vfp4) and the // Cortex-M7 (vfp5).
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs index 8851f7b..d38d2ac 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs index 9f0261c..7e42c91 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs index 3ffa301..56c581b 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs
@@ -1,5 +1,5 @@ use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, + Arch, Cc, CfgAbi, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, }; // This target if is for the Android v7a ABI in thumb mode with @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs index 36b9951..5829d37 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs index 41c4bc9..dc4f898 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
@@ -1,4 +1,4 @@ -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf // target. options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs index bf71d31..da66a53 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(64), has_thumb_interworking: true,
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs index 88b5e67..d591db8 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+vfp3d16".into(), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs index 7426eb9..b9193a2 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them // with +strict-align.
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs index a74719b..1e786a4 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs
@@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them // with +strict-align.
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs index 540d4bd..a3a8da4 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs
@@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs index 2287cce..d8058ba 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
@@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // If the Floating Point extension is implemented in the Cortex-M33 // processor, the Cortex-M33 Technical Reference Manual states that
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs index ec10729..e132066 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs
@@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::Eabi, + cfg_abi: CfgAbi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::arm_none::opts()
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs index 9ff924b..e3ba784 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs
@@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], os: Os::NuttX, - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // If the Floating Point extension is implemented in the Cortex-M33 // processor, the Cortex-M33 Technical Reference Manual states that
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs index 87434cd..459dff9 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs
@@ -1,6 +1,6 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) -use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Arch, CfgAbi, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: Abi::EabiHf, + cfg_abi: CfgAbi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Armv8-R requires a minimum set of floating-point features equivalent to: // fp-armv8, SP-only, with 16 DP (32 SP) registers
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs index cd074a4..1204719 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
@@ -1,7 +1,7 @@ use std::borrow::Cow; use crate::spec::{ - Abi, Arch, Cc, Env, LinkerFlavor, Lld, Os, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, CfgAbi, Env, LinkerFlavor, Lld, Os, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -60,7 +60,7 @@ pub(crate) fn target() -> Target { os: Os::Unknown, env: Env::Sgx, vendor: "fortanix".into(), - abi: Abi::Fortanix, + cfg_abi: CfgAbi::Fortanix, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnumsan.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnumsan.rs new file mode 100644 index 0000000..377aae8 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnumsan.rs
@@ -0,0 +1,16 @@ +use crate::spec::{SanitizerSet, Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::x86_64_unknown_linux_gnu::target(); + base.metadata = TargetMetadata { + description: Some( + "64-bit Linux (kernel 3.2+, glibc 2.17+) with MSAN enabled by default".into(), + ), + tier: Some(2), + host_tools: Some(false), + std: Some(true), + }; + base.supported_sanitizers = SanitizerSet::MEMORY; + base.default_sanitizers = SanitizerSet::MEMORY; + base +}
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnutsan.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnutsan.rs new file mode 100644 index 0000000..bbe377c --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnutsan.rs
@@ -0,0 +1,16 @@ +use crate::spec::{SanitizerSet, Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::x86_64_unknown_linux_gnu::target(); + base.metadata = TargetMetadata { + description: Some( + "64-bit Linux (kernel 3.2+, glibc 2.17+) with TSAN enabled by default".into(), + ), + tier: Some(2), + host_tools: Some(false), + std: Some(true), + }; + base.supported_sanitizers = SanitizerSet::THREAD; + base.default_sanitizers = SanitizerSet::THREAD; + base +}
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs index 7e06a71..793d235 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs
@@ -1,9 +1,11 @@ -use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, Cc, CfgAbi, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base, +}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "x86-64".into(); - base.abi = Abi::X32; + base.cfg_abi = CfgAbi::X32; base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mx32"]); base.stack_probes = StackProbeType::Inline;
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 80674ab..161bb31 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs
@@ -5,7 +5,7 @@ use rustc_macros::HashStable_Generic; use rustc_span::{Symbol, sym}; -use crate::spec::{Arch, FloatAbi, RustcAbi, Target}; +use crate::spec::{Arch, FloatAbi, LlvmAbi, RustcAbi, Target}; /// Features that control behaviour of rustc, rather than the codegen. /// These exist globally and are not in the target-specific lists below. @@ -392,7 +392,11 @@ pub fn toggle_allowed(&self) -> Result<(), &'static str> { "avx512vpopcntdq", ], ), - ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]), + ( + "avx10.2", + Unstable(sym::avx10_target_feature), + &["avx10.1", "avxvnni", "avxvnniint8", "avxvnniint16"], + ), ("avx512bf16", Stable, &["avx512bw"]), ("avx512bitalg", Stable, &["avx512bw"]), ("avx512bw", Stable, &["avx512f"]), @@ -756,8 +760,10 @@ pub fn toggle_allowed(&self) -> Result<(), &'static str> { // tidy-alphabetical-end ]; -const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] = - &[("alu32", Unstable(sym::bpf_target_feature), &[])]; +const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ + ("alu32", Unstable(sym::bpf_target_feature), &[]), + ("allows-misaligned-mem-access", Unstable(sym::bpf_target_feature), &[]), +]; static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start @@ -1174,20 +1180,20 @@ pub fn abi_required_features(&self) -> FeatureConstraints { Arch::RiscV32 | Arch::RiscV64 => { // RISC-V handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. - match &*self.llvm_abiname { - "ilp32d" | "lp64d" => { + match &self.llvm_abiname { + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => { // Requires d (which implies f), incompatible with e and zfinx. FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] } } - "ilp32f" | "lp64f" => { + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => { // Requires f, incompatible with e and zfinx. FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] } } - "ilp32" | "lp64" => { + LlvmAbi::Ilp32 | LlvmAbi::Lp64 => { // Requires nothing, incompatible with e. FeatureConstraints { required: &[], incompatible: &["e"] } } - "ilp32e" => { + LlvmAbi::Ilp32e => { // ilp32e is documented to be incompatible with features that need aligned // load/stores > 32 bits, like `d`. (One could also just generate more // complicated code to align the stack when needed, but the RISCV @@ -1198,7 +1204,7 @@ pub fn abi_required_features(&self) -> FeatureConstraints { // a program while the rest doesn't know they even exist. FeatureConstraints { required: &[], incompatible: &["d"] } } - "lp64e" => { + LlvmAbi::Lp64e => { // As above, `e` is not required. NOTHING } @@ -1208,16 +1214,16 @@ pub fn abi_required_features(&self) -> FeatureConstraints { Arch::LoongArch32 | Arch::LoongArch64 => { // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. - match &*self.llvm_abiname { - "ilp32d" | "lp64d" => { + match &self.llvm_abiname { + LlvmAbi::Ilp32d | LlvmAbi::Lp64d => { // Requires d (which implies f), incompatible with nothing. FeatureConstraints { required: &["d"], incompatible: &[] } } - "ilp32f" | "lp64f" => { + LlvmAbi::Ilp32f | LlvmAbi::Lp64f => { // Requires f, incompatible with nothing. FeatureConstraints { required: &["f"], incompatible: &[] } } - "ilp32s" | "lp64s" => { + LlvmAbi::Ilp32s | LlvmAbi::Lp64s => { // The soft-float ABI does not require any features and is also not // incompatible with any features. Rust targets explicitly specify the // LLVM ABI names, which allows for enabling hard-float support even on
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 7fcaea3..46bc9bd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -507,18 +507,17 @@ pub fn emit_inference_failure_err_with_type_hint( }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty); - if let Some(body) = self.tcx.hir_maybe_body_owned_by( - self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), - ) { + if let Some(body) = + self.tcx.hir_maybe_body_owned_by(self.tcx.typeck_root_def_id_local(body_def_id)) + { let expr = body.value; local_visitor.visit_expr(expr); } let Some(InferSource { span, kind }) = local_visitor.infer_source else { let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id) - && let parent = self.tcx.parent(body_def_id.into()) - && self.tcx.is_automatically_derived(parent) - && let Some(parent) = parent.as_local() + && let parent = self.tcx.local_parent(body_def_id) + && self.tcx.is_automatically_derived(parent.to_def_id()) && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent) && let hir::ItemKind::Impl(imp) = item.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 7f53fdb..6bfd9c7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -105,7 +105,13 @@ pub fn note_and_explain_type_err( if !sp.contains(p_span) { diag.span_label(p_span, format!("{expected}this type parameter")); } - let parent = p_def_id.as_local().and_then(|id| { + let param_def_id = match *proj.self_ty().kind() { + ty::Param(param) => { + tcx.generics_of(body_owner_def_id).type_param(param, tcx).def_id + } + _ => p_def_id, + }; + let parent = param_def_id.as_local().and_then(|id| { let local_id = tcx.local_def_id_to_hir_id(id); let generics = tcx.parent_hir_node(local_id).generics()?; Some((id, generics))
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 6bf0817..d0358b0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -285,14 +285,16 @@ pub fn report_selection_error( let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); let trait_def_id = main_trait_predicate.def_id(); - if self.tcx.is_diagnostic_item(sym::From, trait_def_id) - || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) + let leaf_trait_def_id = leaf_trait_predicate.def_id(); + if (self.tcx.is_diagnostic_item(sym::From, trait_def_id) + || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)) + && (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id) + || self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id)) { let trait_ref = leaf_trait_predicate.skip_binder().trait_ref; - // Defensive: next-solver may produce fewer args than expected. - if trait_ref.args.len() > 1 { - let found_ty = trait_ref.args.type_at(1); + if let Some(found_ty) = trait_ref.args.get(1).and_then(|arg| arg.as_type()) + { let ty = main_trait_predicate.skip_binder().self_ty(); if let Some(cast_ty) = self.find_explicit_cast_type( @@ -2299,6 +2301,11 @@ pub(super) fn report_similar_impl_candidates( // FIXME: this could use a better heuristic, like just checking // that args[1..] is the same. let all_traits_equal = traits.len() == 1; + let mut types: Vec<_> = + candidates.iter().map(|(c, _)| c.self_ty().to_string()).collect(); + types.sort(); + types.dedup(); + let all_types_equal = types.len() == 1; let end = if candidates.len() <= 9 || self.tcx.sess.opts.verbose { candidates.len() @@ -2312,6 +2319,11 @@ pub(super) fn report_similar_impl_candidates( for (c, def_id) in &candidates { let msg = if all_traits_equal { format!("`{}`", self.tcx.short_string(c.self_ty(), err.long_ty_path())) + } else if all_types_equal { + format!( + "`{}`", + self.tcx.short_string(c.print_only_trait_path(), err.long_ty_path()) + ) } else { format!( "`{}` implements `{}`", @@ -2321,13 +2333,19 @@ pub(super) fn report_similar_impl_candidates( }; span.push_span_label(self.tcx.def_span(*def_id), msg); } - err.span_help( - span, + let msg = if all_types_equal { + format!( + "`{}` implements trait `{}`", + self.tcx.short_string(candidates[0].0.self_ty(), err.long_ty_path()), + self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()), + ) + } else { format!( "the following {other}types implement trait `{}`", - trait_ref.print_trait_sugared(), - ), - ); + self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()), + ) + }; + err.span_help(span, msg); } else { let candidate_names: Vec<String> = candidates .iter() @@ -2337,6 +2355,12 @@ pub(super) fn report_similar_impl_candidates( "\n {}", self.tcx.short_string(c.self_ty(), err.long_ty_path()) ) + } else if all_types_equal { + format!( + "\n {}", + self.tcx + .short_string(c.print_only_trait_path(), err.long_ty_path()) + ) } else { format!( "\n `{}` implements `{}`", @@ -2347,9 +2371,21 @@ pub(super) fn report_similar_impl_candidates( } }) .collect(); + let msg = if all_types_equal { + format!( + "`{}` implements trait `{}`", + self.tcx.short_string(candidates[0].0.self_ty(), err.long_ty_path()), + self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()), + ) + } else { + format!( + "the following {other}types implement trait `{}`", + self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()), + ) + }; + err.help(format!( - "the following {other}types implement trait `{}`:{}{}", - trait_ref.print_trait_sugared(), + "{msg}:{}{}", candidate_names[..end].join(""), if candidates.len() > 9 && !self.tcx.sess.opts.verbose { format!("\nand {} others", candidates.len() - 8) @@ -2842,6 +2878,10 @@ fn select_transmute_obligation_for_reporting( trait_predicate: ty::PolyTraitPredicate<'tcx>, root_obligation: &PredicateObligation<'tcx>, ) -> (PredicateObligation<'tcx>, ty::PolyTraitPredicate<'tcx>) { + if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() { + return (obligation.clone(), trait_predicate); + } + let ocx = ObligationCtxt::new(self); let normalized_predicate = self.tcx.erase_and_anonymize_regions( self.tcx.instantiate_bound_regions_with_erased(trait_predicate),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index a0876d8..a543f54 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -99,6 +99,15 @@ fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String "overflow assigning `{a}` to `{b}`", ) } + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => { + let term = with_short_path(self.tcx, term); + struct_span_code_err!( + self.dcx(), + span, + E0275, + "overflow evaluating whether `{term}` is well-formed", + ) + } _ => { let pred_str = with_short_path(self.tcx, predicate); struct_span_code_err!(
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 4a6d5eb..2d9574e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -545,8 +545,12 @@ pub(super) fn suggest_dereferences( .all(|obligation| self.predicate_may_hold(obligation)) }) && steps > 0 { + if span.in_external_macro(self.tcx.sess.source_map()) { + return false; + } let derefs = "*".repeat(steps); let msg = "consider dereferencing here"; + let call_node = self.tcx.hir_node(*call_hir_id); let is_receiver = matches!( call_node, @@ -593,7 +597,6 @@ pub(super) fn suggest_dereferences( }) { // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible - let trait_pred = predicate.unwrap_or(trait_pred); let lhs_ty = self.tcx.instantiate_bound_regions_with_erased(trait_pred.self_ty()); let lhs_autoderef = (self.autoderef_steps)(lhs_ty); @@ -644,6 +647,9 @@ pub(super) fn suggest_dereferences( }) { let make_sugg = |mut expr: &Expr<'_>, mut steps| { + if expr.span.in_external_macro(self.tcx.sess.source_map()) { + return None; + } let mut prefix_span = expr.span.shrink_to_lo(); let mut msg = "consider dereferencing here"; if let hir::ExprKind::AddrOf(_, _, inner) = expr.kind { @@ -661,10 +667,10 @@ pub(super) fn suggest_dereferences( } // Empty suggestions with empty spans ICE with debug assertions if steps == 0 { - return ( + return Some(( msg.trim_end_matches(" and dereferencing instead"), vec![(prefix_span, String::new())], - ); + )); } let derefs = "*".repeat(steps); let needs_parens = steps > 0 && expr_needs_parens(expr); @@ -686,7 +692,7 @@ pub(super) fn suggest_dereferences( if !prefix_span.is_empty() { suggestion.push((prefix_span, String::new())); } - (msg, suggestion) + Some((msg, suggestion)) }; if let Some(lsteps) = lsteps @@ -694,8 +700,13 @@ pub(super) fn suggest_dereferences( && lsteps > 0 && rsteps > 0 { - let mut suggestion = make_sugg(lhs, lsteps).1; - suggestion.append(&mut make_sugg(rhs, rsteps).1); + let Some((_, mut suggestion)) = make_sugg(lhs, lsteps) else { + return false; + }; + let Some((_, mut rhs_suggestion)) = make_sugg(rhs, rsteps) else { + return false; + }; + suggestion.append(&mut rhs_suggestion); err.multipart_suggestion( "consider dereferencing both sides of the expression", suggestion, @@ -705,13 +716,17 @@ pub(super) fn suggest_dereferences( } else if let Some(lsteps) = lsteps && lsteps > 0 { - let (msg, suggestion) = make_sugg(lhs, lsteps); + let Some((msg, suggestion)) = make_sugg(lhs, lsteps) else { + return false; + }; err.multipart_suggestion(msg, suggestion, Applicability::MachineApplicable); return true; } else if let Some(rsteps) = rsteps && rsteps > 0 { - let (msg, suggestion) = make_sugg(rhs, rsteps); + let Some((msg, suggestion)) = make_sugg(rhs, rsteps) else { + return false; + }; err.multipart_suggestion(msg, suggestion, Applicability::MachineApplicable); return true; } @@ -1966,10 +1981,9 @@ pub(super) fn suggest_impl_trait( let mut span = obligation.cause.span; if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) - && let parent = self.tcx.parent(obligation.cause.body_id.into()) + && let parent = self.tcx.local_parent(obligation.cause.body_id) && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent) && self.tcx.asyncness(parent).is_async() - && let Some(parent) = parent.as_local() && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) | Node::TraitItem(hir::TraitItem { @@ -2916,12 +2930,21 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>( | ObligationCauseCode::CheckAssociatedTypeBounds { .. } | ObligationCauseCode::LetElse | ObligationCauseCode::UnOp { .. } - | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) | ObligationCauseCode::AlwaysApplicableImpl | ObligationCauseCode::ConstParam(_) | ObligationCauseCode::ReferenceOutlivesReferent(..) | ObligationCauseCode::ObjectTypeBound(..) => {} + ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. } => { + if let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id) + && let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id) + && tcx.sess.source_map().lookup_char_pos(lhs.span.lo()).line + != tcx.sess.source_map().lookup_char_pos(rhs.span.hi()).line + { + err.span_label(lhs.span, ""); + err.span_label(rhs.span, ""); + } + } ObligationCauseCode::RustCall => { if let Some(pred) = predicate.as_trait_clause() && tcx.is_lang_item(pred.def_id(), LangItem::Sized) @@ -4816,6 +4839,9 @@ pub(super) fn suggest_convert_to_slice( candidate_impls: &[ImplCandidate<'tcx>], span: Span, ) { + if span.in_external_macro(self.tcx.sess.source_map()) { + return; + } // We can only suggest the slice coercion for function and binary operation arguments, // since the suggestion would make no sense in turbofish or call let (ObligationCauseCode::BinOp { .. } | ObligationCauseCode::FunctionArg { .. }) =
diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs index c7699f3..5d200c4 100644 --- a/compiler/rustc_trait_selection/src/solve.rs +++ b/compiler/rustc_trait_selection/src/solve.rs
@@ -1,8 +1,3 @@ -use std::mem; - -use rustc_infer::infer::InferCtxt; -use rustc_infer::traits::{Obligation, ObligationCause}; -use rustc_middle::hooks::TypeErasedInfcx; pub use rustc_next_trait_solver::solve::*; mod delegate; @@ -18,13 +13,10 @@ deeply_normalize, deeply_normalize_with_skipped_universes, deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals, }; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::util::Providers; -use rustc_span::Span; +use rustc_middle::query::Providers; +use rustc_middle::ty::TyCtxt; pub use select::InferCtxtSelectExt; -use crate::traits::ObligationCtxt; - fn evaluate_root_goal_for_proof_tree_raw<'tcx>( tcx: TyCtxt<'tcx>, canonical_input: CanonicalInput<TyCtxt<'tcx>>, @@ -35,46 +27,6 @@ fn evaluate_root_goal_for_proof_tree_raw<'tcx>( ) } -fn try_eagerly_normalize_alias<'a, 'tcx>( - tcx: TyCtxt<'tcx>, - type_erased_infcx: TypeErasedInfcx<'a, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - span: Span, - alias: ty::AliasTy<'tcx>, -) -> Ty<'tcx> { - let infcx = unsafe { - mem::transmute::<TypeErasedInfcx<'a, 'tcx>, &'a InferCtxt<'tcx>>(type_erased_infcx) - }; - - let ocx = ObligationCtxt::new(infcx); - - let infer_term = infcx.next_ty_var(span); - - // Dummy because we ignore the error anyway. - // We do provide a span, because this span is used when registering opaque types. - // For example, if we don't provide a span here, some diagnostics talking about TAIT will refer to a dummy span. - let cause = ObligationCause::dummy_with_span(span); - let obligation = Obligation::new( - tcx, - cause, - param_env, - ty::PredicateKind::AliasRelate( - alias.to_ty(tcx).into(), - infer_term.into(), - ty::AliasRelationDirection::Equate, - ), - ); - - ocx.register_obligation(obligation); - - // We only use this to constrain inference variables. - // We don't care if it errors. - let _ = ocx.try_evaluate_obligations(); - - infcx.resolve_vars_if_possible(infer_term) -} - pub fn provide(providers: &mut Providers) { - providers.hooks.try_eagerly_normalize_alias = try_eagerly_normalize_alias; - providers.queries.evaluate_root_goal_for_proof_tree_raw = evaluate_root_goal_for_proof_tree_raw; + *providers = Providers { evaluate_root_goal_for_proof_tree_raw, ..*providers }; }
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 026ab3a..469e24c 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -472,12 +472,17 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( | ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) | ty::Error(_) => thin_vec![], - // Coroutines and closures could implement `[const] Drop`, + // Closures are [const] Destruct when all of their upvars (captures) are [const] Destruct. + ty::Closure(_, args) => { + let closure_args = args.as_closure(); + thin_vec![ty::TraitRef::new(tcx, destruct_def_id, [closure_args.tupled_upvars_ty()])] + } + + // Coroutines could implement `[const] Drop`, // but they don't really need to right now. - ty::Closure(_, _) - | ty::CoroutineClosure(_, _) - | ty::Coroutine(_, _) - | ty::CoroutineWitness(_, _) => return Err(EvaluationFailure::NoSolution), + ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) | ty::CoroutineWitness(_, _) => { + return Err(EvaluationFailure::NoSolution); + } // FIXME(unsafe_binders): Unsafe binders could implement `[const] Drop` // if their inner type implements it.
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 71a8e08..a575630 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -349,7 +349,7 @@ fn process_obligation( &mut self, pending_obligation: &mut PendingPredicateObligation<'tcx>, ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> { - pending_obligation.stalled_on.truncate(0); + pending_obligation.stalled_on.clear(); let obligation = &mut pending_obligation.obligation;
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 1fde7e5..bdad1b2 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -300,19 +300,14 @@ fn do_normalize_predicates<'tcx>( Ok(predicates) => Ok(predicates), Err(fixup_err) => { // If we encounter a fixup error, it means that some type - // variable wound up unconstrained. I actually don't know - // if this can happen, and I certainly don't expect it to - // happen often, but if it did happen it probably - // represents a legitimate failure due to some kind of - // unconstrained variable. - // - // @lcnr: Let's still ICE here for now. I want a test case - // for that. - span_bug!( + // variable wound up unconstrained. That can happen for + // ill-formed impls, so we delay a bug here instead of + // immediately ICEing and let type checking report the + // actual user-facing errors. + Err(tcx.dcx().span_delayed_bug( span, - "inference variables in normalized parameter environment: {}", - fixup_err - ); + format!("inference variables in normalized parameter environment: {fixup_err}"), + )) } } }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 3df5c9e..72d3ba9 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -659,7 +659,9 @@ fn project<'cx, 'tcx>( ))); } - if let Err(guar) = obligation.predicate.error_reported() { + // We can still compute a projection type when there are only region errors, + // but type/const errors require early return. + if let Err(guar) = obligation.predicate.non_region_error_reported() { return Ok(Projected::Progress(Progress::error_for_term( selcx.tcx(), obligation.predicate,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 4a0a99e..b8f5336 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -942,14 +942,53 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { // FIXME(#27579) RFC also considers adding trait // obligations that don't refer to Self and // checking those - if let Some(principal) = data.principal_def_id() { + if let Some(principal) = data.principal() { + let principal_def_id = principal.skip_binder().def_id; self.out.push(traits::Obligation::with_depth( tcx, self.cause(ObligationCauseCode::WellFormed(None)), self.recursion_depth, self.param_env, - ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)), + ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal_def_id)), )); + + // For the most part we don't add wf predicates corresponding to + // the trait ref's generic arguments which allows code like this + // to compile: + // ```rust + // trait Trait<T: Sized> {} + // fn foo(_: &dyn Trait<[u32]>) {} + // ``` + // + // However, we sometimes incidentally check that const arguments + // have the correct type as a side effect of the anon const + // desugaring. To make this "consistent" for users we explicitly + // check `ConstArgHasType` clauses so that const args that don't + // go through an anon const still have their types checked. + // + // See also: https://rustc-dev-guide.rust-lang.org/const-generics.html + let args = principal.skip_binder().with_self_ty(self.tcx(), t).args; + let obligations = + self.nominal_obligations(principal_def_id, args).into_iter().filter(|o| { + let kind = o.predicate.kind().skip_binder(); + match kind { + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType( + ct, + _, + )) if matches!(ct.kind(), ty::ConstKind::Param(..)) => { + // ConstArgHasType clauses are not higher kinded. Assert as + // such so we can fix this up if that ever changes. + assert!(o.predicate.kind().bound_vars().is_empty()); + // In stable rust, variables from the trait object binder + // cannot be referenced by a ConstArgHasType clause. However, + // under `generic_const_parameter_types`, it can. Ignore those + // predicates for now, to not have HKT-ConstArgHasTypes. + !kind.has_escaping_bound_vars() + } + _ => false, + } + }); + self.out.extend(obligations); } if !t.has_escaping_bound_vars() {
diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs index 11dfbad..874c816 100644 --- a/compiler/rustc_ty_utils/src/nested_bodies.rs +++ b/compiler/rustc_ty_utils/src/nested_bodies.rs
@@ -1,27 +1,26 @@ use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::Visitor; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List<LocalDefId> { let body = tcx.hir_body_owned_by(item); - let mut collector = - NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] }; + let mut collector = NestedBodiesVisitor { tcx, root_def_id: item, nested_bodies: vec![] }; collector.visit_body(body); tcx.mk_local_def_ids(&collector.nested_bodies) } struct NestedBodiesVisitor<'tcx> { tcx: TyCtxt<'tcx>, - root_def_id: DefId, + root_def_id: LocalDefId, nested_bodies: Vec<LocalDefId>, } impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> { fn visit_nested_body(&mut self, id: hir::BodyId) { let body_def_id = self.tcx.hir_body_owner_def_id(id); - if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id { + if self.tcx.typeck_root_def_id_local(body_def_id) == self.root_def_id { // We visit nested bodies before adding the current body. This // means that nested bodies are always stored before their parent. let body = self.tcx.hir_body(id);
diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 9fb16af..c83e0bb 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs
@@ -58,7 +58,7 @@ fn check_representability_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) { // -> check_representability_adt_ty(Bar<Foo>) // -> check_representability(Foo) // -// For the diagnostic output (in `Value::from_cycle_error`), we want to detect +// For the diagnostic output (in `check_representability`), we want to detect // that the `Foo` in the *second* field of the struct is culpable. This // requires traversing the HIR of the struct and calling `params_in_repr(Bar)`. // But we can't call params_in_repr for a given type unless it is known to be
diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index b00f9ee..58fc4d8 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml
@@ -8,7 +8,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" derive-where = "1.6.1" -ena = "0.14.4" +ena = "0.14.3" indexmap = "2.0.0" rustc-hash = "2.0.0" rustc_abi = { path = "../rustc_abi", default-features = false }
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 0b0f0fd..6528aa7 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs
@@ -16,7 +16,7 @@ use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; +use crate::{self as ty, DebruijnIndex, Interner, Ty, UniverseIndex}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -274,7 +274,7 @@ pub struct ValidateBoundVars<I: Interner> { // We only cache types because any complex const will have to step through // a type at some point anyways. We may encounter the same variable at // different levels of binding, so this can't just be `Ty`. - visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>, + visited: SsoHashSet<(ty::DebruijnIndex, Ty<I>)>, } impl<I: Interner> ValidateBoundVars<I> { @@ -297,7 +297,7 @@ fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &Binder<I, T>) -> Self::Resul result } - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + fn visit_ty(&mut self, t: Ty<I>) -> Self::Result { if t.outer_exclusive_binder() < self.binder_index || !self.visited.insert((self.binder_index, t)) { @@ -724,7 +724,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region { } } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: Ty<I>) -> Ty<I> { if !t.has_param() { return t; } @@ -753,7 +753,7 @@ fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses { } impl<'a, I: Interner> ArgFolder<'a, I> { - fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty { + fn ty_for_param(&self, p: I::ParamTy, source_ty: Ty<I>) -> Ty<I> { // Look up the type in the args. It really should be in there. let opt_ty = self.args.get(p.index() as usize).map(|arg| arg.kind()); let ty = match opt_ty { @@ -767,7 +767,7 @@ fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty { #[cold] #[inline(never)] - fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind<I>) -> ! { + fn type_param_expected(&self, p: I::ParamTy, ty: Ty<I>, kind: ty::GenericArgKind<I>) -> ! { panic!( "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}", p, @@ -780,7 +780,7 @@ fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind #[cold] #[inline(never)] - fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! { + fn type_param_out_of_range(&self, p: I::ParamTy, ty: Ty<I>) -> ! { panic!( "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}", p, @@ -1277,7 +1277,7 @@ pub fn new_anon(ui: UniverseIndex, var: ty::BoundVar) -> Self { Self { universe: ui, bound, _tcx: PhantomData } } - pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty { + pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> Ty<I> { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() {
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 49fb94c..9786608 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -117,8 +117,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } #[cfg(feature = "nightly")] -impl<CTX> HashStable<CTX> for InferConst { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for InferConst { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { match self { InferConst::Var(_) => { panic!("const variables should not be hashed: {self:?}")
diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index eba4c7c..ef542af 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs
@@ -2,7 +2,7 @@ use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::NoSolution; -use crate::{self as ty, Interner}; +use crate::{self as ty, Interner, Ty}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)] @@ -36,15 +36,15 @@ pub enum TypeError<I: Interner> { RegionsInsufficientlyPolymorphic(ty::BoundRegion<I>, I::Region), RegionsPlaceholderMismatch, - Sorts(ExpectedFound<I::Ty>), - ArgumentSorts(ExpectedFound<I::Ty>, usize), + Sorts(ExpectedFound<Ty<I>>), + ArgumentSorts(ExpectedFound<Ty<I>>, usize), Traits(ExpectedFound<I::TraitId>), VariadicMismatch(ExpectedFound<bool>), /// Instantiating a type variable with the given type would have /// created a cycle (because it appears somewhere within that /// type). - CyclicTy(I::Ty), + CyclicTy(Ty<I>), CyclicConst(I::Const), ProjectionMismatched(ExpectedFound<I::DefId>), ExistentialMismatch(ExpectedFound<I::BoundExistentialPredicates>),
diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index ed6416a..6bd985a 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs
@@ -50,13 +50,13 @@ pub enum SimplifiedType<DefId> { } #[cfg(feature = "nightly")] -impl<HCX: Clone, DefId: HashStable<HCX>> ToStableHashKey<HCX> for SimplifiedType<DefId> { +impl<Hcx: Clone, DefId: HashStable<Hcx>> ToStableHashKey<Hcx> for SimplifiedType<DefId> { type KeyType = Fingerprint; #[inline] - fn to_stable_hash_key(&self, hcx: &HCX) -> Fingerprint { + fn to_stable_hash_key(&self, hcx: &Hcx) -> Fingerprint { let mut hasher = StableHasher::new(); - let mut hcx: HCX = hcx.clone(); + let mut hcx: Hcx = hcx.clone(); self.hash_stable(&mut hcx, &mut hasher); hasher.finish() } @@ -113,7 +113,7 @@ pub enum TreatParams { /// ¹ meaning that if the outermost layers are different, then the whole types are also different. pub fn simplify_type<I: Interner>( cx: I, - ty: I::Ty, + ty: ty::Ty<I>, treat_params: TreatParams, ) -> Option<SimplifiedType<I::DefId>> { match ty.kind() { @@ -236,11 +236,16 @@ pub fn args_may_unify( self.args_may_unify_inner(obligation_args, impl_args, Self::STARTING_DEPTH) } - pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool { + pub fn types_may_unify(self, lhs: ty::Ty<I>, rhs: ty::Ty<I>) -> bool { self.types_may_unify_inner(lhs, rhs, Self::STARTING_DEPTH) } - pub fn types_may_unify_with_depth(self, lhs: I::Ty, rhs: I::Ty, depth_limit: usize) -> bool { + pub fn types_may_unify_with_depth( + self, + lhs: ty::Ty<I>, + rhs: ty::Ty<I>, + depth_limit: usize, + ) -> bool { self.types_may_unify_inner(lhs, rhs, depth_limit) } @@ -268,7 +273,7 @@ fn args_may_unify_inner( }) } - fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool { + fn types_may_unify_inner(self, lhs: ty::Ty<I>, rhs: ty::Ty<I>, depth: usize) -> bool { if lhs == rhs { return true; } @@ -527,7 +532,7 @@ fn consts_may_unify_inner(self, lhs: I::Const, rhs: I::Const) -> bool { } } - fn var_and_ty_may_unify(self, var: ty::InferTy, ty: I::Ty) -> bool { + fn var_and_ty_may_unify(self, var: ty::InferTy, ty: ty::Ty<I>) -> bool { if !ty.is_known_rigid() { return true; }
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 7e905da..f311298 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs
@@ -1,6 +1,6 @@ use crate::inherent::*; use crate::visit::Flags; -use crate::{self as ty, Interner}; +use crate::{self as ty, Interner, Ty}; bitflags::bitflags! { /// Flags that we track on types. These flags are propagated upwards @@ -91,19 +91,24 @@ pub struct TypeFlags: u32 { | TypeFlags::HAS_TY_INHERENT.bits() | TypeFlags::HAS_CT_PROJECTION.bits(); + /// Is a type or const error reachable? + const HAS_NON_REGION_ERROR = 1 << 15; + /// Is a region error reachable? + const HAS_RE_ERROR = 1 << 16; /// Is an error type/lifetime/const reachable? - const HAS_ERROR = 1 << 15; + const HAS_ERROR = TypeFlags::HAS_NON_REGION_ERROR.bits() + | TypeFlags::HAS_RE_ERROR.bits(); /// Does this have any region that "appears free" in the type? /// Basically anything but `ReBound` and `ReErased`. - const HAS_FREE_REGIONS = 1 << 16; + const HAS_FREE_REGIONS = 1 << 17; /// Does this have any `ReBound` regions? - const HAS_RE_BOUND = 1 << 17; + const HAS_RE_BOUND = 1 << 18; /// Does this have any `Bound` types? - const HAS_TY_BOUND = 1 << 18; + const HAS_TY_BOUND = 1 << 19; /// Does this have any `ConstKind::Bound` consts? - const HAS_CT_BOUND = 1 << 19; + const HAS_CT_BOUND = 1 << 20; /// Does this have any bound variables? /// Used to check if a global bound is safe to evaluate. const HAS_BOUND_VARS = TypeFlags::HAS_RE_BOUND.bits() @@ -111,7 +116,7 @@ pub struct TypeFlags: u32 { | TypeFlags::HAS_CT_BOUND.bits(); /// Does this have any `ReErased` regions? - const HAS_RE_ERASED = 1 << 20; + const HAS_RE_ERASED = 1 << 21; /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? @@ -123,19 +128,19 @@ pub struct TypeFlags: u32 { | TypeFlags::HAS_CT_INFER.bits(); /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`? - const HAS_TY_FRESH = 1 << 21; + const HAS_TY_FRESH = 1 << 22; /// Does this value have `InferConst::Fresh`? - const HAS_CT_FRESH = 1 << 22; + const HAS_CT_FRESH = 1 << 23; /// Does this have any binders with bound vars (e.g. that need to be anonymized)? - const HAS_BINDER_VARS = 1 << 23; + const HAS_BINDER_VARS = 1 << 24; /// Does this type have any coroutines in it? - const HAS_TY_CORO = 1 << 24; + const HAS_TY_CORO = 1 << 25; /// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`? - const HAS_CANONICAL_BOUND = 1 << 25; + const HAS_CANONICAL_BOUND = 1 << 26; } } @@ -240,7 +245,7 @@ fn add_kind(&mut self, kind: &ty::TyKind<I>) { | ty::Str | ty::Foreign(..) => {} - ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), + ty::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR), ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); @@ -430,7 +435,7 @@ fn add_predicate_atom(&mut self, atom: ty::PredicateKind<I>) { } } - fn add_ty(&mut self, ty: I::Ty) { + fn add_ty(&mut self, ty: Ty<I>) { self.add_flags(ty.flags()); self.add_exclusive_binder(ty.outer_exclusive_binder()); } @@ -489,7 +494,7 @@ fn add_const_kind(&mut self, c: &ty::ConstKind<I>) { } } ty::ConstKind::Expr(e) => self.add_args(e.args().as_slice()), - ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), + ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR), } }
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index d1a5059..ef162b2 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs
@@ -135,7 +135,7 @@ fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> t.super_fold_with(self) } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { t.super_fold_with(self) } @@ -177,7 +177,7 @@ fn try_fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> Result<ty::Binder<I, T> t.try_super_fold_with(self) } - fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Self::Error> { + fn try_fold_ty(&mut self, t: ty::Ty<I>) -> Result<ty::Ty<I>, Self::Error> { t.try_super_fold_with(self) } @@ -408,7 +408,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region { } } - fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { + fn fold_ty(&mut self, ty: ty::Ty<I>) -> ty::Ty<I> { match ty.kind() { ty::Bound(BoundVarIndexKind::Bound(debruijn), bound_ty) if debruijn >= self.current_index => @@ -538,7 +538,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region { } } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { if t.has_type_flags( TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, ) {
diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index 5d61274..22a4ebd 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs
@@ -3,7 +3,7 @@ use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::GenericTypeVisitable; -use crate::Interner; +use crate::{Interner, Ty}; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] #[derive(GenericTypeVisitable)] @@ -13,7 +13,7 @@ )] pub enum GenericArgKind<I: Interner> { Lifetime(I::Region), - Type(I::Ty), + Type(Ty<I>), Const(I::Const), } @@ -26,7 +26,7 @@ impl<I: Interner> Eq for GenericArgKind<I> {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub enum TermKind<I: Interner> { - Ty(I::Ty), + Ty(Ty<I>), Const(I::Const), }
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index feafcee..843d1eb 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -6,7 +6,7 @@ use crate::inherent::*; use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; -use crate::{self as ty, Interner, TyVid}; +use crate::{self as ty, Interner, Ty, TyVid}; /// The current typing mode of an inference context. We unfortunately have some /// slightly different typing rules depending on the current context. See the @@ -161,12 +161,9 @@ fn next_trait_solver(&self) -> bool { fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid; fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty; - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty; - fn opportunistic_resolve_float_var( - &self, - vid: ty::FloatVid, - ) -> <Self::Interner as Interner>::Ty; + fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<Self::Interner>; + fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<Self::Interner>; + fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<Self::Interner>; fn opportunistic_resolve_ct_var( &self, vid: ty::ConstVid, @@ -179,7 +176,7 @@ fn opportunistic_resolve_lt_var( fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool; fn next_region_infer(&self) -> <Self::Interner as Interner>::Region; - fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty; + fn next_ty_infer(&self) -> Ty<Self::Interner>; fn next_const_infer(&self) -> <Self::Interner as Interner>::Const; fn fresh_args_for_item( &self, @@ -209,7 +206,7 @@ fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>( target_is_expected: bool, target_vid: ty::TyVid, instantiation_variance: ty::Variance, - source_ty: <Self::Interner as Interner>::Ty, + source_ty: Ty<Self::Interner>, ) -> RelateResult<Self::Interner, ()>; fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue); fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue); @@ -223,10 +220,7 @@ fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>( fn set_tainted_by_errors(&self, e: <Self::Interner as Interner>::ErrorGuaranteed); - fn shallow_resolve( - &self, - ty: <Self::Interner as Interner>::Ty, - ) -> <Self::Interner as Interner>::Ty; + fn shallow_resolve(&self, ty: Ty<Self::Interner>) -> Ty<Self::Interner>; fn shallow_resolve_const( &self, ty: <Self::Interner as Interner>::Const, @@ -254,7 +248,7 @@ fn equate_regions( fn register_ty_outlives( &self, - ty: <Self::Interner as Interner>::Ty, + ty: Ty<Self::Interner>, r: <Self::Interner as Interner>::Region, span: <Self::Interner as Interner>::Span, ); @@ -263,26 +257,26 @@ fn register_ty_outlives( fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries; fn clone_opaque_types_lookup_table( &self, - ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>; + ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, Ty<Self::Interner>)>; fn clone_duplicate_opaque_types( &self, - ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>; + ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, Ty<Self::Interner>)>; fn clone_opaque_types_added_since( &self, prev_entries: Self::OpaqueTypeStorageEntries, - ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>; + ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, Ty<Self::Interner>)>; fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec<ty::AliasTy<Self::Interner>>; fn register_hidden_type_in_storage( &self, opaque_type_key: ty::OpaqueTypeKey<Self::Interner>, - hidden_ty: <Self::Interner as Interner>::Ty, + hidden_ty: Ty<Self::Interner>, span: <Self::Interner as Interner>::Span, - ) -> Option<<Self::Interner as Interner>::Ty>; + ) -> Option<Ty<Self::Interner>>; fn add_duplicate_opaque_type( &self, opaque_type_key: ty::OpaqueTypeKey<Self::Interner>, - hidden_ty: <Self::Interner as Interner>::Ty, + hidden_ty: Ty<Self::Interner>, span: <Self::Interner as Interner>::Span, );
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 116fd10..4559056 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -55,7 +55,7 @@ pub trait Ty<I: Interner<Ty = Self>>: fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self; fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self { - Ty::new_alias( + Self::new_alias( interner, ty::AliasTyKind::Projection, ty::AliasTy::new_from_args(interner, def_id, args), @@ -67,7 +67,7 @@ fn new_projection( def_id: I::DefId, args: impl IntoIterator<Item: Into<I::GenericArg>>, ) -> Self { - Ty::new_alias( + Self::new_alias( interner, ty::AliasTyKind::Projection, ty::AliasTy::new(interner, def_id, args), @@ -108,7 +108,7 @@ fn new_coroutine_witness_for_coroutine( fn new_slice(interner: I, ty: Self) -> Self; - fn new_tup(interner: I, tys: &[I::Ty]) -> Self; + fn new_tup(interner: I, tys: &[ty::Ty<I>]) -> Self; fn new_tup_from_iter<It, T>(interner: I, iter: It) -> T::Output where @@ -121,7 +121,7 @@ fn new_tup_from_iter<It, T>(interner: I, iter: It) -> T::Output fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self; - fn new_unsafe_binder(interner: I, ty: ty::Binder<I, I::Ty>) -> Self; + fn new_unsafe_binder(interner: I, ty: ty::Binder<I, ty::Ty<I>>) -> Self; fn tuple_fields(self) -> I::Tys; @@ -158,7 +158,7 @@ fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> { self.kind().fn_sig(interner) } - fn discriminant_ty(self, interner: I) -> I::Ty; + fn discriminant_ty(self, interner: I) -> ty::Ty<I>; fn is_known_rigid(self) -> bool { self.kind().is_known_rigid() @@ -198,11 +198,11 @@ fn is_guaranteed_unsized_raw(self) -> bool { } pub trait Tys<I: Interner<Tys = Self>>: - Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default + Copy + Debug + Hash + Eq + SliceLike<Item = ty::Ty<I>> + TypeFoldable<I> + Default { fn inputs(self) -> I::FnInputTys; - fn output(self) -> I::Ty; + fn output(self) -> ty::Ty<I>; } pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq { @@ -290,7 +290,7 @@ fn is_ct_error(self) -> bool { } pub trait ValueConst<I: Interner<ValueConst = Self>>: Copy + Debug + Hash + Eq { - fn ty(self) -> I::Ty; + fn ty(self) -> ty::Ty<I>; fn valtree(self) -> I::ValTree; } @@ -310,7 +310,7 @@ pub trait GenericArg<I: Interner<GenericArg = Self>>: + IntoKind<Kind = ty::GenericArgKind<I>> + TypeVisitable<I> + Relate<I> - + From<I::Ty> + + From<ty::Ty<I>> + From<I::Region> + From<I::Const> + From<I::Term> @@ -323,11 +323,11 @@ fn as_term(&self) -> Option<I::Term> { } } - fn as_type(&self) -> Option<I::Ty> { + fn as_type(&self) -> Option<ty::Ty<I>> { if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> I::Ty { + fn expect_ty(&self) -> ty::Ty<I> { self.as_type().expect("expected a type") } @@ -359,11 +359,11 @@ fn is_non_region_infer(self) -> bool { pub trait Term<I: Interner<Term = Self>>: Copy + Debug + Hash + Eq + IntoKind<Kind = ty::TermKind<I>> + TypeFoldable<I> + Relate<I> { - fn as_type(&self) -> Option<I::Ty> { + fn as_type(&self) -> Option<ty::Ty<I>> { if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> I::Ty { + fn expect_ty(&self) -> ty::Ty<I> { self.as_type().expect("expected a type, but found a const") } @@ -413,7 +413,7 @@ fn rebase_onto( target: I::GenericArgs, ) -> I::GenericArgs; - fn type_at(self, i: usize) -> I::Ty; + fn type_at(self, i: usize) -> ty::Ty<I>; fn region_at(self, i: usize) -> I::Region; @@ -459,7 +459,7 @@ pub trait Predicate<I: Interner<Predicate = Self>>: + UpcastFrom<I, ty::TraitRef<I>> + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>> + UpcastFrom<I, ty::TraitPredicate<I>> - + UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>> + + UpcastFrom<I, ty::OutlivesPredicate<I, ty::Ty<I>>> + UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>> + IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>> + Elaboratable<I> @@ -578,7 +578,7 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq { /// Returns the type of the struct tail. /// /// Expects the `AdtDef` to be a struct. If it is not, then this will panic. - fn struct_tail_ty(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>; + fn struct_tail_ty(self, interner: I) -> Option<ty::EarlyBinder<I, ty::Ty<I>>>; fn is_phantom_data(self) -> bool; @@ -591,13 +591,13 @@ fn field_representing_type_info( ) -> Option<FieldInfo<I>>; // FIXME: perhaps use `all_fields` and expose `FieldDef`. - fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>; + fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = ty::Ty<I>>>; fn sizedness_constraint( self, interner: I, sizedness: SizedTraitKind, - ) -> Option<ty::EarlyBinder<I, I::Ty>>; + ) -> Option<ty::EarlyBinder<I, ty::Ty<I>>>; fn is_fundamental(self) -> bool;
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a0b4440..6c838cf 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs
@@ -31,6 +31,7 @@ pub mod relate; pub mod search_graph; pub mod solve; +pub mod sty; pub mod walk; // These modules are not `pub` since they are glob-imported. @@ -78,6 +79,7 @@ pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; use rustc_type_ir_macros::GenericTypeVisitable; +pub use sty::*; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; @@ -443,8 +445,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } pub struct FieldInfo<I: Interner> { - pub base: I::Ty, - pub ty: I::Ty, + pub base: Ty<I>, + pub ty: Ty<I>, pub variant: Option<I::Symbol>, pub variant_idx: VariantIdx, pub name: I::Symbol,
diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index 300e5c0..cc79d65 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs
@@ -8,7 +8,7 @@ use crate::data_structures::SsoHashSet; use crate::inherent::*; use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor}; -use crate::{self as ty, Interner}; +use crate::{self as ty, Interner, Ty}; #[derive_where(Debug; I: Interner)] pub enum Component<I: Interner> { @@ -55,7 +55,7 @@ pub enum Component<I: Interner> { /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. pub fn push_outlives_components<I: Interner>( cx: I, - ty: I::Ty, + ty: Ty<I>, out: &mut SmallVec<[Component<I>; 4]>, ) { ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() }); @@ -64,14 +64,14 @@ pub fn push_outlives_components<I: Interner>( struct OutlivesCollector<'a, I: Interner> { cx: I, out: &'a mut SmallVec<[Component<I>; 4]>, - visited: SsoHashSet<I::Ty>, + visited: SsoHashSet<Ty<I>>, } impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> { #[cfg(not(feature = "nightly"))] type Result = (); - fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: Ty<I>) -> Self::Result { if !self.visited.insert(ty) { return; }
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 113192c..f4975f3 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -101,7 +101,7 @@ pub fn identity(interner: I, def_id: I::TraitId) -> TraitRef<I> { ) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> Self { TraitRef::new( interner, self.def_id, @@ -110,13 +110,13 @@ pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { } #[inline] - pub fn self_ty(&self) -> I::Ty { + pub fn self_ty(&self) -> ty::Ty<I> { self.args.type_at(0) } } impl<I: Interner> ty::Binder<I, TraitRef<I>> { - pub fn self_ty(&self) -> ty::Binder<I, I::Ty> { + pub fn self_ty(&self) -> ty::Binder<I, ty::Ty<I>> { self.map_bound_ref(|tr| tr.self_ty()) } @@ -152,7 +152,7 @@ pub struct TraitPredicate<I: Interner> { impl<I: Interner> Eq for TraitPredicate<I> {} impl<I: Interner> TraitPredicate<I> { - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), polarity: self.polarity, @@ -163,7 +163,7 @@ pub fn def_id(self) -> I::TraitId { self.trait_ref.def_id } - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.trait_ref.self_ty() } } @@ -174,7 +174,7 @@ pub fn def_id(self) -> I::TraitId { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder<I, I::Ty> { + pub fn self_ty(self) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -307,7 +307,7 @@ pub fn def_id(&self) -> I::DefId { /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example). - pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause { + pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty<I>) -> I::Clause { match self.skip_binder() { ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx), ExistentialPredicate::Projection(p) => { @@ -384,7 +384,7 @@ pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> { + pub fn with_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> TraitRef<I> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -401,7 +401,7 @@ pub fn def_id(&self) -> I::TraitId { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> { + pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty<I>) -> ty::Binder<I, TraitRef<I>> { self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty)) } } @@ -459,7 +459,7 @@ pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> { ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args) } - pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> { + pub fn with_self_ty(&self, interner: I, self_ty: ty::Ty<I>) -> ProjectionPredicate<I> { // otherwise the escaping regions would be captured by the binders debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -487,7 +487,7 @@ pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) } impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> { - pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> { + pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty<I>) -> ty::Binder<I, ProjectionPredicate<I>> { self.map_bound(|p| p.with_self_ty(cx, self_ty)) } @@ -683,11 +683,11 @@ pub fn to_term(self, interner: I) -> I::Term { /// The following methods work only with (trait) associated term projections. impl<I: Interner> AliasTerm<I> { - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> Self { AliasTerm::new( interner, self.def_id, @@ -796,11 +796,11 @@ pub struct ProjectionPredicate<I: Interner> { impl<I: Interner> Eq for ProjectionPredicate<I> {} impl<I: Interner> ProjectionPredicate<I> { - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.projection_term.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> ProjectionPredicate<I> { Self { projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty), ..self @@ -859,11 +859,11 @@ pub struct NormalizesTo<I: Interner> { impl<I: Interner> Eq for NormalizesTo<I> {} impl<I: Interner> NormalizesTo<I> { - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.alias.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> NormalizesTo<I> { Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self } } @@ -896,11 +896,11 @@ pub struct HostEffectPredicate<I: Interner> { impl<I: Interner> Eq for HostEffectPredicate<I> {} impl<I: Interner> HostEffectPredicate<I> { - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.trait_ref.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self } } @@ -915,7 +915,7 @@ pub fn def_id(self) -> I::TraitId { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder<I, I::Ty> { + pub fn self_ty(self) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -936,8 +936,8 @@ pub fn constness(self) -> BoundConstness { )] pub struct SubtypePredicate<I: Interner> { pub a_is_expected: bool, - pub a: I::Ty, - pub b: I::Ty, + pub a: ty::Ty<I>, + pub b: ty::Ty<I>, } impl<I: Interner> Eq for SubtypePredicate<I> {} @@ -950,8 +950,8 @@ impl<I: Interner> Eq for SubtypePredicate<I> {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub struct CoercePredicate<I: Interner> { - pub a: I::Ty, - pub b: I::Ty, + pub a: ty::Ty<I>, + pub b: ty::Ty<I>, } impl<I: Interner> Eq for CoercePredicate<I> {}
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 445e85a..b6ff27f 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -5,7 +5,7 @@ use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::{self as ty, Interner}; +use crate::{self as ty, Interner, Ty}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. @@ -25,7 +25,7 @@ pub enum ClauseKind<I: Interner> { RegionOutlives(ty::OutlivesPredicate<I, I::Region>), /// `where T: 'r` - TypeOutlives(ty::OutlivesPredicate<I, I::Ty>), + TypeOutlives(ty::OutlivesPredicate<I, Ty<I>>), /// `where <T as TraitRef>::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. @@ -33,7 +33,7 @@ pub enum ClauseKind<I: Interner> { /// Ensures that a const generic argument to a parameter `const N: u8` /// is of type `u8`. - ConstArgHasType(I::Const, I::Ty), + ConstArgHasType(I::Const, Ty<I>), /// No syntax: `T` well-formed. WellFormed(I::Term),
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 4c1b070..d1076be 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -217,15 +217,15 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[cfg(feature = "nightly")] // This is not a derived impl because a derive would require `I: HashStable` -impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I> +impl<Hcx, I: Interner> HashStable<Hcx> for RegionKind<I> where - I::EarlyParamRegion: HashStable<CTX>, - I::LateParamRegion: HashStable<CTX>, - I::DefId: HashStable<CTX>, - I::Symbol: HashStable<CTX>, + I::EarlyParamRegion: HashStable<Hcx>, + I::LateParamRegion: HashStable<Hcx>, + I::DefId: HashStable<Hcx>, + I::Symbol: HashStable<Hcx>, { #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { std::mem::discriminant(self).hash_stable(hcx, hasher); match self { ReErased | ReStatic | ReError(_) => {
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index d33c6036..31248be 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs
@@ -44,7 +44,7 @@ pub enum VarianceDiagInfo<I: Interner> { Invariant { /// The generic type containing the generic parameter /// that changes the variance (e.g. `*mut T`, `MyStruct<T>`) - ty: I::Ty, + ty: ty::Ty<I>, /// The index of the generic parameter being used /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) param_index: u32, @@ -75,13 +75,13 @@ fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> { fn relate_ty_args( &mut self, - a_ty: I::Ty, - b_ty: I::Ty, + a_ty: ty::Ty<I>, + b_ty: ty::Ty<I>, ty_def_id: I::DefId, a_arg: I::GenericArgs, b_arg: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> I::Ty, - ) -> RelateResult<I, I::Ty>; + mk: impl FnOnce(I::GenericArgs) -> ty::Ty<I>, + ) -> RelateResult<I, ty::Ty<I>>; /// Switch variance for the purpose of relating `a` and `b`. fn relate_with_variance<T: Relate<I>>( @@ -98,7 +98,7 @@ fn relate_with_variance<T: Relate<I>>( // additional hooks for other types in the future if needed // without making older code, which called `relate`, obsolete. - fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty>; + fn tys(&mut self, a: ty::Ty<I>, b: ty::Ty<I>) -> RelateResult<I, ty::Ty<I>>; fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult<I, I::Region>; @@ -332,9 +332,9 @@ fn relate<R: TypeRelation<I>>( #[instrument(level = "trace", skip(relation), ret)] pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( relation: &mut R, - a: I::Ty, - b: I::Ty, -) -> RelateResult<I, I::Ty> { + a: ty::Ty<I>, + b: ty::Ty<I>, +) -> RelateResult<I, ty::Ty<I>> { let cx = relation.cx(); match (a.kind(), b.kind()) { (ty::Infer(_), _) | (_, ty::Infer(_)) => {
diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 72d54c2..11fbbf8 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs
@@ -39,17 +39,15 @@ fn register_predicates( ); /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); - - fn try_eagerly_normalize_alias(&mut self, alias: ty::AliasTy<I>) -> I::Ty; + fn register_alias_relate_predicate(&mut self, a: ty::Ty<I>, b: ty::Ty<I>); } pub fn super_combine_tys<Infcx, I, R>( infcx: &Infcx, relation: &mut R, - a: I::Ty, - b: I::Ty, -) -> RelateResult<I, I::Ty> + a: ty::Ty<I>, + b: ty::Ty<I>, +) -> RelateResult<I, ty::Ty<I>> where Infcx: InferCtxtLike<Interner = I>, I: Interner, @@ -228,13 +226,13 @@ pub fn super_combine_consts<Infcx, I, R>( pub fn combine_ty_args<Infcx, I, R>( infcx: &Infcx, relation: &mut R, - a_ty: I::Ty, - b_ty: I::Ty, + a_ty: ty::Ty<I>, + b_ty: ty::Ty<I>, variances: I::VariancesOf, a_args: I::GenericArgs, b_args: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> I::Ty, -) -> RelateResult<I, I::Ty> + mk: impl FnOnce(I::GenericArgs) -> ty::Ty<I>, +) -> RelateResult<I, ty::Ty<I>> where Infcx: InferCtxtLike<Interner = I>, I: Interner,
diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 541b253..1494d67 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs
@@ -5,7 +5,7 @@ use crate::relate::combine::combine_ty_args; pub use crate::relate::*; use crate::solve::Goal; -use crate::{self as ty, InferCtxtLike, Interner}; +use crate::{self as ty, InferCtxtLike, Interner, Ty}; pub trait RelateExt: InferCtxtLike { fn relate<T: Relate<Self::Interner>>( @@ -15,7 +15,6 @@ fn relate<T: Relate<Self::Interner>>( variance: ty::Variance, rhs: T, span: <Self::Interner as Interner>::Span, - normalize: &mut dyn FnMut(ty::AliasTy<Self::Interner>) -> <Self::Interner as Interner>::Ty, ) -> Result< Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, TypeError<Self::Interner>, @@ -33,46 +32,40 @@ fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>( >; } -impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> RelateExt for Infcx { - fn relate<T: Relate<I>>( +impl<Infcx: InferCtxtLike> RelateExt for Infcx { + fn relate<T: Relate<Self::Interner>>( &self, - param_env: I::ParamEnv, + param_env: <Self::Interner as Interner>::ParamEnv, lhs: T, variance: ty::Variance, rhs: T, - span: I::Span, - normalize: &mut dyn FnMut(ty::AliasTy<I>) -> I::Ty, - ) -> Result<Vec<Goal<I, I::Predicate>>, TypeError<I>> { - let mut relate = SolverRelating::new( - self, - StructurallyRelateAliases::No, - variance, - param_env, - span, - normalize, - ); + span: <Self::Interner as Interner>::Span, + ) -> Result< + Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, + TypeError<Self::Interner>, + > { + let mut relate = + SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env, span); relate.relate(lhs, rhs)?; Ok(relate.goals) } - fn eq_structurally_relating_aliases<T: Relate<I>>( + fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>( &self, - param_env: I::ParamEnv, + param_env: <Self::Interner as Interner>::ParamEnv, lhs: T, rhs: T, - span: I::Span, - ) -> Result<Vec<Goal<I, I::Predicate>>, TypeError<I>> { - // Structurally relating, we treat aliases as rigid, - // so we shouldn't ever try to normalize them. - let mut normalize_unreachable = |_alias| unreachable!(); - + span: <Self::Interner as Interner>::Span, + ) -> Result< + Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, + TypeError<Self::Interner>, + > { let mut relate = SolverRelating::new( self, StructurallyRelateAliases::Yes, ty::Invariant, param_env, span, - &mut normalize_unreachable, ); relate.relate(lhs, rhs)?; Ok(relate.goals) @@ -82,14 +75,12 @@ fn eq_structurally_relating_aliases<T: Relate<I>>( /// Enforce that `a` is equal to or a subtype of `b`. pub struct SolverRelating<'infcx, Infcx, I: Interner> { infcx: &'infcx Infcx, - // Immutable fields. structurally_relate_aliases: StructurallyRelateAliases, param_env: I::ParamEnv, span: I::Span, // Mutable fields. ambient_variance: ty::Variance, - normalize: &'infcx mut dyn FnMut(ty::AliasTy<I>) -> I::Ty, goals: Vec<Goal<I, I::Predicate>>, /// The cache only tracks the `ambient_variance` as it's the /// only field which is mutable and which meaningfully changes @@ -113,7 +104,7 @@ pub struct SolverRelating<'infcx, Infcx, I: Interner> { /// constrain `?1` to `u32`. When using the cache entry from the /// first time we've related these types, this only happens when /// later proving the `Subtype(?0, ?1)` goal from the first relation. - cache: DelayedSet<(ty::Variance, I::Ty, I::Ty)>, + cache: DelayedSet<(ty::Variance, Ty<I>, Ty<I>)>, } impl<'infcx, Infcx, I> SolverRelating<'infcx, Infcx, I> @@ -127,14 +118,12 @@ pub fn new( ambient_variance: ty::Variance, param_env: I::ParamEnv, span: I::Span, - normalize: &'infcx mut dyn FnMut(ty::AliasTy<I>) -> I::Ty, ) -> Self { SolverRelating { infcx, structurally_relate_aliases, span, ambient_variance, - normalize, param_env, goals: vec![], cache: Default::default(), @@ -153,13 +142,13 @@ fn cx(&self) -> I { fn relate_ty_args( &mut self, - a_ty: I::Ty, - b_ty: I::Ty, + a_ty: Ty<I>, + b_ty: Ty<I>, def_id: I::DefId, a_args: I::GenericArgs, b_args: I::GenericArgs, - _: impl FnOnce(I::GenericArgs) -> I::Ty, - ) -> RelateResult<I, I::Ty> { + _: impl FnOnce(I::GenericArgs) -> Ty<I>, + ) -> RelateResult<I, Ty<I>> { if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles @@ -189,7 +178,7 @@ fn relate_with_variance<T: Relate<I>>( } #[instrument(skip(self), level = "trace")] - fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty> { + fn tys(&mut self, a: Ty<I>, b: Ty<I>) -> RelateResult<I, Ty<I>> { if a == b { return Ok(a); } @@ -394,7 +383,7 @@ fn register_goals(&mut self, obligations: impl IntoIterator<Item = Goal<I, I::Pr self.goals.extend(obligations); } - fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) { + fn register_alias_relate_predicate(&mut self, a: Ty<I>, b: Ty<I>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), @@ -417,8 +406,4 @@ fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) { } })]); } - - fn try_eagerly_normalize_alias(&mut self, alias: ty::AliasTy<I>) -> I::Ty { - (self.normalize)(alias) - } }
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 72b7df2..23e6075 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -11,7 +11,7 @@ use crate::lang_items::SolverTraitLangItem; use crate::search_graph::PathKind; -use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; +use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Ty, Upcast}; pub type CanonicalInput<I, T = <I as Interner>::Predicate> = ty::CanonicalQueryInput<I, QueryInput<I, T>>; @@ -254,7 +254,7 @@ impl<I: Interner> Eq for Response<I> {} #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct ExternalConstraintsData<I: Interner> { pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>, - pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>, + pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, Ty<I>)>, pub normalization_nested_goals: NestedNormalizationGoals<I>, }
diff --git a/compiler/rustc_type_ir/src/sty/mod.rs b/compiler/rustc_type_ir/src/sty/mod.rs new file mode 100644 index 0000000..5b73d37 --- /dev/null +++ b/compiler/rustc_type_ir/src/sty/mod.rs
@@ -0,0 +1,3 @@ +/// This type is temporary and exists to cut down the bloat of further PR's +/// moving `struct Ty` from `rustc_middle` to `rustc_type_ir`. +pub type Ty<I> = <I as crate::interner::Interner>::Ty;
diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs index 53994b5..5e297a5 100644 --- a/compiler/rustc_type_ir/src/ty_info.rs +++ b/compiler/rustc_type_ir/src/ty_info.rs
@@ -97,8 +97,8 @@ fn hash<H: Hasher>(&self, s: &mut H) { } #[cfg(feature = "nightly")] -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for WithCachedTypeInfo<T> { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { +impl<T: HashStable<Hcx>, Hcx> HashStable<Hcx> for WithCachedTypeInfo<T> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { // No cached hash available. This can only mean that incremental is disabled. // We don't cache stable hashes in non-incremental mode, because they are used
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 983d8f0..ad7a934 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -100,7 +100,7 @@ pub enum TyKind<I: Interner> { Str, /// An array with the given length. Written as `[T; N]`. - Array(I::Ty, I::Const), + Array(ty::Ty<I>, I::Const), /// A pattern newtype. /// @@ -109,17 +109,17 @@ pub enum TyKind<I: Interner> { /// Only `Copy` and `Clone` will automatically get implemented for pattern types. /// Auto-traits treat this as if it were an aggregate with a single nested type. /// Only supports integer range patterns for now. - Pat(I::Ty, I::Pat), + Pat(ty::Ty<I>, I::Pat), /// The pointee of an array slice. Written as `[T]`. - Slice(I::Ty), + Slice(ty::Ty<I>), /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(I::Ty, Mutability), + RawPtr(ty::Ty<I>, Mutability), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - Ref(I::Region, I::Ty, Mutability), + Ref(I::Region, ty::Ty<I>, Mutability), /// The anonymous type of a function declaration/definition. /// @@ -469,18 +469,18 @@ pub fn is_opaque(self, interner: I) -> bool { matches!(self.kind(interner), AliasTyKind::Opaque) } - pub fn to_ty(self, interner: I) -> I::Ty { + pub fn to_ty(self, interner: I) -> ty::Ty<I> { Ty::new_alias(interner, self.kind(interner), self) } } /// The following methods work only with (trait) associated type projections. impl<I: Interner> AliasTy<I> { - pub fn self_ty(self) -> I::Ty { + pub fn self_ty(self) -> ty::Ty<I> { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty<I>) -> Self { AliasTy::new( interner, self.def_id, @@ -687,15 +687,15 @@ fn tag() -> &'static str { } #[cfg(feature = "nightly")] -impl<CTX> HashStable<CTX> for InferTy { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { +impl<Hcx> HashStable<Hcx> for InferTy { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { use InferTy::*; - std::mem::discriminant(self).hash_stable(ctx, hasher); + std::mem::discriminant(self).hash_stable(hcx, hasher); match self { TyVar(_) | IntVar(_) | FloatVar(_) => { panic!("type variables should not be hashed: {self:?}") } - FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher), + FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(hcx, hasher), } } } @@ -735,7 +735,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { )] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct TypeAndMut<I: Interner> { - pub ty: I::Ty, + pub ty: ty::Ty<I>, pub mutbl: Mutability, } @@ -765,7 +765,7 @@ pub fn inputs(self) -> I::FnInputTys { self.inputs_and_output.inputs() } - pub fn output(self) -> I::Ty { + pub fn output(self) -> ty::Ty<I> { self.inputs_and_output.output() } @@ -783,7 +783,7 @@ pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> { + pub fn input(self, index: usize) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap()) } @@ -792,7 +792,7 @@ pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> { } #[inline] - pub fn output(self) -> ty::Binder<I, I::Ty> { + pub fn output(self) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|fn_sig| fn_sig.output()) } @@ -856,21 +856,21 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } // FIXME: this is a distinct type because we need to define `Encode`/`Decode` -// impls in this crate for `Binder<I, I::Ty>`. +// impls in this crate for `Binder<I, ty::Ty<I>>`. #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] -pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>); +pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, ty::Ty<I>>); impl<I: Interner> Eq for UnsafeBinderInner<I> {} -impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> { - fn from(value: ty::Binder<I, I::Ty>) -> Self { +impl<I: Interner> From<ty::Binder<I, ty::Ty<I>>> for UnsafeBinderInner<I> { + fn from(value: ty::Binder<I, ty::Ty<I>>) -> Self { UnsafeBinderInner(value) } } -impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> { +impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, ty::Ty<I>> { fn from(value: UnsafeBinderInner<I>) -> Self { value.0 } @@ -883,7 +883,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } impl<I: Interner> Deref for UnsafeBinderInner<I> { - type Target = ty::Binder<I, I::Ty>; + type Target = ty::Binder<I, ty::Ty<I>>; fn deref(&self) -> &Self::Target { &self.0 @@ -894,7 +894,7 @@ fn deref(&self) -> &Self::Target { impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E> for UnsafeBinderInner<I> where - I::Ty: rustc_serialize::Encodable<E>, + ty::Ty<I>: rustc_serialize::Encodable<E>, I::BoundVarKinds: rustc_serialize::Encodable<E>, { fn encode(&self, e: &mut E) { @@ -907,7 +907,7 @@ fn encode(&self, e: &mut E) { impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D> for UnsafeBinderInner<I> where - I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>, + ty::Ty<I>: TypeVisitable<I> + rustc_serialize::Decodable<D>, I::BoundVarKinds: rustc_serialize::Decodable<D>, { fn decode(decoder: &mut D) -> Self { @@ -937,7 +937,7 @@ pub fn inputs(self) -> I::FnInputTys { self.inputs_and_output.inputs() } - pub fn output(self) -> I::Ty { + pub fn output(self) -> ty::Ty<I> { self.inputs_and_output.output() } } @@ -960,7 +960,7 @@ pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> { + pub fn input(self, index: usize) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap()) } @@ -969,7 +969,7 @@ pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> { } #[inline] - pub fn output(self) -> ty::Binder<I, I::Ty> { + pub fn output(self) -> ty::Binder<I, ty::Ty<I>> { self.map_bound(|sig_tys| sig_tys.output()) } }
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index e8f94c8..08c303b 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -121,13 +121,13 @@ pub struct ClosureArgsParts<I: Interner> { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: I::Ty, + pub closure_kind_ty: ty::Ty<I>, /// Captures the closure's signature. This closure signature is "tupled", and /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`. - pub closure_sig_as_fn_ptr_ty: I::Ty, + pub closure_sig_as_fn_ptr_ty: ty::Ty<I>, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: I::Ty, + pub tupled_upvars_ty: ty::Ty<I>, } impl<I: Interner> ClosureArgs<I> { @@ -169,14 +169,14 @@ pub fn upvar_tys(self) -> I::Tys { /// Returns the tuple type representing the upvars for this closure. #[inline] - pub fn tupled_upvars_ty(self) -> I::Ty { + pub fn tupled_upvars_ty(self) -> ty::Ty<I> { self.split().tupled_upvars_ty } /// Returns the closure kind for this closure; may return a type /// variable during inference. To get the closure kind during /// inference, use `infcx.closure_kind(args)`. - pub fn kind_ty(self) -> I::Ty { + pub fn kind_ty(self) -> ty::Ty<I> { self.split().closure_kind_ty } @@ -185,7 +185,7 @@ pub fn kind_ty(self) -> I::Ty { // FIXME(eddyb) this should be unnecessary, as the shallowly resolved // type is known at the time of the creation of `ClosureArgs`, // see `rustc_hir_analysis::check::closure`. - pub fn sig_as_fn_ptr_ty(self) -> I::Ty { + pub fn sig_as_fn_ptr_ty(self) -> ty::Ty<I> { self.split().closure_sig_as_fn_ptr_ty } @@ -223,7 +223,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: I::Ty, + pub closure_kind_ty: ty::Ty<I>, /// Represents all of the relevant parts of the coroutine returned by this /// coroutine-closure. This signature parts type will have the general /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where @@ -232,10 +232,10 @@ pub struct CoroutineClosureArgsParts<I: Interner> { /// /// Use `coroutine_closure_sig` to break up this type rather than using it /// yourself. - pub signature_parts_ty: I::Ty, + pub signature_parts_ty: ty::Ty<I>, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: I::Ty, + pub tupled_upvars_ty: ty::Ty<I>, /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. /// This allows us to represent the binder of the self-captures of the closure. /// @@ -243,7 +243,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> { /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, /// while the `tupled_upvars_ty`, representing the by-move version of the same /// captures, will be `(String,)`. - pub coroutine_captures_by_ref_ty: I::Ty, + pub coroutine_captures_by_ref_ty: ty::Ty<I>, } impl<I: Interner> CoroutineClosureArgs<I> { @@ -277,11 +277,11 @@ pub fn upvar_tys(self) -> I::Tys { } #[inline] - pub fn tupled_upvars_ty(self) -> I::Ty { + pub fn tupled_upvars_ty(self) -> ty::Ty<I> { self.split().tupled_upvars_ty } - pub fn kind_ty(self) -> I::Ty { + pub fn kind_ty(self) -> ty::Ty<I> { self.split().closure_kind_ty } @@ -289,7 +289,7 @@ pub fn kind(self) -> ty::ClosureKind { self.kind_ty().to_opt_closure_kind().unwrap() } - pub fn signature_parts_ty(self) -> I::Ty { + pub fn signature_parts_ty(self) -> ty::Ty<I> { self.split().signature_parts_ty } @@ -314,7 +314,7 @@ pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I> }) } - pub fn coroutine_captures_by_ref_ty(self) -> I::Ty { + pub fn coroutine_captures_by_ref_ty(self) -> ty::Ty<I> { self.split().coroutine_captures_by_ref_ty } @@ -358,10 +358,10 @@ fn visit_region(&mut self, r: I::Region) -> Self::Result { #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct CoroutineClosureSignature<I: Interner> { - pub tupled_inputs_ty: I::Ty, - pub resume_ty: I::Ty, - pub yield_ty: I::Ty, - pub return_ty: I::Ty, + pub tupled_inputs_ty: ty::Ty<I>, + pub resume_ty: ty::Ty<I>, + pub yield_ty: ty::Ty<I>, + pub return_ty: ty::Ty<I>, // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types // never actually differ. But we save them rather than recreating them @@ -393,10 +393,10 @@ pub fn to_coroutine( self, cx: I, parent_args: I::GenericArgsSlice, - coroutine_kind_ty: I::Ty, + coroutine_kind_ty: ty::Ty<I>, coroutine_def_id: I::CoroutineId, - tupled_upvars_ty: I::Ty, - ) -> I::Ty { + tupled_upvars_ty: ty::Ty<I>, + ) -> ty::Ty<I> { let coroutine_args = ty::CoroutineArgs::new( cx, ty::CoroutineArgsParts { @@ -424,9 +424,9 @@ pub fn to_coroutine_given_kind_and_upvars( coroutine_def_id: I::CoroutineId, goal_kind: ty::ClosureKind, env_region: I::Region, - closure_tupled_upvars_ty: I::Ty, - coroutine_captures_by_ref_ty: I::Ty, - ) -> I::Ty { + closure_tupled_upvars_ty: ty::Ty<I>, + coroutine_captures_by_ref_ty: ty::Ty<I>, + ) -> ty::Ty<I> { let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( cx, goal_kind, @@ -457,11 +457,11 @@ pub fn to_coroutine_given_kind_and_upvars( pub fn tupled_upvars_by_closure_kind( cx: I, kind: ty::ClosureKind, - tupled_inputs_ty: I::Ty, - closure_tupled_upvars_ty: I::Ty, - coroutine_captures_by_ref_ty: I::Ty, + tupled_inputs_ty: ty::Ty<I>, + closure_tupled_upvars_ty: ty::Ty<I>, + coroutine_captures_by_ref_ty: ty::Ty<I>, env_region: I::Region, - ) -> I::Ty { + ) -> ty::Ty<I> { match kind { ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else { @@ -503,7 +503,7 @@ struct FoldEscapingRegions<I: Interner> { // Depends on `debruijn` because we may have types with regions of different // debruijn depths depending on the binders we've entered. - cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>, + cache: DelayedMap<(ty::DebruijnIndex, ty::Ty<I>), ty::Ty<I>>, } impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> { @@ -511,7 +511,7 @@ fn cx(&self) -> I { self.interner } - fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + fn fold_ty(&mut self, t: ty::Ty<I>) -> ty::Ty<I> { if !t.has_vars_bound_at_or_above(self.debruijn) { t } else if let Some(&t) = self.cache.get(&(self.debruijn, t)) { @@ -553,9 +553,9 @@ fn fold_region(&mut self, r: <I as Interner>::Region) -> <I as Interner>::Region #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct GenSig<I: Interner> { - pub resume_ty: I::Ty, - pub yield_ty: I::Ty, - pub return_ty: I::Ty, + pub resume_ty: ty::Ty<I>, + pub yield_ty: ty::Ty<I>, + pub return_ty: ty::Ty<I>, } impl<I: Interner> Eq for GenSig<I> {} @@ -581,15 +581,15 @@ pub struct CoroutineArgsParts<I: Interner> { /// kind: `i8`/`i16`/`i32`. /// /// For regular coroutines, this field will always just be `()`. - pub kind_ty: I::Ty, + pub kind_ty: ty::Ty<I>, - pub resume_ty: I::Ty, - pub yield_ty: I::Ty, - pub return_ty: I::Ty, + pub resume_ty: ty::Ty<I>, + pub yield_ty: ty::Ty<I>, + pub return_ty: ty::Ty<I>, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: I::Ty, + pub tupled_upvars_ty: ty::Ty<I>, } impl<I: Interner> CoroutineArgs<I> { @@ -619,7 +619,7 @@ pub fn parent_args(self) -> I::GenericArgsSlice { } // Returns the kind of the coroutine. See docs on the `kind_ty` field. - pub fn kind_ty(self) -> I::Ty { + pub fn kind_ty(self) -> ty::Ty<I> { self.split().kind_ty } @@ -638,22 +638,22 @@ pub fn upvar_tys(self) -> I::Tys { /// Returns the tuple type representing the upvars for this coroutine. #[inline] - pub fn tupled_upvars_ty(self) -> I::Ty { + pub fn tupled_upvars_ty(self) -> ty::Ty<I> { self.split().tupled_upvars_ty } /// Returns the type representing the resume type of the coroutine. - pub fn resume_ty(self) -> I::Ty { + pub fn resume_ty(self) -> ty::Ty<I> { self.split().resume_ty } /// Returns the type representing the yield type of the coroutine. - pub fn yield_ty(self) -> I::Ty { + pub fn yield_ty(self) -> ty::Ty<I> { self.split().yield_ty } /// Returns the type representing the return type of the coroutine. - pub fn return_ty(self) -> I::Ty { + pub fn return_ty(self) -> ty::Ty<I> { self.split().return_ty }
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 6e62e10..cfb4588 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs
@@ -52,7 +52,7 @@ use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, TypeFlags}; +use crate::{self as ty, Interner, Ty, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -98,7 +98,7 @@ fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::R t.super_visit_with(self) } - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + fn visit_ty(&mut self, t: Ty<I>) -> Self::Result { t.super_visit_with(self) } @@ -279,6 +279,8 @@ fn references_error(&self) -> bool { fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>; + fn non_region_error_reported(&self) -> Result<(), I::ErrorGuaranteed>; + fn has_non_region_param(&self) -> bool { self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM) } @@ -352,6 +354,11 @@ fn has_bound_vars(&self) -> bool { fn still_further_specializable(&self) -> bool { self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) } + + /// True if a type or const error is reachable + fn has_non_region_error(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_NON_REGION_ERROR) + } } impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T { @@ -376,6 +383,18 @@ fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { Ok(()) } } + + fn non_region_error_reported(&self) -> Result<(), I::ErrorGuaranteed> { + if self.has_non_region_error() { + if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) { + Err(guar) + } else { + panic!("type flags said there was an non region error, but now there is not") + } + } else { + Ok(()) + } + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -417,7 +436,7 @@ fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::R } #[inline] - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + fn visit_ty(&mut self, t: Ty<I>) -> Self::Result { // Note: no `super_visit_with` call. let flags = t.flags(); if flags.intersects(self.flags) { @@ -522,7 +541,7 @@ fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::R } #[inline] - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + fn visit_ty(&mut self, t: Ty<I>) -> Self::Result { // If the outer-exclusive-binder is *strictly greater* than // `outer_index`, that means that `t` contains some content // bound at `outer_index` or above (because
diff --git a/library/Cargo.lock b/library/Cargo.lock index 4801f92..ffa9a63 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock
@@ -146,9 +146,9 @@ [[package]] name = "libc" -version = "0.2.178" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" dependencies = [ "rustc-std-workspace-core", ]
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 541257b..b32e5e9 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@ [dependencies] core = { path = "../core", public = true } -compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["rustc-dep-of-std"] } +compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["compiler-builtins"] } [features] compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 7e09a88..52f099e 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs
@@ -5,7 +5,8 @@ #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] pub use core::alloc::*; -use core::ptr::{self, Alignment, NonNull}; +use core::mem::Alignment; +use core::ptr::{self, NonNull}; use core::{cmp, hint}; unsafe extern "Rust" {
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 4ddfcde..d46b197 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -1364,6 +1364,37 @@ pub fn as_slice(&self) -> &[T] { self.data.as_slice() } + /// Returns a mutable slice of all values in the underlying vector. + /// + /// # Safety + /// + /// The caller must ensure that the slice remains a max-heap, i.e. for all indices + /// `0 < i < slice.len()`, `slice[(i - 1) / 2] >= slice[i]`, before the borrow ends + /// and the binary heap is used. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(binary_heap_as_mut_slice)] + /// + /// use std::collections::BinaryHeap; + /// + /// let mut heap = BinaryHeap::<u32>::from([1, 2, 3, 4, 5, 6, 7]); + /// + /// unsafe { + /// for value in heap.as_mut_slice() { + /// *value = (*value).saturating_mul(2); + /// } + /// } + /// ``` + #[must_use] + #[unstable(feature = "binary_heap_as_mut_slice", issue = "154009")] + pub unsafe fn as_mut_slice(&mut self) -> &mut [T] { + self.data.as_mut_slice() + } + /// Consumes the `BinaryHeap` and returns the underlying vector /// in arbitrary order. ///
diff --git a/library/alloc/src/collections/btree/append.rs b/library/alloc/src/collections/btree/append.rs index 66ea22e..cc8d793 100644 --- a/library/alloc/src/collections/btree/append.rs +++ b/library/alloc/src/collections/btree/append.rs
@@ -1,38 +1,8 @@ use core::alloc::Allocator; -use core::iter::FusedIterator; -use super::merge_iter::MergeIterInner; use super::node::{self, Root}; impl<K, V> Root<K, V> { - /// Appends all key-value pairs from the union of two ascending iterators, - /// incrementing a `length` variable along the way. The latter makes it - /// easier for the caller to avoid a leak when a drop handler panicks. - /// - /// If both iterators produce the same key, this method drops the pair from - /// the left iterator and appends the pair from the right iterator. - /// - /// If you want the tree to end up in a strictly ascending order, like for - /// a `BTreeMap`, both iterators should produce keys in strictly ascending - /// order, each greater than all keys in the tree, including any keys - /// already in the tree upon entry. - pub(super) fn append_from_sorted_iters<I, A: Allocator + Clone>( - &mut self, - left: I, - right: I, - length: &mut usize, - alloc: A, - ) where - K: Ord, - I: Iterator<Item = (K, V)> + FusedIterator, - { - // We prepare to merge `left` and `right` into a sorted sequence in linear time. - let iter = MergeIter(MergeIterInner::new(left, right)); - - // Meanwhile, we build a tree from the sorted sequence in linear time. - self.bulk_push(iter, length, alloc) - } - /// Pushes all key-value pairs to the end of the tree, incrementing a /// `length` variable along the way. The latter makes it easier for the /// caller to avoid a leak when the iterator panicks. @@ -94,24 +64,3 @@ pub(super) fn bulk_push<I, A: Allocator + Clone>( self.fix_right_border_of_plentiful(); } } - -// An iterator for merging two sorted sequences into one -struct MergeIter<K, V, I: Iterator<Item = (K, V)>>(MergeIterInner<I>); - -impl<K: Ord, V, I> Iterator for MergeIter<K, V, I> -where - I: Iterator<Item = (K, V)> + FusedIterator, -{ - type Item = (K, V); - - /// If two keys are equal, returns the key from the left and the value from the right. - fn next(&mut self) -> Option<(K, V)> { - let (a_next, b_next) = self.0.nexts(|a: &(K, V), b: &(K, V)| K::cmp(&a.0, &b.0)); - match (a_next, b_next) { - (Some((a_k, _)), Some((_, b_v))) => Some((a_k, b_v)), - (Some(a), None) => Some(a), - (None, Some(b)) => Some(b), - (None, None) => None, - } - } -}
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index fdeb9e3..e3a6e90 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs
@@ -1219,26 +1219,8 @@ pub fn append(&mut self, other: &mut Self) K: Ord, A: Clone, { - // Do we have to append anything at all? - if other.is_empty() { - return; - } - - // We can just swap `self` and `other` if `self` is empty. - if self.is_empty() { - mem::swap(self, other); - return; - } - - let self_iter = mem::replace(self, Self::new_in((*self.alloc).clone())).into_iter(); - let other_iter = mem::replace(other, Self::new_in((*self.alloc).clone())).into_iter(); - let root = self.root.get_or_insert_with(|| Root::new((*self.alloc).clone())); - root.append_from_sorted_iters( - self_iter, - other_iter, - &mut self.length, - (*self.alloc).clone(), - ) + let other = mem::replace(other, Self::new_in((*self.alloc).clone())); + self.merge(other, |_key, _self_val, other_val| other_val); } /// Moves all elements from `other` into `self`, leaving `other` empty. @@ -2120,7 +2102,9 @@ fn default() -> Self { } } -/// An iterator produced by calling `extract_if` on BTreeMap. +/// This `struct` is created by the [`extract_if`] method on [`BTreeMap`]. +/// +/// [`extract_if`]: BTreeMap::extract_if #[stable(feature = "btree_extract_if", since = "1.91.0")] #[must_use = "iterators are lazy and do nothing unless consumed; \ use `retain` or `extract_if().for_each(drop)` to remove and discard elements"]
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 73546ca..6434874 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -2224,7 +2224,7 @@ fn test_append_drop_leak() { catch_unwind(move || left.append(&mut right)).unwrap_err(); assert_eq!(a.dropped(), 1); - assert_eq!(b.dropped(), 1); // should be 2 were it not for Rust issue #47949 + assert_eq!(b.dropped(), 2); assert_eq!(c.dropped(), 2); }
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index af6f5c7..db80078 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs
@@ -1547,7 +1547,9 @@ fn into_iter(self) -> Iter<'a, T> { } } -/// An iterator produced by calling `extract_if` on BTreeSet. +/// This `struct` is created by the [`extract_if`] method on [`BTreeSet`]. +/// +/// [`extract_if`]: BTreeSet::extract_if #[stable(feature = "btree_extract_if", since = "1.91.0")] #[must_use = "iterators are lazy and do nothing unless consumed; \ use `retain` or `extract_if().for_each(drop)` to remove and discard elements"]
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 674828b..1816349 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs
@@ -1942,7 +1942,9 @@ pub fn back_mut(&mut self) -> Option<&mut T> { } } -/// An iterator produced by calling `extract_if` on LinkedList. +/// This `struct` is created by the [`extract_if`] method on [`LinkedList`]. +/// +/// [`extract_if`]: LinkedList::extract_if #[stable(feature = "extract_if", since = "1.87.0")] #[must_use = "iterators are lazy and do nothing unless consumed; \ use `extract_if().for_each(drop)` to remove and discard elements"]
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 7ac9cdc..bcd9e09 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs
@@ -148,6 +148,7 @@ #![feature(slice_range)] #![feature(std_internals)] #![feature(temporary_niche_types)] +#![feature(titlecase)] #![feature(transmutability)] #![feature(trivial_clone)] #![feature(trusted_fused)]
diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 0915025..cabf6ac 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs
@@ -5,8 +5,8 @@ // run the tests. See the comment there for an explanation why this is the case. use core::marker::{Destruct, PhantomData}; -use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; -use core::ptr::{self, Alignment, NonNull, Unique}; +use core::mem::{Alignment, ManuallyDrop, MaybeUninit, SizedTypeProperties}; +use core::ptr::{self, NonNull, Unique}; use core::{cmp, hint}; #[cfg(not(no_global_oom_handling))] @@ -570,7 +570,7 @@ unsafe fn finish_grow( impl<A: Allocator> RawVecInner<A> { #[inline] const fn new_in(alloc: A, align: Alignment) -> Self { - let ptr = Unique::from_non_null(NonNull::without_provenance(align.as_nonzero())); + let ptr = Unique::from_non_null(NonNull::without_provenance(align.as_nonzero_usize())); // `cap: 0` means "unallocated". zero-sized types are ignored. Self { ptr, cap: ZERO_CAP, alloc } }
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 8a65161..cfca2d9 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs
@@ -252,7 +252,7 @@ #[cfg(not(no_global_oom_handling))] use core::iter; use core::marker::{PhantomData, Unsize}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{self, Alignment, ManuallyDrop}; use core::num::NonZeroUsize; use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; #[cfg(not(no_global_oom_handling))] @@ -261,7 +261,7 @@ #[cfg(not(no_global_oom_handling))] use core::pin::Pin; use core::pin::PinCoerceUnsized; -use core::ptr::{self, Alignment, NonNull, drop_in_place}; +use core::ptr::{self, NonNull, drop_in_place}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::{borrow, fmt, hint}; @@ -1430,29 +1430,32 @@ impl<T: ?Sized> Rc<T> { /// Constructs an `Rc<T>` from a raw pointer. /// /// The raw pointer must have been previously returned by a call to - /// [`Rc<U>::into_raw`][into_raw] with the following requirements: + /// [`Rc<U>::into_raw`][into_raw] or [`Rc<U>::into_raw_with_allocator`][into_raw_with_allocator]. /// + /// # Safety + /// + /// * Creating a `Rc<T>` from a pointer other than one returned from + /// [`Rc<U>::into_raw`][into_raw] or [`Rc<U>::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. /// * If `U` is sized, it must have the same size and alignment as `T`. This /// is trivially true if `U` is `T`. /// * If `U` is unsized, its data pointer must have the same size and /// alignment as `T`. This is trivially true if `Rc<U>` was constructed /// through `Rc<T>` and then converted to `Rc<U>` through an [unsized /// coercion]. - /// - /// Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// - /// The raw pointer must point to a block of memory allocated by the global allocator - /// - /// The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by the global allocator + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. /// /// This function is unsafe because improper use may lead to memory unsafety, /// even if the returned `Rc<T>` is never accessed. /// /// [into_raw]: Rc::into_raw + /// [into_raw_with_allocator]: Rc::into_raw_with_allocator /// [transmute]: core::mem::transmute /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// @@ -1662,29 +1665,32 @@ pub fn as_ptr(this: &Self) -> *const T { /// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator. /// /// The raw pointer must have been previously returned by a call to [`Rc<U, - /// A>::into_raw`][into_raw] with the following requirements: + /// A>::into_raw`][into_raw] or [`Rc<U, A>::into_raw_with_allocator`][into_raw_with_allocator]. /// + /// # Safety + /// + /// * Creating a `Rc<T, A>` from a pointer other than one returned from + /// [`Rc<U, A>::into_raw`][into_raw] or [`Rc<U, A>::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. /// * If `U` is sized, it must have the same size and alignment as `T`. This /// is trivially true if `U` is `T`. /// * If `U` is unsized, its data pointer must have the same size and - /// alignment as `T`. This is trivially true if `Rc<U>` was constructed - /// through `Rc<T>` and then converted to `Rc<U>` through an [unsized + /// alignment as `T`. This is trivially true if `Rc<U, A>` was constructed + /// through `Rc<T, A>` and then converted to `Rc<U, A>` through an [unsized /// coercion]. - /// - /// Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// - /// The raw pointer must point to a block of memory allocated by `alloc` - /// - /// The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by `alloc` + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. /// /// This function is unsafe because improper use may lead to memory unsafety, - /// even if the returned `Rc<T>` is never accessed. + /// even if the returned `Rc<T, A>` is never accessed. /// /// [into_raw]: Rc::into_raw + /// [into_raw_with_allocator]: Rc::into_raw_with_allocator /// [transmute]: core::mem::transmute /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// @@ -2424,9 +2430,6 @@ unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {} #[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {} - #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {}
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2c9fadb..b3e49af 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs
@@ -19,14 +19,14 @@ #[cfg(not(no_global_oom_handling))] use core::iter; use core::marker::{PhantomData, Unsize}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{self, Alignment, ManuallyDrop}; use core::num::NonZeroUsize; use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; #[cfg(not(no_global_oom_handling))] use core::ops::{Residual, Try}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; -use core::ptr::{self, Alignment, NonNull}; +use core::ptr::{self, NonNull}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; @@ -1581,29 +1581,32 @@ impl<T: ?Sized> Arc<T> { /// Constructs an `Arc<T>` from a raw pointer. /// /// The raw pointer must have been previously returned by a call to - /// [`Arc<U>::into_raw`][into_raw] with the following requirements: + /// [`Arc<U>::into_raw`][into_raw] or [`Arc<U>::into_raw_with_allocator`][into_raw_with_allocator]. /// + /// # Safety + /// + /// * Creating a `Arc<T>` from a pointer other than one returned from + /// [`Arc<U>::into_raw`][into_raw] or [`Arc<U>::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. /// * If `U` is sized, it must have the same size and alignment as `T`. This /// is trivially true if `U` is `T`. /// * If `U` is unsized, its data pointer must have the same size and /// alignment as `T`. This is trivially true if `Arc<U>` was constructed /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized /// coercion]. - /// - /// Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// - /// The raw pointer must point to a block of memory allocated by the global allocator. - /// - /// The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by the global allocator. + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. /// /// This function is unsafe because improper use may lead to memory unsafety, /// even if the returned `Arc<T>` is never accessed. /// /// [into_raw]: Arc::into_raw + /// [into_raw_with_allocator]: Arc::into_raw_with_allocator /// [transmute]: core::mem::transmute /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// @@ -1819,29 +1822,32 @@ pub fn as_ptr(this: &Self) -> *const T { /// Constructs an `Arc<T, A>` from a raw pointer. /// /// The raw pointer must have been previously returned by a call to [`Arc<U, - /// A>::into_raw`][into_raw] with the following requirements: + /// A>::into_raw`][into_raw] or [`Arc<U, A>::into_raw_with_allocator`][into_raw_with_allocator]. /// + /// # Safety + /// + /// * Creating a `Arc<T, A>` from a pointer other than one returned from + /// [`Arc<U, A>::into_raw`][into_raw] or [`Arc<U, A>::into_raw_with_allocator`][into_raw_with_allocator] + /// is undefined behavior. /// * If `U` is sized, it must have the same size and alignment as `T`. This /// is trivially true if `U` is `T`. /// * If `U` is unsized, its data pointer must have the same size and - /// alignment as `T`. This is trivially true if `Arc<U>` was constructed - /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized + /// alignment as `T`. This is trivially true if `Arc<U, A>` was constructed + /// through `Arc<T, A>` and then converted to `Arc<U, A>` through an [unsized /// coercion]. - /// - /// Note that if `U` or `U`'s data pointer is not `T` but has the same size - /// and alignment, this is basically like transmuting references of - /// different types. See [`mem::transmute`][transmute] for more information - /// on what restrictions apply in this case. - /// - /// The raw pointer must point to a block of memory allocated by `alloc` - /// - /// The user of `from_raw` has to make sure a specific value of `T` is only - /// dropped once. + /// * Note that if `U` or `U`'s data pointer is not `T` but has the same size + /// and alignment, this is basically like transmuting references of + /// different types. See [`mem::transmute`][transmute] for more information + /// on what restrictions apply in this case. + /// * The raw pointer must point to a block of memory allocated by `alloc` + /// * The user of `from_raw` has to make sure a specific value of `T` is only + /// dropped once. /// /// This function is unsafe because improper use may lead to memory unsafety, /// even if the returned `Arc<T>` is never accessed. /// /// [into_raw]: Arc::into_raw + /// [into_raw_with_allocator]: Arc::into_raw_with_allocator /// [transmute]: core::mem::transmute /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions /// @@ -2426,9 +2432,6 @@ fn deref(&self) -> &T { #[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Arc<T, A> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {} - #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl<T: ?Sized, A: Allocator> DerefPure for Arc<T, A> {}
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 7796f3b..942b2b9 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs
@@ -898,9 +898,17 @@ pub const fn const_make_global(mut self) -> &'static [T] where T: Freeze, { - unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) }; - let me = ManuallyDrop::new(self); - unsafe { slice::from_raw_parts(me.as_ptr(), me.len) } + // `const_make_global` requires the pointer to point to the beginning of a heap allocation, + // which is not the case when `self.capacity()` is 0, or if `T::IS_ZST`, + // which is why we instead return a new slice in this case. + if self.capacity() == 0 || T::IS_ZST { + let me = ManuallyDrop::new(self); + unsafe { slice::from_raw_parts(NonNull::<T>::dangling().as_ptr(), me.len) } + } else { + unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) }; + let me = ManuallyDrop::new(self); + unsafe { slice::from_raw_parts(me.as_ptr(), me.len) } + } } } @@ -1853,7 +1861,7 @@ pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of // size `len` containing properly-initialized `T`s. Data must not be accessed through any // other pointer for the returned lifetime. Further, `len * size_of::<T>` <= - // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses. + // `isize::MAX` and allocation does not "wrap" through overflowing memory addresses. // // * Vec API guarantees that self.buf: // * contains only properly-initialized items within 0..len
diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index 5ab305f..db7da0d 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs
@@ -2764,3 +2764,25 @@ fn const_heap() { assert_eq!([1, 2, 4, 8, 16, 32], X); } + +// regression test for issue #153158. `const_make_global` previously assumed `Vec<T>`'s buf +// always has a heap allocation, which lead to compilation errors. +#[test] +fn const_make_global_empty_or_zst_regression() { + const EMPTY_SLICE: &'static [i32] = { + let empty_vec: Vec<i32> = Vec::new(); + empty_vec.const_make_global() + }; + + assert_eq!(EMPTY_SLICE, &[]); + + const ZST_SLICE: &'static [()] = { + let mut zst_vec: Vec<()> = Vec::new(); + zst_vec.push(()); + zst_vec.push(()); + zst_vec.push(()); + zst_vec.const_make_global() + }; + + assert_eq!(ZST_SLICE, &[(), (), ()]); +}
diff --git a/library/compiler-builtins/builtins-shim/Cargo.toml b/library/compiler-builtins/builtins-shim/Cargo.toml index 37d3407..32b0308 100644 --- a/library/compiler-builtins/builtins-shim/Cargo.toml +++ b/library/compiler-builtins/builtins-shim/Cargo.toml
@@ -39,7 +39,7 @@ cc = { version = "1.2", optional = true } [features] -default = ["compiler-builtins"] +default = [] # Enable compilation of C code in compiler-rt, filling in some more optimized # implementations and also filling in unimplemented intrinsics @@ -50,7 +50,8 @@ # the generic versions on all platforms. no-asm = [] -# Flag this library as the unstable compiler-builtins lib +# Flag this library as the unstable compiler-builtins lib. This must be enabled +# when using as `std`'s dependency.' compiler-builtins = [] # Generate memory-related intrinsics like memcpy @@ -60,9 +61,6 @@ # compiler-rt implementations. Also used for testing mangled-names = [] -# Only used in the compiler's build system -rustc-dep-of-std = ["compiler-builtins"] - # This makes certain traits and function specializations public that # are not normally public but are required by the `builtins-test` unstable-public-internals = []
diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index a8b8920..d9acb83 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml
@@ -34,7 +34,7 @@ cc = { version = "1.2", optional = true } [features] -default = ["compiler-builtins"] +default = [] # Enable compilation of C code in compiler-rt, filling in some more optimized # implementations and also filling in unimplemented intrinsics @@ -45,8 +45,9 @@ # the generic versions on all platforms. no-asm = [] -# Flag this library as the unstable compiler-builtins lib -compiler-builtins = [] +# Flag this library as the unstable compiler-builtins lib. This must be enabled +# when using as `std`'s dependency.' +compiler-builtins = ["dep:core"] # Generate memory-related intrinsics like memcpy mem = [] @@ -55,9 +56,6 @@ # compiler-rt implementations. Also used for testing mangled-names = [] -# Only used in the compiler's build system -rustc-dep-of-std = ["compiler-builtins", "dep:core"] - # This makes certain traits and function specializations public that # are not normally public but are required by the `builtins-test` unstable-public-internals = []
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 011a903..66f5310 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs
@@ -6,8 +6,8 @@ use crate::error::Error; use crate::intrinsics::{unchecked_add, unchecked_mul, unchecked_sub}; -use crate::mem::SizedTypeProperties; -use crate::ptr::{Alignment, NonNull}; +use crate::mem::{Alignment, SizedTypeProperties}; +use crate::ptr::NonNull; use crate::{assert_unsafe_precondition, fmt, mem}; /// Layout of a block of memory. @@ -268,7 +268,7 @@ pub const fn for_value<T: ?Sized>(t: &T) -> Self { #[must_use] #[inline] pub const fn dangling_ptr(&self) -> NonNull<u8> { - NonNull::without_provenance(self.align.as_nonzero()) + NonNull::without_provenance(self.align.as_nonzero_usize()) } /// Creates a layout describing the record that can hold a value
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 4a2cf15..b116841 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs
@@ -405,7 +405,8 @@ fn index_mut(&mut self, index: I) -> &mut Self::Output { /// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] PartialOrd, const N: usize> const PartialOrd for [T; N] { #[inline] fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> { PartialOrd::partial_cmp(&&self[..], &&other[..]) @@ -430,7 +431,8 @@ fn index_mut(&mut self, index: I) -> &mut Self::Output { /// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Ord, const N: usize> Ord for [T; N] { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Ord, const N: usize> const Ord for [T; N] { #[inline] fn cmp(&self, other: &[T; N]) -> Ordering { Ord::cmp(&&self[..], &&other[..])
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index f31cadb..d67693f 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs
@@ -2719,18 +2719,6 @@ fn assert_coerce_unsized( } #[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized> PinCoerceUnsized for UnsafeCell<T> {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized> PinCoerceUnsized for SyncUnsafeCell<T> {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized> PinCoerceUnsized for Cell<T> {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized> PinCoerceUnsized for RefCell<T> {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for Ref<'b, T> {} #[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 87b328c..46d48af 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs
@@ -778,7 +778,72 @@ pub const fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { pub fn is_alphabetic(self) -> bool { match self { 'a'..='z' | 'A'..='Z' => true, - c => c > '\x7f' && unicode::Alphabetic(c), + '\0'..='\u{A9}' => false, + _ => unicode::Alphabetic(self), + } + } + + /// Returns `true` if this `char` has the `Cased` property. + /// A character is cased if and only if it is uppercase, lowercase, or titlecase. + /// + /// `Cased` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(titlecase)] + /// assert!('A'.is_cased()); + /// assert!('a'.is_cased()); + /// assert!(!'京'.is_cased()); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn is_cased(self) -> bool { + match self { + 'a'..='z' | 'A'..='Z' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Cased(self), + } + } + + /// Returns the case of this character: + /// [`Some(CharCase::Upper)`][`CharCase::Upper`] if [`self.is_uppercase()`][`char::is_uppercase`], + /// [`Some(CharCase::Lower)`][`CharCase::Lower`] if [`self.is_lowercase()`][`char::is_lowercase`], + /// [`Some(CharCase::Title)`][`CharCase::Title`] if [`self.is_titlecase()`][`char::is_titlecase`], and + /// `None` if [`!self.is_cased()`][`char::is_cased`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(titlecase)] + /// use core::char::CharCase; + /// assert_eq!('a'.case(), Some(CharCase::Lower)); + /// assert_eq!('δ'.case(), Some(CharCase::Lower)); + /// assert_eq!('A'.case(), Some(CharCase::Upper)); + /// assert_eq!('Δ'.case(), Some(CharCase::Upper)); + /// assert_eq!('Dž'.case(), Some(CharCase::Title)); + /// assert_eq!('中'.case(), None); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn case(self) -> Option<CharCase> { + match self { + 'a'..='z' => Some(CharCase::Lower), + 'A'..='Z' => Some(CharCase::Upper), + '\0'..='\u{A9}' => None, + _ if !unicode::Cased(self) => None, + _ if unicode::Lowercase(self) => Some(CharCase::Lower), + _ if unicode::Uppercase(self) => Some(CharCase::Upper), + _ => Some(CharCase::Title), } } @@ -819,7 +884,42 @@ pub fn is_alphabetic(self) -> bool { pub const fn is_lowercase(self) -> bool { match self { 'a'..='z' => true, - c => c > '\x7f' && unicode::Lowercase(c), + '\0'..='\u{A9}' => false, + _ => unicode::Lowercase(self), + } + } + + /// Returns `true` if this `char` has the general category for titlecase letters. + /// Conceptually, these characters consist of an uppercase portion followed by a lowercase portion. + /// + /// Titlecase letters (code points with the general category of `Lt`) are described in Chapter 4 + /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(titlecase)] + /// assert!('Dž'.is_titlecase()); + /// assert!('ῼ'.is_titlecase()); + /// assert!(!'D'.is_titlecase()); + /// assert!(!'z'.is_titlecase()); + /// assert!(!'中'.is_titlecase()); + /// assert!(!' '.is_titlecase()); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn is_titlecase(self) -> bool { + match self { + '\0'..='\u{01C4}' => false, + _ => self.is_cased() && !self.is_lowercase() && !self.is_uppercase(), } } @@ -860,7 +960,8 @@ pub const fn is_lowercase(self) -> bool { pub const fn is_uppercase(self) -> bool { match self { 'A'..='Z' => true, - c => c > '\x7f' && unicode::Uppercase(c), + '\0'..='\u{BF}' => false, + _ => unicode::Uppercase(self), } } @@ -893,7 +994,8 @@ pub const fn is_uppercase(self) -> bool { pub const fn is_whitespace(self) -> bool { match self { ' ' | '\x09'..='\x0d' => true, - c => c > '\x7f' && unicode::White_Space(c), + '\0'..='\u{84}' => false, + _ => unicode::White_Space(self), } } @@ -920,10 +1022,10 @@ pub const fn is_whitespace(self) -> bool { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_alphanumeric(self) -> bool { - if self.is_ascii() { - self.is_ascii_alphanumeric() - } else { - unicode::Alphabetic(self) || unicode::N(self) + match self { + 'a'..='z' | 'A'..='Z' | '0'..='9' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Alphabetic(self) || unicode::N(self), } } @@ -969,23 +1071,7 @@ pub fn is_control(self) -> bool { #[must_use] #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - !self.is_ascii() && unicode::Grapheme_Extend(self) - } - - /// Returns `true` if this `char` has the `Cased` property. - /// - /// `Cased` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and - /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. - /// - /// [Unicode Standard]: https://www.unicode.org/versions/latest/ - /// [ucd]: https://www.unicode.org/reports/tr44/ - /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt - #[must_use] - #[inline] - #[doc(hidden)] - #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] - pub fn is_cased(self) -> bool { - if self.is_ascii() { self.is_ascii_alphabetic() } else { unicode::Cased(self) } + self > '\u{02FF}' && unicode::Grapheme_Extend(self) } /// Returns `true` if this `char` has the `Case_Ignorable` property. @@ -1047,7 +1133,8 @@ pub fn is_case_ignorable(self) -> bool { pub fn is_numeric(self) -> bool { match self { '0'..='9' => true, - c => c > '\x7f' && unicode::N(c), + '\0'..='\u{B1}' => false, + _ => unicode::N(self), } } @@ -1110,7 +1197,7 @@ pub fn is_numeric(self) -> bool { /// // convert into themselves. /// assert_eq!('山'.to_lowercase().to_string(), "山"); /// ``` - #[must_use = "this returns the lowercase character as a new iterator, \ + #[must_use = "this returns the lowercased character as a new iterator, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1118,9 +1205,115 @@ pub fn to_lowercase(self) -> ToLowercase { ToLowercase(CaseMappingIter::new(conversions::to_lower(self))) } + /// Returns an iterator that yields the titlecase mapping of this `char` as one or more + /// `char`s. + /// + /// This is usually, but not always, equivalent to the uppercase mapping + /// returned by [`Self::to_uppercase`]. Prefer this method when seeking to capitalize + /// Only The First Letter of a word, but use [`Self::to_uppercase`] for ALL CAPS. + /// + /// If this `char` does not have a titlecase mapping, the iterator yields the same `char`. + /// + /// If this `char` has a one-to-one titlecase mapping given by the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`. + /// + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt + /// + /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields + /// the `char`(s) given by [`SpecialCasing.txt`]. + /// + /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt + /// + /// This operation performs an unconditional mapping without tailoring. That is, the conversion + /// is independent of context and language. + /// + /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in + /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// + /// # Examples + /// + /// As an iterator: + /// + /// ``` + /// #![feature(titlecase)] + /// for c in 'ß'.to_titlecase() { + /// print!("{c}"); + /// } + /// println!(); + /// ``` + /// + /// Using `println!` directly: + /// + /// ``` + /// #![feature(titlecase)] + /// println!("{}", 'ß'.to_titlecase()); + /// ``` + /// + /// Both are equivalent to: + /// + /// ``` + /// println!("Ss"); + /// ``` + /// + /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string): + /// + /// ``` + /// #![feature(titlecase)] + /// assert_eq!('c'.to_titlecase().to_string(), "C"); + /// assert_eq!('dž'.to_titlecase().to_string(), "Dž"); + /// assert_eq!('ῼ'.to_titlecase().to_string(), "ῼ"); + /// + /// // Sometimes the result is more than one character: + /// assert_eq!('ß'.to_titlecase().to_string(), "Ss"); + /// + /// // Characters that do not have separate cased forms + /// // convert into themselves. + /// assert_eq!('山'.to_titlecase().to_string(), "山"); + /// ``` + /// + /// # Note on locale + /// + /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two: + /// + /// * 'Dotless': I / ı, sometimes written ï + /// * 'Dotted': İ / i + /// + /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore: + /// + /// ``` + /// #![feature(titlecase)] + /// let upper_i = 'i'.to_titlecase().to_string(); + /// ``` + /// + /// The value of `upper_i` here relies on the language of the text: if we're + /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should + /// be `"İ"`. `to_titlecase()` does not take this into account, and so: + /// + /// ``` + /// #![feature(titlecase)] + /// let upper_i = 'i'.to_titlecase().to_string(); + /// + /// assert_eq!(upper_i, "I"); + /// ``` + /// + /// holds across languages. + #[must_use = "this returns the titlecased character as a new iterator, \ + without modifying the original"] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn to_titlecase(self) -> ToTitlecase { + ToTitlecase(CaseMappingIter::new(conversions::to_title(self))) + } + /// Returns an iterator that yields the uppercase mapping of this `char` as one or more /// `char`s. /// + /// Prefer this method when converting a word into ALL CAPS, but consider [`Self::to_titlecase`] + /// instead if you seek to capitalize Only The First Letter. + /// /// If this `char` does not have an uppercase mapping, the iterator yields the same `char`. /// /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character @@ -1170,9 +1363,11 @@ pub fn to_lowercase(self) -> ToLowercase { /// /// ``` /// assert_eq!('c'.to_uppercase().to_string(), "C"); + /// assert_eq!('dž'.to_uppercase().to_string(), "DŽ"); /// /// // Sometimes the result is more than one character: /// assert_eq!('ſt'.to_uppercase().to_string(), "ST"); + /// assert_eq!('ῼ'.to_uppercase().to_string(), "ΩΙ"); /// /// // Characters that do not have both uppercase and lowercase /// // convert into themselves. @@ -1181,7 +1376,7 @@ pub fn to_lowercase(self) -> ToLowercase { /// /// # Note on locale /// - /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two: + /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two: /// /// * 'Dotless': I / ı, sometimes written ï /// * 'Dotted': İ / i @@ -1193,7 +1388,7 @@ pub fn to_lowercase(self) -> ToLowercase { /// ``` /// /// The value of `upper_i` here relies on the language of the text: if we're - /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should + /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should /// be `"İ"`. `to_uppercase()` does not take this into account, and so: /// /// ``` @@ -1203,7 +1398,7 @@ pub fn to_lowercase(self) -> ToLowercase { /// ``` /// /// holds across languages. - #[must_use = "this returns the uppercase character as a new iterator, \ + #[must_use = "this returns the uppercased character as a new iterator, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1446,7 +1641,7 @@ pub const fn make_ascii_lowercase(&mut self) { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_alphabetic(&self) -> bool { - matches!(*self, 'A'..='Z' | 'a'..='z') + matches!(*self, 'a'..='z' | 'A'..='Z') } /// Checks if the value is an ASCII uppercase character:
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 82a3f6f..3231c41 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs
@@ -363,13 +363,21 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } macro_rules! casemappingiter_impls { - ($(#[$attr:meta])* $ITER_NAME:ident) => { + ( + #[$stab:meta] + #[$dendstab:meta] + #[$fusedstab:meta] + #[$exactstab:meta] + #[$displaystab:meta] + $(#[$attr:meta])* + $ITER_NAME:ident + ) => { $(#[$attr])* - #[stable(feature = "rust1", since = "1.0.0")] + #[$stab] #[derive(Debug, Clone)] pub struct $ITER_NAME(CaseMappingIter); - #[stable(feature = "rust1", since = "1.0.0")] + #[$stab] impl Iterator for $ITER_NAME { type Item = char; fn next(&mut self) -> Option<char> { @@ -405,7 +413,7 @@ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { } } - #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[$dendstab] impl DoubleEndedIterator for $ITER_NAME { fn next_back(&mut self) -> Option<char> { self.0.next_back() @@ -423,10 +431,10 @@ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { } } - #[stable(feature = "fused", since = "1.26.0")] + #[$fusedstab] impl FusedIterator for $ITER_NAME {} - #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[$exactstab] impl ExactSizeIterator for $ITER_NAME { fn len(&self) -> usize { self.0.len() @@ -453,7 +461,7 @@ unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME { #[unstable(feature = "std_internals", issue = "none")] unsafe impl TrustedRandomAccess for $ITER_NAME {} - #[stable(feature = "char_struct_display", since = "1.16.0")] + #[$displaystab] impl fmt::Display for $ITER_NAME { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -464,16 +472,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } casemappingiter_impls! { - /// Returns an iterator that yields the lowercase equivalent of a `char`. - /// - /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See - /// its documentation for more. - /// - /// [`to_lowercase`]: char::to_lowercase - ToLowercase -} - -casemappingiter_impls! { + #[stable(feature = "rust1", since = "1.0.0")] + #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[stable(feature = "fused", since = "1.26.0")] + #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[stable(feature = "char_struct_display", since = "1.16.0")] /// Returns an iterator that yields the uppercase equivalent of a `char`. /// /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See @@ -483,6 +486,36 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ToUppercase } +casemappingiter_impls! { + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + /// Returns an iterator that yields the titlecase equivalent of a `char`. + /// + /// This `struct` is created by the [`to_titlecase`] method on [`char`]. See + /// its documentation for more. + /// + /// [`to_titlecase`]: char::to_titlecase + ToTitlecase +} + +casemappingiter_impls! { + #[stable(feature = "rust1", since = "1.0.0")] + #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[stable(feature = "fused", since = "1.26.0")] + #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[stable(feature = "char_struct_display", since = "1.16.0")] + /// Returns an iterator that yields the lowercase equivalent of a `char`. + /// + /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See + /// its documentation for more. + /// + /// [`to_lowercase`]: char::to_lowercase + ToLowercase +} + #[derive(Debug, Clone)] struct CaseMappingIter(core::array::IntoIter<char, 3>); @@ -603,3 +636,23 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { #[stable(feature = "u8_from_char", since = "1.59.0")] impl Error for TryFromCharError {} + +/// The case of a cased character, +/// as returned by [`char::case`]. +/// +/// Titlecase characters conceptually are composed of an uppercase portion +/// followed by a lowercase portion. +/// The variant discriminants represent this: +/// the most significant bit represents whether the case +/// conceptually starts as uppercase, while the least significant bit +/// represents whether it conceptually ends as uppercase. +#[unstable(feature = "titlecase", issue = "153892")] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum CharCase { + /// Lowercase. Corresponds to the `Lowercase` Unicode property. + Lower = 0b00, + /// Titlecase. Corresponds to the `Titlecase_Letter` Unicode general category. + Title = 0b10, + /// Uppercase. Corresponds to the `Uppercase` Unicode property. + Upper = 0b11, +}
diff --git a/library/core/src/ffi/c_double.md b/library/core/src/ffi/c_double.md index d49e29b..8586dec 100644 --- a/library/core/src/ffi/c_double.md +++ b/library/core/src/ffi/c_double.md
@@ -1,6 +1,6 @@ Equivalent to C's `double` type. -This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard. +This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`]; some 16-bit systems use [`f32`], for example. Esoteric systems could use something entirely different from the IEEE-754 standard. [IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754 [`float`]: c_float
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 5fc97d9a..62b3d75 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs
@@ -716,7 +716,7 @@ fn index(&self, index: ops::RangeFrom<usize>) -> &CStr { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl ops::Index<range::RangeFrom<usize>> for CStr { type Output = CStr;
diff --git a/library/core/src/ffi/primitives.rs b/library/core/src/ffi/primitives.rs index fa23cf3..11dad9a 100644 --- a/library/core/src/ffi/primitives.rs +++ b/library/core/src/ffi/primitives.rs
@@ -15,24 +15,27 @@ macro_rules! type_alias { } } -type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] } +// `#[doc(cfg(true))]` is used to prevent rustdoc from displaying a "Available on ..." box. +// The implementation of these constants is target-specific, but every target does define them. + +type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(true))] } type_alias! { "c_schar.md", c_schar = i8; } type_alias! { "c_uchar.md", c_uchar = u8; } type_alias! { "c_short.md", c_short = i16; } type_alias! { "c_ushort.md", c_ushort = u16; } -type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] } -type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] } +type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(true))] } +type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(true))] } -type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] } -type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] } +type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(true))] } +type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(true))] } type_alias! { "c_longlong.md", c_longlong = i64; } type_alias! { "c_ulonglong.md", c_ulonglong = u64; } type_alias! { "c_float.md", c_float = f32; } -type_alias! { "c_double.md", c_double = f64; } +type_alias! { "c_double.md", c_double= c_double_definition::c_double; #[doc(cfg(true))] } mod c_char_definition { crate::cfg_select! { @@ -183,3 +186,18 @@ mod c_int_definition { } } } + +mod c_double_definition { + crate::cfg_select! { + target_arch = "avr" => { + // avr: + // Per https://gcc.gnu.org/wiki/avr-gcc#Type_Layout. The table says `4,8` because + // in C the width of `double` can be changed with the `-mdouble=32/64` setting. But + // 32-bits is the default for the rust avr target. + pub(super) type c_double = f32; + } + _ => { + pub(super) type c_double = f64; + } + } +}
diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index b6dfe3a..f0f58a0 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs
@@ -244,7 +244,7 @@ pub(crate) const fn duplicate(&self) -> Self { #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] impl<'f> const Clone for VaList<'f> { - #[inline] + #[inline] // Avoid codegen when not used to help backends that don't support VaList. fn clone(&self) -> Self { // We only implement Clone and not Copy because some future target might not be able to // implement Copy (e.g. because it allocates). For the same reason we use an intrinsic @@ -256,6 +256,7 @@ fn clone(&self) -> Self { #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] impl<'f> const Drop for VaList<'f> { + #[inline] // Avoid codegen when not used to help backends that don't support VaList. fn drop(&mut self) { // SAFETY: this variable argument list is being dropped, so won't be read from again. unsafe { va_end(self) } @@ -326,7 +327,7 @@ impl<'f> VaList<'f> { /// /// Calling this function with an incompatible type, an invalid value, or when there /// are no more variable arguments, is unsound. - #[inline] + #[inline] // Avoid codegen when not used to help backends that don't support VaList. #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] pub const unsafe fn arg<T: VaArgSafe>(&mut self) -> T { // SAFETY: the caller must uphold the safety contract for `va_arg`.
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index dfa27e3..e9302a6 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs
@@ -594,6 +594,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Include wasm32 in here since it doesn't reflect the native pointer size, and // often cares strongly about getting a smaller code size. #[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +#[doc(auto_cfg = false)] mod imp { use super::*; impl_Display!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into display_u64); @@ -601,6 +602,7 @@ mod imp { } #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] +#[doc(auto_cfg = false)] mod imp { use super::*; impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into display_u32);
diff --git a/library/core/src/intrinsics/bounds.rs b/library/core/src/intrinsics/bounds.rs index 35390859..2170500 100644 --- a/library/core/src/intrinsics/bounds.rs +++ b/library/core/src/intrinsics/bounds.rs
@@ -39,3 +39,14 @@ impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *mut T { impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *const T { type Output = *const U; } + +/// Built-in float types (f16, f32, f64 and f128). +/// +/// # Safety +/// Must actually *be* such a type. +pub unsafe trait FloatPrimitive: Sized + Copy {} + +unsafe impl FloatPrimitive for f16 {} +unsafe impl FloatPrimitive for f32 {} +unsafe impl FloatPrimitive for f64 {} +unsafe impl FloatPrimitive for f128 {}
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 68e4f1c..6f9d351 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs
@@ -1573,7 +1573,7 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fadd_fast<T: Copy>(a: T, b: T) -> T; +pub unsafe fn fadd_fast<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1581,7 +1581,7 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fsub_fast<T: Copy>(a: T, b: T) -> T; +pub unsafe fn fsub_fast<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1589,7 +1589,7 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmul_fast<T: Copy>(a: T, b: T) -> T; +pub unsafe fn fmul_fast<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1597,7 +1597,7 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fdiv_fast<T: Copy>(a: T, b: T) -> T; +pub unsafe fn fdiv_fast<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1605,7 +1605,7 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn frem_fast<T: Copy>(a: T, b: T) -> T; +pub unsafe fn frem_fast<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range /// (<https://github.com/rust-lang/rust/issues/10184>) @@ -1613,42 +1613,43 @@ pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; +pub unsafe fn float_to_int_unchecked<Float: bounds::FloatPrimitive, Int: Copy>(value: Float) +-> Int; /// Float addition that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T; +pub const fn fadd_algebraic<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fsub_algebraic<T: Copy>(a: T, b: T) -> T; +pub const fn fsub_algebraic<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fmul_algebraic<T: Copy>(a: T, b: T) -> T; +pub const fn fmul_algebraic<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T; +pub const fn fdiv_algebraic<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn frem_algebraic<T: Copy>(a: T, b: T) -> T; +pub const fn frem_algebraic<T: bounds::FloatPrimitive>(a: T, b: T) -> T; /// Returns the number of bits set in an integer type `T` /// @@ -2502,14 +2503,6 @@ const fn compiletime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? { /// particular value, ever. However, the compiler will generally make it /// return `true` only if the value of the argument is actually known. /// -/// # Stability concerns -/// -/// While it is safe to call, this intrinsic may behave differently in -/// a `const` context than otherwise. See the [`const_eval_select()`] -/// documentation for an explanation of the issues this can cause. Unlike -/// `const_eval_select`, this intrinsic isn't guaranteed to behave -/// deterministically even in a `const` context. -/// /// # Type Requirements /// /// `T` must be either a `bool`, a `char`, a primitive numeric type (e.g. `f32`, @@ -2590,6 +2583,12 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool { /// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the /// user has UB checks disabled, the checks will still get optimized out. This intrinsic is /// primarily used by [`crate::ub_checks::assert_unsafe_precondition`]. +/// +/// # Consteval +/// +/// In consteval, this function currently returns `true`. This is because the value of the `ub_checks` +/// configuration can differ across crates, but we need this function to always return the same +/// value in consteval in order to avoid unsoundness. #[rustc_intrinsic_const_stable_indirect] // just for UB checks #[inline(always)] #[rustc_intrinsic] @@ -2609,6 +2608,12 @@ pub const fn ub_checks() -> bool { /// `#[inline]`), gating assertions on `overflow_checks()` rather than `cfg!(overflow_checks)` means that /// assertions are enabled whenever the *user crate* has overflow checks enabled. However if the /// user has overflow checks disabled, the checks will still get optimized out. +/// +/// # Consteval +/// +/// In consteval, this function currently returns `true`. This is because the value of the `overflow_checks` +/// configuration can differ across crates, but we need this function to always return the same +/// value in consteval in order to avoid unsoundness. #[inline(always)] #[rustc_intrinsic] pub const fn overflow_checks() -> bool { @@ -3385,39 +3390,14 @@ pub const fn maximumf128(x: f128, y: f128) -> f128 { } } -/// Returns the absolute value of an `f16`. +/// Returns the absolute value of a floating-point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::abs`](../../std/primitive.f16.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf16(x: f16) -> f16; - -/// Returns the absolute value of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::abs`](../../std/primitive.f32.html#method.abs) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `abs` method. For example, [`f32::abs`]. #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn fabsf32(x: f32) -> f32; - -/// Returns the absolute value of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::abs`](../../std/primitive.f64.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -pub const fn fabsf64(x: f64) -> f64; - -/// Returns the absolute value of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::abs`](../../std/primitive.f128.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf128(x: f128) -> f128; +pub const fn fabs<T: bounds::FloatPrimitive>(x: T) -> T; /// Copies the sign from `y` to `x` for `f16` values. ///
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 5fb2102..ae86690 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs
@@ -62,6 +62,7 @@ /// Adds two simd vectors elementwise. /// /// `T` must be a vector of integers or floats. +/// For integers, wrapping arithmetic is used. #[rustc_intrinsic] #[rustc_nounwind] pub const unsafe fn simd_add<T>(x: T, y: T) -> T; @@ -69,6 +70,7 @@ /// Subtracts `rhs` from `lhs` elementwise. /// /// `T` must be a vector of integers or floats. +/// For integers, wrapping arithmetic is used. #[rustc_intrinsic] #[rustc_nounwind] pub const unsafe fn simd_sub<T>(lhs: T, rhs: T) -> T; @@ -76,6 +78,7 @@ /// Multiplies two simd vectors elementwise. /// /// `T` must be a vector of integers or floats. +/// For integers, wrapping arithmetic is used. #[rustc_intrinsic] #[rustc_nounwind] pub const unsafe fn simd_mul<T>(x: T, y: T) -> T; @@ -233,8 +236,7 @@ /// Negates a vector elementwise. /// /// `T` must be a vector of integers or floats. -/// -/// Rust panics for `-<int>::Min` due to overflow, but it is not UB with this intrinsic. +/// For integers, wrapping arithmetic is used. #[rustc_intrinsic] #[rustc_nounwind] pub const unsafe fn simd_neg<T>(x: T) -> T; @@ -250,19 +252,27 @@ /// /// `T` must be a vector of floating-point primitive types. /// -/// Follows IEEE-754 `minNum` semantics. +/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// zeros deterministically. In particular, for each vector lane: +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_fmin<T>(x: T, y: T) -> T; +pub const unsafe fn simd_minimum_number_nsz<T>(x: T, y: T) -> T; /// Returns the maximum of two vectors, elementwise. /// /// `T` must be a vector of floating-point primitive types. /// -/// Follows IEEE-754 `maxNum` semantics. +/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// zeros deterministically. In particular, for each vector lane: +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_fmax<T>(x: T, y: T) -> T; +pub const unsafe fn simd_maximum_number_nsz<T>(x: T, y: T) -> T; /// Tests elementwise equality of two vectors. ///
diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index bb94ed0..f64dea2 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs
@@ -1,5 +1,4 @@ use crate::fmt; -use crate::iter::{Fuse, FusedIterator}; /// An iterator adapter that places a separator between all elements. /// @@ -14,15 +13,7 @@ pub struct Intersperse<I: Iterator> started: bool, separator: I::Item, next_item: Option<I::Item>, - iter: Fuse<I>, -} - -#[unstable(feature = "iter_intersperse", issue = "79524")] -impl<I> FusedIterator for Intersperse<I> -where - I: FusedIterator, - I::Item: Clone, -{ + iter: I, } impl<I: Iterator> Intersperse<I> @@ -30,7 +21,7 @@ impl<I: Iterator> Intersperse<I> I::Item: Clone, { pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self { - Self { started: false, separator, next_item: None, iter: iter.fuse() } + Self { started: false, separator, next_item: None, iter } } } @@ -57,8 +48,9 @@ fn next(&mut self) -> Option<Self::Item> { } } } else { - self.started = true; - self.iter.next() + let item = self.iter.next(); + self.started = item.is_some(); + item } } @@ -95,15 +87,7 @@ pub struct IntersperseWith<I, G> started: bool, separator: G, next_item: Option<I::Item>, - iter: Fuse<I>, -} - -#[unstable(feature = "iter_intersperse", issue = "79524")] -impl<I, G> FusedIterator for IntersperseWith<I, G> -where - I: FusedIterator, - G: FnMut() -> I::Item, -{ + iter: I, } #[unstable(feature = "iter_intersperse", issue = "79524")] @@ -146,7 +130,7 @@ impl<I, G> IntersperseWith<I, G> G: FnMut() -> I::Item, { pub(in crate::iter) fn new(iter: I, separator: G) -> Self { - Self { started: false, separator, next_item: None, iter: iter.fuse() } + Self { started: false, separator, next_item: None, iter } } } @@ -173,8 +157,9 @@ fn next(&mut self) -> Option<Self::Item> { } } } else { - self.started = true; - self.iter.next() + let item = self.iter.next(); + self.started = item.is_some(); + item } }
diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index cef5563..9398fbb 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs
@@ -14,10 +14,7 @@ pub struct MapWindows<I: Iterator, F, const N: usize> { } struct MapWindowsInner<I: Iterator, const N: usize> { - // We fuse the inner iterator because there shouldn't be "holes" in - // the sliding window. Once the iterator returns a `None`, we make - // our `MapWindows` iterator return `None` forever. - iter: Option<I>, + iter: I, // Since iterators are assumed lazy, i.e. it only yields an item when // `Iterator::next()` is called, and `MapWindows` is not an exception. // @@ -26,7 +23,7 @@ struct MapWindowsInner<I: Iterator, const N: usize> { // we collect the first `N` items yielded from the inner iterator and // put it into the buffer. // - // When the inner iterator has returned a `None` (i.e. fused), we take + // When the inner iterator has returned a `None`, we take // away this `buffer` and leave it `None` to reclaim its resources. // // FIXME: should we shrink the size of `buffer` using niche optimization? @@ -64,19 +61,16 @@ pub(in crate::iter) fn new(iter: I, f: F) -> Self { impl<I: Iterator, const N: usize> MapWindowsInner<I, N> { #[inline] fn new(iter: I) -> Self { - Self { iter: Some(iter), buffer: None } + Self { iter, buffer: None } } fn next_window(&mut self) -> Option<&[I::Item; N]> { - let iter = self.iter.as_mut()?; match self.buffer { // It is the first time to advance. We collect // the first `N` items from `self.iter` to initialize `self.buffer`. - None => self.buffer = Buffer::try_from_iter(iter), - Some(ref mut buffer) => match iter.next() { + None => self.buffer = Buffer::try_from_iter(&mut self.iter), + Some(ref mut buffer) => match self.iter.next() { None => { - // Fuse the inner iterator since it yields a `None`. - self.iter.take(); self.buffer.take(); } // Advance the iterator. We first call `next` before changing our buffer @@ -89,8 +83,7 @@ fn new(iter: I) -> Self { } fn size_hint(&self) -> (usize, Option<usize>) { - let Some(ref iter) = self.iter else { return (0, Some(0)) }; - let (lo, hi) = iter.size_hint(); + let (lo, hi) = self.iter.size_hint(); if self.buffer.is_some() { // If the first `N` items are already yielded by the inner iterator, // the size hint is then equal to the that of the inner iterator's. @@ -253,12 +246,10 @@ fn size_hint(&self) -> (usize, Option<usize>) { } } -// Note that even if the inner iterator not fused, the `MapWindows` is still fused, -// because we don't allow "holes" in the mapping window. #[unstable(feature = "iter_map_windows", issue = "87155")] impl<I, F, R, const N: usize> FusedIterator for MapWindows<I, F, N> where - I: Iterator, + I: FusedIterator, F: FnMut(&[I::Item; N]) -> R, { }
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 350b5d3..951bb5d 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs
@@ -29,7 +29,8 @@ unsafe impl TrustedStep for $type {} unstable `Step` trait" )] #[unstable(feature = "step_trait", issue = "42168")] -pub trait Step: Clone + PartialOrd + Sized { +#[rustc_const_unstable(feature = "step_trait", issue = "42168")] +pub const trait Step: [const] Clone + [const] PartialOrd + Sized { /// Returns the bounds on the number of *successor* steps required to get from `start` to `end` /// like [`Iterator::size_hint()`][Iterator::size_hint()]. /// @@ -262,7 +263,8 @@ macro_rules! step_integer_impls { $( #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", issue = "42168")] - impl Step for $u_narrower { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for $u_narrower { step_identical_methods!(); step_unsigned_methods!(); @@ -296,7 +298,8 @@ fn backward_checked(start: Self, n: usize) -> Option<Self> { #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", issue = "42168")] - impl Step for $i_narrower { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for $i_narrower { step_identical_methods!(); step_signed_methods!($u_narrower); @@ -362,7 +365,8 @@ fn backward_checked(start: Self, n: usize) -> Option<Self> { $( #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", issue = "42168")] - impl Step for $u_wider { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for $u_wider { step_identical_methods!(); step_unsigned_methods!(); @@ -392,7 +396,8 @@ fn backward_checked(start: Self, n: usize) -> Option<Self> { #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", issue = "42168")] - impl Step for $i_wider { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for $i_wider { step_identical_methods!(); step_signed_methods!($u_wider); @@ -449,7 +454,8 @@ fn backward_checked(start: Self, n: usize) -> Option<Self> { } #[unstable(feature = "step_trait", issue = "42168")] -impl Step for char { +#[rustc_const_unstable(feature = "step_trait", issue = "42168")] +impl const Step for char { #[inline] fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) { let start = start as u32; @@ -536,7 +542,8 @@ unsafe fn backward_unchecked(start: char, count: usize) -> char { } #[unstable(feature = "step_trait", issue = "42168")] -impl Step for AsciiChar { +#[rustc_const_unstable(feature = "step_trait", issue = "42168")] +impl const Step for AsciiChar { #[inline] fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) { Step::steps_between(&start.to_u8(), &end.to_u8()) @@ -578,7 +585,8 @@ unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar { } #[unstable(feature = "step_trait", issue = "42168")] -impl Step for Ipv4Addr { +#[rustc_const_unstable(feature = "step_trait", issue = "42168")] +impl const Step for Ipv4Addr { #[inline] fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) { u32::steps_between(&start.to_bits(), &end.to_bits()) @@ -610,7 +618,8 @@ unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr { } #[unstable(feature = "step_trait", issue = "42168")] -impl Step for Ipv6Addr { +#[rustc_const_unstable(feature = "step_trait", issue = "42168")] +impl const Step for Ipv6Addr { #[inline] fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) { u128::steps_between(&start.to_bits(), &end.to_bits())
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 2e82f45..943e869 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs
@@ -635,11 +635,24 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> /// of the original iterator. /// /// Specifically on fused iterators, it is guaranteed that the new iterator - /// places a copy of `separator` between adjacent `Some(_)` items. However, - /// for non-fused iterators, [`intersperse`] will create a new iterator that - /// is a fused version of the original iterator and place a copy of `separator` - /// between adjacent `Some(_)` items. This behavior for non-fused iterators - /// is subject to change. + /// places a copy of `separator` between *adjacent* `Some(_)` items. For non-fused iterators, + /// it is guaranteed that [`intersperse`] will create a new iterator that places a copy + /// of `separator` between `Some(_)` items, particularly just right before the subsequent + /// `Some(_)` item. + /// + /// For example, consider the following non-fused iterator: + /// + /// ```text + /// Some(1) -> Some(2) -> None -> Some(3) -> Some(4) -> ... + /// ``` + /// + /// If this non-fused iterator were to be interspersed with `0`, + /// then the interspersed iterator will produce: + /// + /// ```text + /// Some(1) -> Some(0) -> Some(2) -> None -> Some(0) -> Some(3) -> Some(0) -> + /// Some(4) -> ... + /// ``` /// /// In case `separator` does not implement [`Clone`] or needs to be /// computed every time, use [`intersperse_with`]. @@ -688,10 +701,23 @@ fn intersperse(self, separator: Self::Item) -> Intersperse<Self> /// /// Specifically on fused iterators, it is guaranteed that the new iterator /// places an item generated by `separator` between adjacent `Some(_)` items. - /// However, for non-fused iterators, [`intersperse_with`] will create a new - /// iterator that is a fused version of the original iterator and place an item - /// generated by `separator` between adjacent `Some(_)` items. This - /// behavior for non-fused iterators is subject to change. + /// For non-fused iterators, it is guaranteed that [`intersperse_with`] will + /// create a new iterator that places an item generated by `separator` between `Some(_)` + /// items, particularly just right before the subsequent `Some(_)` item. + /// + /// For example, consider the following non-fused iterator: + /// + /// ```text + /// Some(1) -> Some(2) -> None -> Some(3) -> Some(4) -> ... + /// ``` + /// + /// If this non-fused iterator were to be interspersed with a `separator` closure + /// that returns `0` repeatedly, the interspersed iterator will produce: + /// + /// ```text + /// Some(1) -> Some(0) -> Some(2) -> None -> Some(0) -> Some(3) -> Some(0) -> + /// Some(4) -> ... + /// ``` /// /// The `separator` closure will be called exactly once each time an item /// is placed between two adjacent items from the underlying iterator; @@ -1631,11 +1657,6 @@ fn flatten(self) -> Flatten<Self> /// items yielded by `self`). If 𝑘 is less than `N`, this method yields an /// empty iterator. /// - /// The returned iterator implements [`FusedIterator`], because once `self` - /// returns `None`, even if it returns a `Some(T)` again in the next iterations, - /// we cannot put it into a contiguous array buffer, and thus the returned iterator - /// should be fused. - /// /// [`slice::windows()`]: slice::windows /// [`FusedIterator`]: crate::iter::FusedIterator /// @@ -1696,7 +1717,7 @@ fn flatten(self) -> Flatten<Self> /// assert_eq!(it.next(), None); /// ``` /// - /// For non-fused iterators, they are fused after `map_windows`. + /// For non-fused iterators, the window is reset after `None` is yielded. /// /// ``` /// #![feature(iter_map_windows)] @@ -1713,11 +1734,11 @@ fn flatten(self) -> Flatten<Self> /// let val = self.state; /// self.state = self.state + 1; /// - /// // yields `0..5` first, then only even numbers since `6..`. - /// if val < 5 || val % 2 == 0 { - /// Some(val) - /// } else { + /// // Skip every 5th number + /// if (val + 1) % 5 == 0 { /// None + /// } else { + /// Some(val) /// } /// } /// } @@ -1725,32 +1746,35 @@ fn flatten(self) -> Flatten<Self> /// /// let mut iter = NonFusedIterator::default(); /// - /// // yields 0..5 first. /// assert_eq!(iter.next(), Some(0)); /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), Some(3)); - /// assert_eq!(iter.next(), Some(4)); - /// // then we can see our iterator going back and forth /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), Some(5)); /// assert_eq!(iter.next(), Some(6)); - /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), Some(7)); /// assert_eq!(iter.next(), Some(8)); /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), Some(10)); + /// assert_eq!(iter.next(), Some(11)); /// - /// // however, with `.map_windows()`, it is fused. /// let mut iter = NonFusedIterator::default() /// .map_windows(|arr: &[_; 2]| *arr); /// /// assert_eq!(iter.next(), Some([0, 1])); /// assert_eq!(iter.next(), Some([1, 2])); /// assert_eq!(iter.next(), Some([2, 3])); - /// assert_eq!(iter.next(), Some([3, 4])); /// assert_eq!(iter.next(), None); /// - /// // it will always return `None` after the first time. + /// assert_eq!(iter.next(), Some([5, 6])); + /// assert_eq!(iter.next(), Some([6, 7])); + /// assert_eq!(iter.next(), Some([7, 8])); /// assert_eq!(iter.next(), None); - /// assert_eq!(iter.next(), None); + /// + /// assert_eq!(iter.next(), Some([10, 11])); + /// assert_eq!(iter.next(), Some([11, 12])); + /// assert_eq!(iter.next(), Some([12, 13])); /// assert_eq!(iter.next(), None); /// ``` #[inline]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 35f93d8f..e0750f0 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs
@@ -110,6 +110,7 @@ #![feature(offset_of_enum)] #![feature(panic_internals)] #![feature(pattern_type_macro)] +#![feature(sealed)] #![feature(ub_checks)] // tidy-alphabetical-end // @@ -216,6 +217,14 @@ pub mod from { pub use crate::macros::builtin::From; } +mod sealed { + /// This trait being unreachable from outside the crate + /// prevents outside implementations of our extension traits. + /// This allows adding more trait methods in the future. + #[unstable(feature = "sealed", issue = "none")] + pub trait Sealed {} +} + // We don't export this through #[macro_export] for now, to avoid breakage. #[unstable(feature = "autodiff", issue = "124509")] /// Unstable module containing the unstable `autodiff` macro.
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 49e1acd..7f35e94 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs
@@ -124,8 +124,6 @@ macro_rules! assert_ne { }; } -// FIXME add back debug_assert_matches doc link after bootstrap. - /// Asserts that an expression matches the provided pattern. /// /// This macro is generally preferable to `assert!(matches!(value, pattern))`, because it can print @@ -137,9 +135,11 @@ macro_rules! assert_ne { /// otherwise this macro will panic. /// /// Assertions are always checked in both debug and release builds, and cannot -/// be disabled. See `debug_assert_matches!` for assertions that are disabled in +/// be disabled. See [`debug_assert_matches!`] for assertions that are disabled in /// release builds by default. /// +/// [`debug_assert_matches!`]: crate::debug_assert_matches +/// /// On panic, this macro will print the value of the expression with its debug representation. /// /// Like [`assert!`], this macro has a second form, where a custom panic message can be provided.
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/mem/alignment.rs similarity index 91% rename from library/core/src/ptr/alignment.rs rename to library/core/src/mem/alignment.rs index b106314..a8c4c8e 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/mem/alignment.rs
@@ -11,7 +11,8 @@ /// Note that particularly large alignments, while representable in this type, /// are likely not to be supported by actual allocators and linkers. #[unstable(feature = "ptr_alignment_type", issue = "102070")] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[repr(transparent)] pub struct Alignment { // This field is never used directly (nor is the enum), @@ -37,7 +38,7 @@ impl Alignment { /// /// ``` /// #![feature(ptr_alignment_type)] - /// use std::ptr::Alignment; + /// use std::mem::Alignment; /// /// assert_eq!(Alignment::MIN.as_usize(), 1); /// ``` @@ -65,7 +66,7 @@ pub const fn of<T>() -> Self { /// /// ``` /// #![feature(ptr_alignment_type)] - /// use std::ptr::Alignment; + /// use std::mem::Alignment; /// /// assert_eq!(Alignment::of_val(&5i32).as_usize(), 4); /// ``` @@ -112,14 +113,13 @@ pub const fn of_val<T: MetaSized>(val: &T) -> Self { /// /// ``` /// #![feature(ptr_alignment_type)] - /// use std::ptr::Alignment; + /// use std::mem::Alignment; /// /// assert_eq!(unsafe { Alignment::of_val_raw(&5i32) }.as_usize(), 4); /// ``` #[inline] #[must_use] #[unstable(feature = "ptr_alignment_type", issue = "102070")] - // #[unstable(feature = "layout_for_ptr", issue = "69835")] pub const unsafe fn of_val_raw<T: MetaSized>(val: *const T) -> Self { // SAFETY: precondition propagated to the caller let align = unsafe { mem::align_of_val_raw(val) }; @@ -169,16 +169,28 @@ pub const fn new(align: usize) -> Option<Self> { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn as_usize(self) -> usize { - // Going through `as_nonzero` helps this be more clearly the inverse of + // Going through `as_nonzero_usize` helps this be more clearly the inverse of // `new_unchecked`, letting MIR optimizations fold it away. - self.as_nonzero().get() + self.as_nonzero_usize().get() + } + + /// Returns the alignment as a <code>[NonZero]<[usize]></code>. + #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[deprecated( + since = "CURRENT_RUSTC_VERSION", + note = "renamed to `as_nonzero_usize`", + suggestion = "as_nonzero_usize" + )] + #[inline] + pub const fn as_nonzero(self) -> NonZero<usize> { + self.as_nonzero_usize() } /// Returns the alignment as a <code>[NonZero]<[usize]></code>. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] - pub const fn as_nonzero(self) -> NonZero<usize> { + pub const fn as_nonzero_usize(self) -> NonZero<usize> { // This transmutes directly to avoid the UbCheck in `NonZero::new_unchecked` // since there's no way for the user to trip that check anyway -- the // validity invariant of the type would have to have been broken earlier -- @@ -204,7 +216,7 @@ pub const fn as_nonzero(self) -> NonZero<usize> { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn log2(self) -> u32 { - self.as_nonzero().trailing_zeros() + self.as_nonzero_usize().trailing_zeros() } /// Returns a bit mask that can be used to match this alignment. @@ -214,9 +226,10 @@ pub const fn log2(self) -> u32 { /// # Examples /// /// ``` - /// #![feature(ptr_alignment_type)] /// #![feature(ptr_mask)] - /// use std::ptr::{Alignment, NonNull}; + /// #![feature(ptr_alignment_type)] + /// use std::mem::Alignment; + /// use std::ptr::NonNull; /// /// #[repr(align(1))] struct Align1(u8); /// #[repr(align(2))] struct Align2(u16); @@ -246,7 +259,7 @@ pub(crate) const fn max(a: Self, b: Self) -> Self { #[unstable(feature = "ptr_alignment_type", issue = "102070")] impl fmt::Debug for Alignment { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?} (1 << {:?})", self.as_nonzero(), self.log2()) + write!(f, "{:?} (1 << {:?})", self.as_nonzero_usize(), self.log2()) } } @@ -277,7 +290,7 @@ fn try_from(align: usize) -> Result<Alignment, Self::Error> { impl const From<Alignment> for NonZero<usize> { #[inline] fn from(align: Alignment) -> NonZero<usize> { - align.as_nonzero() + align.as_nonzero_usize() } } @@ -291,15 +304,17 @@ fn from(align: Alignment) -> usize { } #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl cmp::Ord for Alignment { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const cmp::Ord for Alignment { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { - self.as_nonzero().get().cmp(&other.as_nonzero().get()) + self.as_nonzero_usize().cmp(&other.as_nonzero_usize()) } } #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl cmp::PartialOrd for Alignment { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const cmp::PartialOrd for Alignment { #[inline] fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) @@ -310,7 +325,7 @@ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { impl hash::Hash for Alignment { #[inline] fn hash<H: hash::Hasher>(&self, state: &mut H) { - self.as_nonzero().hash(state) + self.as_nonzero_usize().hash(state) } } @@ -324,7 +339,8 @@ fn default() -> Alignment { } #[cfg(target_pointer_width = "16")] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[repr(usize)] enum AlignmentEnum { _Align1Shl0 = 1 << 0, @@ -346,7 +362,8 @@ enum AlignmentEnum { } #[cfg(target_pointer_width = "32")] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[repr(usize)] enum AlignmentEnum { _Align1Shl0 = 1 << 0, @@ -384,7 +401,8 @@ enum AlignmentEnum { } #[cfg(target_pointer_width = "64")] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[repr(usize)] enum AlignmentEnum { _Align1Shl0 = 1 << 0,
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index b321908..a987970 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs
@@ -34,9 +34,12 @@ use crate::clone::TrivialClone; use crate::marker::{Destruct, DiscriminantKind}; use crate::panic::const_assert; -use crate::ptr::Alignment; use crate::{clone, cmp, fmt, hash, intrinsics, ptr}; +mod alignment; +#[unstable(feature = "ptr_alignment_type", issue = "102070")] +pub use alignment::Alignment; + mod manually_drop; #[stable(feature = "manually_drop", since = "1.20.0")] pub use manually_drop::ManuallyDrop;
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index a1bfd77..db94f52 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs
@@ -68,7 +68,8 @@ pub enum IpAddr { /// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex /// ``` #[rustc_diagnostic_item = "Ipv4Addr"] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Ipv4Addr { octets: [u8; 4], @@ -161,7 +162,8 @@ fn hash<H: Hasher>(&self, state: &mut H) { /// assert_eq!(localhost.is_loopback(), true); /// ``` #[rustc_diagnostic_item = "Ipv6Addr"] -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy)] +#[derive_const(Clone, PartialEq, Eq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Ipv6Addr { octets: [u8; 16], @@ -177,15 +179,17 @@ fn hash<H: Hasher>(&self, state: &mut H) { } } -/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2]. +/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2], +/// which updates [IETF RFC 4291 section 2.7]. /// /// # Stability Guarantees /// -/// Not all possible values for a multicast scope have been assigned. -/// Future RFCs may introduce new scopes, which will be added as variants to this enum; -/// because of this the enum is marked as `#[non_exhaustive]`. +/// Scopes 0 and F are currently reserved by IETF, and may be assigned in the future. +/// For this reason, the enum variants for those two scopes are not currently nameable. +/// You can still check for them in your code using `as` casts. /// /// # Examples +/// /// ``` /// #![feature(ip)] /// @@ -204,32 +208,76 @@ fn hash<H: Hasher>(&self, state: &mut H) { /// Some(SiteLocal) => println!("Site-Local scope"), /// Some(OrganizationLocal) => println!("Organization-Local scope"), /// Some(Global) => println!("Global scope"), -/// Some(_) => println!("Unknown scope"), +/// Some(s) => { +/// let snum = s as u8; +/// if matches!(0x0 | 0xF, snum) { +/// println!("Reserved scope {snum:X}") +/// } else { +/// println!("Unassigned scope {snum:X}") +/// } +/// } /// None => println!("Not a multicast address!") /// } -/// /// ``` /// /// [IPv6 multicast address]: Ipv6Addr /// [IETF RFC 7346 section 2]: https://tools.ietf.org/html/rfc7346#section-2 -#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)] +/// [IETF RFC 4291 section 2.7]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.7 +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[unstable(feature = "ip", issue = "27709")] -#[non_exhaustive] pub enum Ipv6MulticastScope { + /// Reserved by IETF. + #[doc(hidden)] + #[unstable( + feature = "ip_multicast_reserved", + reason = "not yet assigned by IETF", + issue = "none" + )] + Reserved0 = 0x0, /// Interface-Local scope. - InterfaceLocal, + InterfaceLocal = 0x1, /// Link-Local scope. - LinkLocal, + LinkLocal = 0x2, /// Realm-Local scope. - RealmLocal, + RealmLocal = 0x3, /// Admin-Local scope. - AdminLocal, + AdminLocal = 0x4, /// Site-Local scope. - SiteLocal, + SiteLocal = 0x5, + + /// Scope 6. Unassigned, available for administrators + /// to define additional multicast regions. + Unassigned6 = 0x6, + /// Scope 7. Unassigned, available for administrators + /// to define additional multicast regions. + Unassigned7 = 0x7, /// Organization-Local scope. - OrganizationLocal, + OrganizationLocal = 0x8, + /// Scope 9. Unassigned, available for administrators + /// to define additional multicast regions. + Unassigned9 = 0x9, + /// Scope A. Unassigned, available for administrators + /// to define additional multicast regions. + UnassignedA = 0xA, + /// Scope B. Unassigned, available for administrators + /// to define additional multicast regions. + UnassignedB = 0xB, + /// Scope C. Unassigned, available for administrators + /// to define additional multicast regions. + UnassignedC = 0xC, + /// Scope D. Unassigned, available for administrators + /// to define additional multicast regions. + UnassignedD = 0xD, /// Global scope. - Global, + Global = 0xE, + /// Reserved by IETF. + #[doc(hidden)] + #[unstable( + feature = "ip_multicast_reserved", + reason = "not yet assigned by IETF", + issue = "none" + )] + ReservedF = 0xF, } impl IpAddr { @@ -1183,7 +1231,8 @@ fn eq(&self, other: &IpAddr) -> bool { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Ipv4Addr { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const PartialOrd for Ipv4Addr { #[inline] fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> { Some(self.cmp(other)) @@ -1213,7 +1262,8 @@ fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Ipv4Addr { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Ord for Ipv4Addr { #[inline] fn cmp(&self, other: &Ipv4Addr) -> Ordering { self.octets.cmp(&other.octets) @@ -1848,14 +1898,23 @@ pub const fn is_unicast_global(&self) -> bool { pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> { if self.is_multicast() { match self.segments()[0] & 0x000f { - 1 => Some(Ipv6MulticastScope::InterfaceLocal), - 2 => Some(Ipv6MulticastScope::LinkLocal), - 3 => Some(Ipv6MulticastScope::RealmLocal), - 4 => Some(Ipv6MulticastScope::AdminLocal), - 5 => Some(Ipv6MulticastScope::SiteLocal), - 8 => Some(Ipv6MulticastScope::OrganizationLocal), - 14 => Some(Ipv6MulticastScope::Global), - _ => None, + 0x0 => Some(Ipv6MulticastScope::Reserved0), + 0x1 => Some(Ipv6MulticastScope::InterfaceLocal), + 0x2 => Some(Ipv6MulticastScope::LinkLocal), + 0x3 => Some(Ipv6MulticastScope::RealmLocal), + 0x4 => Some(Ipv6MulticastScope::AdminLocal), + 0x5 => Some(Ipv6MulticastScope::SiteLocal), + 0x6 => Some(Ipv6MulticastScope::Unassigned6), + 0x7 => Some(Ipv6MulticastScope::Unassigned7), + 0x8 => Some(Ipv6MulticastScope::OrganizationLocal), + 0x9 => Some(Ipv6MulticastScope::Unassigned9), + 0xA => Some(Ipv6MulticastScope::UnassignedA), + 0xB => Some(Ipv6MulticastScope::UnassignedB), + 0xC => Some(Ipv6MulticastScope::UnassignedC), + 0xD => Some(Ipv6MulticastScope::UnassignedD), + 0xE => Some(Ipv6MulticastScope::Global), + 0xF => Some(Ipv6MulticastScope::ReservedF), + _ => unreachable!(), } } else { None @@ -2177,7 +2236,8 @@ fn eq(&self, other: &Ipv6Addr) -> bool { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Ipv6Addr { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const PartialOrd for Ipv6Addr { #[inline] fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> { Some(self.cmp(other)) @@ -2207,7 +2267,8 @@ fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Ipv6Addr { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Ord for Ipv6Addr { #[inline] fn cmp(&self, other: &Ipv6Addr) -> Ordering { self.segments().cmp(&other.segments())
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 68c87b4..d833653 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs
@@ -1409,7 +1409,7 @@ pub fn clamp_magnitude(self, limit: f128) -> f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf128(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`.
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 3412e49..b0664ab 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs
@@ -1393,7 +1393,7 @@ pub fn clamp_magnitude(self, limit: f16) -> f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf16(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`.
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index e33cb098..b85bd2b 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs
@@ -1568,7 +1568,7 @@ pub fn clamp_magnitude(self, limit: f32) -> f32 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f32 { - intrinsics::fabsf32(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 872f567..3e7c1e7 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs
@@ -1566,7 +1566,7 @@ pub fn clamp_magnitude(self, limit: f64) -> f64 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f64 { - intrinsics::fabsf64(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`.
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index aba0eaf..b148c75 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs
@@ -3944,5 +3944,89 @@ pub fn clamp_magnitude(self, limit: $UnsignedT) -> Self { self } } + + /// Truncate an integer to an integer of the same size or smaller, preserving the least + /// significant bits. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".truncate());")] + #[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").truncate());")] + /// assert_eq!(120i8, 376i32.truncate()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn truncate<Target>(self) -> Target + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_truncate(self) + } + + /// Truncate an integer to an integer of the same size or smaller, saturating at numeric bounds + /// instead of truncating. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".saturating_truncate());")] + #[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").saturating_truncate());")] + /// assert_eq!(127i8, 376i32.saturating_truncate()); + /// assert_eq!(-128i8, (-1000i32).saturating_truncate()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn saturating_truncate<Target>(self) -> Target + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_saturating_truncate(self) + } + + /// Truncate an integer to an integer of the same size or smaller, returning `None` if the value + /// is outside the bounds of the smaller type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(Some(120i8), 120", stringify!($SelfT), ".checked_truncate());")] + #[doc = concat!("assert_eq!(Some(-120i8), (-120", stringify!($SelfT), ").checked_truncate());")] + /// assert_eq!(None, 376i32.checked_truncate::<i8>()); + /// assert_eq!(None, (-1000i32).checked_truncate::<i8>()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn checked_truncate<Target>(self) -> Option<Target> + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_checked_truncate(self) + } + + /// Extend to an integer of the same size or larger, preserving its value. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120i128, 120i8.extend());")] + #[doc = concat!("assert_eq!(-120i128, (-120i8).extend());")] + /// ``` + #[must_use = "this returns the extended value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn extend<Target>(self) -> Target + where Self: [const] traits::ExtendTarget<Target> + { + traits::ExtendTarget::internal_extend(self) + } } }
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 333e446..5ba3695 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs
@@ -46,6 +46,7 @@ macro_rules! sign_dependent_expr { mod float_parse; mod nonzero; mod saturating; +mod traits; mod wrapping; /// 100% perma-unstable @@ -1795,3 +1796,12 @@ macro_rules! run_checked_loop { from_str_int_impl! { signed isize i8 i16 i32 i64 i128 } from_str_int_impl! { unsigned usize u8 u16 u32 u64 u128 } + +macro_rules! impl_sealed { + ($($t:ty)*) => {$( + /// Allows extension traits within `core`. + #[unstable(feature = "sealed", issue = "none")] + impl crate::sealed::Sealed for $t {} + )*} +} +impl_sealed! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
diff --git a/library/core/src/num/traits.rs b/library/core/src/num/traits.rs new file mode 100644 index 0000000..9ce4d87 --- /dev/null +++ b/library/core/src/num/traits.rs
@@ -0,0 +1,129 @@ +/// Definitions of traits for numeric types +// Implementation based on `num_conv` by jhpratt, under (MIT OR Apache-2.0). + +/// Trait for types that this type can be truncated to +#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")] +#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] +pub const trait TruncateTarget<Target>: crate::sealed::Sealed { + #[doc(hidden)] + fn internal_truncate(self) -> Target; + + #[doc(hidden)] + fn internal_saturating_truncate(self) -> Target; + + #[doc(hidden)] + fn internal_checked_truncate(self) -> Option<Target>; +} + +/// Trait for types that this type can be truncated to +#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")] +#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] +pub const trait ExtendTarget<Target>: crate::sealed::Sealed { + #[doc(hidden)] + fn internal_extend(self) -> Target; +} + +macro_rules! impl_truncate { + ($($from:ty => $($to:ty),+;)*) => {$($( + const _: () = assert!( + size_of::<$from>() >= size_of::<$to>(), + concat!( + "cannot truncate ", + stringify!($from), + " to ", + stringify!($to), + " because ", + stringify!($from), + " is smaller than ", + stringify!($to) + ) + ); + + #[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + impl const TruncateTarget<$to> for $from { + #[inline] + fn internal_truncate(self) -> $to { + self as _ + } + + #[inline] + fn internal_saturating_truncate(self) -> $to { + if self > <$to>::MAX as Self { + <$to>::MAX + } else if self < <$to>::MIN as Self { + <$to>::MIN + } else { + self as _ + } + } + + #[inline] + fn internal_checked_truncate(self) -> Option<$to> { + if self > <$to>::MAX as Self || self < <$to>::MIN as Self { + None + } else { + Some(self as _) + } + } + } + )+)*}; +} + +macro_rules! impl_extend { + ($($from:ty => $($to:ty),+;)*) => {$($( + const _: () = assert!( + size_of::<$from>() <= size_of::<$to>(), + concat!( + "cannot extend ", + stringify!($from), + " to ", + stringify!($to), + " because ", + stringify!($from), + " is larger than ", + stringify!($to) + ) + ); + + #[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + impl const ExtendTarget<$to> for $from { + fn internal_extend(self) -> $to { + self as _ + } + } + )+)*}; +} + +impl_truncate! { + u8 => u8; + u16 => u16, u8; + u32 => u32, u16, u8; + u64 => u64, u32, u16, u8; + u128 => u128, u64, u32, u16, u8; + usize => usize, u16, u8; + + i8 => i8; + i16 => i16, i8; + i32 => i32, i16, i8; + i64 => i64, i32, i16, i8; + i128 => i128, i64, i32, i16, i8; + isize => isize, i16, i8; +} + +impl_extend! { + u8 => u8, u16, u32, u64, u128, usize; + u16 => u16, u32, u64, u128, usize; + u32 => u32, u64, u128; + u64 => u64, u128; + u128 => u128; + usize => usize; + + i8 => i8, i16, i32, i64, i128, isize; + i16 => i16, i32, i64, i128, isize; + i32 => i32, i64, i128; + i64 => i64, i128; + i128 => i128; + isize => isize; +}
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index ae8324c..e048f8f 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs
@@ -447,7 +447,7 @@ pub const fn rotate_right(self, n: u32) -> Self { pub const fn funnel_shl(self, rhs: Self, n: u32) -> Self { assert!(n < Self::BITS, "attempt to funnel shift left with overflow"); // SAFETY: just checked that `shift` is in-range - unsafe { intrinsics::unchecked_funnel_shl(self, rhs, n) } + unsafe { self.unchecked_funnel_shl(rhs, n) } } /// Performs a right funnel shift (concatenates `self` and `rhs`, with `self` @@ -482,7 +482,61 @@ pub const fn funnel_shl(self, rhs: Self, n: u32) -> Self { pub const fn funnel_shr(self, rhs: Self, n: u32) -> Self { assert!(n < Self::BITS, "attempt to funnel shift right with overflow"); // SAFETY: just checked that `shift` is in-range - unsafe { intrinsics::unchecked_funnel_shr(self, rhs, n) } + unsafe { self.unchecked_funnel_shr(rhs, n) } + } + + /// Unchecked funnel shift left. + /// + /// # Safety + /// + /// This results in undefined behavior if `n` is greater than or equal to + #[doc = concat!("`", stringify!($SelfT) , "::BITS`,")] + /// i.e. when [`funnel_shl`](Self::funnel_shl) would panic. + /// + #[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")] + #[unstable(feature = "funnel_shifts", issue = "145686")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + #[track_caller] + pub const unsafe fn unchecked_funnel_shl(self, low: Self, n: u32) -> Self { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_funnel_shl cannot overflow"), + (n: u32 = n) => n < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_funnel_shl(self, low, n) + } + } + + /// Unchecked funnel shift right. + /// + /// # Safety + /// + /// This results in undefined behavior if `n` is greater than or equal to + #[doc = concat!("`", stringify!($SelfT) , "::BITS`,")] + /// i.e. when [`funnel_shr`](Self::funnel_shr) would panic. + /// + #[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")] + #[unstable(feature = "funnel_shifts", issue = "145686")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + #[track_caller] + pub const unsafe fn unchecked_funnel_shr(self, low: Self, n: u32) -> Self { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_funnel_shr cannot overflow"), + (n: u32 = n) => n < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_funnel_shr(self, low, n) + } } /// Performs a carry-less multiplication, returning the lower bits. @@ -4053,5 +4107,83 @@ pub const fn min_value() -> Self { Self::MIN } #[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on this type")] #[rustc_diagnostic_item = concat!(stringify!($SelfT), "_legacy_fn_max_value")] pub const fn max_value() -> Self { Self::MAX } + + /// Truncate an integer to an integer of the same size or smaller, preserving the least + /// significant bits. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120u8, 120", stringify!($SelfT), ".truncate());")] + /// assert_eq!(120u8, 376u32.truncate()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn truncate<Target>(self) -> Target + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_truncate(self) + } + + /// Truncate an integer to an integer of the same size or smaller, saturating at numeric bounds + /// instead of truncating. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120u8, 120", stringify!($SelfT), ".saturating_truncate());")] + /// assert_eq!(255u8, 376u32.saturating_truncate()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn saturating_truncate<Target>(self) -> Target + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_saturating_truncate(self) + } + + /// Truncate an integer to an integer of the same size or smaller, returning `None` if the value + /// is outside the bounds of the smaller type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(Some(120u8), 120", stringify!($SelfT), ".checked_truncate());")] + /// assert_eq!(None, 376u32.checked_truncate::<u8>()); + /// ``` + #[must_use = "this returns the truncated value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn checked_truncate<Target>(self) -> Option<Target> + where Self: [const] traits::TruncateTarget<Target> + { + traits::TruncateTarget::internal_checked_truncate(self) + } + + /// Extend to an integer of the same size or larger, preserving its value. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_extend_truncate)] + #[doc = concat!("assert_eq!(120u128, 120u8.extend());")] + /// ``` + #[must_use = "this returns the extended value and does not modify the original"] + #[unstable(feature = "integer_extend_truncate", issue = "154330")] + #[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")] + #[inline] + pub const fn extend<Target>(self) -> Target + where Self: [const] traits::ExtendTarget<Target> + { + traits::ExtendTarget::internal_extend(self) + } } }
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index eb92e62..ea3ba8c 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs
@@ -740,7 +740,7 @@ //! //! While counter-intuitive, it's often the easier choice: if you do not expose a //! <code>[Pin]<[&mut] Field></code>, you do not need to be careful about other code -//! moving out of that field, you just have to ensure is that you never create pinning +//! moving out of that field, you just have to ensure that you never create a pinning //! reference to that field. This does of course also mean that if you decide a field does not //! have structural pinning, you must not write [`unsafe`] code that assumes (invalidly) that the //! field *is* structurally pinned! @@ -1829,9 +1829,10 @@ impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> /// /// # Safety /// -/// If this type implements `Deref`, then the concrete type returned by `deref` -/// and `deref_mut` must not change without a modification. The following -/// operations are not considered modifications: +/// Given a pointer of this type, the concrete type returned by its +/// `deref` method and (if it implements `DerefMut`) its `deref_mut` method +/// must be the same type and must not change without a modification. +/// The following operations are not considered modifications: /// /// * Moving the pointer. /// * Performing unsizing coercions on the pointer. @@ -1842,7 +1843,7 @@ impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> /// to. The concrete type of a slice is an array of the same element type and /// the length specified in the metadata. The concrete type of a sized type /// is the type itself. -pub unsafe trait PinCoerceUnsized {} +pub unsafe trait PinCoerceUnsized: Deref {} #[stable(feature = "pin", since = "1.33.0")] unsafe impl<'a, T: ?Sized> PinCoerceUnsized for &'a T {} @@ -1853,12 +1854,6 @@ unsafe impl<'a, T: ?Sized> PinCoerceUnsized for &'a mut T {} #[stable(feature = "pin", since = "1.33.0")] unsafe impl<T: PinCoerceUnsized> PinCoerceUnsized for Pin<T> {} -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl<T: ?Sized> PinCoerceUnsized for *const T {} - -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl<T: ?Sized> PinCoerceUnsized for *mut T {} - /// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally. /// /// Unlike [`Box::pin`], this does not create a new heap allocation. As explained
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 48e1e20..ddeb1cc 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs
@@ -412,9 +412,10 @@ use crate::num::NonZero; use crate::{fmt, hash, intrinsics, ub_checks}; -mod alignment; #[unstable(feature = "ptr_alignment_type", issue = "102070")] -pub use alignment::Alignment; +#[deprecated(since = "CURRENT_RUSTC_VERSION", note = "moved from `ptr` to `mem`")] +/// Deprecated re-export of [mem::Alignment]. +pub type Alignment = mem::Alignment; mod metadata; #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 8be7d3a..90f27ca 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs
@@ -4,7 +4,6 @@ use crate::mem::{MaybeUninit, SizedTypeProperties, transmute}; use crate::num::NonZero; use crate::ops::{CoerceUnsized, DispatchFromDyn}; -use crate::pin::PinCoerceUnsized; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; use crate::ub_checks::assert_unsafe_precondition; @@ -128,8 +127,8 @@ pub const fn without_provenance(addr: NonZero<usize>) -> Self { #[must_use] #[inline] pub const fn dangling() -> Self { - let align = crate::ptr::Alignment::of::<T>(); - NonNull::without_provenance(align.as_nonzero()) + let align = crate::mem::Alignment::of::<T>(); + NonNull::without_provenance(align.as_nonzero_usize()) } /// Converts an address back to a mutable pointer, picking up some previously 'exposed' @@ -139,8 +138,9 @@ pub const fn dangling() -> Self { /// /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[stable(feature = "nonnull_provenance", since = "1.89.0")] + #[rustc_const_unstable(feature = "const_nonnull_with_exposed_provenance", issue = "154215")] #[inline] - pub fn with_exposed_provenance(addr: NonZero<usize>) -> Self { + pub const fn with_exposed_provenance(addr: NonZero<usize>) -> Self { // SAFETY: we know `addr` is non-zero. unsafe { let ptr = crate::ptr::with_exposed_provenance_mut(addr.get()); @@ -1692,9 +1692,6 @@ impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl<T: PointeeSized> PinCoerceUnsized for NonNull<T> {} - #[stable(feature = "nonnull", since = "1.25.0")] impl<T: PointeeSized> fmt::Debug for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 3160c9d..6e55f0e 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs
@@ -2,7 +2,6 @@ use crate::fmt; use crate::marker::{PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; -use crate::pin::PinCoerceUnsized; use crate::ptr::NonNull; /// A wrapper around a raw non-null `*mut T` that indicates that the possessor @@ -176,9 +175,6 @@ impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> wh #[unstable(feature = "ptr_internals", issue = "none")] impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: PointeeSized> PinCoerceUnsized for Unique<T> {} - #[unstable(feature = "ptr_internals", issue = "none")] impl<T: PointeeSized> fmt::Debug for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 3c2c40d..d4be1b6 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs
@@ -1,19 +1,18 @@ -//! # Experimental replacement range types +//! # Replacement range types //! -//! The types within this module are meant to replace the existing -//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition. +//! The types within this module are meant to replace the legacy `Range`, +//! `RangeInclusive`, `RangeToInclusive` and `RangeFrom` types in a future edition. //! //! ``` -//! #![feature(new_range_api)] -//! use core::range::{Range, RangeFrom, RangeInclusive}; +//! use core::range::{Range, RangeFrom, RangeInclusive, RangeToInclusive}; //! //! let arr = [0, 1, 2, 3, 4]; -//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); -//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); -//! assert_eq!(arr[ ..=3 ], [0, 1, 2, 3 ]); -//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); -//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); -//! assert_eq!(arr[RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); +//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); +//! assert_eq!(arr[RangeToInclusive::from( ..=3)], [0, 1, 2, 3 ]); +//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); +//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); +//! assert_eq!(arr[ RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); //! ``` use crate::fmt; @@ -21,15 +20,18 @@ mod iter; -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "new_range_api_legacy", issue = "125687")] pub mod legacy; #[doc(inline)] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] +pub use iter::RangeFromIter; +#[doc(inline)] #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] pub use iter::RangeInclusiveIter; #[doc(inline)] -#[unstable(feature = "new_range_api", issue = "125687")] -pub use iter::{RangeFromIter, RangeIter}; +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] +pub use iter::RangeIter; // FIXME(#125687): re-exports temporarily removed // Because re-exports of stable items (Bound, RangeBounds, RangeFull, RangeTo) @@ -54,7 +56,6 @@ /// # Examples /// /// ``` -/// #![feature(new_range_api)] /// use core::range::Range; /// /// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); @@ -63,17 +64,17 @@ #[lang = "RangeCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, Default, PartialEq, Eq)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub struct Range<Idx> { /// The lower bound of the range (inclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub start: Idx, /// The upper bound of the range (exclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub end: Idx, } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; @@ -91,7 +92,6 @@ impl<Idx: Step> Range<Idx> { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// let mut i = Range::from(3..9).iter().map(|n| n*n); @@ -99,7 +99,7 @@ impl<Idx: Step> Range<Idx> { /// assert_eq!(i.next(), Some(16)); /// assert_eq!(i.next(), Some(25)); /// ``` - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn iter(&self) -> RangeIter<Idx> { self.clone().into_iter() @@ -112,7 +112,6 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3..5).contains(&2)); @@ -129,7 +128,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> { /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5)); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn contains<U>(&self, item: &U) -> bool where @@ -144,7 +143,6 @@ pub const fn contains<U>(&self, item: &U) -> bool /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3..5).is_empty()); @@ -155,7 +153,6 @@ pub const fn contains<U>(&self, item: &U) -> bool /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(new_range_api)] /// use core::range::Range; /// /// assert!(!Range::from(3.0..5.0).is_empty()); @@ -163,7 +160,7 @@ pub const fn contains<U>(&self, item: &U) -> bool /// assert!( Range::from(f32::NAN..5.0).is_empty()); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn is_empty(&self) -> bool where @@ -173,7 +170,7 @@ pub const fn is_empty(&self) -> bool } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const RangeBounds<T> for Range<T> { fn start_bound(&self) -> Bound<&T> { @@ -190,7 +187,7 @@ fn end_bound(&self) -> Bound<&T> { /// If you need to use this implementation where `T` is unsized, /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..end` with `(Bound::Included(start), Bound::Excluded(end))`. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const RangeBounds<T> for Range<&T> { fn start_bound(&self) -> Bound<&T> { @@ -201,8 +198,7 @@ fn end_bound(&self) -> Bound<&T> { } } -// #[unstable(feature = "range_into_bounds", issue = "136903")] -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const IntoBounds<T> for Range<T> { fn into_bounds(self) -> (Bound<T>, Bound<T>) { @@ -210,7 +206,7 @@ fn into_bounds(self) -> (Bound<T>, Bound<T>) { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] impl<T> const From<Range<T>> for legacy::Range<T> { #[inline] @@ -218,8 +214,7 @@ fn from(value: Range<T>) -> Self { Self { start: value.start, end: value.end } } } - -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] impl<T> const From<legacy::Range<T>> for Range<T> { #[inline] @@ -416,14 +411,13 @@ fn from(value: legacy::RangeInclusive<T>) -> Self { /// /// The `RangeFrom` `start..` contains all values with `x >= start`. /// -/// *Note*: Overflow in the [`Iterator`] implementation (when the contained +/// *Note*: Overflow in the [`IntoIterator`] implementation (when the contained /// data type reaches its numerical limit) is allowed to panic, wrap, or /// saturate. This behavior is defined by the implementation of the [`Step`] /// trait. For primitive integers, this follows the normal rules, and respects -/// the overflow checks profile (panic in debug, wrap in release). Note also -/// that overflow happens earlier than you might assume: the overflow happens -/// in the call to `next` that yields the maximum value, as the range must be -/// set to a state to yield the next value. +/// the overflow checks profile (panic in debug, wrap in release). Unlike +/// its legacy counterpart, the iterator will only panic after yielding the +/// maximum value when overflow checks are enabled. /// /// [`Step`]: crate::iter::Step /// @@ -432,7 +426,6 @@ fn from(value: legacy::RangeInclusive<T>) -> Self { /// The `start..` syntax is a `RangeFrom`: /// /// ``` -/// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); @@ -441,14 +434,14 @@ fn from(value: legacy::RangeInclusive<T>) -> Self { #[lang = "RangeFromCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, PartialEq, Eq)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] pub struct RangeFrom<Idx> { /// The lower bound of the range (inclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] pub start: Idx, } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; @@ -465,7 +458,6 @@ impl<Idx: Step> RangeFrom<Idx> { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n); @@ -473,7 +465,7 @@ impl<Idx: Step> RangeFrom<Idx> { /// assert_eq!(i.next(), Some(16)); /// assert_eq!(i.next(), Some(25)); /// ``` - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn iter(&self) -> RangeFromIter<Idx> { self.clone().into_iter() @@ -486,7 +478,6 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// assert!(!RangeFrom::from(3..).contains(&2)); @@ -498,7 +489,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5)); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn contains<U>(&self, item: &U) -> bool where @@ -509,7 +500,7 @@ pub const fn contains<U>(&self, item: &U) -> bool } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const RangeBounds<T> for RangeFrom<T> { fn start_bound(&self) -> Bound<&T> { @@ -526,7 +517,7 @@ fn end_bound(&self) -> Bound<&T> { /// If you need to use this implementation where `T` is unsized, /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const RangeBounds<T> for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { @@ -537,8 +528,7 @@ fn end_bound(&self) -> Bound<&T> { } } -// #[unstable(feature = "range_into_bounds", issue = "136903")] -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const IntoBounds<T> for RangeFrom<T> { fn into_bounds(self) -> (Bound<T>, Bound<T>) { @@ -547,7 +537,6 @@ fn into_bounds(self) -> (Bound<T>, Bound<T>) { } #[unstable(feature = "one_sided_range", issue = "69780")] -// #[unstable(feature = "new_range_api", issue = "125687")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const OneSidedRange<T> for RangeFrom<T> where @@ -558,7 +547,7 @@ fn bound(self) -> (OneSidedRangeBound, T) { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] impl<T> const From<RangeFrom<T>> for legacy::RangeFrom<T> { #[inline] @@ -566,7 +555,7 @@ fn from(value: RangeFrom<T>) -> Self { Self { start: value.start } } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> { #[inline] @@ -697,7 +686,6 @@ fn end_bound(&self) -> Bound<&T> { } } -// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const IntoBounds<T> for RangeToInclusive<T> { @@ -706,7 +694,6 @@ fn into_bounds(self) -> (Bound<T>, Bound<T>) { } } -// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[unstable(feature = "one_sided_range", issue = "69780")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl<T> const OneSidedRange<T> for RangeToInclusive<T>
diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index c1d4fbb..a5db369 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs
@@ -6,13 +6,27 @@ use crate::{intrinsics, mem}; /// By-value [`Range`] iterator. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug, Clone)] pub struct RangeIter<A>(legacy::Range<A>); impl<A> RangeIter<A> { - #[unstable(feature = "new_range_api", issue = "125687")] + #[unstable(feature = "new_range_remainder", issue = "154458")] /// Returns the remainder of the range being iterated over. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_remainder)] + /// + /// let range = core::range::Range::from(3..11); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder(), range); + /// iter.next(); + /// assert_eq!(iter.clone().remainder(), core::range::Range::from(4..11)); + /// iter.by_ref().for_each(drop); + /// assert!(iter.remainder().is_empty()); + /// ``` pub fn remainder(self) -> Range<A> { Range { start: self.0.start, end: self.0.end } } @@ -50,7 +64,7 @@ unsafe impl TrustedRandomAccessNoCoerce for RangeIter<$t> { u64 i64 } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> Iterator for RangeIter<A> { type Item = A; @@ -118,7 +132,7 @@ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> DoubleEndedIterator for RangeIter<A> { #[inline] fn next_back(&mut self) -> Option<A> { @@ -139,10 +153,10 @@ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<A: TrustedStep> TrustedLen for RangeIter<A> {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> FusedIterator for RangeIter<A> {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> IntoIterator for Range<A> { type Item = A; type IntoIter = RangeIter<A>; @@ -161,7 +175,21 @@ impl<A: Step> RangeInclusiveIter<A> { /// Returns the remainder of the range being iterated over. /// /// If the iterator is exhausted or empty, returns `None`. - #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_remainder)] + /// + /// let range = core::range::RangeInclusive::from(3..=11); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder().unwrap(), range); + /// iter.next(); + /// assert_eq!(iter.clone().remainder().unwrap(), core::range::RangeInclusive::from(4..=11)); + /// iter.by_ref().for_each(drop); + /// assert!(iter.remainder().is_none()); + /// ``` + #[unstable(feature = "new_range_remainder", issue = "154458")] pub fn remainder(self) -> Option<RangeInclusive<A>> { if self.0.is_empty() { return None; @@ -271,7 +299,7 @@ fn into_iter(self) -> Self::IntoIter { // since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl ExactSizeIterator for RangeIter<$t> { } )*) } @@ -294,46 +322,75 @@ impl ExactSizeIterator for RangeInclusiveIter<$t> { } } /// By-value [`RangeFrom`] iterator. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug, Clone)] pub struct RangeFromIter<A> { start: A, - /// Whether the first element of the iterator has yielded. + /// Whether the maximum value of the iterator has yielded. /// Only used when overflow checks are enabled. - first: bool, + exhausted: bool, } impl<A: Step> RangeFromIter<A> { /// Returns the remainder of the range being iterated over. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_remainder)] + /// + /// let range = core::range::RangeFrom::from(3..); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder(), range); + /// iter.next(); + /// assert_eq!(iter.remainder(), core::range::RangeFrom::from(4..)); + /// ``` #[inline] #[rustc_inherit_overflow_checks] - #[unstable(feature = "new_range_api", issue = "125687")] + #[unstable(feature = "new_range_remainder", issue = "154458")] pub fn remainder(self) -> RangeFrom<A> { - if intrinsics::overflow_checks() { - if !self.first { - return RangeFrom { start: Step::forward(self.start, 1) }; - } + // Need to handle this case even if overflow-checks are disabled, + // because a `RangeFromIter` could be exhausted in a crate with + // overflow-checks enabled, but then passed to a crate with them + // disabled before this is called. + if self.exhausted { + return RangeFrom { start: Step::forward(self.start, 1) }; } RangeFrom { start: self.start } } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> Iterator for RangeFromIter<A> { type Item = A; #[inline] #[rustc_inherit_overflow_checks] fn next(&mut self) -> Option<A> { - if intrinsics::overflow_checks() { - if self.first { - self.first = false; - return Some(self.start.clone()); - } - + if self.exhausted { + // This should panic if overflow checks are enabled, since + // `forward_checked` returned `None` in prior iteration. self.start = Step::forward(self.start.clone(), 1); - return Some(self.start.clone()); + + // If we get here, if means this iterator was exhausted by a crate + // with overflow-checks enabled, but now we're iterating in a crate with + // overflow-checks disabled. Since we successfully incremented `self.start` + // above (in many cases this will wrap around to MIN), we now unset + // the flag so we don't repeat this process in the next iteration. + // + // This could also happen if `forward_checked` returned None but + // (for whatever reason, not applicable to any std implementors) + // `forward` doesn't panic when overflow-checks are enabled. In that + // case, this is also the correct behavior. + self.exhausted = false; + } + if intrinsics::overflow_checks() { + let Some(n) = Step::forward_checked(self.start.clone(), 1) else { + self.exhausted = true; + return Some(self.start.clone()); + }; + return Some(mem::replace(&mut self.start, n)); } let n = Step::forward(self.start.clone(), 1); @@ -348,18 +405,22 @@ fn size_hint(&self) -> (usize, Option<usize>) { #[inline] #[rustc_inherit_overflow_checks] fn nth(&mut self, n: usize) -> Option<A> { + // Typically `forward` will cause an overflow-check panic here, + // but unset the exhausted flag to handle the uncommon cases. + // See the comments in `next` for more details. + if self.exhausted { + self.start = Step::forward(self.start.clone(), 1); + self.exhausted = false; + } if intrinsics::overflow_checks() { - if self.first { - self.first = false; - - let plus_n = Step::forward(self.start.clone(), n); - self.start = plus_n.clone(); - return Some(plus_n); - } - let plus_n = Step::forward(self.start.clone(), n); - self.start = Step::forward(plus_n.clone(), 1); - return Some(self.start.clone()); + if let Some(plus_n1) = Step::forward_checked(plus_n.clone(), 1) { + self.start = plus_n1; + } else { + self.start = plus_n.clone(); + self.exhausted = true; + } + return Some(plus_n); } let plus_n = Step::forward(self.start.clone(), n); @@ -371,15 +432,15 @@ fn nth(&mut self, n: usize) -> Option<A> { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<A: TrustedStep> TrustedLen for RangeFromIter<A> {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> FusedIterator for RangeFromIter<A> {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl<A: Step> IntoIterator for RangeFrom<A> { type Item = A; type IntoIter = RangeFromIter<A>; fn into_iter(self) -> Self::IntoIter { - RangeFromIter { start: self.start, first: true } + RangeFromIter { start: self.start, exhausted: false } } }
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 2390ca7..69a01ee 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs
@@ -3,7 +3,9 @@ use super::{from_raw_parts, memchr}; use crate::ascii; use crate::cmp::{self, BytewiseEq, Ordering}; +use crate::convert::Infallible; use crate::intrinsics::compare_bytes; +use crate::marker::Destruct; use crate::mem::SizedTypeProperties; use crate::num::NonZero; use crate::ops::ControlFlow; @@ -33,7 +35,8 @@ impl<T: [const] Eq> const Eq for [T] {} /// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Ord> Ord for [T] { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Ord> const Ord for [T] { fn cmp(&self, other: &[T]) -> Ordering { SliceOrd::compare(self, other) } @@ -52,7 +55,8 @@ const fn as_underlying(x: ControlFlow<bool>) -> u8 { /// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialOrd> PartialOrd for [T] { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] PartialOrd> const PartialOrd for [T] { #[inline] fn partial_cmp(&self, other: &[T]) -> Option<Ordering> { SlicePartialOrd::partial_compare(self, other) @@ -175,19 +179,31 @@ const trait SliceChain: Sized { type AlwaysBreak<B> = ControlFlow<B, crate::convert::Infallible>; -impl<A: PartialOrd> SlicePartialOrd for A { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] PartialOrd> const SlicePartialOrd for A { default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> { - let elem_chain = |a, b| match PartialOrd::partial_cmp(a, b) { - Some(Ordering::Equal) => ControlFlow::Continue(()), - non_eq => ControlFlow::Break(non_eq), - }; - let len_chain = |a: &_, b: &_| ControlFlow::Break(usize::partial_cmp(a, b)); + // FIXME(const-hack): revert this to a const closure once possible + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + const fn elem_chain<A: [const] PartialOrd>(a: &A, b: &A) -> ControlFlow<Option<Ordering>> { + match PartialOrd::partial_cmp(a, b) { + Some(Ordering::Equal) => ControlFlow::Continue(()), + non_eq => ControlFlow::Break(non_eq), + } + } + + // FIXME(const-hack): revert this to a const closure once possible + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + const fn len_chain(a: &usize, b: &usize) -> ControlFlow<Option<Ordering>, Infallible> { + ControlFlow::Break(usize::partial_cmp(a, b)) + } + let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain); b } } -impl<A: PartialOrd> SliceChain for A { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] PartialOrd> const SliceChain for A { default fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool> { chaining_impl(left, right, PartialOrd::__chaining_lt, usize::__chaining_lt) } @@ -202,12 +218,13 @@ impl<A: PartialOrd> SliceChain for A { } } +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] #[inline] -fn chaining_impl<'l, 'r, A: PartialOrd, B, C>( +const fn chaining_impl<'l, 'r, A: PartialOrd, B, C>( left: &'l [A], right: &'r [A], - elem_chain: impl Fn(&'l A, &'r A) -> ControlFlow<B>, - len_chain: impl for<'a> FnOnce(&'a usize, &'a usize) -> ControlFlow<B, C>, + elem_chain: impl [const] Fn(&'l A, &'r A) -> ControlFlow<B> + [const] Destruct, + len_chain: impl for<'a> [const] FnOnce(&'a usize, &'a usize) -> ControlFlow<B, C> + [const] Destruct, ) -> ControlFlow<B, C> { let l = cmp::min(left.len(), right.len()); @@ -216,8 +233,11 @@ fn chaining_impl<'l, 'r, A: PartialOrd, B, C>( let lhs = &left[..l]; let rhs = &right[..l]; - for i in 0..l { + // FIXME(const-hack): revert this to `for i in 0..l` once `impl const Iterator for Range<T>` + let mut i: usize = 0; + while i < l { elem_chain(&lhs[i], &rhs[i])?; + i += 1; } len_chain(&left.len(), &right.len()) @@ -270,13 +290,24 @@ const trait SliceOrd: Sized { fn compare(left: &[Self], right: &[Self]) -> Ordering; } -impl<A: Ord> SliceOrd for A { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] Ord> const SliceOrd for A { default fn compare(left: &[Self], right: &[Self]) -> Ordering { - let elem_chain = |a, b| match Ord::cmp(a, b) { - Ordering::Equal => ControlFlow::Continue(()), - non_eq => ControlFlow::Break(non_eq), - }; - let len_chain = |a: &_, b: &_| ControlFlow::Break(usize::cmp(a, b)); + // FIXME(const-hack): revert this to a const closure once possible + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + const fn elem_chain<A: [const] Ord>(a: &A, b: &A) -> ControlFlow<Ordering> { + match Ord::cmp(a, b) { + Ordering::Equal => ControlFlow::Continue(()), + non_eq => ControlFlow::Break(non_eq), + } + } + + // FIXME(const-hack): revert this to a const closure once possible + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + const fn len_chain(a: &usize, b: &usize) -> ControlFlow<Ordering, Infallible> { + ControlFlow::Break(usize::cmp(a, b)) + } + let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain); b }
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 1709bc7..f1727a1 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs
@@ -125,13 +125,13 @@ impl Sealed for ops::RangeToInclusive<usize> {} #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {} - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::Range<usize> {} #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] impl Sealed for range::RangeInclusive<usize> {} #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeToInclusive<usize> {} - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeFrom<usize> {} impl Sealed for ops::IndexRange {} @@ -458,7 +458,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> { type Output = [T]; @@ -588,7 +588,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> { type Output = [T];
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 88a8a97..da0039f 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs
@@ -258,7 +258,7 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex<str> for range::Range<usize> { type Output = str; @@ -555,7 +555,7 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex<str> for range::RangeFrom<usize> { type Output = str;
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 0077b5b..0047722 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs
@@ -2136,7 +2136,7 @@ pub fn try_update( /// ``` #[inline] #[stable(feature = "atomic_try_update", since = "1.95.0")] - #[cfg(target_has_atomic = "8")] + #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn update(
diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 4c220e3..22a1166 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs
@@ -4,12 +4,12 @@ // for use in alloc, not re-exported in std. #[rustfmt::skip] -pub use unicode_data::case_ignorable::lookup as Case_Ignorable; -pub use unicode_data::cased::lookup as Cased; pub use unicode_data::conversions; #[rustfmt::skip] pub(crate) use unicode_data::alphabetic::lookup as Alphabetic; +pub(crate) use unicode_data::case_ignorable::lookup as Case_Ignorable; +pub(crate) use unicode_data::cased::lookup as Cased; pub(crate) use unicode_data::grapheme_extend::lookup as Grapheme_Extend; pub(crate) use unicode_data::lowercase::lookup as Lowercase; pub(crate) use unicode_data::n::lookup as N;
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index dd37126..f602cd5 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs
@@ -9,7 +9,8 @@ // White_Space : 256 bytes, 19 codepoints in 8 ranges (U+000085 - U+003001) using cascading // to_lower : 1112 bytes, 1462 codepoints in 185 ranges (U+0000C0 - U+01E921) using 2-level LUT // to_upper : 1998 bytes, 1554 codepoints in 299 ranges (U+0000B5 - U+01E943) using 2-level LUT -// Total : 9657 bytes +// to_title : 340 bytes, 135 codepoints in 49 ranges (U+0000DF - U+00FB17) using 2-level LUT +// Total : 9997 bytes #[inline(always)] const fn bitset_search< @@ -823,14 +824,10 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) } } - fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { - if input.is_ascii() { - return [ascii, '\0', '\0']; - } - + fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> { let (input_high, input_low) = deconstruct(input); let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else { - return [input, '\0', '\0']; + return None; }; let idx = l2_lut.singles.binary_search_by(|(range, _)| { @@ -844,6 +841,7 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { Ordering::Equal } }); + if let Ok(idx) = idx { // SAFETY: binary search guarantees that the index is in bounds. let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) }; @@ -852,7 +850,7 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { let output_low = input_low.wrapping_add_signed(output_delta); // SAFETY: Table data are guaranteed to be valid Unicode. let output = unsafe { reconstruct(input_high, output_low) }; - return [output, '\0', '\0']; + return Some([output, '\0', '\0']); } }; @@ -861,18 +859,37 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) }; // SAFETY: Table data are guaranteed to be valid Unicode. let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) }); - return output; + return Some(output); }; - [input, '\0', '\0'] + None } pub fn to_lower(c: char) -> [char; 3] { - lookup(c, c.to_ascii_lowercase(), &LOWERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Lowercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{C0}' { + return [c.to_ascii_lowercase(), '\0', '\0']; + } + + lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0']) } pub fn to_upper(c: char) -> [char; 3] { - lookup(c, c.to_ascii_uppercase(), &UPPERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Uppercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']) + } + + pub fn to_title(c: char) -> [char; 3] { + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Titlecased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0']) } static LOWERCASE_LUT: L1Lut = L1Lut { @@ -1150,4 +1167,45 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { }, ], }; + + static TITLECASE_LUT: L1Lut = L1Lut { + l2_luts: [ + L2Lut { + singles: &[ // 26 entries, 156 bytes + (Range::singleton(0x01c4), 1), (Range::singleton(0x01c5), 0), + (Range::singleton(0x01c6), -1), (Range::singleton(0x01c7), 1), + (Range::singleton(0x01c8), 0), (Range::singleton(0x01c9), -1), + (Range::singleton(0x01ca), 1), (Range::singleton(0x01cb), 0), + (Range::singleton(0x01cc), -1), (Range::singleton(0x01f1), 1), + (Range::singleton(0x01f2), 0), (Range::singleton(0x01f3), -1), + (Range::step_by_1(0x10d0..=0x10fa), 0), (Range::step_by_1(0x10fd..=0x10ff), 0), + (Range::step_by_1(0x1f80..=0x1f87), 8), (Range::step_by_1(0x1f88..=0x1f8f), 0), + (Range::step_by_1(0x1f90..=0x1f97), 8), (Range::step_by_1(0x1f98..=0x1f9f), 0), + (Range::step_by_1(0x1fa0..=0x1fa7), 8), (Range::step_by_1(0x1fa8..=0x1faf), 0), + (Range::singleton(0x1fb3), 9), (Range::singleton(0x1fbc), 0), (Range::singleton(0x1fc3), 9), + (Range::singleton(0x1fcc), 0), (Range::singleton(0x1ff3), 9), (Range::singleton(0x1ffc), 0), + ], + multis: &[ // 23 entries, 184 bytes + (0x00df, [0x0053, 0x0073, 0x0000]), (0x0587, [0x0535, 0x0582, 0x0000]), + (0x1fb2, [0x1fba, 0x0345, 0x0000]), (0x1fb4, [0x0386, 0x0345, 0x0000]), + (0x1fb7, [0x0391, 0x0342, 0x0345]), (0x1fc2, [0x1fca, 0x0345, 0x0000]), + (0x1fc4, [0x0389, 0x0345, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0345]), + (0x1ff2, [0x1ffa, 0x0345, 0x0000]), (0x1ff4, [0x038f, 0x0345, 0x0000]), + (0x1ff7, [0x03a9, 0x0342, 0x0345]), (0xfb00, [0x0046, 0x0066, 0x0000]), + (0xfb01, [0x0046, 0x0069, 0x0000]), (0xfb02, [0x0046, 0x006c, 0x0000]), + (0xfb03, [0x0046, 0x0066, 0x0069]), (0xfb04, [0x0046, 0x0066, 0x006c]), + (0xfb05, [0x0053, 0x0074, 0x0000]), (0xfb06, [0x0053, 0x0074, 0x0000]), + (0xfb13, [0x0544, 0x0576, 0x0000]), (0xfb14, [0x0544, 0x0565, 0x0000]), + (0xfb15, [0x0544, 0x056b, 0x0000]), (0xfb16, [0x054e, 0x0576, 0x0000]), + (0xfb17, [0x0544, 0x056d, 0x0000]), + ], + }, + L2Lut { + singles: &[ // 0 entries, 0 bytes + ], + multis: &[ // 0 entries, 0 bytes + ], + }, + ], + }; }
diff --git a/library/coretests/benches/lib.rs b/library/coretests/benches/lib.rs index 6b65eca..e8dc815 100644 --- a/library/coretests/benches/lib.rs +++ b/library/coretests/benches/lib.rs
@@ -8,7 +8,9 @@ #![feature(iter_array_chunks)] #![feature(iter_next_chunk)] #![feature(iter_advance_by)] +#![feature(num_internals)] #![feature(uint_gather_scatter_bits)] +#![allow(internal_features)] extern crate test;
diff --git a/library/coretests/tests/array.rs b/library/coretests/tests/array.rs index 2b44290..43fed94 100644 --- a/library/coretests/tests/array.rs +++ b/library/coretests/tests/array.rs
@@ -646,7 +646,7 @@ fn array_mixed_equality_integers() { #[test] fn array_mixed_equality_nans() { - let array3: [f32; 3] = [1.0, std::f32::NAN, 3.0]; + let array3: [f32; 3] = [1.0, f32::NAN, 3.0]; let slice3: &[f32] = &{ array3 }; assert!(!(array3 == slice3)); @@ -741,3 +741,18 @@ const fn maybe_doubler(x: usize) -> Option<usize> { struct Zst; assert_eq!([(); 10].try_map(|()| Some(Zst)), Some([const { Zst }; 10])); } + +#[test] +const fn extra_const_array_ops() { + let x: [u8; 4] = + { std::array::from_fn(const |i| i + 4).map(const |x| x * 2).map(const |x| x as _) }; + let y = 4; + struct Z(u16); + impl const Drop for Z { + fn drop(&mut self) {} + } + let w = Z(2); + let _x: [u8; 4] = { + std::array::from_fn(const |_| x[0] + y).map(const |x| x * (w.0 as u8)).map(const |x| x as _) + }; +}
diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index f0f6a24..877017f 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs
@@ -1,5 +1,6 @@ +use std::char::{self, CharCase}; +use std::str; use std::str::FromStr; -use std::{char, str}; #[test] fn test_convert() { @@ -40,6 +41,30 @@ fn test_from_str() { } #[test] +fn test_is_cased() { + assert!('a'.is_cased()); + assert!('ö'.is_cased()); + assert!('ß'.is_cased()); + assert!('Ü'.is_cased()); + assert!('P'.is_cased()); + assert!('ª'.is_cased()); + assert!(!'攂'.is_cased()); +} + +#[test] +#[cfg_attr(miri, ignore)] // Miri is too slow +fn test_char_case() { + for c in '\0'..='\u{10FFFF}' { + match c.case() { + None => assert!(!c.is_cased()), + Some(CharCase::Lower) => assert!(c.is_lowercase()), + Some(CharCase::Upper) => assert!(c.is_uppercase()), + Some(CharCase::Title) => assert!(c.is_titlecase()), + } + } +} + +#[test] fn test_is_lowercase() { assert!('a'.is_lowercase()); assert!('ö'.is_lowercase()); @@ -49,6 +74,17 @@ fn test_is_lowercase() { } #[test] +fn test_is_titlecase() { + assert!('Dž'.is_titlecase()); + assert!('ᾨ'.is_titlecase()); + assert!(!'h'.is_titlecase()); + assert!(!'ä'.is_titlecase()); + assert!(!'ß'.is_titlecase()); + assert!(!'Ö'.is_titlecase()); + assert!(!'T'.is_titlecase()); +} + +#[test] fn test_is_uppercase() { assert!(!'h'.is_uppercase()); assert!(!'ä'.is_uppercase()); @@ -58,6 +94,27 @@ fn test_is_uppercase() { } #[test] +fn titlecase_fast_path() { + for c in '\0'..='\u{01C4}' { + assert!(!(c.is_cased() && !c.is_lowercase() && !c.is_uppercase())) + } +} + +#[test] +#[cfg_attr(miri, ignore)] // Miri is too slow +fn at_most_one_case() { + for c in '\0'..='\u{10FFFF}' { + assert_eq!( + !c.is_cased() as u8 + + c.is_lowercase() as u8 + + c.is_uppercase() as u8 + + c.is_titlecase() as u8, + 1 + ); + } +} + +#[test] fn test_is_whitespace() { assert!(' '.is_whitespace()); assert!('\u{2007}'.is_whitespace());
diff --git a/library/coretests/tests/iter/adapters/intersperse.rs b/library/coretests/tests/iter/adapters/intersperse.rs index df6be79..bcb7709 100644 --- a/library/coretests/tests/iter/adapters/intersperse.rs +++ b/library/coretests/tests/iter/adapters/intersperse.rs
@@ -153,10 +153,6 @@ fn test_try_fold_specialization_intersperse_err() { assert_eq!(iter.next(), None); } -// FIXME(iter_intersperse): `intersperse` current behavior may change for -// non-fused iterators, so this test will likely have to -// be adjusted; see PR #152855 and issue #79524 -// if `intersperse` doesn't change, remove this FIXME. #[test] fn test_non_fused_iterator_intersperse() { #[derive(Debug)] @@ -183,24 +179,26 @@ fn next(&mut self) -> Option<Self::Item> { } let counter = 0; - // places a 2 between `Some(_)` items + // places a 1 between `Some(_)` items let non_fused_iter = TestCounter { counter }; - let mut intersperse_iter = non_fused_iter.intersperse(2); - // Since `intersperse` currently transforms the original - // iterator into a fused iterator, this intersperse_iter - // should always have `None` - for _ in 0..counter + 6 { - assert_eq!(intersperse_iter.next(), None); - } + let mut intersperse_iter = non_fused_iter.intersperse(1); + // Interspersed iter produces: + // `None` -> `Some(2)` -> `None` -> `Some(1)` -> Some(4)` -> `None` -> `Some(1)` -> + // `Some(6)` -> and then `None` endlessly + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(2)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(4)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(6)); + assert_eq!(intersperse_iter.next(), None); - // Extra check to make sure it is `None` after processing 6 items + // Extra check to make sure it is `None` after processing all items assert_eq!(intersperse_iter.next(), None); } -// FIXME(iter_intersperse): `intersperse` current behavior may change for -// non-fused iterators, so this test will likely have to -// be adjusted; see PR #152855 and issue #79524 -// if `intersperse` doesn't change, remove this FIXME. #[test] fn test_non_fused_iterator_intersperse_2() { #[derive(Debug)] @@ -228,35 +226,26 @@ fn next(&mut self) -> Option<Self::Item> { } let counter = 0; - // places a 2 between `Some(_)` items + // places a 100 between `Some(_)` items let non_fused_iter = TestCounter { counter }; - let mut intersperse_iter = non_fused_iter.intersperse(2); - // Since `intersperse` currently transforms the original - // iterator into a fused iterator, this interspersed iter - // will be `Some(1)` -> `Some(2)` -> `Some(2)` -> and then - // `None` endlessly - let mut items_processed = 0; - for num in 0..counter + 6 { - if num < 3 { - if num % 2 != 0 { - assert_eq!(intersperse_iter.next(), Some(2)); - } else { - items_processed += 1; - assert_eq!(intersperse_iter.next(), Some(items_processed)); - } - } else { - assert_eq!(intersperse_iter.next(), None); - } - } + let mut intersperse_iter = non_fused_iter.intersperse(100); + // Interspersed iter produces: + // `Some(1)` -> `Some(100)` -> `Some(2)` -> `None` -> `Some(100)` + // -> `Some(4)` -> `Some(100)` -> `Some(5)` -> `None` endlessly + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(2)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(4)); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(5)); + assert_eq!(intersperse_iter.next(), None); // Extra check to make sure it is `None` after processing 6 items assert_eq!(intersperse_iter.next(), None); } -// FIXME(iter_intersperse): `intersperse_with` current behavior may change for -// non-fused iterators, so this test will likely have to -// be adjusted; see PR #152855 and issue #79524 -// if `intersperse_with` doesn't change, remove this FIXME. #[test] fn test_non_fused_iterator_intersperse_with() { #[derive(Debug)] @@ -285,22 +274,24 @@ fn next(&mut self) -> Option<Self::Item> { let counter = 0; let non_fused_iter = TestCounter { counter }; // places a 2 between `Some(_)` items - let mut intersperse_iter = non_fused_iter.intersperse_with(|| 2); - // Since `intersperse` currently transforms the original - // iterator into a fused iterator, this intersperse_iter - // should always have `None` - for _ in 0..counter + 6 { - assert_eq!(intersperse_iter.next(), None); - } + let mut intersperse_iter = non_fused_iter.intersperse_with(|| 1); + // Interspersed iter produces: + // `None` -> `Some(2)` -> `None` -> `Some(1)` -> Some(4)` -> `None` -> `Some(1)` -> + // `Some(6)` -> and then `None` endlessly + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(2)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(4)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(6)); + assert_eq!(intersperse_iter.next(), None); // Extra check to make sure it is `None` after processing 6 items assert_eq!(intersperse_iter.next(), None); } -// FIXME(iter_intersperse): `intersperse_with` current behavior may change for -// non-fused iterators, so this test will likely have to -// be adjusted; see PR #152855 and issue #79524 -// if `intersperse_with` doesn't change, remove this FIXME. #[test] fn test_non_fused_iterator_intersperse_with_2() { #[derive(Debug)] @@ -328,26 +319,21 @@ fn next(&mut self) -> Option<Self::Item> { } let counter = 0; - // places a 2 between `Some(_)` items + // places a 100 between `Some(_)` items let non_fused_iter = TestCounter { counter }; - let mut intersperse_iter = non_fused_iter.intersperse(2); - // Since `intersperse` currently transforms the original - // iterator into a fused iterator, this interspersed iter - // will be `Some(1)` -> `Some(2)` -> `Some(2)` -> and then - // `None` endlessly - let mut items_processed = 0; - for num in 0..counter + 6 { - if num < 3 { - if num % 2 != 0 { - assert_eq!(intersperse_iter.next(), Some(2)); - } else { - items_processed += 1; - assert_eq!(intersperse_iter.next(), Some(items_processed)); - } - } else { - assert_eq!(intersperse_iter.next(), None); - } - } + let mut intersperse_iter = non_fused_iter.intersperse_with(|| 100); + // Interspersed iter produces: + // `Some(1)` -> `Some(100)` -> `Some(2)` -> `None` -> `Some(100)` + // -> `Some(4)` -> `Some(100)` -> `Some(5)` -> `None` endlessly + assert_eq!(intersperse_iter.next(), Some(1)); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(2)); + assert_eq!(intersperse_iter.next(), None); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(4)); + assert_eq!(intersperse_iter.next(), Some(100)); + assert_eq!(intersperse_iter.next(), Some(5)); + assert_eq!(intersperse_iter.next(), None); // Extra check to make sure it is `None` after processing 6 items assert_eq!(intersperse_iter.next(), None);
diff --git a/library/coretests/tests/iter/adapters/map_windows.rs b/library/coretests/tests/iter/adapters/map_windows.rs index 01cebc9..994ec08 100644 --- a/library/coretests/tests/iter/adapters/map_windows.rs +++ b/library/coretests/tests/iter/adapters/map_windows.rs
@@ -284,3 +284,29 @@ fn check_size_hint<const N: usize>( check_size_hint::<5>((5, Some(5)), (1, Some(1))); check_size_hint::<5>((5, Some(10)), (1, Some(6))); } + +#[test] +fn test_unfused() { + #[derive(Default)] + struct UnfusedIter(usize); + impl Iterator for UnfusedIter { + type Item = usize; + + fn next(&mut self) -> Option<usize> { + let curr = self.0; + self.0 += 1; + if curr % 7 == 0 { None } else { Some(curr) } + } + } + + let mut iter = UnfusedIter(1).map_windows(|a: &[_; 3]| *a); + assert_eq!(iter.by_ref().collect::<Vec<_>>(), vec![[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]); + assert_eq!( + iter.by_ref().collect::<Vec<_>>(), + vec![[8, 9, 10], [9, 10, 11], [10, 11, 12], [11, 12, 13]] + ); + assert_eq!( + iter.by_ref().collect::<Vec<_>>(), + vec![[15, 16, 17], [16, 17, 18], [17, 18, 19], [18, 19, 20]] + ); +}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index b0ba070..90a33ae 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs
@@ -17,6 +17,7 @@ #![feature(const_bool)] #![feature(const_cell_traits)] #![feature(const_clone)] +#![feature(const_closures)] #![feature(const_cmp)] #![feature(const_convert)] #![feature(const_default)] @@ -84,7 +85,6 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(new_range_api)] #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(nonzero_from_str_radix)] @@ -112,6 +112,7 @@ #![feature(step_trait)] #![feature(str_internals)] #![feature(strict_provenance_lints)] +#![feature(titlecase)] #![feature(trusted_len)] #![feature(trusted_random_access)] #![feature(try_blocks)]
diff --git a/library/coretests/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs index 37336f4..2b641f5 100644 --- a/library/coretests/tests/num/int_macros.rs +++ b/library/coretests/tests/num/int_macros.rs
@@ -2,7 +2,8 @@ ($T:ident, $U:ident) => { use core::num::ParseIntError; use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; - use core::$T::*; + const MAX: $T = $T::MAX; + const MIN: $T = $T::MIN; const UMAX: $U = $U::MAX;
diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs index 240c66f..8dfa092 100644 --- a/library/coretests/tests/num/uint_macros.rs +++ b/library/coretests/tests/num/uint_macros.rs
@@ -2,15 +2,14 @@ ($T:ident) => { use core::num::ParseIntError; use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; - use core::$T::*; use crate::num; #[test] fn test_overflows() { - assert!(MAX > 0); - assert!(MIN <= 0); - assert!((MIN + MAX).wrapping_add(1) == 0); + assert!($T::MAX > 0); + assert!($T::MIN <= 0); + assert!(($T::MIN + $T::MAX).wrapping_add(1) == 0); } #[test] @@ -25,7 +24,7 @@ fn test_bitwise_operators() { assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); assert!(0b1110 as $T == (0b0111 as $T).shl(1)); assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not()); + assert!($T::MAX - (0b1011 as $T) == (0b1011 as $T).not()); } const A: $T = 0b0101100; @@ -361,7 +360,7 @@ fn test_pow() { assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T); assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None); assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true)); - assert_eq_const_safe!($T: R.saturating_pow(2), MAX); + assert_eq_const_safe!($T: R.saturating_pow(2), $T::MAX); } } @@ -468,14 +467,14 @@ fn test_div_ceil() { fn test_next_multiple_of() { assert_eq_const_safe!($T: (16 as $T).next_multiple_of(8), 16); assert_eq_const_safe!($T: (23 as $T).next_multiple_of(8), 24); - assert_eq_const_safe!($T: MAX.next_multiple_of(1), MAX); + assert_eq_const_safe!($T: $T::MAX.next_multiple_of(1), $T::MAX); } fn test_checked_next_multiple_of() { assert_eq_const_safe!(Option<$T>: (16 as $T).checked_next_multiple_of(8), Some(16)); assert_eq_const_safe!(Option<$T>: (23 as $T).checked_next_multiple_of(8), Some(24)); assert_eq_const_safe!(Option<$T>: (1 as $T).checked_next_multiple_of(0), None); - assert_eq_const_safe!(Option<$T>: MAX.checked_next_multiple_of(2), None); + assert_eq_const_safe!(Option<$T>: $T::MAX.checked_next_multiple_of(2), None); } fn test_is_next_multiple_of() {
diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs index b3fb06e..37a729a 100644 --- a/library/coretests/tests/pin.rs +++ b/library/coretests/tests/pin.rs
@@ -45,22 +45,6 @@ mod pin_coerce_unsized { pub trait MyTrait {} impl MyTrait for String {} - // These Pins should continue to compile. - // Do note that these instances of Pin types cannot be used - // meaningfully because all methods require a Deref/DerefMut - // bounds on the pointer type and Cell, RefCell and UnsafeCell - // do not implement Deref/DerefMut. - - pub fn cell(arg: Pin<Cell<Box<String>>>) -> Pin<Cell<Box<dyn MyTrait>>> { - arg - } - pub fn ref_cell(arg: Pin<RefCell<Box<String>>>) -> Pin<RefCell<Box<dyn MyTrait>>> { - arg - } - pub fn unsafe_cell(arg: Pin<UnsafeCell<Box<String>>>) -> Pin<UnsafeCell<Box<dyn MyTrait>>> { - arg - } - // These sensible Pin coercions are possible. pub fn pin_mut_ref(arg: Pin<&mut String>) -> Pin<&mut dyn MyTrait> { arg @@ -68,15 +52,6 @@ pub fn pin_mut_ref(arg: Pin<&mut String>) -> Pin<&mut dyn MyTrait> { pub fn pin_ref(arg: Pin<&String>) -> Pin<&dyn MyTrait> { arg } - pub fn pin_ptr(arg: Pin<*const String>) -> Pin<*const dyn MyTrait> { - arg - } - pub fn pin_ptr_mut(arg: Pin<*mut String>) -> Pin<*mut dyn MyTrait> { - arg - } - pub fn pin_non_null(arg: Pin<NonNull<String>>) -> Pin<NonNull<dyn MyTrait>> { - arg - } pub fn nesting_pins(arg: Pin<Pin<&String>>) -> Pin<Pin<&dyn MyTrait>> { arg }
diff --git a/library/coretests/tests/unicode.rs b/library/coretests/tests/unicode.rs index 1fae74f..a8a221d 100644 --- a/library/coretests/tests/unicode.rs +++ b/library/coretests/tests/unicode.rs
@@ -27,17 +27,21 @@ fn test_boolean_property(ranges: &[RangeInclusive<char>], lookup: fn(char) -> bo } #[track_caller] -fn test_case_mapping(ranges: &[(char, [char; 3])], lookup: fn(char) -> [char; 3]) { +fn test_case_mapping( + ranges: &[(char, [char; 3])], + lookup: fn(char) -> [char; 3], + fallback: fn(char) -> [char; 3], +) { let mut start = '\u{80}'; for &(key, val) in ranges { for c in start..key { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + assert_eq!(lookup(c), fallback(c), "{c:?}"); } assert_eq!(lookup(key), val, "{key:?}"); start = char::from_u32(key as u32 + 1).unwrap(); } for c in start..=char::MAX { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + assert_eq!(lookup(c), fallback(c), "{c:?}"); } } @@ -45,6 +49,7 @@ fn test_boolean_property(ranges: &[RangeInclusive<char>], lookup: fn(char) -> bo #[cfg_attr(miri, ignore)] // Miri is too slow fn alphabetic() { test_boolean_property(test_data::ALPHABETIC, unicode_data::alphabetic::lookup); + test_boolean_property(test_data::ALPHABETIC, char::is_alphabetic); } #[test] @@ -57,6 +62,7 @@ fn case_ignorable() { #[cfg_attr(miri, ignore)] // Miri is too slow fn cased() { test_boolean_property(test_data::CASED, unicode_data::cased::lookup); + test_boolean_property(test_data::CASED, char::is_cased); } #[test] @@ -69,34 +75,52 @@ fn grapheme_extend() { #[cfg_attr(miri, ignore)] // Miri is too slow fn lowercase() { test_boolean_property(test_data::LOWERCASE, unicode_data::lowercase::lookup); + test_boolean_property(test_data::LOWERCASE, char::is_lowercase); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn n() { test_boolean_property(test_data::N, unicode_data::n::lookup); + test_boolean_property(test_data::N, char::is_numeric); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn uppercase() { test_boolean_property(test_data::UPPERCASE, unicode_data::uppercase::lookup); + test_boolean_property(test_data::UPPERCASE, char::is_uppercase); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn white_space() { test_boolean_property(test_data::WHITE_SPACE, unicode_data::white_space::lookup); + test_boolean_property(test_data::WHITE_SPACE, char::is_whitespace); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn to_lowercase() { - test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower); + test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower, |c| { + [c, '\0', '\0'] + }); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn to_uppercase() { - test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper); + test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper, |c| { + [c, '\0', '\0'] + }); +} + +#[test] +#[cfg_attr(miri, ignore)] // Miri is too slow +fn to_titlecase() { + test_case_mapping( + test_data::TO_TITLE, + unicode_data::conversions::to_title, + unicode_data::conversions::to_upper, + ); }
diff --git a/library/coretests/tests/unicode/test_data.rs b/library/coretests/tests/unicode/test_data.rs index cfc6954..3071aed 100644 --- a/library/coretests/tests/unicode/test_data.rs +++ b/library/coretests/tests/unicode/test_data.rs
@@ -2900,3 +2900,81 @@ ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), ]; + +#[rustfmt::skip] +pub(super) static TO_TITLE: &[(char, [char; 3]); 135] = &[ + ('\u{df}', ['S', 's', '\u{0}']), ('\u{1c4}', ['\u{1c5}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c5}', '\u{0}', '\u{0}']), ('\u{1c6}', ['\u{1c5}', '\u{0}', '\u{0}']), + ('\u{1c7}', ['\u{1c8}', '\u{0}', '\u{0}']), ('\u{1c8}', ['\u{1c8}', '\u{0}', '\u{0}']), + ('\u{1c9}', ['\u{1c8}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cb}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1cb}', '\u{0}', '\u{0}']), ('\u{1cc}', ['\u{1cb}', '\u{0}', '\u{0}']), + ('\u{1f1}', ['\u{1f2}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f2}', '\u{0}', '\u{0}']), + ('\u{1f3}', ['\u{1f2}', '\u{0}', '\u{0}']), ('\u{587}', ['\u{535}', '\u{582}', '\u{0}']), + ('\u{10d0}', ['\u{10d0}', '\u{0}', '\u{0}']), ('\u{10d1}', ['\u{10d1}', '\u{0}', '\u{0}']), + ('\u{10d2}', ['\u{10d2}', '\u{0}', '\u{0}']), ('\u{10d3}', ['\u{10d3}', '\u{0}', '\u{0}']), + ('\u{10d4}', ['\u{10d4}', '\u{0}', '\u{0}']), ('\u{10d5}', ['\u{10d5}', '\u{0}', '\u{0}']), + ('\u{10d6}', ['\u{10d6}', '\u{0}', '\u{0}']), ('\u{10d7}', ['\u{10d7}', '\u{0}', '\u{0}']), + ('\u{10d8}', ['\u{10d8}', '\u{0}', '\u{0}']), ('\u{10d9}', ['\u{10d9}', '\u{0}', '\u{0}']), + ('\u{10da}', ['\u{10da}', '\u{0}', '\u{0}']), ('\u{10db}', ['\u{10db}', '\u{0}', '\u{0}']), + ('\u{10dc}', ['\u{10dc}', '\u{0}', '\u{0}']), ('\u{10dd}', ['\u{10dd}', '\u{0}', '\u{0}']), + ('\u{10de}', ['\u{10de}', '\u{0}', '\u{0}']), ('\u{10df}', ['\u{10df}', '\u{0}', '\u{0}']), + ('\u{10e0}', ['\u{10e0}', '\u{0}', '\u{0}']), ('\u{10e1}', ['\u{10e1}', '\u{0}', '\u{0}']), + ('\u{10e2}', ['\u{10e2}', '\u{0}', '\u{0}']), ('\u{10e3}', ['\u{10e3}', '\u{0}', '\u{0}']), + ('\u{10e4}', ['\u{10e4}', '\u{0}', '\u{0}']), ('\u{10e5}', ['\u{10e5}', '\u{0}', '\u{0}']), + ('\u{10e6}', ['\u{10e6}', '\u{0}', '\u{0}']), ('\u{10e7}', ['\u{10e7}', '\u{0}', '\u{0}']), + ('\u{10e8}', ['\u{10e8}', '\u{0}', '\u{0}']), ('\u{10e9}', ['\u{10e9}', '\u{0}', '\u{0}']), + ('\u{10ea}', ['\u{10ea}', '\u{0}', '\u{0}']), ('\u{10eb}', ['\u{10eb}', '\u{0}', '\u{0}']), + ('\u{10ec}', ['\u{10ec}', '\u{0}', '\u{0}']), ('\u{10ed}', ['\u{10ed}', '\u{0}', '\u{0}']), + ('\u{10ee}', ['\u{10ee}', '\u{0}', '\u{0}']), ('\u{10ef}', ['\u{10ef}', '\u{0}', '\u{0}']), + ('\u{10f0}', ['\u{10f0}', '\u{0}', '\u{0}']), ('\u{10f1}', ['\u{10f1}', '\u{0}', '\u{0}']), + ('\u{10f2}', ['\u{10f2}', '\u{0}', '\u{0}']), ('\u{10f3}', ['\u{10f3}', '\u{0}', '\u{0}']), + ('\u{10f4}', ['\u{10f4}', '\u{0}', '\u{0}']), ('\u{10f5}', ['\u{10f5}', '\u{0}', '\u{0}']), + ('\u{10f6}', ['\u{10f6}', '\u{0}', '\u{0}']), ('\u{10f7}', ['\u{10f7}', '\u{0}', '\u{0}']), + ('\u{10f8}', ['\u{10f8}', '\u{0}', '\u{0}']), ('\u{10f9}', ['\u{10f9}', '\u{0}', '\u{0}']), + ('\u{10fa}', ['\u{10fa}', '\u{0}', '\u{0}']), ('\u{10fd}', ['\u{10fd}', '\u{0}', '\u{0}']), + ('\u{10fe}', ['\u{10fe}', '\u{0}', '\u{0}']), ('\u{10ff}', ['\u{10ff}', '\u{0}', '\u{0}']), + ('\u{1f80}', ['\u{1f88}', '\u{0}', '\u{0}']), ('\u{1f81}', ['\u{1f89}', '\u{0}', '\u{0}']), + ('\u{1f82}', ['\u{1f8a}', '\u{0}', '\u{0}']), ('\u{1f83}', ['\u{1f8b}', '\u{0}', '\u{0}']), + ('\u{1f84}', ['\u{1f8c}', '\u{0}', '\u{0}']), ('\u{1f85}', ['\u{1f8d}', '\u{0}', '\u{0}']), + ('\u{1f86}', ['\u{1f8e}', '\u{0}', '\u{0}']), ('\u{1f87}', ['\u{1f8f}', '\u{0}', '\u{0}']), + ('\u{1f88}', ['\u{1f88}', '\u{0}', '\u{0}']), ('\u{1f89}', ['\u{1f89}', '\u{0}', '\u{0}']), + ('\u{1f8a}', ['\u{1f8a}', '\u{0}', '\u{0}']), ('\u{1f8b}', ['\u{1f8b}', '\u{0}', '\u{0}']), + ('\u{1f8c}', ['\u{1f8c}', '\u{0}', '\u{0}']), ('\u{1f8d}', ['\u{1f8d}', '\u{0}', '\u{0}']), + ('\u{1f8e}', ['\u{1f8e}', '\u{0}', '\u{0}']), ('\u{1f8f}', ['\u{1f8f}', '\u{0}', '\u{0}']), + ('\u{1f90}', ['\u{1f98}', '\u{0}', '\u{0}']), ('\u{1f91}', ['\u{1f99}', '\u{0}', '\u{0}']), + ('\u{1f92}', ['\u{1f9a}', '\u{0}', '\u{0}']), ('\u{1f93}', ['\u{1f9b}', '\u{0}', '\u{0}']), + ('\u{1f94}', ['\u{1f9c}', '\u{0}', '\u{0}']), ('\u{1f95}', ['\u{1f9d}', '\u{0}', '\u{0}']), + ('\u{1f96}', ['\u{1f9e}', '\u{0}', '\u{0}']), ('\u{1f97}', ['\u{1f9f}', '\u{0}', '\u{0}']), + ('\u{1f98}', ['\u{1f98}', '\u{0}', '\u{0}']), ('\u{1f99}', ['\u{1f99}', '\u{0}', '\u{0}']), + ('\u{1f9a}', ['\u{1f9a}', '\u{0}', '\u{0}']), ('\u{1f9b}', ['\u{1f9b}', '\u{0}', '\u{0}']), + ('\u{1f9c}', ['\u{1f9c}', '\u{0}', '\u{0}']), ('\u{1f9d}', ['\u{1f9d}', '\u{0}', '\u{0}']), + ('\u{1f9e}', ['\u{1f9e}', '\u{0}', '\u{0}']), ('\u{1f9f}', ['\u{1f9f}', '\u{0}', '\u{0}']), + ('\u{1fa0}', ['\u{1fa8}', '\u{0}', '\u{0}']), ('\u{1fa1}', ['\u{1fa9}', '\u{0}', '\u{0}']), + ('\u{1fa2}', ['\u{1faa}', '\u{0}', '\u{0}']), ('\u{1fa3}', ['\u{1fab}', '\u{0}', '\u{0}']), + ('\u{1fa4}', ['\u{1fac}', '\u{0}', '\u{0}']), ('\u{1fa5}', ['\u{1fad}', '\u{0}', '\u{0}']), + ('\u{1fa6}', ['\u{1fae}', '\u{0}', '\u{0}']), ('\u{1fa7}', ['\u{1faf}', '\u{0}', '\u{0}']), + ('\u{1fa8}', ['\u{1fa8}', '\u{0}', '\u{0}']), ('\u{1fa9}', ['\u{1fa9}', '\u{0}', '\u{0}']), + ('\u{1faa}', ['\u{1faa}', '\u{0}', '\u{0}']), ('\u{1fab}', ['\u{1fab}', '\u{0}', '\u{0}']), + ('\u{1fac}', ['\u{1fac}', '\u{0}', '\u{0}']), ('\u{1fad}', ['\u{1fad}', '\u{0}', '\u{0}']), + ('\u{1fae}', ['\u{1fae}', '\u{0}', '\u{0}']), ('\u{1faf}', ['\u{1faf}', '\u{0}', '\u{0}']), + ('\u{1fb2}', ['\u{1fba}', '\u{345}', '\u{0}']), + ('\u{1fb3}', ['\u{1fbc}', '\u{0}', '\u{0}']), ('\u{1fb4}', ['\u{386}', '\u{345}', '\u{0}']), + ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{345}']), + ('\u{1fbc}', ['\u{1fbc}', '\u{0}', '\u{0}']), + ('\u{1fc2}', ['\u{1fca}', '\u{345}', '\u{0}']), + ('\u{1fc3}', ['\u{1fcc}', '\u{0}', '\u{0}']), ('\u{1fc4}', ['\u{389}', '\u{345}', '\u{0}']), + ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{345}']), + ('\u{1fcc}', ['\u{1fcc}', '\u{0}', '\u{0}']), + ('\u{1ff2}', ['\u{1ffa}', '\u{345}', '\u{0}']), + ('\u{1ff3}', ['\u{1ffc}', '\u{0}', '\u{0}']), ('\u{1ff4}', ['\u{38f}', '\u{345}', '\u{0}']), + ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{345}']), + ('\u{1ffc}', ['\u{1ffc}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'f', '\u{0}']), + ('\u{fb01}', ['F', 'i', '\u{0}']), ('\u{fb02}', ['F', 'l', '\u{0}']), + ('\u{fb03}', ['F', 'f', 'i']), ('\u{fb04}', ['F', 'f', 'l']), + ('\u{fb05}', ['S', 't', '\u{0}']), ('\u{fb06}', ['S', 't', '\u{0}']), + ('\u{fb13}', ['\u{544}', '\u{576}', '\u{0}']), + ('\u{fb14}', ['\u{544}', '\u{565}', '\u{0}']), + ('\u{fb15}', ['\u{544}', '\u{56b}', '\u{0}']), + ('\u{fb16}', ['\u{54e}', '\u{576}', '\u{0}']), + ('\u{fb17}', ['\u{544}', '\u{56d}', '\u{0}']), +];
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index efd7c24..175cbce 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs
@@ -385,13 +385,13 @@ fn copysign(self, sign: Self) -> Self { #[inline] fn simd_min(self, other: Self) -> Self { // Safety: `self` and `other` are float vectors - unsafe { core::intrinsics::simd::simd_fmin(self, other) } + unsafe { core::intrinsics::simd::simd_minimum_number_nsz(self, other) } } #[inline] fn simd_max(self, other: Self) -> Self { // Safety: `self` and `other` are floating point vectors - unsafe { core::intrinsics::simd::simd_fmax(self, other) } + unsafe { core::intrinsics::simd::simd_maximum_number_nsz(self, other) } } #[inline]
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 1b7a41d..f7bc729 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml
@@ -33,7 +33,7 @@ addr2line = { version = "0.25.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.178", default-features = false, features = [ +libc = { version = "0.2.183", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } @@ -62,7 +62,7 @@ rand = { version = "0.9.0", default-features = false, features = ["alloc"] } rand_xorshift = "0.4.0" -[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "xous", target_os = "vexos", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] +[target.'cfg(any(all(target_family = "wasm", not(any(unix, target_os = "wasi"))), target_os = "xous", target_os = "vexos", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] dlmalloc = { version = "0.2.10", features = ['rustc-dep-of-std'] } [target.x86_64-fortanix-unknown-sgx.dependencies]
diff --git a/library/std/src/env.rs b/library/std/src/env.rs index edf0127..d3e4417 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs
@@ -15,7 +15,7 @@ use crate::num::NonZero; use crate::ops::Try; use crate::path::{Path, PathBuf}; -use crate::sys::{env as env_imp, os as os_imp}; +use crate::sys::{env as env_imp, paths as paths_imp}; use crate::{array, fmt, io, sys}; /// Returns the current working directory as a [`PathBuf`]. @@ -51,7 +51,7 @@ #[doc(alias = "GetCurrentDirectory")] #[stable(feature = "env", since = "1.0.0")] pub fn current_dir() -> io::Result<PathBuf> { - os_imp::getcwd() + paths_imp::getcwd() } /// Changes the current working directory to the specified path. @@ -78,7 +78,7 @@ pub fn current_dir() -> io::Result<PathBuf> { #[doc(alias = "chdir", alias = "SetCurrentDirectory", alias = "SetCurrentDirectoryW")] #[stable(feature = "env", since = "1.0.0")] pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { - os_imp::chdir(path.as_ref()) + paths_imp::chdir(path.as_ref()) } /// An iterator over a snapshot of the environment variables of this process. @@ -444,7 +444,7 @@ pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) { #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "env", since = "1.0.0")] pub struct SplitPaths<'a> { - inner: os_imp::SplitPaths<'a>, + inner: paths_imp::SplitPaths<'a>, } /// Parses input according to platform conventions for the `PATH` @@ -480,7 +480,7 @@ pub struct SplitPaths<'a> { /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> { - SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) } + SplitPaths { inner: paths_imp::split_paths(unparsed.as_ref()) } } #[stable(feature = "env", since = "1.0.0")] @@ -508,7 +508,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[derive(Debug)] #[stable(feature = "env", since = "1.0.0")] pub struct JoinPathsError { - inner: os_imp::JoinPathsError, + inner: paths_imp::JoinPathsError, } /// Joins a collection of [`Path`]s appropriately for the `PATH` @@ -579,7 +579,7 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> I: IntoIterator<Item = T>, T: AsRef<OsStr>, { - os_imp::join_paths(paths.into_iter()).map_err(|e| JoinPathsError { inner: e }) + paths_imp::join_paths(paths.into_iter()).map_err(|e| JoinPathsError { inner: e }) } #[stable(feature = "env", since = "1.0.0")] @@ -641,7 +641,7 @@ fn description(&self) -> &str { #[must_use] #[stable(feature = "env", since = "1.0.0")] pub fn home_dir() -> Option<PathBuf> { - os_imp::home_dir() + paths_imp::home_dir() } /// Returns the path of a temporary directory. @@ -701,7 +701,7 @@ pub fn home_dir() -> Option<PathBuf> { #[doc(alias = "GetTempPath", alias = "GetTempPath2")] #[stable(feature = "env", since = "1.0.0")] pub fn temp_dir() -> PathBuf { - os_imp::temp_dir() + paths_imp::temp_dir() } /// Returns the full filesystem path of the current running executable. @@ -752,7 +752,7 @@ pub fn temp_dir() -> PathBuf { /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn current_exe() -> io::Result<PathBuf> { - os_imp::current_exe() + paths_imp::current_exe() } /// An iterator over the arguments of a process, yielding a [`String`] value for
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 885bf37..9643d3f 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs
@@ -815,7 +815,8 @@ pub fn sync_data(&self) -> io::Result<()> { /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired. /// - /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. + /// This acquires an exclusive lock; no other file handle to this file, in this or any other + /// process, may acquire another lock. /// /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with @@ -868,8 +869,8 @@ pub fn lock(&self) -> io::Result<()> { /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired. /// - /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may - /// hold an exclusive lock at the same time. + /// This acquires a shared lock; more than one file handle, in this or any other process, may + /// hold a shared lock, but none may hold an exclusive lock at the same time. /// /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with @@ -923,7 +924,8 @@ pub fn lock_shared(&self) -> io::Result<()> { /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file /// (via another handle/descriptor). /// - /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. + /// This acquires an exclusive lock; no other file handle to this file, in this or any other + /// process, may acquire another lock. /// /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with @@ -987,8 +989,8 @@ pub fn try_lock(&self) -> Result<(), TryLockError> { /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file /// (via another handle/descriptor). /// - /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may - /// hold an exclusive lock at the same time. + /// This acquires a shared lock; more than one file handle, in this or any other process, may + /// hold a shared lock, but none may hold an exclusive lock at the same time. /// /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index 6ad4158..e335d8a 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs
@@ -391,16 +391,16 @@ fn test_read_until() { let mut v = Vec::new(); reader.read_until(0, &mut v).unwrap(); assert_eq!(v, [0]); - v.truncate(0); + v.clear(); reader.read_until(2, &mut v).unwrap(); assert_eq!(v, [1, 2]); - v.truncate(0); + v.clear(); reader.read_until(1, &mut v).unwrap(); assert_eq!(v, [1]); - v.truncate(0); + v.clear(); reader.read_until(8, &mut v).unwrap(); assert_eq!(v, [0]); - v.truncate(0); + v.clear(); reader.read_until(9, &mut v).unwrap(); assert_eq!(v, []); } @@ -429,13 +429,13 @@ fn test_read_line() { let mut s = String::new(); reader.read_line(&mut s).unwrap(); assert_eq!(s, "a\n"); - s.truncate(0); + s.clear(); reader.read_line(&mut s).unwrap(); assert_eq!(s, "b\n"); - s.truncate(0); + s.clear(); reader.read_line(&mut s).unwrap(); assert_eq!(s, "c"); - s.truncate(0); + s.clear(); reader.read_line(&mut s).unwrap(); assert_eq!(s, ""); }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 623c34c..cba578c 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs
@@ -3348,6 +3348,7 @@ fn upper_bound(&self) -> Option<usize> { /// [`split`]: BufRead::split #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] +#[cfg_attr(not(test), rustc_diagnostic_item = "IoSplit")] pub struct Split<B> { buf: B, delim: u8,
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index b22988d..a56359d 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs
@@ -17,10 +17,10 @@ fn read_until() { let mut v = Vec::new(); assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); assert_eq!(v, b"123"); - v.truncate(0); + v.clear(); assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); assert_eq!(v, b"3"); - v.truncate(0); + v.clear(); assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); assert_eq!(v, []); } @@ -80,10 +80,10 @@ fn read_line() { let mut v = String::new(); assert_eq!(buf.read_line(&mut v).unwrap(), 3); assert_eq!(v, "12\n"); - v.truncate(0); + v.clear(); assert_eq!(buf.read_line(&mut v).unwrap(), 1); assert_eq!(v, "\n"); - v.truncate(0); + v.clear(); assert_eq!(buf.read_line(&mut v).unwrap(), 0); assert_eq!(v, ""); }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c8c8a6c..1730742 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs
@@ -94,8 +94,8 @@ //! pull-requests for your suggested changes. //! //! Contributions are appreciated! If you see a part of the docs that can be -//! improved, submit a PR, or chat with us first on [Zulip][rust-zulip] -//! #docs. +//! improved, submit a PR, or chat with us first on [Zulip][t-libs-zulip] +//! #t-libs. //! //! # A Tour of The Rust Standard Library //! @@ -209,7 +209,7 @@ //! [multithreading]: thread //! [other]: #what-is-in-the-standard-library-documentation //! [primitive types]: ../book/ch03-02-data-types.html -//! [rust-zulip]: https://rust-lang.zulipchat.com/ +//! [t-libs-zulip]: https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/ //! [array]: prim@array //! [slice]: prim@slice @@ -337,6 +337,8 @@ #![feature(formatting_options)] #![feature(funnel_shifts)] #![feature(generic_atomic)] +#![feature(hash_map_internals)] +#![feature(hash_map_macro)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] #![feature(hint_must_use)] @@ -535,7 +537,7 @@ pub use core::pin; #[stable(feature = "rust1", since = "1.0.0")] pub use core::ptr; -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_api", since = "CURRENT_RUSTC_VERSION")] pub use core::range; #[stable(feature = "rust1", since = "1.0.0")] pub use core::result;
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 0bb1455..108cd3c 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs
@@ -5,6 +5,9 @@ //! library. // ignore-tidy-dbg +#[cfg(test)] +mod tests; + #[doc = include_str!("../../core/src/macros/panic.md")] #[macro_export] #[rustc_builtin_macro(std_panic)] @@ -359,19 +362,16 @@ macro_rules! dbg { }; } -/// Internal macro that processes a list of expressions and produces a chain of -/// nested `match`es, one for each expression, before finally calling `eprint!` -/// with the collected information and returning all the evaluated expressions -/// in a tuple. +/// Internal macro that processes a list of expressions, binds their results +/// with `match`, calls `eprint!` with the collected information, and returns +/// all the evaluated expressions in a tuple. /// /// E.g. `dbg_internal!(() () (1, 2))` expands into /// ```rust, ignore -/// match 1 { -/// tmp_1 => match 2 { -/// tmp_2 => { -/// eprint!("...", &tmp_1, &tmp_2, /* some other arguments */); -/// (tmp_1, tmp_2) -/// } +/// match (1, 2) { +/// (tmp_1, tmp_2) => { +/// eprint!("...", &tmp_1, &tmp_2, /* some other arguments */); +/// (tmp_1, tmp_2) /// } /// } /// ``` @@ -380,37 +380,117 @@ macro_rules! dbg { #[doc(hidden)] #[rustc_macro_transparency = "semiopaque"] pub macro dbg_internal { - (($($piece:literal),+) ($($processed:expr => $bound:expr),+) ()) => {{ - $crate::eprint!( - $crate::concat!($($piece),+), - $( - $crate::stringify!($processed), - // The `&T: Debug` check happens here (not in the format literal desugaring) - // to avoid format literal related messages and suggestions. - &&$bound as &dyn $crate::fmt::Debug - ),+, - // The location returned here is that of the macro invocation, so - // it will be the same for all expressions. Thus, label these - // arguments so that they can be reused in every piece of the - // formatting template. - file=$crate::file!(), - line=$crate::line!(), - column=$crate::column!() - ); - // Comma separate the variables only when necessary so that this will - // not yield a tuple for a single expression, but rather just parenthesize - // the expression. - ($($bound),+) - }}, - (($($piece:literal),*) ($($processed:expr => $bound:expr),*) ($val:expr $(,$rest:expr)*)) => { + (($($piece:literal),+) ($($processed:expr => $bound:ident),+) ()) => { // Use of `match` here is intentional because it affects the lifetimes // of temporaries - https://stackoverflow.com/a/48732525/1063961 - match $val { - tmp => $crate::macros::dbg_internal!( - ($($piece,)* "[{file}:{line}:{column}] {} = {:#?}\n") - ($($processed => $bound,)* $val => tmp) - ($($rest),*) - ), + // Always put the arguments in a tuple to avoid an unused parens lint on the pattern. + match ($($processed,)+) { + ($($bound,)+) => { + $crate::eprint!( + $crate::concat!($($piece),+), + $( + $crate::stringify!($processed), + // The `&T: Debug` check happens here (not in the format literal desugaring) + // to avoid format literal related messages and suggestions. + &&$bound as &dyn $crate::fmt::Debug + ),+, + // The location returned here is that of the macro invocation, so + // it will be the same for all expressions. Thus, label these + // arguments so that they can be reused in every piece of the + // formatting template. + file=$crate::file!(), + line=$crate::line!(), + column=$crate::column!() + ); + // Comma separate the variables only when necessary so that this will + // not yield a tuple for a single expression, but rather just parenthesize + // the expression. + ($($bound),+) + + } } }, + (($($piece:literal),*) ($($processed:expr => $bound:ident),*) ($val:expr $(,$rest:expr)*)) => { + $crate::macros::dbg_internal!( + ($($piece,)* "[{file}:{line}:{column}] {} = {:#?}\n") + ($($processed => $bound,)* $val => tmp) + ($($rest),*) + ) + }, +} + +#[doc(hidden)] +#[macro_export] +#[allow_internal_unstable(hash_map_internals)] +#[unstable(feature = "hash_map_internals", issue = "none")] +macro_rules! repetition_utils { + (@count $($tokens:tt),*) => {{ + [$($crate::repetition_utils!(@replace $tokens => ())),*].len() + }}; + + (@replace $x:tt => $y:tt) => { $y } +} + +/// Creates a [`HashMap`] containing the arguments. +/// +/// `hash_map!` allows specifying the entries that make +/// up the [`HashMap`] where the key and value are separated by a `=>`. +/// +/// The entries are separated by commas with a trailing comma being allowed. +/// +/// It is semantically equivalent to using repeated [`HashMap::insert`] +/// on a newly created hashmap. +/// +/// `hash_map!` will attempt to avoid repeated reallocations by +/// using [`HashMap::with_capacity`]. +/// +/// # Examples +/// +/// ```rust +/// #![feature(hash_map_macro)] +/// use std::hash_map; +/// +/// let map = hash_map! { +/// "key" => "value", +/// "key1" => "value1" +/// }; +/// +/// assert_eq!(map.get("key"), Some(&"value")); +/// assert_eq!(map.get("key1"), Some(&"value1")); +/// assert!(map.get("brrrrrrooooommm").is_none()); +/// ``` +/// +/// And with a trailing comma +/// +///```rust +/// #![feature(hash_map_macro)] +/// use std::hash_map; +/// +/// let map = hash_map! { +/// "key" => "value", // notice the , +/// }; +/// +/// assert_eq!(map.get("key"), Some(&"value")); +/// ``` +/// +/// The key and value are moved into the HashMap. +/// +/// [`HashMap`]: crate::collections::HashMap +/// [`HashMap::insert`]: crate::collections::HashMap::insert +/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity +#[macro_export] +#[allow_internal_unstable(hash_map_internals)] +#[unstable(feature = "hash_map_macro", issue = "144032")] +macro_rules! hash_map { + () => {{ + $crate::collections::HashMap::new() + }}; + + ( $( $key:expr => $value:expr ),* $(,)? ) => {{ + let mut map = $crate::collections::HashMap::with_capacity( + const { $crate::repetition_utils!(@count $($key),*) } + ); + $( map.insert($key, $value); )* + map + }} }
diff --git a/library/std/src/macros/tests.rs b/library/std/src/macros/tests.rs new file mode 100644 index 0000000..db2be92 --- /dev/null +++ b/library/std/src/macros/tests.rs
@@ -0,0 +1,13 @@ +// ignore-tidy-dbg + +/// Test for <https://github.com/rust-lang/rust/issues/153850>: +/// `dbg!` shouldn't drop arguments' temporaries. +#[test] +fn no_dropping_temps() { + fn temp() {} + + *dbg!(&temp()); + *dbg!(&temp(), 1).0; + *dbg!(0, &temp()).1; + *dbg!(0, &temp(), 2).1; +}
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 136803a..5da6b38 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs
@@ -129,6 +129,10 @@ pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> { /// hold the message bytes. If a message is too long to fit in the supplied buffer, /// excess bytes may be discarded. /// + /// Refer to the platform-specific documentation on this function; it is considered + /// correct for its behavior to differ from [`UdpSocket::recv`] if the underlying system + /// call does so. + /// /// # Examples /// /// ```no_run @@ -711,6 +715,10 @@ pub fn send(&self, buf: &[u8]) -> io::Result<usize> { /// [`UdpSocket::connect`] will connect this socket to a remote address. This /// method will fail if the socket is not connected. /// + /// Refer to the platform-specific documentation on this function; it is considered + /// correct for its behavior to differ from [`UdpSocket::recv_from`] if the underlying + /// system call does so. + /// /// # Examples /// /// ```no_run
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index 73f3e58..7fd46b3 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs
@@ -138,6 +138,8 @@ fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> { } /// Windows-specific extensions to [`fs::OpenOptions`]. +// WARNING: This trait is not sealed. DON'T add any new methods! +// Add them to OpenOptionsExt2 instead. #[stable(feature = "open_options_ext", since = "1.10.0")] pub trait OpenOptionsExt { /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`] @@ -305,18 +307,6 @@ pub trait OpenOptionsExt { /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut Self; - - /// If set to `true`, prevent the "last access time" of the file from being changed. - /// - /// Default to `false`. - #[unstable(feature = "windows_freeze_file_times", issue = "149715")] - fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; - - /// If set to `true`, prevent the "last write time" of the file from being changed. - /// - /// Default to `false`. - #[unstable(feature = "windows_freeze_file_times", issue = "149715")] - fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; } #[stable(feature = "open_options_ext", since = "1.10.0")] @@ -345,7 +335,28 @@ fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions { self.as_inner_mut().security_qos_flags(flags); self } +} +#[unstable(feature = "windows_freeze_file_times", issue = "149715")] +pub trait OpenOptionsExt2: Sealed { + /// If set to `true`, prevent the "last access time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; + + /// If set to `true`, prevent the "last write time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; +} + +#[unstable(feature = "sealed", issue = "none")] +impl Sealed for OpenOptions {} + +#[unstable(feature = "windows_freeze_file_times", issue = "149715")] +impl OpenOptionsExt2 for OpenOptions { fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self { self.as_inner_mut().freeze_last_access_time(freeze); self
diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 0b2b5f7..6b894f6 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs
@@ -1364,7 +1364,7 @@ fn _push(&mut self, path: &Path) { // absolute `path` replaces `self` if need_clear { - self.inner.truncate(0); + self.inner.clear(); // verbatim paths need . and .. removed } else if comps.prefix_verbatim() && !path.inner.is_empty() { @@ -2725,6 +2725,41 @@ pub fn strip_prefix<P>(&self, base: P) -> Result<&Path, StripPrefixError> self._strip_prefix(base.as_ref()) } + /// Returns a path with the optional prefix removed. + /// + /// If `base` is not a prefix of `self` (i.e., [`starts_with`] returns `false`), returns the original path (`self`) + /// + /// [`starts_with`]: Path::starts_with + /// + /// # Examples + /// + /// ``` + /// #![feature(trim_prefix_suffix)] + /// use std::path::Path; + /// + /// let path = Path::new("/test/haha/foo.txt"); + /// + /// // Prefix present - remove it + /// assert_eq!(path.trim_prefix("/"), Path::new("test/haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test"), Path::new("haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test/"), Path::new("haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test/haha/foo.txt"), Path::new("")); + /// assert_eq!(path.trim_prefix("/test/haha/foo.txt/"), Path::new("")); + /// + /// // Prefix absent - return original + /// assert_eq!(path.trim_prefix("test"), path); + /// assert_eq!(path.trim_prefix("/te"), path); + /// assert_eq!(path.trim_prefix("/haha"), path); + /// ``` + #[must_use = "this returns the remaining path as a new path, without modifying the original"] + #[unstable(feature = "trim_prefix_suffix", issue = "142312")] + pub fn trim_prefix<P>(&self, base: P) -> &Path + where + P: AsRef<Path>, + { + self._strip_prefix(base.as_ref()).unwrap_or(self) + } + fn _strip_prefix(&self, base: &Path) -> Result<&Path, StripPrefixError> { iter_after(self.components(), base.components()) .map(|c| c.as_path())
diff --git a/library/std/src/sys/args/uefi.rs b/library/std/src/sys/args/uefi.rs index 02dada3..edf6f68 100644 --- a/library/std/src/sys/args/uefi.rs +++ b/library/std/src/sys/args/uefi.rs
@@ -93,7 +93,7 @@ fn parse_lp_cmd_line(code_units: &[u16]) -> Option<Vec<OsString>> { // If not `in_quotes`, a space or tab ends the argument. SPACE if !in_quotes => { ret_val.push(OsString::from(&cur[..])); - cur.truncate(0); + cur.clear(); // Skip whitespace. while code_units_iter.next_if_eq(&Ok(SPACE)).is_some() {}
diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index c198865..bd26db7 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs
@@ -12,9 +12,9 @@ use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; use crate::sys::helpers::WStrUnits; -use crate::sys::pal::os::current_exe; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::path::get_long_path; +use crate::sys::paths::current_exe; use crate::sys::{AsInner, c, to_u16s}; use crate::{io, iter, ptr}; @@ -106,7 +106,7 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( // If not `in_quotes`, a space or tab ends the argument. SPACE | TAB if !in_quotes => { ret_val.push(OsString::from_wide(&cur[..])); - cur.truncate(0); + cur.clear(); // Skip whitespace. code_units.advance_while(|w| w == SPACE || w == TAB);
diff --git a/library/std/src/sys/env/unix.rs b/library/std/src/sys/env/unix.rs index 66805ce..7a19f97 100644 --- a/library/std/src/sys/env/unix.rs +++ b/library/std/src/sys/env/unix.rs
@@ -38,8 +38,25 @@ pub unsafe fn environ() -> *mut *const *const c_char { unsafe { libc::_NSGetEnviron() as *mut *const *const c_char } } +// On FreeBSD, environ comes from CRT rather than libc +#[cfg(target_os = "freebsd")] +pub unsafe fn environ() -> *mut *const *const c_char { + use crate::sync::LazyLock; + + struct Environ(*mut *const *const c_char); + unsafe impl Send for Environ {} + unsafe impl Sync for Environ {} + + static ENVIRON: LazyLock<Environ> = LazyLock::new(|| { + Environ(unsafe { + libc::dlsym(libc::RTLD_DEFAULT, c"environ".as_ptr()) as *mut *const *const c_char + }) + }); + ENVIRON.0 +} + // Use the `environ` static which is part of POSIX. -#[cfg(not(target_vendor = "apple"))] +#[cfg(not(any(target_os = "freebsd", target_vendor = "apple")))] pub unsafe fn environ() -> *mut *const *const c_char { unsafe extern "C" { static mut environ: *const *const c_char;
diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 1e281eb..5992766 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs
@@ -109,15 +109,15 @@ pub struct DirBuilder { impl FileAttr { pub fn modified(&self) -> io::Result<SystemTime> { - Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec)) + SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec.into()) } pub fn accessed(&self) -> io::Result<SystemTime> { - Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec)) + SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec.into()) } pub fn created(&self) -> io::Result<SystemTime> { - Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec)) + SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec.into()) } pub fn size(&self) -> u64 {
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 2a85718..9b0ef55 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs
@@ -1872,7 +1872,12 @@ fn file_time_to_timespec(time: Option<SystemTime>) -> io::Result<libc::timespec> io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time", )), - None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), + None => Ok({ + let mut ts = libc::timespec::default(); + ts.tv_sec = 0; + ts.tv_nsec = libc::UTIME_OMIT as _; + ts + }), } }
diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index d760708..c093443 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs
@@ -1,6 +1,9 @@ use crate::sys::pal::{api, c}; use crate::{io, ptr}; +#[cfg(test)] +mod tests; + pub fn errno() -> i32 { api::get_last_error().code as i32 }
diff --git a/library/std/src/sys/pal/windows/os/tests.rs b/library/std/src/sys/io/error/windows/tests.rs similarity index 92% rename from library/std/src/sys/pal/windows/os/tests.rs rename to library/std/src/sys/io/error/windows/tests.rs index 458d6e1..7fc545a 100644 --- a/library/std/src/sys/pal/windows/os/tests.rs +++ b/library/std/src/sys/io/error/windows/tests.rs
@@ -1,5 +1,5 @@ use crate::io::Error; -use crate::sys::c; +use crate::sys::pal::c; // tests `error_string` above #[test]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 5ad2397..fe0c103 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs
@@ -18,6 +18,7 @@ pub mod net; pub mod os_str; pub mod path; +pub mod paths; pub mod pipe; pub mod platform_version; pub mod process;
diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index 59f515d..e2ee248 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs
@@ -260,7 +260,7 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = netc::linger { l_onoff: linger.is_some() as i32, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, + l_linger: cmp::min(linger.unwrap_or_default().as_secs(), c_int::MAX as u64) as c_int, }; unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) }
diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index e20a3fb..7305100 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs
@@ -319,7 +319,8 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = netc::linger { l_onoff: linger.is_some() as netc::c_int, - l_linger: linger.unwrap_or_default().as_secs() as netc::c_int, + l_linger: cmp::min(linger.unwrap_or_default().as_secs(), netc::c_int::MAX as u64) + as netc::c_int, }; unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) }
diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index f3c8608..71d819a 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs
@@ -432,8 +432,8 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { #[cfg(not(target_os = "cygwin"))] pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = libc::linger { - l_onoff: linger.is_some() as libc::c_int, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, + l_onoff: linger.is_some() as c_int, + l_linger: cmp::min(linger.unwrap_or_default().as_secs(), c_int::MAX as u64) as c_int, }; unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) } @@ -443,7 +443,8 @@ pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = libc::linger { l_onoff: linger.is_some() as libc::c_ushort, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_ushort, + l_linger: cmp::min(linger.unwrap_or_default().as_secs(), libc::c_ushort::MAX as u64) + as libc::c_ushort, }; unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) }
diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index b23fb9c..e533f31 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs
@@ -413,7 +413,8 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = c::LINGER { l_onoff: linger.is_some() as c_ushort, - l_linger: linger.unwrap_or_default().as_secs() as c_ushort, + l_linger: cmp::min(linger.unwrap_or_default().as_secs(), c_ushort::MAX as u64) + as c_ushort, }; unsafe { setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger) }
diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 1e58db0..85962ce 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs
@@ -9,7 +9,9 @@ pub(crate) enum Tcp { V4(tcp4::Tcp4), } -// SAFETY: UEFI has no threads. +// SAFETY: UEFI has no regular threads, and as per <https://github.com/rust-lang/rust/issues/133604> +// std does not support being invoked from "irregular threads" such as interrupt handlers or other +// CPU cores that run outside the scope of UEFI. unsafe impl Send for Tcp {} impl Tcp {
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index f10a090..53f6ddd 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -22,7 +22,7 @@ use crate::sys::env; pub mod futex; -pub mod os; +#[path = "../unix/time.rs"] pub mod time; pub fn unsupported<T>() -> io::Result<T> {
diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs deleted file mode 100644 index 188cade..0000000 --- a/library/std/src/sys/pal/hermit/os.rs +++ /dev/null
@@ -1,57 +0,0 @@ -use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; -use crate::path::{self, PathBuf}; -use crate::sys::unsupported; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - Ok(PathBuf::from("/")) -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on hermit yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - PathBuf::from("/tmp") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs deleted file mode 100644 index b9851eb..0000000 --- a/library/std/src/sys/pal/hermit/time.rs +++ /dev/null
@@ -1,110 +0,0 @@ -use hermit_abi::{self, timespec}; - -use crate::cmp::Ordering; -use crate::hash::{Hash, Hasher}; -use crate::time::Duration; - -const NSEC_PER_SEC: i32 = 1_000_000_000; - -#[derive(Copy, Clone, Debug)] -pub struct Timespec { - pub t: timespec, -} - -impl Timespec { - pub const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1); - - pub const MIN: Timespec = Self::new(i64::MIN, 0); - - pub const fn zero() -> Timespec { - Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } } - } - - pub const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec { - assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC); - // SAFETY: The assert above checks tv_nsec is within the valid range - Timespec { t: timespec { tv_sec, tv_nsec } } - } - - pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { - fn sub_ge_to_unsigned(a: i64, b: i64) -> u64 { - debug_assert!(a >= b); - a.wrapping_sub(b).cast_unsigned() - } - - if self >= other { - // Logic here is identical to Unix version of `Timestamp::sub_timespec`, - // check comments there why operations do not overflow. - Ok(if self.t.tv_nsec >= other.t.tv_nsec { - Duration::new( - sub_ge_to_unsigned(self.t.tv_sec, other.t.tv_sec), - (self.t.tv_nsec - other.t.tv_nsec) as u32, - ) - } else { - Duration::new( - sub_ge_to_unsigned(self.t.tv_sec - 1, other.t.tv_sec), - (self.t.tv_nsec + NSEC_PER_SEC - other.t.tv_nsec) as u32, - ) - }) - } else { - match other.sub_timespec(self) { - Ok(d) => Err(d), - Err(d) => Ok(d), - } - } - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?; - - // Nano calculations can't overflow because nanos are <1B which fit - // in a u32. - let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap(); - if nsec >= NSEC_PER_SEC.try_into().unwrap() { - nsec -= u32::try_from(NSEC_PER_SEC).unwrap(); - secs = secs.checked_add(1)?; - } - Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?; - - // Similar to above, nanos can't overflow. - let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; - if nsec < 0 { - nsec += NSEC_PER_SEC as i32; - secs = secs.checked_sub(1)?; - } - Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } -} - -impl PartialEq for Timespec { - fn eq(&self, other: &Timespec) -> bool { - self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec - } -} - -impl Eq for Timespec {} - -impl PartialOrd for Timespec { - fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for Timespec { - fn cmp(&self, other: &Timespec) -> Ordering { - let me = (self.t.tv_sec, self.t.tv_nsec); - let other = (other.t.tv_sec, other.t.tv_nsec); - me.cmp(&other) - } -} - -impl Hash for Timespec { - fn hash<H: Hasher>(&self, state: &mut H) { - self.t.tv_sec.hash(state); - self.t.tv_nsec.hash(state); - } -}
diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index a520375..705413c 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs
@@ -1,7 +1,5 @@ #![allow(unsafe_op_in_unsafe_fn)] -pub mod os; - pub use moto_rt::futex; use crate::io;
diff --git a/library/std/src/sys/pal/motor/os.rs b/library/std/src/sys/pal/motor/os.rs deleted file mode 100644 index 0af5793..0000000 --- a/library/std/src/sys/pal/motor/os.rs +++ /dev/null
@@ -1,64 +0,0 @@ -use super::map_motor_error; -use crate::error::Error as StdError; -use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; -use crate::os::motor::ffi::OsStrExt; -use crate::path::{self, PathBuf}; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error) -} - -pub fn chdir(path: &path::Path) -> io::Result<()> { - moto_rt::fs::chdir(path.as_os_str().as_str()).map_err(map_motor_error) -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) - } -} - -impl StdError for JoinPathsError { - #[allow(deprecated)] - fn description(&self) -> &str { - "not supported on this platform yet" - } -} - -pub fn current_exe() -> io::Result<PathBuf> { - moto_rt::process::current_exe().map(PathBuf::from).map_err(map_motor_error) -} - -pub fn temp_dir() -> PathBuf { - PathBuf::from(moto_rt::fs::TEMP_DIR) -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index aaf380d..c269431 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -8,7 +8,6 @@ use crate::convert::TryInto; use crate::mem::{self, ManuallyDrop, MaybeUninit}; use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut}; -use crate::pin::PinCoerceUnsized; use crate::ptr::{self, NonNull}; use crate::slice::SliceIndex; use crate::{cmp, intrinsics, slice}; @@ -773,9 +772,6 @@ fn drop(&mut self) { #[unstable(feature = "sgx_platform", issue = "56975")] impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] -unsafe impl<T: ?Sized> PinCoerceUnsized for UserRef<T> {} - #[unstable(feature = "sgx_platform", issue = "56975")] impl<T, I> Index<I> for UserRef<[T]> where
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 1de3ca4..2b284cc 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -10,7 +10,6 @@ pub mod abi; mod libunwind_integration; -pub mod os; pub mod thread_parking; pub mod waitqueue;
diff --git a/library/std/src/sys/pal/sgx/os.rs b/library/std/src/sys/pal/sgx/os.rs deleted file mode 100644 index 5b0af37..0000000 --- a/library/std/src/sys/pal/sgx/os.rs +++ /dev/null
@@ -1,57 +0,0 @@ -use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; -use crate::path::{self, PathBuf}; -use crate::sys::{sgx_ineffective, unsupported}; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - sgx_ineffective(()) -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported in SGX yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem in SGX") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 1376af8..c3f9e47 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs
@@ -19,7 +19,6 @@ pub mod itron { // `error` is `pub(crate)` so that it can be accessed by `itron/error.rs` as // `crate::sys::error` pub(crate) mod error; -pub mod os; pub use self::itron::thread_parking; // SAFETY: must be called only once during runtime initialization.
diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs deleted file mode 100644 index 79bb91b..0000000 --- a/library/std/src/sys/pal/solid/os.rs +++ /dev/null
@@ -1,56 +0,0 @@ -use super::unsupported; -use crate::ffi::{OsStr, OsString}; -use crate::path::{self, PathBuf}; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(&'a !); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - *self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no standard temporary directory on this platform") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 7d2ecdb..5caed27 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -7,7 +7,6 @@ #![allow(dead_code)] pub mod conf; -pub mod os; #[path = "../unix/time.rs"] pub mod time;
diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs deleted file mode 100644 index c86fa55..0000000 --- a/library/std/src/sys/pal/teeos/os.rs +++ /dev/null
@@ -1,62 +0,0 @@ -//! Implementation of `std::os` functionality for teeos - -use core::marker::PhantomData; - -use super::unsupported; -use crate::ffi::{OsStr, OsString}; -use crate::path::PathBuf; -use crate::{fmt, io, path}; - -// Everything below are stubs and copied from unsupported.rs - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem on this platform") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs index b785c2d..ec2d938 100644 --- a/library/std/src/sys/pal/trusty/mod.rs +++ b/library/std/src/sys/pal/trusty/mod.rs
@@ -3,7 +3,5 @@ #[path = "../unsupported/common.rs"] #[deny(unsafe_op_in_unsafe_fn)] mod common; -#[path = "../unsupported/os.rs"] -pub mod os; pub use common::*;
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index e4a8f50..67499d2 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -14,7 +14,6 @@ #![forbid(unsafe_op_in_unsafe_fn)] pub mod helpers; -pub mod os; pub mod system_time; #[cfg(test)]
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 9931b4d..0be150a 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs
@@ -8,7 +8,6 @@ pub mod futex; #[cfg(target_os = "linux")] pub mod linux; -pub mod os; pub mod stack_overflow; pub mod sync; pub mod thread_parking;
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 632f619..5d53de7 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -429,6 +429,11 @@ unsafe fn install_main_guard() -> Option<Range<usize>> { #[forbid(unsafe_op_in_unsafe_fn)] unsafe fn install_main_guard_linux(page_size: usize) -> Option<Range<usize>> { + // See the corresponding conditional in init(). + // Avoid stack_start_aligned, which makes slow syscalls to read /proc/self/maps + if cfg!(panic = "immediate-abort") { + return None; + } // Linux doesn't allocate the whole stack right away, and // the kernel has its own stack-guard mechanism to fault // when growing too close to an existing mapping. If we map @@ -456,6 +461,10 @@ unsafe fn install_main_guard_linux_musl(_page_size: usize) -> Option<Range<usize #[forbid(unsafe_op_in_unsafe_fn)] #[cfg(target_os = "freebsd")] unsafe fn install_main_guard_freebsd(page_size: usize) -> Option<Range<usize>> { + // See the corresponding conditional in install_main_guard_linux(). + if cfg!(panic = "immediate-abort") { + return None; + } // FreeBSD's stack autogrows, and optionally includes a guard page // at the bottom. If we try to remap the bottom of the stack // ourselves, FreeBSD's guard page moves upwards. So we'll just use @@ -489,6 +498,10 @@ unsafe fn install_main_guard_freebsd(page_size: usize) -> Option<Range<usize>> { #[forbid(unsafe_op_in_unsafe_fn)] unsafe fn install_main_guard_bsds(page_size: usize) -> Option<Range<usize>> { + // See the corresponding conditional in install_main_guard_linux(). + if cfg!(panic = "immediate-abort") { + return None; + } // OpenBSD stack already includes a guard page, and stack is // immutable. // NetBSD stack includes the guard page.
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index fbea94e..26fb6d3 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs
@@ -1,3 +1,4 @@ +use core::mem; use core::num::niche_types::Nanoseconds; use crate::io; @@ -6,8 +7,12 @@ const NSEC_PER_SEC: u64 = 1_000_000_000; #[allow(dead_code)] // Used for pthread condvar timeouts -pub const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 }; +pub const TIMESPEC_MAX: libc::timespec = { + let mut ts = unsafe { mem::zeroed::<libc::timespec>() }; + ts.tv_sec = <libc::time_t>::MAX; + ts.tv_nsec = 1_000_000_000 - 1; + ts +}; // This additional constant is only used when calling // `libc::pthread_cond_timedwait`. @@ -17,7 +22,7 @@ tv_nsec: (u64::MAX % NSEC_PER_SEC) as i64, }; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub(crate) struct Timespec { pub tv_sec: i64, pub tv_nsec: Nanoseconds, @@ -66,6 +71,7 @@ pub const fn new(tv_sec: i64, tv_nsec: i64) -> Result<Timespec, io::Error> { } } + #[allow(dead_code)] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; @@ -163,9 +169,11 @@ pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { #[allow(dead_code)] pub fn to_timespec(&self) -> Option<libc::timespec> { - Some(libc::timespec { - tv_sec: self.tv_sec.try_into().ok()?, - tv_nsec: self.tv_nsec.as_inner().try_into().ok()?, + Some({ + let mut ts = libc::timespec::default(); + ts.tv_sec = self.tv_sec.try_into().ok()?; + ts.tv_nsec = self.tv_nsec.as_inner().try_into().ok()?; + ts }) }
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index 0f15781..c4b14ab 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -1,6 +1,4 @@ #![deny(unsafe_op_in_unsafe_fn)] -pub mod os; - mod common; pub use common::*;
diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index d1380ab..61bbe78 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs
@@ -1,6 +1,3 @@ -#[path = "../unsupported/os.rs"] -pub mod os; - #[expect(dead_code)] #[path = "../unsupported/common.rs"] mod unsupported_common;
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 66d9107..6f60993 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -10,7 +10,6 @@ #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; -pub mod os; pub mod stack_overflow; #[path = "../unix/time.rs"] pub mod time;
diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs deleted file mode 100644 index b1c26ac..0000000 --- a/library/std/src/sys/pal/wasi/os.rs +++ /dev/null
@@ -1,87 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use crate::ffi::{CStr, OsStr, OsString}; -use crate::marker::PhantomData; -use crate::os::wasi::prelude::*; -use crate::path::{self, PathBuf}; -use crate::sys::helpers::run_path_with_cstr; -use crate::sys::unsupported; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - let mut buf = Vec::with_capacity(512); - loop { - unsafe { - let ptr = buf.as_mut_ptr() as *mut libc::c_char; - if !libc::getcwd(ptr, buf.capacity()).is_null() { - let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len(); - buf.set_len(len); - buf.shrink_to_fit(); - return Ok(PathBuf::from(OsString::from_vec(buf))); - } else { - let error = io::Error::last_os_error(); - if error.raw_os_error() != Some(libc::ERANGE) { - return Err(error); - } - } - - // Trigger the internal buffer resizing logic of `Vec` by requiring - // more space than the current capacity. - let cap = buf.capacity(); - buf.set_len(cap); - buf.reserve(1); - } - } -} - -pub fn chdir(p: &path::Path) -> io::Result<()> { - let result = run_path_with_cstr(p, &|p| unsafe { Ok(libc::chdir(p.as_ptr())) })?; - match result == (0 as libc::c_int) { - true => Ok(()), - false => Err(io::Error::last_os_error()), - } -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on wasm yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem on wasm") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 5f56edd..24a2ab8 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -16,9 +16,6 @@ #![deny(unsafe_op_in_unsafe_fn)] -#[path = "../unsupported/os.rs"] -pub mod os; - #[cfg(target_feature = "atomics")] #[path = "atomics/futex.rs"] pub mod futex;
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 0cd9152..b67ba37 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs
@@ -18,7 +18,6 @@ #[cfg(not(target_vendor = "win7"))] pub mod futex; pub mod handle; -pub mod os; pub mod time; cfg_select! { // We don't care about printing nice error messages for panic=immediate-abort
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 9b22fb8..b5b3fd9 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs
@@ -1,6 +1,5 @@ #![forbid(unsafe_op_in_unsafe_fn)] -pub mod os; pub mod params; #[path = "../unsupported/common.rs"]
diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs deleted file mode 100644 index fe8adde..0000000 --- a/library/std/src/sys/pal/xous/os.rs +++ /dev/null
@@ -1,57 +0,0 @@ -use super::unsupported; -use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; -use crate::path::{self, PathBuf}; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem on this platform") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 1b18adb..1a64d3c 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -11,7 +11,6 @@ pub const WORD_SIZE: usize = size_of::<u32>(); pub mod abi; -pub mod os; use crate::io as std_io;
diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs deleted file mode 100644 index fe8adde..0000000 --- a/library/std/src/sys/pal/zkvm/os.rs +++ /dev/null
@@ -1,57 +0,0 @@ -use super::unsupported; -use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; -use crate::path::{self, PathBuf}; -use crate::{fmt, io}; - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - self.0 - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) - } -} - -impl crate::error::Error for JoinPathsError {} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem on this platform") -} - -pub fn home_dir() -> Option<PathBuf> { - None -}
diff --git a/library/std/src/sys/paths/hermit.rs b/library/std/src/sys/paths/hermit.rs new file mode 100644 index 0000000..36f667d --- /dev/null +++ b/library/std/src/sys/paths/hermit.rs
@@ -0,0 +1,10 @@ +use crate::io; +use crate::path::PathBuf; + +pub fn getcwd() -> io::Result<PathBuf> { + Ok(PathBuf::from("/")) +} + +pub fn temp_dir() -> PathBuf { + PathBuf::from("/tmp") +}
diff --git a/library/std/src/sys/paths/mod.rs b/library/std/src/sys/paths/mod.rs new file mode 100644 index 0000000..8880a83 --- /dev/null +++ b/library/std/src/sys/paths/mod.rs
@@ -0,0 +1,59 @@ +cfg_select! { + target_os = "hermit" => { + mod hermit; + #[expect(dead_code)] + mod unsupported; + mod imp { + pub use super::hermit::{getcwd, temp_dir}; + pub use super::unsupported::{chdir, SplitPaths, split_paths, JoinPathsError, join_paths, current_exe, home_dir}; + } + } + target_os = "motor" => { + mod motor; + #[expect(dead_code)] + mod unsupported; + mod imp { + pub use super::motor::{getcwd, chdir, current_exe, temp_dir}; + pub use super::unsupported::{SplitPaths, split_paths, JoinPathsError, join_paths, home_dir}; + } + } + all(target_vendor = "fortanix", target_env = "sgx") => { + mod sgx; + #[expect(dead_code)] + mod unsupported; + mod imp { + pub use super::sgx::chdir; + pub use super::unsupported::{getcwd, SplitPaths, split_paths, JoinPathsError, join_paths, current_exe, temp_dir, home_dir}; + } + } + target_os = "uefi" => { + mod uefi; + use uefi as imp; + } + target_family = "unix" => { + mod unix; + use unix as imp; + } + target_os = "wasi" => { + mod wasi; + #[expect(dead_code)] + mod unsupported; + mod imp { + pub use super::wasi::{getcwd, chdir, temp_dir}; + pub use super::unsupported::{current_exe, SplitPaths, split_paths, JoinPathsError, join_paths, home_dir}; + } + } + target_os = "windows" => { + mod windows; + use windows as imp; + } + _ => { + mod unsupported; + use unsupported as imp; + } +} + +pub use imp::{ + JoinPathsError, SplitPaths, chdir, current_exe, getcwd, home_dir, join_paths, split_paths, + temp_dir, +};
diff --git a/library/std/src/sys/paths/motor.rs b/library/std/src/sys/paths/motor.rs new file mode 100644 index 0000000..33d746b --- /dev/null +++ b/library/std/src/sys/paths/motor.rs
@@ -0,0 +1,20 @@ +use crate::io; +use crate::os::motor::ffi::OsStrExt; +use crate::path::{self, PathBuf}; +use crate::sys::pal::map_motor_error; + +pub fn getcwd() -> io::Result<PathBuf> { + moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error) +} + +pub fn chdir(path: &path::Path) -> io::Result<()> { + moto_rt::fs::chdir(path.as_os_str().as_str()).map_err(map_motor_error) +} + +pub fn current_exe() -> io::Result<PathBuf> { + moto_rt::process::current_exe().map(PathBuf::from).map_err(map_motor_error) +} + +pub fn temp_dir() -> PathBuf { + PathBuf::from(moto_rt::fs::TEMP_DIR) +}
diff --git a/library/std/src/sys/paths/sgx.rs b/library/std/src/sys/paths/sgx.rs new file mode 100644 index 0000000..6a4cbe9 --- /dev/null +++ b/library/std/src/sys/paths/sgx.rs
@@ -0,0 +1,7 @@ +use crate::io; +use crate::path::Path; +use crate::sys::pal::sgx_ineffective; + +pub fn chdir(_: &Path) -> io::Result<()> { + sgx_ineffective(()) +}
diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/paths/uefi.rs similarity index 96% rename from library/std/src/sys/pal/uefi/os.rs rename to library/std/src/sys/paths/uefi.rs index b25be43..7fddcfd 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/paths/uefi.rs
@@ -1,9 +1,9 @@ use r_efi::efi::protocols::{device_path, loaded_image_device_path}; -use super::{helpers, unsupported_err}; use crate::ffi::{OsStr, OsString}; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::path::{self, PathBuf}; +use crate::sys::pal::{helpers, unsupported_err}; use crate::{fmt, io}; const PATHS_SEP: u16 = b';' as u16; @@ -115,7 +115,7 @@ pub fn current_exe() -> io::Result<PathBuf> { } pub fn temp_dir() -> PathBuf { - panic!("no filesystem on this platform") + panic!("UEFI doesn't have a dedicated temp directory") } pub fn home_dir() -> Option<PathBuf> {
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/paths/unix.rs similarity index 98% rename from library/std/src/sys/pal/unix/os.rs rename to library/std/src/sys/paths/unix.rs index f69614c..544d495 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/paths/unix.rs
@@ -7,8 +7,8 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::os::unix::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::cvt; use crate::sys::helpers::run_path_with_cstr; +use crate::sys::pal::cvt; use crate::{fmt, io, iter, mem, ptr, slice, str}; const PATH_SEPARATOR: u8 = b':'; @@ -47,7 +47,7 @@ pub fn getcwd() -> io::Result<PathBuf> { #[cfg(target_os = "espidf")] pub fn chdir(_p: &path::Path) -> io::Result<()> { - super::unsupported::unsupported() + crate::sys::pal::unsupported::unsupported() } #[cfg(not(target_os = "espidf"))] @@ -372,7 +372,7 @@ pub fn current_exe() -> io::Result<PathBuf> { #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] pub fn current_exe() -> io::Result<PathBuf> { - super::unsupported::unsupported() + crate::sys::pal::unsupported::unsupported() } #[cfg(target_os = "fuchsia")]
diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/paths/unsupported.rs similarity index 96% rename from library/std/src/sys/pal/unsupported/os.rs rename to library/std/src/sys/paths/unsupported.rs index fe8adde..024830a 100644 --- a/library/std/src/sys/pal/unsupported/os.rs +++ b/library/std/src/sys/paths/unsupported.rs
@@ -1,7 +1,7 @@ -use super::unsupported; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::path::{self, PathBuf}; +use crate::sys::pal::unsupported; use crate::{fmt, io}; pub fn getcwd() -> io::Result<PathBuf> {
diff --git a/library/std/src/sys/paths/wasi.rs b/library/std/src/sys/paths/wasi.rs new file mode 100644 index 0000000..1e1f951 --- /dev/null +++ b/library/std/src/sys/paths/wasi.rs
@@ -0,0 +1,45 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + +use crate::ffi::{CStr, OsString}; +use crate::io; +use crate::os::wasi::prelude::*; +use crate::path::{self, PathBuf}; +use crate::sys::helpers::run_path_with_cstr; + +pub fn getcwd() -> io::Result<PathBuf> { + let mut buf = Vec::with_capacity(512); + loop { + unsafe { + let ptr = buf.as_mut_ptr() as *mut libc::c_char; + if !libc::getcwd(ptr, buf.capacity()).is_null() { + let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len(); + buf.set_len(len); + buf.shrink_to_fit(); + return Ok(PathBuf::from(OsString::from_vec(buf))); + } else { + let error = io::Error::last_os_error(); + if error.raw_os_error() != Some(libc::ERANGE) { + return Err(error); + } + } + + // Trigger the internal buffer resizing logic of `Vec` by requiring + // more space than the current capacity. + let cap = buf.capacity(); + buf.set_len(cap); + buf.reserve(1); + } + } +} + +pub fn chdir(p: &path::Path) -> io::Result<()> { + let result = run_path_with_cstr(p, &|p| unsafe { Ok(libc::chdir(p.as_ptr())) })?; + match result == (0 as libc::c_int) { + true => Ok(()), + false => Err(io::Error::last_os_error()), + } +} + +pub fn temp_dir() -> PathBuf { + panic!("not supported by WASI yet") +}
diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/paths/windows.rs similarity index 87% rename from library/std/src/sys/pal/windows/os.rs rename to library/std/src/sys/paths/windows.rs index 30cad2a..cfdc938 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/paths/windows.rs
@@ -2,17 +2,13 @@ #![allow(nonstandard_style)] -#[cfg(test)] -mod tests; - -use super::api; -#[cfg(not(target_vendor = "uwp"))] -use super::api::WinError; use crate::ffi::{OsStr, OsString}; use crate::os::windows::ffi::EncodeWide; use crate::os::windows::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::pal::{c, cvt}; +#[cfg(not(target_vendor = "uwp"))] +use crate::sys::pal::api::WinError; +use crate::sys::pal::{api, c, cvt, fill_utf16_buf, os2path}; use crate::{fmt, io, ptr}; pub struct SplitPaths<'a> { @@ -56,11 +52,7 @@ fn next(&mut self) -> Option<PathBuf> { } } - if !must_yield && in_progress.is_empty() { - None - } else { - Some(super::os2path(&in_progress)) - } + if !must_yield && in_progress.is_empty() { None } else { Some(os2path(&in_progress)) } } } @@ -104,14 +96,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl crate::error::Error for JoinPathsError {} pub fn current_exe() -> io::Result<PathBuf> { - super::fill_utf16_buf( - |buf, sz| unsafe { c::GetModuleFileNameW(ptr::null_mut(), buf, sz) }, - super::os2path, - ) + fill_utf16_buf(|buf, sz| unsafe { c::GetModuleFileNameW(ptr::null_mut(), buf, sz) }, os2path) } pub fn getcwd() -> io::Result<PathBuf> { - super::fill_utf16_buf(|buf, sz| unsafe { c::GetCurrentDirectoryW(sz, buf) }, super::os2path) + fill_utf16_buf(|buf, sz| unsafe { c::GetCurrentDirectoryW(sz, buf) }, os2path) } pub fn chdir(p: &path::Path) -> io::Result<()> { @@ -123,7 +112,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { } pub fn temp_dir() -> PathBuf { - super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, super::os2path).unwrap() + fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, os2path).unwrap() } #[cfg(all(not(target_vendor = "uwp"), not(target_vendor = "win7")))] @@ -132,7 +121,7 @@ fn home_dir_crt() -> Option<PathBuf> { // Defined in processthreadsapi.h. const CURRENT_PROCESS_TOKEN: usize = -4_isize as usize; - super::fill_utf16_buf( + fill_utf16_buf( |buf, mut sz| { // GetUserProfileDirectoryW does not quite use the usual protocol for // negotiating the buffer size, so we have to translate. @@ -146,7 +135,7 @@ fn home_dir_crt() -> Option<PathBuf> { _ => sz - 1, // sz includes the null terminator } }, - super::os2path, + os2path, ) .ok() } @@ -163,7 +152,7 @@ fn home_dir_crt() -> Option<PathBuf> { return None; } let _handle = Handle::from_raw_handle(token); - super::fill_utf16_buf( + fill_utf16_buf( |buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { 0 if api::get_last_error() != WinError::INSUFFICIENT_BUFFER => 0, @@ -171,7 +160,7 @@ fn home_dir_crt() -> Option<PathBuf> { _ => sz - 1, // sz includes the null terminator } }, - super::os2path, + os2path, ) .ok() }
diff --git a/library/std/src/sys/sync/rwlock/no_threads.rs b/library/std/src/sys/sync/rwlock/no_threads.rs index 573d0d6..6b919bd 100644 --- a/library/std/src/sys/sync/rwlock/no_threads.rs +++ b/library/std/src/sys/sync/rwlock/no_threads.rs
@@ -37,8 +37,10 @@ pub fn try_read(&self) -> bool { #[inline] pub fn write(&self) { - if self.mode.replace(-1) != 0 { - rtabort!("rwlock locked for reading") + if self.mode.get() == 0 { + self.mode.set(-1); + } else { + rtabort!("rwlock locked for reading"); } }
diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 5d4eabc..2f3ef17 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs
@@ -570,10 +570,10 @@ unsafe fn nanosleep(rqtp: *const libc::timespec, rmtp: *mut libc::timespec) -> l // nanosleep will fill in `ts` with the remaining time. unsafe { while secs > 0 || nsecs > 0 { - let mut ts = libc::timespec { - tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t, - tv_nsec: nsecs, - }; + let mut ts = libc::timespec::default(); + ts.tv_sec = cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t; + ts.tv_nsec = nsecs; + secs -= ts.tv_sec as u64; let ts_ptr = &raw mut ts; let r = nanosleep(ts_ptr, ts_ptr);
diff --git a/library/std/src/sys/time/hermit.rs b/library/std/src/sys/time/hermit.rs index 18ece2e..4e8e5df 100644 --- a/library/std/src/sys/time/hermit.rs +++ b/library/std/src/sys/time/hermit.rs
@@ -1,18 +1,21 @@ use hermit_abi::{self, CLOCK_MONOTONIC, CLOCK_REALTIME}; -use crate::hash::Hash; +use crate::io; use crate::sys::pal::time::Timespec; use crate::time::Duration; +fn clock_gettime(clock: hermit_abi::clockid_t) -> Timespec { + let mut t = hermit_abi::timespec { tv_sec: 0, tv_nsec: 0 }; + unsafe { hermit_abi::clock_gettime(clock, &raw mut t) }.unwrap(); + Timespec::new(t.tv_sec, t.tv_nsec.into()).unwrap() +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Timespec); impl Instant { pub fn now() -> Instant { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_MONOTONIC, &raw mut time.t) }; - - Instant(time) + Instant(clock_gettime(CLOCK_MONOTONIC)) } pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { @@ -38,15 +41,12 @@ impl SystemTime { pub const MIN: SystemTime = SystemTime(Timespec::MIN); - pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime { - SystemTime(Timespec::new(tv_sec, tv_nsec)) + pub fn new(tv_sec: i64, tv_nsec: i64) -> Result<SystemTime, io::Error> { + Ok(SystemTime(Timespec::new(tv_sec, tv_nsec)?)) } pub fn now() -> SystemTime { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_REALTIME, &raw mut time.t) }; - - SystemTime(time) + SystemTime(clock_gettime(CLOCK_REALTIME)) } pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
diff --git a/library/std/tests/sync/mpmc.rs b/library/std/tests/sync/mpmc.rs index bf80ab9..db221ff 100644 --- a/library/std/tests/sync/mpmc.rs +++ b/library/std/tests/sync/mpmc.rs
@@ -475,7 +475,6 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; - let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { @@ -483,7 +482,6 @@ fn stress_recv_timeout_two_threads() { recv_count += 1; } Err(RecvTimeoutError::Timeout) => { - got_timeout = true; continue; } Err(RecvTimeoutError::Disconnected) => break, @@ -491,7 +489,6 @@ fn stress_recv_timeout_two_threads() { } assert_eq!(recv_count, stress); - assert!(got_timeout); } #[test]
diff --git a/library/std/tests/sync/mpsc.rs b/library/std/tests/sync/mpsc.rs index 9de4a71..4dc4b95 100644 --- a/library/std/tests/sync/mpsc.rs +++ b/library/std/tests/sync/mpsc.rs
@@ -438,7 +438,6 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; - let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { @@ -446,7 +445,6 @@ fn stress_recv_timeout_two_threads() { recv_count += 1; } Err(RecvTimeoutError::Timeout) => { - got_timeout = true; continue; } Err(RecvTimeoutError::Disconnected) => break, @@ -454,7 +452,6 @@ fn stress_recv_timeout_two_threads() { } assert_eq!(recv_count, stress); - assert!(got_timeout); } #[test]
diff --git a/library/std_detect/src/detect/os/darwin/aarch64.rs b/library/std_detect/src/detect/os/darwin/aarch64.rs index a23d65a..5805d5c 100644 --- a/library/std_detect/src/detect/os/darwin/aarch64.rs +++ b/library/std_detect/src/detect/os/darwin/aarch64.rs
@@ -81,6 +81,7 @@ pub(crate) fn detect_features() -> cache::Initializer { let sme_f64f64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F64F64"); let sme_i16i64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_I16I64"); let ssbs = _sysctlbyname(c"hw.optional.arm.FEAT_SSBS"); + let sve_b16b16 = _sysctlbyname(c"hw.optional.arm.FEAT_SVE_B16B16"); let wfxt = _sysctlbyname(c"hw.optional.arm.FEAT_WFxT"); // The following features are not exposed by `is_aarch64_feature_detected`, @@ -160,6 +161,7 @@ pub(crate) fn detect_features() -> cache::Initializer { enable_feature(Feature::sme_f64f64, sme_f64f64); enable_feature(Feature::sme_i16i64, sme_i16i64); enable_feature(Feature::ssbs, ssbs); + enable_feature(Feature::sve_b16b16, sve_b16b16); enable_feature(Feature::wfxt, wfxt); value
diff --git a/library/std_detect/src/detect/os/x86.rs b/library/std_detect/src/detect/os/x86.rs index f2205ba..b24ef6a 100644 --- a/library/std_detect/src/detect/os/x86.rs +++ b/library/std_detect/src/detect/os/x86.rs
@@ -202,6 +202,28 @@ pub(crate) fn detect_features() -> cache::Initializer { // Test `XCR0.APX[19]` with the mask `0b1000_0000_0000_0000_0000 == 0x80000` let os_apx_support = xcr0 & 0x80000 == 0x80000; + if os_amx_support { + enable(extended_features_edx, 24, Feature::amx_tile); + enable(extended_features_edx, 25, Feature::amx_int8); + enable(extended_features_edx, 22, Feature::amx_bf16); + enable(extended_features_eax_leaf_1, 21, Feature::amx_fp16); + enable(extended_features_edx_leaf_1, 8, Feature::amx_complex); + + if max_basic_leaf >= 0x1e { + let CpuidResult { eax: amx_feature_flags_eax, .. } = + __cpuid_count(0x1e_u32, 1); + + enable(amx_feature_flags_eax, 4, Feature::amx_fp8); + enable(amx_feature_flags_eax, 6, Feature::amx_tf32); + enable(amx_feature_flags_eax, 7, Feature::amx_avx512); + enable(amx_feature_flags_eax, 8, Feature::amx_movrs); + } + } + + if os_apx_support { + enable(extended_features_edx_leaf_1, 21, Feature::apxf); + } + // Only if the OS and the CPU support saving/restoring the AVX // registers we enable `xsave` support: if os_avx_support { @@ -236,9 +258,10 @@ pub(crate) fn detect_features() -> cache::Initializer { enable(extended_features_ebx, 5, Feature::avx2); // "Short" versions of AVX512 instructions - enable(extended_features_eax_leaf_1, 4, Feature::avxvnni); - enable(extended_features_eax_leaf_1, 23, Feature::avxifma); - enable(extended_features_edx_leaf_1, 4, Feature::avxvnniint8); + let avxvnni = enable(extended_features_eax_leaf_1, 4, Feature::avxvnni); + let avxvnniint8 = enable(extended_features_eax_leaf_1, 23, Feature::avxifma); + let avxvnniint16 = + enable(extended_features_edx_leaf_1, 4, Feature::avxvnniint8); enable(extended_features_edx_leaf_1, 5, Feature::avxneconvert); enable(extended_features_edx_leaf_1, 10, Feature::avxvnniint16); @@ -269,37 +292,18 @@ pub(crate) fn detect_features() -> cache::Initializer { enable(extended_features_edx, 8, Feature::avx512vp2intersect); enable(extended_features_edx, 23, Feature::avx512fp16); enable(extended_features_eax_leaf_1, 5, Feature::avx512bf16); - } - } - if os_amx_support { - enable(extended_features_edx, 24, Feature::amx_tile); - enable(extended_features_edx, 25, Feature::amx_int8); - enable(extended_features_edx, 22, Feature::amx_bf16); - enable(extended_features_eax_leaf_1, 21, Feature::amx_fp16); - enable(extended_features_edx_leaf_1, 8, Feature::amx_complex); + let avx10_1 = enable(extended_features_edx_leaf_1, 19, Feature::avx10_1); + if avx10_1 { + let CpuidResult { ebx, .. } = __cpuid(0x24); + let avx10_version = ebx & 0xff; - if max_basic_leaf >= 0x1e { - let CpuidResult { eax: amx_feature_flags_eax, .. } = - __cpuid_count(0x1e_u32, 1); - - enable(amx_feature_flags_eax, 4, Feature::amx_fp8); - enable(amx_feature_flags_eax, 6, Feature::amx_tf32); - enable(amx_feature_flags_eax, 7, Feature::amx_avx512); - enable(amx_feature_flags_eax, 8, Feature::amx_movrs); - } - } - - if os_apx_support { - enable(extended_features_edx_leaf_1, 21, Feature::apxf); - } - - let avx10_1 = enable(extended_features_edx_leaf_1, 19, Feature::avx10_1); - if avx10_1 { - let CpuidResult { ebx, .. } = __cpuid(0x24); - let avx10_version = ebx & 0xff; - if avx10_version >= 2 { - value.set(Feature::avx10_2 as u32); + // AVX10.2 supports masked versions of dot-product instructions available in avxvnni etc, + // so it doesn't make sense to have it without the unmasked versions + if avx10_version >= 2 && avxvnni && avxvnniint8 && avxvnniint16 { + value.set(Feature::avx10_2 as u32); + } + } } } }
diff --git a/library/stdarch/crates/core_arch/src/mips/msa.rs b/library/stdarch/crates/core_arch/src/mips/msa.rs index 563e121..6246433 100644 --- a/library/stdarch/crates/core_arch/src/mips/msa.rs +++ b/library/stdarch/crates/core_arch/src/mips/msa.rs
@@ -9187,7 +9187,6 @@ mod tests { core_arch::{mips::msa::*, simd::*}, mem, }; - use std::{f32, f64}; use stdarch_test::simd_test; #[simd_test(enable = "msa")]
diff --git a/library/stdarch/crates/core_arch/src/nvptx/packed.rs b/library/stdarch/crates/core_arch/src/nvptx/packed.rs index 856aeea..1c7e812 100644 --- a/library/stdarch/crates/core_arch/src/nvptx/packed.rs +++ b/library/stdarch/crates/core_arch/src/nvptx/packed.rs
@@ -99,7 +99,7 @@ pub unsafe fn f16x2_neg(a: f16x2) -> f16x2 { #[cfg_attr(test, assert_instr(min.f16x2))] #[unstable(feature = "stdarch_nvptx", issue = "111199")] pub unsafe fn f16x2_min(a: f16x2, b: f16x2) -> f16x2 { - simd_fmin(a, b) + simd_minimum_number_nsz(a, b) } /// Find the minimum of two values, NaNs pass through. @@ -123,7 +123,7 @@ pub unsafe fn f16x2_min_nan(a: f16x2, b: f16x2) -> f16x2 { #[cfg_attr(test, assert_instr(max.f16x2))] #[unstable(feature = "stdarch_nvptx", issue = "111199")] pub unsafe fn f16x2_max(a: f16x2, b: f16x2) -> f16x2 { - simd_fmax(a, b) + simd_maximum_number_nsz(a, b) } /// Find the maximum of two values, NaNs pass through.
diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 3f7781c..9183eab 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs
@@ -208,7 +208,7 @@ pub fn _mm_min_ss(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(minps))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_ps(a: __m128, b: __m128) -> __m128 { - // See the `test_mm_min_ps` test why this can't be implemented using `simd_fmin`. + // See the `test_mm_min_ps` test why this can't be implemented using `simd_minimum_number_nsz`. unsafe { minps(a, b) } } @@ -234,7 +234,7 @@ pub fn _mm_max_ss(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(maxps))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_ps(a: __m128, b: __m128) -> __m128 { - // See the `test_mm_min_ps` test why this can't be implemented using `simd_fmax`. + // See the `test_mm_min_ps` test why this can't be implemented using `simd_maximum_number_nsz`. unsafe { maxps(a, b) } } @@ -2227,11 +2227,11 @@ fn test_mm_min_ps() { let r = _mm_min_ps(a, b); assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0)); - // `_mm_min_ps` can **not** be implemented using the `simd_min` rust intrinsic. `simd_min` - // is lowered by the llvm codegen backend to `llvm.minnum.v*` llvm intrinsic. This intrinsic - // doesn't specify how -0.0 is handled. Unfortunately it happens to behave different from - // the `minps` x86 instruction on x86. The `llvm.minnum.v*` llvm intrinsic equals - // `r1` to `a` and `r2` to `b`. + // `_mm_min_ps` can **not** be implemented using the `simd_minimum_number_nsz` rust + // intrinsic. That intrinsic is lowered by the llvm codegen backend to `llvm.minimumnum.v*` + // llvm intrinsic with the `nsz` attribute. The `nsz` attribute means -0.0 is handled + // non-deterministically. The `minps` x86 instruction however has a deterministic semantics + // for signed zeros. let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0); let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0); let r1 = _mm_min_ps(a, b).as_f32x4().to_bits();
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index d694f8e..a6d8d46 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock
@@ -757,9 +757,9 @@ [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc",
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 7187a5a..9b1039b 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml
@@ -50,7 +50,7 @@ serde_derive = "1.0" serde_json = "1.0" sha2 = "0.10" -tar = { version = "0.4.44", default-features = false } +tar = { version = "0.4.45", default-features = false } termcolor = "1.4" toml = "0.5" walkdir = "2.4"
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 105e41c..b893bb3 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py
@@ -1259,7 +1259,12 @@ def parse_args(args): """Parse the command line arguments that the python script needs.""" - parser = argparse.ArgumentParser(add_help=False) + + # Pass allow_abbrev=False to remove support for inexact matches (e.g., + # `--json` turning on `--json-output`). The argument list here is partial, + # most flags are matched in the Rust bootstrap code. This prevents the the + # default ambiguity checks in argparse from functioning correctly. + parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False) parser.add_argument("-h", "--help", action="store_true") parser.add_argument("--config") parser.add_argument("--build-dir")
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index 2ca19f08..dd68964 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/153179 +Last change is for: https://github.com/rust-lang/rust/pull/154485
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index a6cb6a4..a2cf801 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -1558,6 +1558,8 @@ fn supported_sanitizers( &["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan"], ), "x86_64-unknown-linux-gnuasan" => common_libs("linux", "x86_64", &["asan"]), + "x86_64-unknown-linux-gnumsan" => common_libs("linux", "x86_64", &["msan"]), + "x86_64-unknown-linux-gnutsan" => common_libs("linux", "x86_64", &["tsan"]), "x86_64-unknown-linux-musl" => { common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"]) }
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 2079f3a..897e03c 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -180,6 +180,10 @@ fn run(self, builder: &Builder<'_>) { // Forward arguments. This may contain further arguments to the program // after another --, so this must be at the end. miri.args(builder.config.args()); + // Add default edition for Miri tests (2021); defaulting to 2015 is often confusing. + if !builder.config.args().iter().any(|arg| arg.starts_with("--edition")) { + miri.arg("--edition=2021"); + } miri.into_cmd().run(builder); }
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 16065cb..b4ef00b 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -122,6 +122,9 @@ pub fn new( cmd_kind: Kind, ) -> Cargo { let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind); + if target.synthetic { + cargo.arg("-Zjson-target-spec"); + } match cmd_kind { // No need to configure the target linker for these command types. @@ -165,7 +168,11 @@ pub fn new_for_mir_opt_tests( target: TargetSelection, cmd_kind: Kind, ) -> Cargo { - builder.cargo(compiler, mode, source_type, target, cmd_kind) + let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind); + if target.synthetic { + cargo.arg("-Zjson-target-spec"); + } + cargo } pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo {
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ca8af27..c4a6b68 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs
@@ -37,6 +37,8 @@ pub struct Finder { /// when the newly-bumped stage 0 compiler now knows about the formerly-missing targets. const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "x86_64-unknown-linux-gnumsan", + "x86_64-unknown-linux-gnutsan", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index f130381..6af11d9 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs
@@ -883,6 +883,12 @@ fn rustc_features(&self, kind: Kind, target: TargetSelection, crates: &[String]) features.push("check_only"); } + if crates.iter().any(|c| c == "rustc_transmute") { + // for `x test rustc_transmute`, this feature isn't enabled automatically by a + // dependent crate. + features.push("rustc"); + } + // If debug logging is on, then we want the default for tracing: // https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26 // which is everything (including debug/trace/etc.)
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index f8af8f3..3ae2373 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -616,4 +616,9 @@ pub fn human_readable_changes(changes: &[ChangeInfo]) -> String { severity: ChangeSeverity::Warning, summary: "`x.py test --no-doc` is renamed to `--all-targets`. Additionally `--tests` is added which only executes unit and integration tests.", }, + ChangeInfo { + change_id: 154508, + severity: ChangeSeverity::Info, + summary: "`x.py` stopped accepting partial argument names. Use full names to avoid errors.", + }, ];
diff --git a/src/build_helper/src/npm.rs b/src/build_helper/src/npm.rs index 2a558b5..311bf8d 100644 --- a/src/build_helper/src/npm.rs +++ b/src/build_helper/src/npm.rs
@@ -1,7 +1,7 @@ use std::error::Error; use std::path::{Path, PathBuf}; use std::process::Command; -use std::{fs, io}; +use std::{env, fs, io}; /// Install all the npm deps, and return the path of `node_modules`. pub fn install(src_root_path: &Path, out_dir: &Path, yarn: &Path) -> Result<PathBuf, io::Error> { @@ -19,7 +19,7 @@ pub fn install(src_root_path: &Path, out_dir: &Path, yarn: &Path) -> Result<Path let mut cmd = Command::new(yarn); cmd.arg("install"); // make sure our `yarn.lock` file actually means something - cmd.arg("--frozen"); + cmd.arg("--frozen-lockfile"); cmd.current_dir(out_dir); let exit_status = cmd @@ -38,5 +38,13 @@ pub fn install(src_root_path: &Path, out_dir: &Path, yarn: &Path) -> Result<Path "yarn install returned exit code {exit_status}" )))); } + if env::var("BOOTSTRAP_SKIP_YARN_LOCK_CHECK").is_err() + && fs::read_to_string(src_root_path.join("yarn.lock"))? + != fs::read_to_string(out_dir.join("yarn.lock"))? + { + return Err(io::Error::other(Box::<dyn Error + Send + Sync>::from(format!( + "yarn lockfile was modified despite --frozen-lockfile. please file a bug report. this check can be bypassed by setting $BOOTSTRAP_SKIP_YARN_LOCK_CHECK`" + )))); + } Ok(nm_path) }
diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index fe1c92f..a208de4 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock
@@ -170,6 +170,7 @@ "clap", "csv", "diff", + "flate2", "glob-match", "insta", "serde", @@ -344,12 +345,13 @@ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -630,6 +632,7 @@ checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -813,6 +816,12 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] name = "similar" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1187,3 +1196,9 @@ "quote", "syn", ] + +[[package]] +name = "zlib-rs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 0b1f2fe7..f97d5e8 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml
@@ -9,6 +9,7 @@ clap = { version = "4.5", features = ["derive"] } csv = "1" diff = "0.1" +flate2 = { version = "1.1.9", default-features = false, features = ["zlib-rs"] } # For feature flag only glob-match = "0.2" serde = { version = "1", features = ["derive"] } serde_yaml = "0.9"
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile index a62f98b..31d009b 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -57,10 +57,9 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV RUST_CONFIGURE_ARGS \ - --musl-root-i586=/musl-i586 \ +ENV RUST_CONFIGURE_ARGS="--musl-root-i586=/musl-i586 \ --musl-root-i686=/musl-i686 \ - --disable-docs + --disable-docs" # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our @@ -73,6 +72,5 @@ ENV TARGETS=i586-unknown-linux-gnu,i686-unknown-linux-musl -ENV SCRIPT \ - python3 ../x.py --stage 2 test --host='' --target $TARGETS && \ - python3 ../x.py dist --host='' --target $TARGETS,i586-unknown-linux-musl +ENV SCRIPT="python3 ../x.py --stage 2 test --host= --target $TARGETS && \ + python3 ../x.py dist --host= --target $TARGETS,i586-unknown-linux-musl"
diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index ea5b208..8165258 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
@@ -70,15 +70,14 @@ ENV HOSTS=i686-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS \ - --enable-full-tools \ +ENV RUST_CONFIGURE_ARGS="--enable-full-tools \ --enable-sanitizers \ --enable-profiler \ --set target.i686-unknown-linux-gnu.linker=clang \ --build=i686-unknown-linux-gnu \ --set llvm.ninja=false \ - --set rust.jemalloc -ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS + --set rust.jemalloc" +ENV SCRIPT="python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS" ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang # This was added when we switched from gcc to clang. It's not clear why this is @@ -89,17 +88,17 @@ # misaligned stack access. # # Added in #50200 there's some more logs there -ENV CFLAGS -mstackrealign +ENV CFLAGS="-mstackrealign" # When we build cargo in this container, we don't want it to use the system # libcurl, instead it should compile its own. -ENV LIBCURL_NO_PKG_CONFIG 1 +ENV LIBCURL_NO_PKG_CONFIG="1" # There was a bad interaction between "old" 32-bit binaries on current 64-bit # kernels with selinux enabled, where ASLR mmap would sometimes choose a low # address and then block it for being below `vm.mmap_min_addr` -> `EACCES`. # This is probably a kernel bug, but setting `ulimit -Hs` works around it. # See also `src/ci/run.sh` where this takes effect. -ENV SET_HARD_RLIMIT_STACK 1 +ENV SET_HARD_RLIMIT_STACK="1" -ENV DIST_REQUIRE_ALL_TOOLS 1 +ENV DIST_REQUIRE_ALL_TOOLS="1"
diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile index 4a090dc..3d7f5f8 100644 --- a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=mips-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile index 18b0375..3c798d7 100644 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=mips64-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile index 8740720..32fd634 100644 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=mips64el-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile index 553f6ea..73ab0cf 100644 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=mipsel-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile index 7081d95..8253924 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=powerpc-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile index 0464062..ad0e210 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile
@@ -26,5 +26,5 @@ ENV HOSTS=powerpc64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile index 7c8a1e6..17783b9 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile
@@ -27,13 +27,12 @@ ENV HOSTS=powerpc64-unknown-linux-musl -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ --disable-docs \ --set target.powerpc64-unknown-linux-musl.crt-static=false \ - --musl-root-powerpc64=/x-tools/powerpc64-unknown-linux-musl/powerpc64-unknown-linux-musl/sysroot/usr + --musl-root-powerpc64=/x-tools/powerpc64-unknown-linux-musl/powerpc64-unknown-linux-musl/sysroot/usr" -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-gnu/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-gnu/Dockerfile index e3ba51e..6a9573c 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-gnu/Dockerfile
@@ -27,11 +27,10 @@ ENV HOSTS=powerpc64le-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ - --disable-docs + --disable-docs" -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/Dockerfile index 601c8e9..be16966 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/Dockerfile
@@ -27,13 +27,12 @@ ENV HOSTS=powerpc64le-unknown-linux-musl -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ --disable-docs \ --set target.powerpc64le-unknown-linux-musl.crt-static=false \ - --musl-root-powerpc64le=/x-tools/powerpc64le-unknown-linux-musl/powerpc64le-unknown-linux-musl/sysroot/usr + --musl-root-powerpc64le=/x-tools/powerpc64le-unknown-linux-musl/powerpc64le-unknown-linux-musl/sysroot/usr" -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index ac169d7..e248e1e 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -124,6 +124,8 @@ ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl ENV TARGETS_SANITIZERS=x86_64-unknown-linux-gnuasan +ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnumsan +ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnutsan # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211 # we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index f42e6f7..e62aa74 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -35,10 +35,9 @@ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS \ - --enable-full-tools \ +ENV RUST_CONFIGURE_ARGS="--enable-full-tools \ --enable-extended \ --enable-profiler \ --enable-sanitizers \ - --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS + --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile index 37a8dc56..0675c3c 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
@@ -36,5 +36,5 @@ ENV HOSTS=x86_64-unknown-illumos -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python2.7 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index cb57478..b168c73 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -80,8 +80,7 @@ ENV HOSTS=x86_64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS \ - --enable-full-tools \ +ENV RUST_CONFIGURE_ARGS="--enable-full-tools \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs \ @@ -94,23 +93,23 @@ --set rust.jemalloc \ --set rust.bootstrap-override-lld=true \ --set rust.lto=thin \ - --set rust.codegen-units=1 + --set rust.codegen-units=1" COPY host-x86_64/dist-x86_64-linux/dist.sh /scripts/ COPY host-x86_64/dist-x86_64-linux/dist-alt.sh /scripts/ -ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" +ENV SCRIPT="Must specify DOCKER_SCRIPT for this image" ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs -ENV DIST_SRC 1 +ENV DIST_SRC="1" # When we build cargo in this container, we don't want it to use the system # libcurl, instead it should compile its own. -ENV LIBCURL_NO_PKG_CONFIG 1 +ENV LIBCURL_NO_PKG_CONFIG="1" -ENV DIST_REQUIRE_ALL_TOOLS 1 +ENV DIST_REQUIRE_ALL_TOOLS="1" # FIXME: Without this, LLVMgold.so incorrectly resolves to the system # libstdc++, instead of the one we build.
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index 32b5058..68f914a 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
@@ -35,14 +35,13 @@ ENV HOSTS=x86_64-unknown-linux-musl -ENV RUST_CONFIGURE_ARGS \ - --musl-root-x86_64=/usr/local/x86_64-linux-musl \ +ENV RUST_CONFIGURE_ARGS="--musl-root-x86_64=/usr/local/x86_64-linux-musl \ --enable-extended \ --enable-sanitizers \ --enable-profiler \ --enable-lld \ --set target.x86_64-unknown-linux-musl.crt-static=false \ - --build $HOSTS + --build $HOSTS" # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our @@ -54,4 +53,4 @@ -Wl,--compress-debug-sections=none" # To run native tests replace `dist` below with `test` -ENV SCRIPT python3 ../x.py dist --build $HOSTS +ENV SCRIPT="python3 ../x.py dist --build $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile index effdc99..3bb2c74 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
@@ -22,5 +22,5 @@ ENV HOSTS=x86_64-unknown-netbsd -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile index 4d77f0a..b11e8cd 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile
@@ -32,5 +32,5 @@ ENV HOSTS=x86_64-pc-solaris -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS"
diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile index be3df9d..fdc296a 100644 --- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
@@ -22,8 +22,8 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests +ENV RUST_CONFIGURE_ARGS="--build=i686-unknown-linux-gnu --disable-optimize-tests" COPY scripts/stage_2_test_set1.sh /scripts/ COPY scripts/stage_2_test_set2.sh /scripts/ COPY scripts/i686-gnu-nopt-2.sh /scripts/ -ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" +ENV SCRIPT="Must specify DOCKER_SCRIPT for this image"
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile index 00cd24b..d0f3d1a 100644 --- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -23,7 +23,7 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu +ENV RUST_CONFIGURE_ARGS="--build=i686-unknown-linux-gnu" COPY scripts/stage_2_test_set1.sh /scripts/ COPY scripts/stage_2_test_set2.sh /scripts/ -ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" +ENV SCRIPT="Must specify DOCKER_SCRIPT for this image"
diff --git a/src/doc/embedded-book b/src/doc/embedded-book index e88aa44..2463ede 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book
@@ -1 +1 @@ -Subproject commit e88aa4403b4bf2071c8df9509160477e40179099 +Subproject commit 2463edeb8003c5743918b3739a9f6870b86396f5
diff --git a/src/doc/reference b/src/doc/reference index c49e89c..7446bf9 160000 --- a/src/doc/reference +++ b/src/doc/reference
@@ -1 +1 @@ -Subproject commit c49e89cc8c7c2c43ca625a8d5b7ad9a53a9ce978 +Subproject commit 7446bf9697c95d155eef33c6a9d91fbd29a5e359
diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 4038f11..a9b4d18 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
@@ -15,7 +15,7 @@ struct Cli { /// Modify files that do not comply overwrite: bool, /// Applies to lines that are to be split - #[arg(long, default_value_t = 100)] + #[arg(long, default_value_t = 80)] line_length_limit: usize, }
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index db94926..a51e46f 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@ -eda4fc7733ee89e484d7120cafbd80dcb2fce66e +562dee4820c458d823175268e41601d4c060588a
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index 56fa49e..0b6bb0d 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -1,6 +1,5 @@ # Updating LLVM -<!-- date-check: Aug 2024 --> Rust supports building against multiple LLVM versions: * Tip-of-tree for the current LLVM development branch is usually supported within a few days. @@ -91,7 +90,6 @@ ## New LLVM Release Updates -<!-- date-check: Jul 2023 --> Unlike bugfixes, updating to a new release of LLVM typically requires a lot more work. @@ -172,12 +170,14 @@ You'll change at least `src/llvm-project` and will likely also change [`llvm-wrapper`] as well. - <!-- date-check: mar 2025 --> + <!-- date-check: March 2026 --> > For prior art, here are some previous LLVM updates: > - [LLVM 17](https://github.com/rust-lang/rust/pull/115959) > - [LLVM 18](https://github.com/rust-lang/rust/pull/120055) > - [LLVM 19](https://github.com/rust-lang/rust/pull/127513) > - [LLVM 20](https://github.com/rust-lang/rust/pull/135763) + > - [LLVM 21](https://github.com/rust-lang/rust/pull/143684) + > - [LLVM 22](https://github.com/rust-lang/rust/pull/150722) Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating `src/llvm-project`.
diff --git a/src/doc/rustc-dev-guide/src/borrow-check/region-inference/member-constraints.md b/src/doc/rustc-dev-guide/src/borrow-check/region-inference/member-constraints.md index 2804c97..21a56da 100644 --- a/src/doc/rustc-dev-guide/src/borrow-check/region-inference/member-constraints.md +++ b/src/doc/rustc-dev-guide/src/borrow-check/region-inference/member-constraints.md
@@ -1,17 +1,18 @@ # Member constraints A member constraint `'m member of ['c_1..'c_N]` expresses that the -region `'m` must be *equal* to some **choice regions** `'c_i` (for -some `i`). These constraints cannot be expressed by users, but they -arise from `impl Trait` due to its lifetime capture rules. Consider a -function such as the following: +region `'m` must be *equal* to some **choice regions** `'c_i` (for some `i`). +These constraints cannot be expressed by users, but they +arise from `impl Trait` due to its lifetime capture rules. +Consider a function such as the following: ```rust,ignore fn make(a: &'a u32, b: &'b u32) -> impl Trait<'a, 'b> { .. } ``` Here, the true return type (often called the "hidden type") is only -permitted to capture the lifetimes `'a` or `'b`. You can kind of see +permitted to capture the lifetimes `'a` or `'b`. +You can kind of see this more clearly by desugaring that `impl Trait` return type into its more explicit form: @@ -23,7 +24,8 @@ Here, the idea is that the hidden type must be some type that could have been written in place of the `impl Trait<'x, 'y>` -- but clearly such a type can only reference the regions `'x` or `'y` (or -`'static`!), as those are the only names in scope. This limitation is +`'static`!), as those are the only names in scope. +This limitation is then translated into a restriction to only access `'a` or `'b` because we are returning `MakeReturn<'a, 'b>`, where `'x` and `'y` have been replaced with `'a` and `'b` respectively. @@ -31,8 +33,8 @@ ## Detailed example To help us explain member constraints in more detail, let's spell out -the `make` example in a bit more detail. First off, let's assume that -you have some dummy trait: +the `make` example in a bit more detail. +First off, let's assume that you have some dummy trait: ```rust,ignore trait Trait<'a, 'b> { } @@ -49,8 +51,8 @@ ``` What happens in this case is that the return type will be `(&'0 u32, &'1 u32)`, -where `'0` and `'1` are fresh region variables. We will have the following -region constraints: +where `'0` and `'1` are fresh region variables. +We will have the following region constraints: ```txt '0 live at {L} @@ -67,11 +69,11 @@ `'1` might have slightly different liveness sets, but that's not very interesting to the point we are illustrating here). -The `'a: '0` and `'b: '1` constraints arise from subtyping. When we -construct the `(a, b)` value, it will be assigned type `(&'0 u32, &'1 +The `'a: '0` and `'b: '1` constraints arise from subtyping. +When we construct the `(a, b)` value, it will be assigned type `(&'0 u32, &'1 u32)` -- the region variables reflect that the lifetimes of these -references could be made smaller. For this value to be created from -`a` and `b`, however, we do require that: +references could be made smaller. +For this value to be created from `a` and `b`, however, we do require that: ```txt (&'a u32, &'b u32) <: (&'0 u32, &'1 u32) @@ -82,35 +84,39 @@ Note that if we ignore member constraints, the value of `'0` would be inferred to some subset of the function body (from the liveness -constraints, which we did not write explicitly). It would never become +constraints, which we did not write explicitly). +It would never become `'a`, because there is no need for it too -- we have a constraint that -`'a: '0`, but that just puts a "cap" on how *large* `'0` can grow to -become. Since we compute the *minimal* value that we can, we are happy -to leave `'0` as being just equal to the liveness set. This is where -member constraints come in. +`'a: '0`, but that just puts a "cap" on how *large* `'0` can grow to become. +Since we compute the *minimal* value that we can, we are happy +to leave `'0` as being just equal to the liveness set. +This is where member constraints come in. ## Choices are always lifetime parameters At present, the "choice" regions from a member constraint are always lifetime -parameters from the current function. As of <!-- date-check --> October 2021, +parameters from the current function. As of <!-- date-check --> March 2026, this falls out from the placement of impl Trait, though in the future it may not -be the case. We take some advantage of this fact, as it simplifies the current -code. In particular, we don't have to consider a case like `'0 member of ['1, +be the case. +We take some advantage of this fact, as it simplifies the current code. +In particular, we don't have to consider a case like `'0 member of ['1, 'static]`, in which the value of both `'0` and `'1` are being inferred and hence -changing. See [rust-lang/rust#61773][#61773] for more information. +changing. +See [rust-lang/rust#61773][#61773] for more information. [#61773]: https://github.com/rust-lang/rust/issues/61773 ## Applying member constraints -Member constraints are a bit more complex than other forms of -constraints. This is because they have a "or" quality to them -- that +Member constraints are a bit more complex than other forms of constraints. +This is because they have a "or" quality to them -- that is, they describe multiple choices that we must select from. E.g., in our example constraint `'0 member of ['a, 'b, 'static]`, it might be -that `'0` is equal to `'a`, `'b`, *or* `'static`. How can we pick the -correct one? What we currently do is to look for a *minimal choice* --- if we find one, then we will grow `'0` to be equal to that minimal -choice. To find that minimal choice, we take two factors into +that `'0` is equal to `'a`, `'b`, *or* `'static`. +How can we pick the correct one? +What we currently do is to look for a *minimal choice* +-- if we find one, then we will grow `'0` to be equal to that minimal choice. +To find that minimal choice, we take two factors into consideration: lower and upper bounds. ### Lower bounds @@ -121,30 +127,34 @@ `'0` because we computed its minimal value (or at least, the lower bounds considering everything but member constraints). -Let `LB` be the current value of `'0`. We know then that `'0: LB` must -hold, whatever the final value of `'0` is. Therefore, we can rule out +Let `LB` be the current value of `'0`. +We know then that `'0: LB` must hold, whatever the final value of `'0` is. +Therefore, we can rule out any choice `'choice` where `'choice: LB` does not hold. -Unfortunately, in our example, this is not very helpful. The lower -bound for `'0` will just be the liveness set `{L}`, and we know that -all the lifetime parameters outlive that set. So we are left with the -same set of choices here. (But in other examples, particularly those +Unfortunately, in our example, this is not very helpful. +The lower bound for `'0` will just be the liveness set `{L}`, and we know that +all the lifetime parameters outlive that set. +So we are left with the same set of choices here. +(But in other examples, particularly those with different variance, lower bound constraints may be relevant.) ### Upper bounds The *upper bounds* are those lifetimes that *must outlive* `'0` -- i.e., that `'0` must be *smaller* than. In our example, this would be -`'a`, because we have the constraint that `'a: '0`. In more complex -examples, the chain may be more indirect. +`'a`, because we have the constraint that `'a: '0`. +In more complex examples, the chain may be more indirect. We can use upper bounds to rule out members in a very similar way to -lower bounds. If UB is some upper bound, then we know that `UB: +lower bounds. +If UB is some upper bound, then we know that `UB: '0` must hold, so we can rule out any choice `'choice` where `UB: 'choice` does not hold. In our example, we would be able to reduce our choice set from `['a, -'b, 'static]` to just `['a]`. This is because `'0` has an upper bound +'b, 'static]` to just `['a]`. +This is because `'0` has an upper bound of `'a`, and neither `'a: 'b` nor `'a: 'static` is known to hold. (For notes on how we collect upper bounds in the implementation, see @@ -153,39 +163,45 @@ ### Minimal choice After applying lower and upper bounds, we can still sometimes have -multiple possibilities. For example, imagine a variant of our example -using types with the opposite variance. In that case, we would have -the constraint `'0: 'a` instead of `'a: '0`. Hence the current value -of `'0` would be `{L, 'a}`. Using this as a lower bound, we would be +multiple possibilities. +For example, imagine a variant of our example +using types with the opposite variance. +In that case, we would have the constraint `'0: 'a` instead of `'a: '0`. +Hence the current value of `'0` would be `{L, 'a}`. +Using this as a lower bound, we would be able to narrow down the member choices to `['a, 'static]` because `'b: -'a` is not known to hold (but `'a: 'a` and `'static: 'a` do hold). We -would not have any upper bounds, so that would be our final set of choices. +'a` is not known to hold (but `'a: 'a` and `'static: 'a` do hold). +We would not have any upper bounds, so that would be our final set of choices. In that case, we apply the **minimal choice** rule -- basically, if -one of our choices if smaller than the others, we can use that. In -this case, we would opt for `'a` (and not `'static`). +one of our choices if smaller than the others, we can use that. +In this case, we would opt for `'a` (and not `'static`). This choice is consistent with the general 'flow' of region propagation, which always aims to compute a minimal value for the -region being inferred. However, it is somewhat arbitrary. +region being inferred. +However, it is somewhat arbitrary. <a id="collecting"></a> ### Collecting upper bounds in the implementation In practice, computing upper bounds is a bit inconvenient, because our -data structures are setup for the opposite. What we do is to compute +data structures are setup for the opposite. +What we do is to compute the **reverse SCC graph** (we do this lazily and cache the result) -- -that is, a graph where `'a: 'b` induces an edge `SCC('b) -> -SCC('a)`. Like the normal SCC graph, this is a DAG. We can then do a -depth-first search starting from `SCC('0)` in this graph. This will -take us to all the SCCs that must outlive `'0`. +that is, a graph where `'a: 'b` induces an edge `SCC('b) -> SCC('a)`. +Like the normal SCC graph, this is a DAG. +We can then do a depth-first search starting from `SCC('0)` in this graph. +This will take us to all the SCCs that must outlive `'0`. One wrinkle is that, as we walk the "upper bound" SCCs, their values -will not yet have been fully computed. However, we **have** already +will not yet have been fully computed. +However, we **have** already applied their liveness constraints, so we have some information about -their value. In particular, for any regions representing lifetime +their value. +In particular, for any regions representing lifetime parameters, their value will contain themselves (i.e., the initial -value for `'a` includes `'a` and the value for `'b` contains `'b`). So -we can collect all of the lifetime parameters that are reachable, +value for `'a` includes `'a` and the value for `'b` contains `'b`). +So we can collect all of the lifetime parameters that are reachable, which is precisely what we are interested in.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index 9a302f9..b5bb44c 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md
@@ -10,7 +10,7 @@ The explanations are written in Markdown (see the [CommonMark Spec] for specifics around syntax), and all of them are linked in the [`rustc_error_codes`] crate. Please read [RFC 1567] for details on how to format and write long error codes. -As of <!-- date-check --> February 2023, there is an +As of <!-- date-check --> March 2026, there is an effort[^new-explanations] to replace this largely outdated RFC with a new more flexible standard. Error explanations should expand on the error message and provide details about
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index 7b98bc6..cda975a 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -3,15 +3,14 @@ This page documents some of the machinery around lint registration and how we run lints in the compiler. -The [`LintStore`] is the central piece of infrastructure, around which -everything rotates. The `LintStore` is held as part of the [`Session`], and it +The [`LintStore`] is the central piece of infrastructure, around which everything rotates. +The `LintStore` is held as part of the [`Session`], and it gets populated with the list of lints shortly after the `Session` is created. ## Lints vs. lint passes -There are two parts to the linting mechanism within the compiler: lints and -lint passes. Unfortunately, a lot of the documentation we have refers to both -of these as just "lints." +There are two parts to the linting mechanism within the compiler: lints and lint passes. +Unfortunately, a lot of the documentation we have refers to both of these as just "lints." First, we have the lint declarations themselves, and this is where the name and default lint level and other metadata come from. @@ -21,14 +20,14 @@ as the macro is somewhat unwieldy to add new fields to, like all macros). -As of <!-- date-check --> Aug 2022, we lint against direct declarations without the use of the macro. Lint declarations don't carry any "state" - they are merely global identifiers -and descriptions of lints. We assert at runtime that they are not registered -twice (by lint name). +and descriptions of lints. +We assert at runtime that they are not registered twice (by lint name). -Lint passes are the meat of any lint. Notably, there is not a one-to-one +Lint passes are the meat of any lint. +Notably, there is not a one-to-one relationship between lints and lint passes; a lint might not have any lint pass that emits it, it could have many, or just one -- the compiler doesn't track whether a pass is in any way associated with a particular lint, and frequently @@ -45,36 +44,33 @@ There are three 'sources' of lints: * internal lints: lints only used by the rustc codebase -* builtin lints: lints built into the compiler and not provided by some outside - source -* `rustc_interface::Config`[`register_lints`]: lints passed into the compiler - during construction +* builtin lints: lints built into the compiler and not provided by some outside source +* `rustc_interface::Config`[`register_lints`]: lints passed into the compiler during construction -Lints are registered via the [`LintStore::register_lint`] function. This should -happen just once for any lint, or an ICE will occur. +Lints are registered via the [`LintStore::register_lint`] function. +This should happen just once for any lint, or an ICE will occur. -Once the registration is complete, we "freeze" the lint store by placing it in -an `Arc`. +Once the registration is complete, we "freeze" the lint store by placing it in an `Arc`. Lint passes are registered separately into one of the categories -(pre-expansion, early, late, late module). Passes are registered as a closure +(pre-expansion, early, late, late module). +Passes are registered as a closure -- i.e., `impl Fn() -> Box<dyn X>`, where `dyn X` is either an early or late -lint pass trait object. When we run the lint passes, we run the closure and -then invoke the lint pass methods. The lint pass methods take `&mut self` so -they can keep track of state internally. +lint pass trait object. +When we run the lint passes, we run the closure and then invoke the lint pass methods. +The lint pass methods take `&mut self` so they can keep track of state internally. #### Internal lints -These are lints used just by the compiler or drivers like `clippy`. They can be -found in [`rustc_lint::internal`]. +These are lints used just by the compiler or drivers like `clippy`. +They can be found in [`rustc_lint::internal`]. An example of such a lint is the check that lint passes are implemented using -the `declare_lint_pass!` macro and not by hand. This is accomplished with the -`LINT_PASS_IMPL_WITHOUT_MACRO` lint. +the `declare_lint_pass!` macro and not by hand. +This is accomplished with the `LINT_PASS_IMPL_WITHOUT_MACRO` lint. Registration of these lints happens in the [`rustc_lint::register_internals`] -function which is called when constructing a new lint store inside -[`rustc_lint::new_lint_store`]. +function which is called when constructing a new lint store inside [`rustc_lint::new_lint_store`]. #### Builtin Lints @@ -84,19 +80,18 @@ and the latter provides the lint pass definitions (and implementations), but this is not always true. -The builtin lint registration happens in -the [`rustc_lint::register_builtins`] function. +The builtin lint registration happens in the [`rustc_lint::register_builtins`] function. Just like with internal lints, this happens inside of [`rustc_lint::new_lint_store`]. #### Driver lints These are the lints provided by drivers via the `rustc_interface::Config` -[`register_lints`] field, which is a callback. Drivers should, if finding it -already set, call the function currently set within the callback they add. The -best way for drivers to get access to this is by overriding the -`Callbacks::config` function which gives them direct access to the `Config` -structure. +[`register_lints`] field, which is a callback. +Drivers should, if finding it +already set, call the function currently set within the callback they add. +The best way for drivers to get access to this is by overriding the +`Callbacks::config` function which gives them direct access to the `Config` structure. ## Compiler lint passes are combined into one pass @@ -106,8 +101,8 @@ individual lint passes; this is because then we get the benefits of static over dynamic dispatch for each of the (often empty) trait methods. -Ideally, we'd not have to do this, since it adds to the complexity of -understanding the code. However, with the current type-erased lint store +Ideally, we'd not have to do this, since it adds to the complexity of understanding the code. +However, with the current type-erased lint store approach, it is beneficial to do so for performance reasons. [`LintStore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html
diff --git a/src/doc/rustc-dev-guide/src/early-late-parameters.md b/src/doc/rustc-dev-guide/src/early-late-parameters.md index 7651dee..d78d533 100644 --- a/src/doc/rustc-dev-guide/src/early-late-parameters.md +++ b/src/doc/rustc-dev-guide/src/early-late-parameters.md
@@ -11,7 +11,8 @@ ## What does it mean to be "early" bound or "late" bound -Every function definition has a corresponding ZST that implements the `Fn*` traits known as a [function item type][function_item_type]. This part of the chapter will talk a little bit about the "desugaring" of function item types as it is useful context for explaining the difference between early bound and late bound generic parameters. +Every function definition has a corresponding ZST that implements the `Fn*` traits known as a [function item type][function_item_type]. +This part of the chapter will talk a little bit about the "desugaring" of function item types as it is useful context for explaining the difference between early bound and late bound generic parameters. Let's start with a very trivial example involving no generic parameters: @@ -36,7 +37,7 @@ A slightly more complicated example would involve introducing generic parameters to the function: ```rust -fn foo<T: Sized>(a: T) -> T { +fn foo<T: Sized>(a: T) -> T { # a /* snip */ } @@ -51,7 +52,8 @@ } ``` -Note that the function item type `FooFnItem` is generic over some type parameter `T` as defined on the function `foo`. However, not all generic parameters defined on functions are also defined on the function item type as demonstrated here: +Note that the function item type `FooFnItem` is generic over some type parameter `T` as defined on the function `foo`. +However, not all generic parameters defined on functions are also defined on the function item type as demonstrated here: ```rust fn foo<'a, T: Sized>(a: &'a T) -> &'a T { # a @@ -71,12 +73,13 @@ The lifetime parameter `'a` from the function `foo` is not present on the function item type `FooFnItem` and is instead introduced on the builtin impl solely for use in representing the argument types. Generic parameters not all being defined on the function item type means that there are two steps where generic arguments are provided when calling a function. -1. Naming the function (e.g. `let a = foo;`) the arguments for `FooFnItem` are provided. +1. Naming the function (e.g. `let a = foo;`) the arguments for `FooFnItem` are provided. 2. Calling the function (e.g. `a(&10);`) any parameters defined on the builtin impl are provided. -This two-step system is where the early vs late naming scheme comes from, early bound parameters are provided in the *earliest* step (naming the function), whereas late bound parameters are provided in the *latest* step (calling the function). +This two-step system is where the early vs late naming scheme comes from, early bound parameters are provided in the *earliest* step (naming the function), whereas late bound parameters are provided in the *latest* step (calling the function). -Looking at the desugaring from the previous example we can tell that `T` is an early bound type parameter and `'a` is a late bound lifetime parameter as `T` is present on the function item type but `'a` is not. See this example of calling `foo` annotated with where each generic parameter has an argument provided: +Looking at the desugaring from the previous example we can tell that `T` is an early bound type parameter and `'a` is a late bound lifetime parameter as `T` is present on the function item type but `'a` is not. +See this example of calling `foo` annotated with where each generic parameter has an argument provided: ```rust fn foo<'a, T: Sized>(a: &'a T) -> &'a T { # a @@ -96,15 +99,17 @@ ## Differences between early and late bound parameters -### Higher ranked function pointers and trait bounds +### Higher ranked function pointers and trait bounds -A generic parameter being late bound allows for more flexible usage of the function item. For example if we have some function `foo` with an early bound lifetime parameter and some function `bar` with a late bound lifetime parameter `'a` we would have the following builtin `Fn` impls: +A generic parameter being late bound allows for more flexible usage of the function item. +For example, if we have some function `foo` with an early bound lifetime parameter and some function `bar` with a late bound lifetime parameter `'a`, we would have the following builtin `Fn` impls: ```rust,ignore impl<'a> Fn<(&'a String,)> for FooFnItem<'a> { /* ... */ } impl<'a> Fn<(&'a String,)> for BarFnItem { /* ... */ } ``` -The `bar` function has a strictly more flexible signature as the function item type can be called with a borrow with *any* lifetime, whereas the `foo` function item type would only be callable with a borrow with the same lifetime on the function item type. We can show this by simply trying to call `foo`'s function item type multiple times with different lifetimes: +The `bar` function has a strictly more flexible signature as the function item type can be called with a borrow with *any* lifetime, whereas the `foo` function item type would only be callable with a borrow with the same lifetime on the function item type. +We can show this by simply trying to call `foo`'s function item type multiple times with different lifetimes: ```rust // The `'a: 'a` bound forces this lifetime to be early bound. @@ -125,9 +130,12 @@ f(&String::new()); ``` -In this example we call `foo`'s function item type twice, each time with a borrow of a temporary. These two borrows could not possible have lifetimes that overlap as the temporaries are only alive during the function call, not after. The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime, as this is not possible the borrow checker errors. +In this example, we call `foo`'s function item type twice, each time with a borrow of a temporary. +These two borrows could not possibly have lifetimes that overlap as the temporaries are only alive during the function call, not after. +The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime, as this is not possible the borrow checker errors. -If the lifetime parameter on `foo` was late bound this would be able to compile as each caller could provide a different lifetime argument for its borrow. See the following example which demonstrates this using the `bar` function defined above: +If the lifetime parameter on `foo` was late bound, this would be able to compile as each caller could provide a different lifetime argument for its borrow. +See the following example, which demonstrates this using the `bar` function defined above: ```rust # fn foo<'a: 'a>(b: &'a String) -> &'a String { b } @@ -143,7 +151,8 @@ b(&String::new()); ``` -This is reflected in the ability to coerce function item types to higher ranked function pointers and prove higher ranked `Fn` trait bounds. We can demonstrate this with the following example: +This is reflected in the ability to coerce function item types to higher ranked function pointers and prove higher ranked `Fn` trait bounds. +We can demonstrate this with the following example: ```rust // The `'a: 'a` bound forces this lifetime to be early bound. fn foo<'a: 'a>(b: &'a String) -> &'a String { b } @@ -163,14 +172,15 @@ fn higher_ranked_fn_ptr() { let bar_fn_item = bar; let fn_ptr: for<'a> fn(&'a String) -> &'a String = bar_fn_item; - + let foo_fn_item = foo::<'_>; // errors let fn_ptr: for<'a> fn(&'a String) -> &'a String = foo_fn_item; } ``` -In both of these cases the borrow checker errors as it does not consider `foo_fn_item` to be callable with a borrow of any lifetime. This is due to the fact that the lifetime parameter on `foo` is early bound, causing `foo_fn_item` to have a type of `FooFnItem<'_>` which (as demonstrated by the desugared `Fn` impl) is only callable with a borrow of the same lifetime `'_`. +In both of these cases, the borrow checker errors as it does not consider `foo_fn_item` to be callable with a borrow of any lifetime. +This is due to the fact that the lifetime parameter on `foo` is early bound, causing `foo_fn_item` to have a type of `FooFnItem<'_>` which (as demonstrated by the desugared `Fn` impl) is only callable with a borrow of the same lifetime `'_`. ### Turbofishing in the presence of late bound parameters @@ -188,15 +198,17 @@ let f /* : FooFnItem<????> */ = foo::<'static>; ``` -The above example errors as the lifetime parameter `'a` is late bound and so cannot be instantiated as part of the "naming a function" step. If we make the lifetime parameter early bound we will see this code start to compile: +The above example errors as the lifetime parameter `'a` is late bound and so cannot be instantiated as part of the "naming a function" step. +If we make the lifetime parameter early bound we will see this code start to compile: ```rust fn foo<'a: 'a>(b: &'a u32) -> &'a u32 { b } let f /* : FooFnItem<'static> */ = foo::<'static>; ``` -What the current implementation of the compiler aims to do is error when specifying lifetime arguments to a function that has both early *and* late bound lifetime parameters. In practice, due to excessive breakage, some cases are actually only future compatibility warnings ([#42868](https://github.com/rust-lang/rust/issues/42868)): -- When the amount of lifetime arguments is the same as the number of early bound lifetime parameters a FCW is emitted instead of an error +What the current implementation of the compiler aims to do is error when specifying lifetime arguments to a function that has both early *and* late bound lifetime parameters. +In practice, due to excessive breakage, some cases are actually only future compatibility warnings ([#42868](https://github.com/rust-lang/rust/issues/42868)): +- When the amount of lifetime arguments is the same as the number of early bound lifetime parameters, a FCW is emitted instead of an error - An error is always downgraded to a FCW when using method call syntax To demonstrate this we can write out the different kinds of functions and give them both a late and early bound lifetime: @@ -287,7 +299,8 @@ free_function::<'static, 'static, 'static>(&(), &()); ``` -Even when specifying enough lifetime arguments for both the late and early bound lifetime parameter, these arguments are not actually used to annotate the lifetime provided to late bound parameters. We can demonstrate this by turbofishing `'static` to a function while providing a non-static borrow: +Even when specifying enough lifetime arguments for both the late and early bound lifetime parameter, these arguments are not actually used to annotate the lifetime provided to late bound parameters. +We can demonstrate this by turbofishing `'static` to a function while providing a non-static borrow: ```rust struct Foo; @@ -302,7 +315,8 @@ ### Liveness of types with late bound parameters -When checking type outlives bounds involving function item types we take into account early bound parameters. For example: +When checking type outlives bounds involving function item types we take into account early bound parameters. +For example: ```rust fn foo<T>(_: T) {} @@ -315,9 +329,11 @@ } ``` -As the type parameter `T` is early bound, the desugaring of the function item type for `foo` would look something like `struct FooFnItem<T>`. Then in order for `FooFnItem<T>: 'static` to hold we must also require `T: 'static` to hold as otherwise we would wind up with soundness bugs. +As the type parameter `T` is early bound, the desugaring of the function item type for `foo` would look something like `struct FooFnItem<T>`. +Then, in order for `FooFnItem<T>: 'static` to hold, we must also require `T: 'static` to hold as otherwise we would wind up with soundness bugs. -Unfortunately, due to bugs in the compiler, we do not take into account early bound *lifetimes*, which is the cause of the open soundness bug [#84366](https://github.com/rust-lang/rust/issues/84366). This means that it's impossible to demonstrate a "difference" between early/late bound parameters for liveness/type outlives bounds as the only kind of generic parameters that are able to be late bound are lifetimes which are handled incorrectly. +Unfortunately, due to bugs in the compiler, we do not take into account early bound *lifetimes*, which is the cause of the open soundness bug [#84366](https://github.com/rust-lang/rust/issues/84366). +This means that it's impossible to demonstrate a "difference" between early/late bound parameters for liveness/type outlives bounds as the only kind of generic parameters that are able to be late bound are lifetimes which are handled incorrectly. Regardless, in theory the code example below *should* demonstrate such a difference once [#84366](https://github.com/rust-lang/rust/issues/84366) is fixed: ```rust @@ -341,17 +357,20 @@ ### Must be a lifetime parameter -Type and Const parameters are not able to be late bound as we do not have a way to support types such as `dyn for<T> Fn(Box<T>)` or `for<T> fn(Box<T>)`. Calling such types requires being able to monomorphize the underlying function which is not possible with indirection through dynamic dispatch. +Type and Const parameters are not able to be late bound as we do not have a way to support types such as `dyn for<T> Fn(Box<T>)` or `for<T> fn(Box<T>)`. +Calling such types requires being able to monomorphize the underlying function which is not possible with indirection through dynamic dispatch. ### Must not be used in a where clause -Currently when a generic parameter is used in a where clause it must be early bound. For example: +Currently when a generic parameter is used in a where clause it must be early bound. +For example: ```rust # trait Trait<'a> {} fn foo<'a, T: Trait<'a>>(_: &'a String, _: T) {} ``` -In this example the lifetime parameter `'a` is considered to be early bound as it appears in the where clause `T: Trait<'a>`. This is true even for "trivial" where clauses such as `'a: 'a` or those implied by wellformedness of function arguments, for example: +In this example the lifetime parameter `'a` is considered to be early bound as it appears in the where clause `T: Trait<'a>`. +This is true even for "trivial" where clauses such as `'a: 'a` or those implied by wellformedness of function arguments, for example: ```rust fn foo<'a: 'a>(_: &'a String) {} fn bar<'a, T: 'a>(_: &'a T) {} @@ -375,9 +394,12 @@ At *some point* during type checking an error should be emitted for this code as `String` does not implement `Trait` for any lifetime. -If the lifetime `'a` were late bound then this becomes difficult to check. When naming `foo` we do not know what lifetime should be used as part of the `T: Trait<'a>` trait bound as it has not yet been instantiated. When coercing the function item type to a function pointer we have no way of tracking the `String: Trait<'a>` trait bound that must be proven when calling the function. +If the lifetime `'a` were late bound then this becomes difficult to check. +When naming `foo` we do not know what lifetime should be used as part of the `T: Trait<'a>` trait bound as it has not yet been instantiated. +When coercing the function item type to a function pointer we have no way of tracking the `String: Trait<'a>` trait bound that must be proven when calling the function. -If the lifetime `'a` is early bound (which it is in the current implementation in rustc), then the trait bound can be checked when naming the function `foo`. Requiring parameters used in where clauses to be early bound gives a natural place to check where clauses defined on the function. +If the lifetime `'a` is early bound (which it is in the current implementation in rustc), then the trait bound can be checked when naming the function `foo`. +Requiring parameters used in where clauses to be early bound gives a natural place to check where clauses defined on the function. Finally, we do not require lifetimes to be early bound if they are used in *implied bounds*, for example: ```rust @@ -388,11 +410,13 @@ f(&String::new()); ``` -This code compiles, demonstrating that the lifetime parameter is late bound, even though `'a` is used in the type `&'a T` which implicitly requires `T: 'a` to hold. Implied bounds can be treated specially as any types introducing implied bounds are in the signature of the function pointer type, which means that when calling the function we know to prove `T: 'a`. +This code compiles, demonstrating that the lifetime parameter is late bound, even though `'a` is used in the type `&'a T` which implicitly requires `T: 'a` to hold. +Implied bounds can be treated specially as any types introducing implied bounds are in the signature of the function pointer type, which means that when calling the function we know to prove `T: 'a`. ### Must be constrained by argument types -It is important that builtin impls on function item types do not wind up with unconstrained generic parameters as this can lead to unsoundness. This is the same kind of restriction as applies to user written impls, for example the following code results in an error: +It is important that builtin impls on function item types do not wind up with unconstrained generic parameters as this can lead to unsoundness. +This is the same kind of restriction as applies to user written impls, for example the following code results in an error: ```rust trait Trait { type Assoc;
diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index f83aaa6..c4e0663 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md
@@ -11,7 +11,8 @@ As of <!-- date-check --> November 2024, most of the rust compiler is now parallelized. -- The codegen part is executed concurrently by default. You can use the `-C +- The codegen part is executed concurrently by default. + You can use the `-C codegen-units=n` option to control the number of concurrent tasks. - The parts after HIR lowering to codegen such as type checking, borrowing checking, and mir optimization are parallelized in the nightly version. @@ -31,17 +32,19 @@ ## Code generation During monomorphization the compiler splits up all the code to -be generated into smaller chunks called _codegen units_. These are then generated by -independent instances of LLVM running in parallel. At the end, the linker -is run to combine all the codegen units together into one binary. This process -occurs in the [`rustc_codegen_ssa::base`] module. +be generated into smaller chunks called _codegen units_. +These are then generated by independent instances of LLVM running in parallel. +At the end, the linker +is run to combine all the codegen units together into one binary. +This process occurs in the [`rustc_codegen_ssa::base`] module. [`rustc_codegen_ssa::base`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/index.html ## Data structures The underlying thread-safe data-structures used in the parallel compiler -can be found in the [`rustc_data_structures::sync`] module. These data structures +can be found in the [`rustc_data_structures::sync`] module. +These data structures are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | @@ -61,21 +64,25 @@ or the authoring of persistent documentation covering the specific of the invariants, the atomicity, and the lock orderings. -- On the other hand, we still need to figure out what other invariants +- On the other hand, we still need to figure out what other invariants during compilation might not hold in parallel compilation. [`rustc_data_structures::sync`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sync/index.html ### WorkerLocal -[`WorkerLocal`] is a special data structure implemented for parallel compilers. It -holds worker-locals values for each thread in a thread pool. You can only +[`WorkerLocal`] is a special data structure implemented for parallel compilers. +It holds worker-locals values for each thread in a thread pool. +You can only access the worker local value through the `Deref` `impl` on the thread pool it -was constructed on. It panics otherwise. +was constructed on. +It panics otherwise. `WorkerLocal` is used to implement the `Arena` allocator in the parallel -environment, which is critical in parallel queries. Its implementation is -located in the [`rustc_data_structures::sync::worker_local`] module. However, +environment, which is critical in parallel queries. +Its implementation is +located in the [`rustc_data_structures::sync::worker_local`] module. +However, in the non-parallel compiler, it is implemented as `(OneThread<T>)`, whose `T` can be accessed directly through `Deref::deref`. @@ -85,10 +92,11 @@ ## Parallel iterator The parallel iterators provided by the [`rayon`] crate are easy ways to -implement parallelism. In the current implementation of the parallel compiler -we use a custom [fork][rustc-rayon] of `rayon` to run tasks in parallel. +implement parallelism. +In the current implementation of the parallel compiler, +we use [a custom fork of `rayon`][rustc-rayon] to run tasks in parallel. -Some iterator functions are implemented to run loops in parallel +Some iterator functions are implemented to run loops in parallel when `parallel-compiler` is true. | Function(Omit `Send` and `Sync`) | Introduction | Owning Module | @@ -142,15 +150,17 @@ start evaluating. - If there *is* another query invocation for the same key in progress, we release the lock, and just block the thread until the other invocation has - computed the result we are waiting for. **Cycle error detection** in the parallel - compiler requires more complex logic than in single-threaded mode. When - worker threads in parallel queries stop making progress due to interdependence, - the compiler uses an extra thread *(named deadlock handler)* to detect, remove and + computed the result we are waiting for. + **Cycle error detection** in the parallel + compiler requires more complex logic than in single-threaded mode. + When + worker threads in parallel queries stop making progress due to interdependence, + the compiler uses an extra thread *(named deadlock handler)* to detect, remove and report the cycle error. The parallel query feature still has implementation to do, most of which is -related to the previous `Data Structures` and `Parallel Iterators`. See [this -open feature tracking issue][tracking]. +related to the previous `Data Structures` and `Parallel Iterators`. +See [this open feature tracking issue][tracking]. ## Rustdoc
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index 014d1a0..d68c90f 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
@@ -479,11 +479,11 @@ and the projection queries act as a "firewall", shielding their dependents from the unconditionally red `no_hash` node. - - `cache_on_disk_if` - This attribute is what determines which query results - are persisted in the incremental compilation query result cache. - The attribute takes an expression that allows per query invocation decisions. - For example, it makes no sense to store values from upstream - crates in the cache because they are already available in the upstream crate's metadata. + - `cache_on_disk` - The query's return values are cached to disk, and can be + loaded by subsequent sessions if the corresponding dep node is green. + If the `separate_provide_extern` modifier is also present, values will only + be cached to disk for "local" keys, because values for external crates should + be loadable from crate metadata instead. [mod]: ../query.html#adding-a-new-kind-of-query
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 680393a..df0c21c 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md
@@ -275,8 +275,9 @@ rustc_queries! { /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { - cache_on_disk_if { key.is_local() } desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } + cache_on_disk + separate_provide_extern } ... }
diff --git a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md index 4615234..7fc3926 100644 --- a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md +++ b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md
@@ -1,16 +1,23 @@ # Candidate preference -There are multiple ways to prove `Trait` and `NormalizesTo` goals. Each such option is called a [`Candidate`]. If there are multiple applicable candidates, we prefer some candidates over others. We store the relevant information in their [`CandidateSource`]. +There are multiple ways to prove `Trait` and `NormalizesTo` goals. +Each such option is called a [`Candidate`]. +If there are multiple applicable candidates, we prefer some candidates over others. +We store the relevant information in their [`CandidateSource`]. -This preference may result in incorrect inference or region constraints and would therefore be unsound during coherence. Because of this, we simply try to merge all candidates in coherence. +This preference may result in incorrect inference or region constraints and would therefore be unsound during coherence. +Because of this, we simply try to merge all candidates in coherence. ## `Trait` goals -Trait goals merge their applicable candidates in [`fn merge_trait_candidates`]. This document provides additional details and references to explain *why* we've got the current preference rules. +Trait goals merge their applicable candidates in [`fn merge_trait_candidates`]. +This document provides additional details and references to explain *why* we've got the current preference rules. ### `CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))` -Trivial builtin impls are builtin impls which are known to be always applicable for well-formed types. This means that if one exists, using another candidate should never have fewer constraints. We currently only consider `Sized` - and `MetaSized` - impls to be trivial. +Trivial builtin impls are builtin impls which are known to be always applicable for well-formed types. +This means that if one exists, using another candidate should never have fewer constraints. +We currently only consider `Sized` - and `MetaSized` - impls to be trivial. This is necessary to prevent a lifetime error for the following pattern @@ -25,7 +32,7 @@ { // Elaborating the `&'a str: Trait<T>` where-bound results in a // `&'a str: Sized` where-bound. We do not want to prefer this - // over the builtin impl. + // over the builtin impl. is_sized(x); } ``` @@ -50,7 +57,8 @@ ### `CandidateSource::ParamEnv` Once there's at least one *non-global* `ParamEnv` candidate, we prefer *all* `ParamEnv` candidates over other candidate kinds. -A where-bound is global if it is not higher-ranked and doesn't contain any generic parameters. It may contain `'static`. +A where-bound is global if it is not higher-ranked and doesn't contain any generic parameters. +It may contain `'static`. We try to apply where-bounds over other candidates as users tends to have the most control over them, so they can most easily adjust them in case our candidate preference is incorrect. @@ -68,7 +76,8 @@ } ``` -We also need this as shadowed impls can result in currently ambiguous solver cycles: [trait-system-refactor-initiative#76]. Without preference we'd be forced to fail with ambiguity +We also need this as shadowed impls can result in currently ambiguous solver cycles: [trait-system-refactor-initiative#76]. +Without preference, we'd be forced to fail with ambiguity errors if the where-bound results in region constraints to avoid incompleteness. ```rust trait Super { @@ -89,13 +98,15 @@ fn overflow<T: Trait>() { // We can use the elaborated `Super<SuperAssoc = Self::TraitAssoc>` where-bound // to prove the where-bound of the `T: Trait` implementation. This currently results in - // overflow. + // overflow. let x: <T as Trait>::TraitAssoc; } ``` -This preference causes a lot of issues. See [#24066]. Most of the -issues are caused by preferring where-bounds over impls even if the where-bound guides type inference: +This preference causes a lot of issues. +See [#24066]. +Most of the +issues are caused by preferring where-bounds over impls even, if the where-bound guides type inference: ```rust trait Trait<T> { fn call_me(&self, x: T) {} @@ -167,7 +178,10 @@ #### Why no preference for global where-bounds -Global where-bounds are either fully implied by an impl or unsatisfiable. If they are unsatisfiable, we don't really care what happens. If a where-bound is fully implied then using the impl to prove the trait goal cannot result in additional constraints. For trait goals this is only useful for where-bounds which use `'static`: +Global where-bounds are either fully implied by an impl or unsatisfiable. +If they are unsatisfiable, we don't really care what happens. +If a where-bound is fully implied, then using the impl to prove the trait goal cannot result in additional constraints. +For trait goals, this is only useful for where-bounds which use `'static`: ```rust trait A { @@ -181,13 +195,15 @@ x.test(); } ``` -More importantly, by using impls here we prevent global where-bounds from shadowing impls when normalizing associated types. There are no known issues from preferring impls over global where-bounds. +More importantly, by using impls here, we prevent global where-bounds from shadowing impls when normalizing associated types. +There are no known issues from preferring impls over global where-bounds. #### Why still consider global where-bounds Given that we just use impls even if there exists a global where-bounds, you may ask why we don't just ignore these global where-bounds entirely: we use them to weaken the inference guidance from non-global where-bounds. -Without a global where-bound, we currently prefer non-global where bounds even though there would be an applicable impl as well. By adding a non-global where-bound, this unnecessary inference guidance is disabled, allowing the following to compile: +Without a global where-bound, we currently prefer non-global where bounds even though there would be an applicable impl as well. +By adding a non-global where-bound, this unnecessary inference guidance is disabled, allowing the following to compile: ```rust fn check<Color>(color: Color) where @@ -209,7 +225,9 @@ ### `CandidateSource::AliasBound` -We prefer alias-bound candidates over impls. We currently use this preference to guide type inference, causing the following to compile. I personally don't think this preference is desirable 🤷 +We prefer alias-bound candidates over impls. +We currently use this preference to guide type inference, causing the following to compile. +I personally don't think this preference is desirable 🤷 ```rust pub trait Dyn { type Word: Into<u64>; @@ -254,7 +272,9 @@ ### `CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_))` -We prefer builtin trait object impls over user-written impls. This is **unsound** and should be remoed in the future. See [#57893](https://github.com/rust-lang/rust/issues/57893) and [#141347](https://github.com/rust-lang/rust/pull/141347) for more details. +We prefer builtin trait object impls over user-written impls. +This is **unsound** and should be remoed in the future. +See [#57893] and [#141347] for more details. ## `NormalizesTo` goals @@ -336,7 +356,7 @@ #### We prefer "orphaned" where-bounds We add "orphaned" `Projection` clauses into the `ParamEnv` when normalizing item bounds of GATs and RPITIT in `fn check_type_bounds`. -We need to prefer these `ParamEnv` candidates over impls and other where-bounds. +We need to prefer these `ParamEnv` candidates over impls and other where-bounds. ```rust #![feature(associated_type_defaults)] trait Foo { @@ -355,7 +375,8 @@ #### We prefer global where-bounds over impls -This is necessary for the following to compile. I don't know whether anything relies on it in practice 🤷 +This is necessary for the following to compile. +I don't know whether anything relies on it in practice 🤷 ```rust trait Id { type This; @@ -423,7 +444,8 @@ #### RPITIT `type_of` cycles -We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788]. +We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. +It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788]. ```rust use std::future::Future; @@ -454,6 +476,31 @@ } ``` +<!-- date-check: Mar 2026 --> +#### Trait definition cannot use associated types from always applicable impls + +The `T: Trait` assumption in the trait definition prevents it from normalizing +`<Self as Trait>::Assoc` to `T` by using the blanket impl. +This feels like a somewhat desirable constraint, if not incredibly so. + +```rust +trait Eq<T> {} +impl<T> Eq<T> for T {} +struct IsEqual<T: Eq<U>, U>(T, U); + +trait Trait: Sized { + type Assoc; + fn foo() -> IsEqual<Self, Self::Assoc> { + //~^ ERROR the trait bound `Self: Eq<<Self as Trait>::Assoc>` is not satisfied + todo!() + } +} + +impl<T> Trait for T { + type Assoc = T; +} +``` + [`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/struct.Candidate.html [`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/enum.CandidateSource.html [`fn merge_trait_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L1342-L1424 @@ -462,4 +509,6 @@ [#24066]: https://github.com/rust-lang/rust/issues/24066 [#133044]: https://github.com/rust-lang/rust/issues/133044 [#139762]: https://github.com/rust-lang/rust/pull/139762 -[#139788]: https://github.com/rust-lang/rust/issues/139788 \ No newline at end of file +[#139788]: https://github.com/rust-lang/rust/issues/139788 +[#57893]: https://github.com/rust-lang/rust/issues/57893 +[#141347]: https://github.com/rust-lang/rust/pull/141347
diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 5161194..5581b7e 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md
@@ -109,11 +109,13 @@ At any given time, at most a single `auto` build is being executed. Find out more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). -Normally, when an auto job fails, the whole CI workflow immediately ends. However, it can be useful to +Normally, when an auto job fails, the whole CI workflow immediately ends. +However, it can be useful to create auto jobs that are "non-blocking", or optional, to test them on CI for some time before blocking -merges on them. This can be useful if those jobs can be flaky. +merges on them. +This can be useful if those jobs can be flaky. -To do that, prefix such a job with `optional-`, and set `continue_on_error: true` for it in [`jobs.yml`]. +To do that, prefix such a job with `optional-`, and set `continue_on_error: true` for it in [`jobs.yml`]. [platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support [auto]: https://github.com/rust-lang/rust/tree/automation/bors/auto
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9049828..cc10f47 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md
@@ -155,5 +155,7 @@ - [x86_64-unknown-linux-none](platform-support/x86_64-unknown-linux-none.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [x86_64-unknown-linux-gnuasan](platform-support/x86_64-unknown-linux-gnuasan.md) + - [x86_64-unknown-linux-gnumsan](platform-support/x86_64-unknown-linux-gnumsan.md) + - [x86_64-unknown-linux-gnutsan](platform-support/x86_64-unknown-linux-gnutsan.md) - [xtensa-\*-none-elf](platform-support/xtensa.md) - [\*-nuttx-\*](platform-support/nuttx.md)
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index 1502e69..1e5822d 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -194,7 +194,7 @@ INSTALL_TOOLCHAIN = ["rustup", "toolchain", "install", "--profile", "minimal"] subprocess.run(INSTALL_TOOLCHAIN + ["nightly"]) -LOWER_BOUND = 87 +LOWER_BOUND = 91 NIGHTLY_VERSION = minor_version(subprocess.run( ["rustc", "+nightly", "--version"], capture_output=True, @@ -256,6 +256,6 @@ | 1.78 - 1.81 | 18 | | 1.82 - 1.86 | 19 | | 1.87 - 1.90 | 20 | -| 1.91 - 1.93 | 21 | +| 1.91 - 1.94 | 21 | Note that the compatibility policy for this feature might change in the future.
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index a8b2111..26dd6b3 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md
@@ -216,6 +216,8 @@ [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android [`x86_64-unknown-linux-gnuasan`](platform-support/x86_64-unknown-linux-gnuasan.md) | ✓ | 64-bit Linux (kernel 3.2+, glibc 2.17+) with ASAN enabled by default +[`x86_64-unknown-linux-gnumsan`](platform-support/x86_64-unknown-linux-gnumsan.md) | ✓ | 64-bit Linux (kernel 3.2+, glibc 2.17+) with MSAN enabled by default +[`x86_64-unknown-linux-gnutsan`](platform-support/x86_64-unknown-linux-gnutsan.md) | ✓ | 64-bit Linux (kernel 3.2+, glibc 2.17+) with TSAN enabled by default [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15+, glibc 2.27) [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnumsan.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnumsan.md new file mode 100644 index 0000000..3b56436 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnumsan.md
@@ -0,0 +1,56 @@ +# `x86_64-unknown-linux-gnumsan` + +**Tier: 2** + +Target mirroring `x86_64-unknown-linux-gnu` with MemorySanitizer enabled by +default. +The goal of this target is to allow shipping MSAN-instrumented standard +libraries through rustup, enabling a fully instrumented binary without requiring +nightly features (build-std). +Once build-std stabilizes, this target is no longer needed and will be removed. + +## Target maintainers + +- [@jakos-sec](https://github.com/jakos-sec) +- [@1c3t3a](https://github.com/1c3t3a) +- [@rust-lang/project-exploit-mitigations][project-exploit-mitigations] + +## Requirements + +The target is for cross-compilation only. Host tools are not supported, since +there is no need to have the host tools instrumented with MSAN. std is fully +supported. + +In all other aspects the target is equivalent to `x86_64-unknown-linux-gnu`. + +## Building the target + +The target can be built by enabling it for a rustc build: + +```toml +[build] +target = ["x86_64-unknown-linux-gnumsan"] +``` + +## Building Rust programs + +Rust programs can be compiled by adding this target via rustup: + +```sh +$ rustup target add x86_64-unknown-linux-gnumsan +``` + +and then compiling with the target: + +```sh +$ rustc foo.rs --target x86_64-unknown-linux-gnumsan +``` + +## Testing + +Created binaries will run on Linux without any external requirements. + +## Cross-compilation toolchains and C code + +The target supports C code and should use the same toolchain target as +`x86_64-unknown-linux-gnu`.
diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnutsan.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnutsan.md new file mode 100644 index 0000000..71488f4 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-gnutsan.md
@@ -0,0 +1,56 @@ +# `x86_64-unknown-linux-gnutsan` + +**Tier: 2** + +Target mirroring `x86_64-unknown-linux-gnu` with ThreadSanitizer enabled by +default. +The goal of this target is to allow shipping TSAN-instrumented standard +libraries through rustup, enabling a fully instrumented binary without requiring +nightly features (build-std). +Once build-std stabilizes, this target is no longer needed and will be removed. + +## Target maintainers + +- [@jakos-sec](https://github.com/jakos-sec) +- [@1c3t3a](https://github.com/1c3t3a) +- [@rust-lang/project-exploit-mitigations][project-exploit-mitigations] + +## Requirements + +The target is for cross-compilation only. Host tools are not supported, since +there is no need to have the host tools instrumented with TSAN. std is fully +supported. + +In all other aspects the target is equivalent to `x86_64-unknown-linux-gnu`. + +## Building the target + +The target can be built by enabling it for a rustc build: + +```toml +[build] +target = ["x86_64-unknown-linux-gnutsan"] +``` + +## Building Rust programs + +Rust programs can be compiled by adding this target via rustup: + +```sh +$ rustup target add x86_64-unknown-linux-gnutsan +``` + +and then compiling with the target: + +```sh +$ rustc foo.rs --target x86_64-unknown-linux-gnutsan +``` + +## Testing + +Created binaries will run on Linux without any external requirements. + +## Cross-compilation toolchains and C code + +The target supports C code and should use the same toolchain target as +`x86_64-unknown-linux-gnu`.
diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index c05077b..9dee33e 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md
@@ -190,6 +190,16 @@ pub fn no_code_example() {} ``` +This lint is not emitted on the following items: + + * Impl blocks (both trait and inherent) + * Enum variants + * Struct/union fields + * Type aliases, including associated types + * Statics/constants + * Modules (including the top-level module of a crate) + * Foreign items from reexports (functions, statics, types, etc) + ## `private_doc_tests` This lint is **allowed by default**. It detects documentation tests when they
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 1771d13..eb070c2 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -22,6 +22,8 @@ * [AddressSanitizer](#addresssanitizer) a fast memory error detector. * [HWAddressSanitizer](#hwaddresssanitizer) a memory error detector similar to AddressSanitizer, but based on partial hardware assistance. + * [KernelHWAddressSanitizer](#kernelhwaddresssanitizer) variant of + HWAddressSanitizer that is designed for bare metal environments. * [LeakSanitizer](#leaksanitizer) a run-time memory leak detector. * [MemorySanitizer](#memorysanitizer) a detector of uninitialized reads. * [RealtimeSanitizer](#realtimesanitizer) a detector of calls to function with @@ -622,6 +624,16 @@ SUMMARY: HWAddressSanitizer: tag-mismatch (/.../main+0x54a94) ``` +# KernelHWAddressSanitizer + +KernelHWAddressSanitizer is the kernel version of [HWAddressSanitizer](#hwaddresssanitizer), +which achieves the same purpose but is designed for bare-metal environments. + +HWAddressSanitizer is supported on the `aarch64*-unknown-none` and +`aarch64*-unknown-none-softfloat` targets. + +See the [Clang HWAddressSanitizer documentation][clang-hwasan] for more details. + # KernelControlFlowIntegrity The LLVM Kernel Control Flow Integrity (CFI) support to the Rust compiler
diff --git a/src/doc/unstable-book/src/language-features/try-blocks.md b/src/doc/unstable-book/src/language-features/try-blocks.md index e342c26..f72467f 100644 --- a/src/doc/unstable-book/src/language-features/try-blocks.md +++ b/src/doc/unstable-book/src/language-features/try-blocks.md
@@ -1,8 +1,8 @@ # `try_blocks` -The tracking issue for this feature is: [#31436] +The tracking issue for this feature is: [#154391] -[#31436]: https://github.com/rust-lang/rust/issues/31436 +[#154391]: https://github.com/rust-lang/rust/issues/154391 ------------------------ @@ -14,14 +14,14 @@ use std::num::ParseIntError; -let result: Result<i32, ParseIntError> = try { +let result = try { "1".parse::<i32>()? + "2".parse::<i32>()? + "3".parse::<i32>()? }; assert_eq!(result, Ok(6)); -let result: Result<i32, ParseIntError> = try { +let result = try { "1".parse::<i32>()? + "foo".parse::<i32>()? + "3".parse::<i32>()?
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 3ec2bc3..ee03431 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs
@@ -3,6 +3,7 @@ // FIXME: Once the portability lint RFC is implemented (see tracking issue #41619), // switch to use those structures instead. +use std::str::FromStr; use std::sync::Arc; use std::{fmt, mem, ops}; @@ -15,6 +16,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; +use rustc_target::spec; use crate::display::{Joined as _, MaybeDisplay, Wrapped}; use crate::html::escape::Escape; @@ -421,54 +423,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { (sym::unix, None) => "Unix", (sym::windows, None) => "Windows", (sym::debug_assertions, None) => "debug-assertions enabled", - (sym::target_os, Some(os)) => match os.as_str() { - "android" => "Android", - "cygwin" => "Cygwin", - "dragonfly" => "DragonFly BSD", - "emscripten" => "Emscripten", - "freebsd" => "FreeBSD", - "fuchsia" => "Fuchsia", - "haiku" => "Haiku", - "hermit" => "Hermit", - "illumos" => "illumos", - "ios" => "iOS", - "l4re" => "L4Re", - "linux" => "Linux", - "macos" => "macOS", - "netbsd" => "NetBSD", - "openbsd" => "OpenBSD", - "redox" => "Redox", - "solaris" => "Solaris", - "tvos" => "tvOS", - "wasi" => "WASI", - "watchos" => "watchOS", - "windows" => "Windows", - "visionos" => "visionOS", - _ => "", - }, - (sym::target_arch, Some(arch)) => match arch.as_str() { - "aarch64" => "AArch64", - "arm" => "ARM", - "loongarch32" => "LoongArch LA32", - "loongarch64" => "LoongArch LA64", - "m68k" => "M68k", - "csky" => "CSKY", - "mips" => "MIPS", - "mips32r6" => "MIPS Release 6", - "mips64" => "MIPS-64", - "mips64r6" => "MIPS-64 Release 6", - "msp430" => "MSP430", - "powerpc" => "PowerPC", - "powerpc64" => "PowerPC-64", - "riscv32" => "RISC-V RV32", - "riscv64" => "RISC-V RV64", - "s390x" => "s390x", - "sparc64" => "SPARC64", - "wasm32" | "wasm64" => "WebAssembly", - "x86" => "x86", - "x86_64" => "x86-64", - _ => "", - }, + (sym::target_os, Some(os)) => human_readable_target_os(*os).unwrap_or_default(), + (sym::target_arch, Some(arch)) => { + human_readable_target_arch(*arch).unwrap_or_default() + } (sym::target_vendor, Some(vendor)) => match vendor.as_str() { "apple" => "Apple", "pc" => "PC", @@ -476,15 +434,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { "fortanix" => "Fortanix", _ => "", }, - (sym::target_env, Some(env)) => match env.as_str() { - "gnu" => "GNU", - "msvc" => "MSVC", - "musl" => "musl", - "newlib" => "Newlib", - "uclibc" => "uClibc", - "sgx" => "SGX", - _ => "", - }, + (sym::target_env, Some(env)) => { + human_readable_target_env(*env).unwrap_or_default() + } (sym::target_endian, Some(endian)) => { return write!(fmt, "{endian}-endian"); } @@ -527,6 +479,135 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { } } +fn human_readable_target_os(os: Symbol) -> Option<&'static str> { + let os = spec::Os::from_str(os.as_str()).ok()?; + + use spec::Os::*; + Some(match os { + // tidy-alphabetical-start + Aix => "AIX", + AmdHsa => "AMD HSA", + Android => "Android", + Cuda => "CUDA", + Cygwin => "Cygwin", + Dragonfly => "DragonFly BSD", + Emscripten => "Emscripten", + EspIdf => "ESP-IDF", + FreeBsd => "FreeBSD", + Fuchsia => "Fuchsia", + Haiku => "Haiku", + HelenOs => "HelenOS", + Hermit => "Hermit", + Horizon => "Horizon", + Hurd => "GNU/Hurd", + IOs => "iOS", + Illumos => "illumos", + L4Re => "L4Re", + Linux => "Linux", + LynxOs178 => "LynxOS-178", + MacOs => "macOS", + Managarm => "Managarm", + Motor => "Motor OS", + NetBsd => "NetBSD", + None => "bare-metal", // FIXME(scrabsha): is this appropriate? + Nto => "QNX Neutrino", + NuttX => "NuttX", + OpenBsd => "OpenBSD", + Psp => "Play Station Portable", + Psx => "Play Station 1", + Qurt => "QuRT", + Redox => "Redox OS", + Rtems => "RTEMS OS", + Solaris => "Solaris", + SolidAsp3 => "SOLID ASP3", + TeeOs => "TEEOS", + Trusty => "Trusty", + TvOs => "tvOS", + Uefi => "UEFI", + VexOs => "VEXos", + VisionOs => "visionOS", + Vita => "Play Station Vita", + VxWorks => "VxWorks", + Wasi => "WASI", + WatchOs => "watchOS", + Windows => "Windows", + Xous => "Xous", + Zkvm => "zero knowledge Virtual Machine", + // tidy-alphabetical-end + Unknown | Other(_) => return Option::None, + }) +} + +fn human_readable_target_arch(os: Symbol) -> Option<&'static str> { + let arch = spec::Arch::from_str(os.as_str()).ok()?; + + use spec::Arch::*; + Some(match arch { + // tidy-alphabetical-start + AArch64 => "AArch64", + AmdGpu => "AMG GPU", + Arm => "ARM", + Arm64EC => "ARM64EC", + Avr => "AVR", + Bpf => "BPF", + CSky => "C-SKY", + Hexagon => "Hexagon", + LoongArch32 => "LoongArch64", + LoongArch64 => "LoongArch32", + M68k => "Motorola 680x0", + Mips => "MIPS", + Mips32r6 => "MIPS release 6", + Mips64 => "MIPS-64", + Mips64r6 => "MIPS-64 release 6", + Msp430 => "MSP430", + Nvptx64 => "NVidia GPU", + PowerPC => "PowerPC", + PowerPC64 => "PowerPC64", + RiscV32 => "RISC-V RV32", + RiscV64 => "RISC-V RV64", + S390x => "s390x", + Sparc => "SPARC", + Sparc64 => "SPARC-64", + SpirV => "SPIR-V", + Wasm32 | Wasm64 => "WebAssembly", + X86 => "x86", + X86_64 => "x86-64", + Xtensa => "Xtensa", + // tidy-alphabetical-end + Other(_) => return None, + }) +} + +fn human_readable_target_env(env: Symbol) -> Option<&'static str> { + let env = spec::Env::from_str(env.as_str()).ok()?; + + use spec::Env::*; + Some(match env { + // tidy-alphabetical-start + Gnu => "GNU", + MacAbi => "Catalyst", + Mlibc => "mac ABI", + Msvc => "MSVC", + Musl => "musl", + Newlib => "Newlib", + Nto70 => "Neutrino 7.0", + Nto71 => "Neutrino 7.1", + Nto71IoSock => "Neutrino 7.1 with io-sock", + Nto80 => "Neutrino 8.0", + Ohos => "OpenHarmony", + P1 => "WASIp1", + P2 => "WASIp2", + P3 => "WASIp3", + Relibc => "relibc", + Sgx => "SGX", + Sim => "Simulator", + Uclibc => "uClibc", + V5 => "V5", + // tidy-alphabetical-end + Unspecified | Other(_) => return None, + }) +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] struct NameValueCfg { name: Symbol,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 13a9c78..f543394 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs
@@ -2776,7 +2776,12 @@ fn get_name( // These kinds of item either don't need a `name` or accept a `None` one so we handle them // before. match item.kind { - ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), + ItemKind::Impl(ref impl_) => { + // If `renamed` is `Some()` for an `impl`, it means it's been inlined because we use + // it as a marker to indicate that this is an inlined impl and that we should + // generate an impl placeholder and not a "real" impl item. + return clean_impl(impl_, item.owner_id.def_id, cx, renamed.is_some()); + } ItemKind::Use(path, kind) => { return clean_use_statement( item, @@ -2909,10 +2914,27 @@ fn clean_impl<'tcx>( impl_: &hir::Impl<'tcx>, def_id: LocalDefId, cx: &mut DocContext<'tcx>, + // If true, this is an inlined impl and it will be handled later on in the code. + // In here, we will generate a placeholder for it in order to be able to compute its + // `doc_cfg` info. + is_inlined: bool, ) -> Vec<Item> { let tcx = cx.tcx; let mut ret = Vec::new(); - let trait_ = impl_.of_trait.map(|t| clean_trait_ref(&t.trait_ref, cx)); + let trait_ = match impl_.of_trait { + Some(t) => { + if is_inlined { + return vec![Item::from_def_id_and_parts( + def_id.to_def_id(), + None, + PlaceholderImplItem, + cx, + )]; + } + Some(clean_trait_ref(&t.trait_ref, cx)) + } + None => None, + }; let items = impl_ .items .iter()
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 431e9ff..ad70fc1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs
@@ -885,6 +885,9 @@ pub(crate) enum ItemKind { TraitItem(Box<Trait>), TraitAliasItem(TraitAlias), ImplItem(Box<Impl>), + /// This variant is used only as a placeholder for trait impls in order to correctly compute + /// `doc_cfg` as trait impls are added to `clean::Crate` after we went through the whole tree. + PlaceholderImplItem, /// A required method in a trait declaration meaning it's only a function signature. RequiredMethodItem(Box<Function>, Defaultness), /// A method in a trait impl or a provided method in a trait declaration. @@ -964,7 +967,8 @@ pub(crate) fn inner_items(&self) -> impl Iterator<Item = &Item> { | AssocTypeItem(..) | StrippedItem(_) | KeywordItem - | AttributeItem => [].iter(), + | AttributeItem + | PlaceholderImplItem => [].iter(), } } }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index d721034..3caff6e 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs
@@ -522,6 +522,18 @@ fn println_condition(condition: Condition) { } } + if output_format == OutputFormat::Json { + if let Some(emit_flag) = emit.iter().find_map(|emit| match emit { + EmitType::HtmlStaticFiles => Some("html-static-files"), + EmitType::HtmlNonStaticFiles => Some("html-non-static-files"), + EmitType::DepInfo(_) => None, + }) { + dcx.fatal(format!( + "the `--emit={emit_flag}` flag is not supported with `--output-format=json`", + )); + } + } + let to_check = matches.opt_strs("check-theme"); if !to_check.is_empty() { let mut content =
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index a875d6d..42d7237 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs
@@ -309,19 +309,14 @@ pub(crate) fn create_config( &EMPTY_SET }; // In case typeck does end up being called, don't ICE in case there were name resolution errors - providers.queries.typeck = move |tcx, def_id| { - // Closures' tables come from their outermost function, - // as they are part of the same "inference environment". - // This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`) - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(); - if typeck_root_def_id != def_id { - return tcx.typeck(typeck_root_def_id); - } + providers.queries.typeck_root = move |tcx, def_id| { + // Panic before code below breaks in case of someone calls typeck_root directly + assert!(!tcx.is_typeck_child(def_id.to_def_id())); let body = tcx.hir_body_owned_by(def_id); debug!("visiting body for {def_id:?}"); EmitIgnoredResolutionErrors::new(tcx).visit_body(body); - (rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck)(tcx, def_id) + (rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck_root)(tcx, def_id) }; }), extra_symbols: Vec::new(),
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index c970fdb..8b9db46 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs
@@ -97,7 +97,8 @@ fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind { | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem - | AttributeItem => kind, + | AttributeItem + | PlaceholderImplItem => kind, } }
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 5a97d8e..35071f4 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs
@@ -389,6 +389,8 @@ fn is_from_private_dep(tcx: TyCtxt<'_>, cache: &Cache, def_id: DefId) -> bool { // So would rather leave them to an expert, // as at least the list is better than `_ => {}`. } + + clean::PlaceholderImplItem => return None, } // Maintain the parent stack.
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 6830c1e..eb3492e 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs
@@ -122,7 +122,7 @@ fn from(item: &'a clean::Item) -> ItemType { clean::StaticItem(..) => ItemType::Static, clean::ConstantItem(..) => ItemType::Constant, clean::TraitItem(..) => ItemType::Trait, - clean::ImplItem(..) => ItemType::Impl, + clean::ImplItem(..) | clean::PlaceholderImplItem => ItemType::Impl, clean::RequiredMethodItem(..) => ItemType::TyMethod, clean::MethodItem(..) => ItemType::Method, clean::StructFieldItem(..) => ItemType::StructField,
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bc9ad16..5d1f477 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs
@@ -353,6 +353,8 @@ fn from_clean_item(item: &clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum name: name.as_ref().unwrap().to_string(), rename: src.map(|x| x.to_string()), }, + // All placeholder impl items should have been removed in the stripper passes. + PlaceholderImplItem => unreachable!(), } }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6718505..751db71 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs
@@ -904,13 +904,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { return; } - for owner_id in tcx.hir_crate_items(()).delayed_lint_items() { - if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { - for lint in &delayed_lints.lints { - rustc_hir_analysis::emit_delayed_lint(lint, tcx); - } - } - } + rustc_interface::passes::emit_delayed_lints(tcx); if render_opts.dep_info().is_some() { rustc_interface::passes::write_dep_info(tcx);
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 77b3a2e..ac5e780 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -203,6 +203,10 @@ fn visit_item(&mut self, i: &clean::Item) { // don't count items in stripped modules return; } + clean::PlaceholderImplItem => { + // The "real" impl items are handled below. + return; + } // docs on `use` and `extern crate` statements are not displayed, so they're not // worth counting clean::ImportItem(..) | clean::ExternCrateItem { .. } => {}
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index a1578ab..ff7535f 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -80,6 +80,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::ImplAssocConstItem(..) | clean::RequiredAssocTypeItem(..) | clean::ImplItem(_) + | clean::PlaceholderImplItem ) { return false;
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3e68ed9..8b66672 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1067,17 +1067,27 @@ impl LinkCollector<'_, '_> { #[instrument(level = "debug", skip_all)] fn resolve_links(&mut self, item: &Item) { let tcx = self.cx.tcx; - if !self.cx.document_private() - && let Some(def_id) = item.item_id.as_def_id() - && let Some(def_id) = def_id.as_local() - && !tcx.effective_visibilities(()).is_exported(def_id) - && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs) + let document_private = self.cx.document_private(); + let effective_visibilities = tcx.effective_visibilities(()); + let should_skip_link_resolution = |item_id: DefId| { + !document_private + && item_id + .as_local() + .is_some_and(|local_def_id| !effective_visibilities.is_exported(local_def_id)) + && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs) + }; + + if let Some(def_id) = item.item_id.as_def_id() + && should_skip_link_resolution(def_id) { // Skip link resolution for non-exported items. return; } - let mut insert_links = |item_id, doc: &str| { + let mut try_insert_links = |item_id, doc: &str| { + if should_skip_link_resolution(item_id) { + return; + } let module_id = match tcx.def_kind(item_id) { DefKind::Mod if item.inner_docs(tcx) => item_id, _ => find_nearest_parent_module(tcx, item_id).unwrap(), @@ -1108,7 +1118,7 @@ fn resolve_links(&mut self, item: &Item) { // NOTE: if there are links that start in one crate and end in another, this will not resolve them. // This is a degenerate case and it's not supported by rustdoc. let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id()); - insert_links(item_id, &doc) + try_insert_links(item_id, &doc) } // Also resolve links in the note text of `#[deprecated]`. @@ -1137,7 +1147,7 @@ fn resolve_links(&mut self, item: &Item) { } else { item.item_id.expect_def_id() }; - insert_links(item_id, note) + try_insert_links(item_id, note) } }
diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 54da158..f73db25 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs
@@ -1,10 +1,11 @@ //! Propagates [`#[doc(cfg(...))]`](https://github.com/rust-lang/rust/issues/43781) to child items. +use rustc_data_structures::fx::FxHashMap; use rustc_hir::Attribute; use rustc_hir::attrs::{AttributeKind, DocAttribute}; use crate::clean::inline::{load_attrs, merge_attrs}; -use crate::clean::{CfgInfo, Crate, Item, ItemKind}; +use crate::clean::{CfgInfo, Crate, Item, ItemId, ItemKind}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::Pass; @@ -17,7 +18,8 @@ pub(crate) fn propagate_doc_cfg(cr: Crate, cx: &mut DocContext<'_>) -> Crate { if cx.tcx.features().doc_cfg() { - CfgPropagator { cx, cfg_info: CfgInfo::default() }.fold_crate(cr) + CfgPropagator { cx, cfg_info: CfgInfo::default(), impl_cfg_info: FxHashMap::default() } + .fold_crate(cr) } else { cr } @@ -26,6 +28,10 @@ pub(crate) fn propagate_doc_cfg(cr: Crate, cx: &mut DocContext<'_>) -> Crate { struct CfgPropagator<'a, 'tcx> { cx: &'a mut DocContext<'tcx>, cfg_info: CfgInfo, + + /// To ensure the `doc_cfg` feature works with how `rustdoc` handles impls, we need to store + /// the `cfg` info of `impl`s placeholder to use them later on the "real" impl item. + impl_cfg_info: FxHashMap<ItemId, CfgInfo>, } /// This function goes through the attributes list (`new_attrs`) and extract the `cfg` tokens from @@ -78,7 +84,22 @@ impl DocFolder for CfgPropagator<'_, '_> { fn fold_item(&mut self, mut item: Item) -> Option<Item> { let old_cfg_info = self.cfg_info.clone(); - self.merge_with_parent_attributes(&mut item); + // If we have an impl, we check if it has an associated `cfg` "context", and if so we will + // use that context instead of the actual (wrong) one. + if let ItemKind::ImplItem(_) = item.kind + && let Some(cfg_info) = self.impl_cfg_info.remove(&item.item_id) + { + self.cfg_info = cfg_info; + } + + if let ItemKind::PlaceholderImplItem = item.kind { + // If we have a placeholder impl, we store the current `cfg` "context" to be used + // on the actual impl later on (the impls are generated after we go through the whole + // AST so they're stored in the `krate` object at the end). + self.impl_cfg_info.insert(item.item_id, self.cfg_info.clone()); + } else { + self.merge_with_parent_attributes(&mut item); + } let result = self.fold_item_recur(item); self.cfg_info = old_cfg_info;
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 5139ca3..c8691fd 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs
@@ -107,7 +107,8 @@ fn fold_item(&mut self, mut item: Item) -> Option<Item> { | ItemKind::AssocTypeItem(..) | ItemKind::PrimitiveItem(..) | ItemKind::KeywordItem - | ItemKind::AttributeItem => own_stability, + | ItemKind::AttributeItem + | ItemKind::PlaceholderImplItem => own_stability, ItemKind::StrippedItem(..) => unreachable!(), }
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 99d2252..bf4e842 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs
@@ -120,6 +120,10 @@ fn fold_item(&mut self, i: Item) -> Option<Item> { clean::ImplItem(..) => {} + // Since the `doc_cfg` propagation was handled before the current pass, we can (and + // should) remove all placeholder impl items. + clean::PlaceholderImplItem => return None, + // tymethods etc. have no control over privacy clean::RequiredMethodItem(..) | clean::RequiredAssocConstItem(..)
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index cc78dec..63b869c 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs
@@ -3,7 +3,7 @@ use std::fs; use std::path::PathBuf; -use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::DiagCtxtHandle; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; @@ -15,7 +15,7 @@ use rustc_session::getopts; use rustc_span::def_id::{CrateNum, DefPathHash, LOCAL_CRATE}; use rustc_span::edition::Edition; -use rustc_span::{BytePos, FileName, SourceFile}; +use rustc_span::{BytePos, FileName, SourceFile, Span}; use tracing::{debug, trace, warn}; use crate::html::render::Context; @@ -114,6 +114,7 @@ struct FindCalls<'a, 'tcx> { target_crates: Vec<CrateNum>, calls: &'a mut AllCallLocations, bin_crate: bool, + call_ident_spans: FxHashSet<Span>, } impl<'a, 'tcx> Visitor<'tcx> for FindCalls<'a, 'tcx> @@ -165,6 +166,10 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { } }; + if !self.call_ident_spans.insert(ident_span) { + return; + } + // If this span comes from a macro expansion, then the source code may not actually show // a use of the given item, so it would be a poor example. Hence, we skip all uses in // macros. @@ -300,7 +305,13 @@ pub(crate) fn run( // Run call-finder on all items let mut calls = FxIndexMap::default(); - let mut finder = FindCalls { calls: &mut calls, cx, target_crates, bin_crate }; + let mut finder = FindCalls { + calls: &mut calls, + cx, + target_crates, + bin_crate, + call_ident_spans: FxHashSet::default(), + }; tcx.hir_visit_all_item_likes_in_crate(&mut finder); // The visitor might have found a type error, which we need to
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index 9f6bf00..9cf7d6b 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs
@@ -50,7 +50,8 @@ fn visit_inner_recur(&mut self, kind: &'a ItemKind) { | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem - | AttributeItem => {} + | AttributeItem + | PlaceholderImplItem => {} } }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index fd6ea21..906289b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs
@@ -373,6 +373,19 @@ fn reexport_public_and_not_hidden( } #[inline] + fn add_impl_to_current_mod(&mut self, item: &'tcx hir::Item<'_>, impl_: hir::Impl<'_>) { + self.add_to_current_mod( + item, + // The symbol here is used as a "sentinel" value and has no meaning in + // itself. It just tells that this is an inlined impl and that it should not + // be cleaned as a normal `ImplItem` but instead as a `PlaceholderImplItem`. + // It's to ensure that `doc_cfg` inheritance works as expected. + if impl_.of_trait.is_none() { None } else { Some(rustc_span::symbol::kw::Impl) }, + None, + ); + } + + #[inline] fn add_to_current_mod( &mut self, item: &'tcx hir::Item<'_>, @@ -426,12 +439,8 @@ fn visit_item_inner( // } // Bar::bar(); // ``` - if let hir::ItemKind::Impl(impl_) = item.kind && - // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick - // them up regardless of where they're located. - impl_.of_trait.is_none() - { - self.add_to_current_mod(item, None, None); + if let hir::ItemKind::Impl(impl_) = item.kind { + self.add_impl_to_current_mod(item, impl_); } return; } @@ -530,10 +539,10 @@ fn visit_item_inner( } } hir::ItemKind::Impl(impl_) => { - // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick + // Don't duplicate impls when inlining, we'll pick // them up regardless of where they're located. - if !self.inlining && impl_.of_trait.is_none() { - self.add_to_current_mod(item, None, None); + if !self.inlining { + self.add_impl_to_current_mod(item, impl_); } } }
diff --git a/src/llvm-project b/src/llvm-project index 41f177e..1cb4e38 160000 --- a/src/llvm-project +++ b/src/llvm-project
@@ -1 +1 @@ -Subproject commit 41f177ed26a5252a30ea6090a4da66ce0a96bf44 +Subproject commit 1cb4e3833c1919c2e6fb579a23ac0e2b22587b7e
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index c0271bb..0b766a3 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml
@@ -8,9 +8,9 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1.0.32" -flate2 = "1.0.26" +flate2 = { version = "1.1.9", default-features = false, features = ["zlib-rs"] } xz2 = "0.1.7" -tar = "0.4.29" +tar = "0.4.45" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2"
diff --git a/src/tools/cargo b/src/tools/cargo index e84cb63..888f675 160000 --- a/src/tools/cargo +++ b/src/tools/cargo
@@ -1 +1 @@ -Subproject commit e84cb639edfea2c42efd563b72a9be0cc5de6523 +Subproject commit 888f675344eb1cf2308fd53183e667bdd2c58e51
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs index eb14ef1..63968a8 100644 --- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs +++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -5,7 +5,7 @@ use clippy_utils::{is_in_test, sym}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::{Arm, Closure, ClosureKind, CoroutineKind, Expr, ExprKind, LetStmt, LocalSource, Node, Stmt, StmtKind}; +use rustc_hir::{Closure, ClosureKind, CoroutineKind, Expr, ExprKind, LetStmt, LocalSource, Node, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::{Span, SyntaxContext}; @@ -92,16 +92,15 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { (macro_call.span, String::from("()")) } }, - ExprKind::Match(first, arms, _) => { - let vals = collect_vals(first, arms); - let suggestion = match *vals.as_slice() { + ExprKind::Match(args, _, _) => { + let suggestion = match args.kind { // dbg!(1) => 1 - [val] => { + ExprKind::Tup([val]) => { snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability) .to_string() }, // dbg!(2, 3) => (2, 3) - [first, .., last] => { + ExprKind::Tup([first, .., last]) => { let snippet = snippet_with_applicability( cx, first.span.source_callsite().to(last.span.source_callsite()), @@ -165,39 +164,3 @@ fn is_async_move_desugar<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> { macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id)) } - -/// Extracts all value expressions from the `match`-tree generated by `dbg!`. -/// -/// E.g. from -/// ```rust, ignore -/// match 1 { -/// tmp_1 => match 2 { -/// tmp_2 => { -/// /* printing */ -/// (tmp_1, tmp_2) -/// } -/// } -/// } -/// ``` -/// this extracts `1` and `2`. -fn collect_vals<'hir>(first: &'hir Expr<'hir>, mut arms: &'hir [Arm<'hir>]) -> Vec<&'hir Expr<'hir>> { - let mut vals = vec![first]; - loop { - let [arm] = arms else { - unreachable!("dbg! macro expansion only has single-arm matches") - }; - - match is_async_move_desugar(arm.body) - .unwrap_or(arm.body) - .peel_drop_temps() - .kind - { - ExprKind::Block(..) => return vals, - ExprKind::Match(val, a, _) => { - vals.push(val); - arms = a; - }, - _ => unreachable!("dbg! macro expansion only results in block or match expressions"), - } - } -}
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 04c6571..7c1b3ef 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -24,7 +24,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let hir::ItemKind::Fn { ref sig, body: ref body_id, @@ -65,7 +65,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let Some((attr_span, reason)) = attr { check_needless_must_use( cx, @@ -98,7 +98,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let Some((attr_span, reason)) = attr { check_needless_must_use( cx,
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index ad81810..1ae8198 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -269,5 +269,5 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &'tcx hir::Ty<'tcx, Ambig fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx .hir_parent_id_iter(hir_id) - .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..) | CfgAttrTrace)) + .any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace)) }
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 9ababe8..703c913 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -92,7 +92,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(..)) + && !find_attr!(cx.tcx, item.hir_id(), NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -113,7 +113,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { "this seems like a manual implementation of the non-exhaustive pattern", |diag| { if let Some(non_exhaustive_span) = - find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(span) => *span) + find_attr!(cx.tcx, item.hir_id(), NonExhaustive(span) => *span) { diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive"); } else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 4577be3..cfda39e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
@@ -39,7 +39,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..))) + .any(|id| find_attr!(cx.tcx, id, CfgTrace(..))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 8b0743c..6c45964 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -332,7 +332,7 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { if let ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_kind && let Ok(trait_item_id) = trait_item_def_id { - let impl_id = cx.tcx.parent(owner_id.into()); + let impl_id = cx.tcx.local_parent(owner_id.def_id); let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity(); ( trait_item_id,
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 4fa22ff..4ddf827 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -179,7 +179,7 @@ fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { } fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool { - let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id()); + let scope_tree = cx.tcx.region_scope_tree(owner); if let Some(first_scope) = scope_tree.var_scope(first) && let Some(second_scope) = scope_tree.var_scope(second) {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 50cfb0e..9a463d1 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -280,7 +280,7 @@ pub fn eq_arm(l: &Arm, r: &Arm) -> bool { l.is_placeholder == r.is_placeholder && eq_pat(&l.pat, &r.pat) && eq_expr_opt(l.body.as_deref(), r.body.as_deref()) - && eq_expr_opt(l.guard.as_deref(), r.guard.as_deref()) + && eq_expr_opt(l.guard.as_deref().map(|g| &g.cond), r.guard.as_deref().map(|g| &g.cond)) && over(&l.attrs, &r.attrs, eq_attr) }
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index b37558c..8f028ba 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1710,7 +1710,7 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir_attrs(hir_id), Repr { .. }) + find_attr!(cx.tcx, hir_id, Repr { .. }) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { @@ -2410,7 +2410,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl FnOnce(& && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind // We could also check for the type name `test::TestDescAndFn` && let Res::Def(DefKind::Struct, _) = path.res - && find_attr!(tcx.hir_attrs(item.hir_id()), RustcTestMarker(..)) + && find_attr!(tcx, item.hir_id(), RustcTestMarker(..)) { names.push(ident.name); } @@ -2468,7 +2468,7 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), CfgTrace(cfgs) => cfgs) + if let Some(cfgs) = find_attr!(tcx, id, CfgTrace(cfgs) => cfgs) && cfgs .iter() .any(|(cfg, _)| matches!(cfg, CfgEntry::NameValue { name: sym::test, .. }))
diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index bb67e43..7d579d8 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs
@@ -200,7 +200,6 @@ macro_rules! generate { cx, cycle, cyclomatic_complexity, - dbg_macro, de, debug_struct, deprecated_in_future,
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed index 2c79446..852c4dd 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed
@@ -23,6 +23,6 @@ //~^ unnested_or_patterns if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} //~^ unnested_or_patterns - if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} + if let box (box (0 | 2 | 4)) = Box::new(Box::new(0)) {} //~^ unnested_or_patterns }
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr index 3fc8fa1..3deef33 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
@@ -93,7 +93,7 @@ help: nest the patterns | LL - if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} -LL + if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} +LL + if let box (box (0 | 2 | 4)) = Box::new(Box::new(0)) {} | error: aborting due to 8 previous errors
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index bc94a81..7cac7f5 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs
@@ -168,6 +168,7 @@ pub enum Sanitizer { Dataflow, Kcfi, KernelAddress, + KernelHwaddress, Leak, Memory, Memtag,
diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 9af881b..5421a97 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs
@@ -179,6 +179,7 @@ "needs-sanitizer-hwaddress", "needs-sanitizer-kasan", "needs-sanitizer-kcfi", + "needs-sanitizer-khwasan", "needs-sanitizer-leak", "needs-sanitizer-memory", "needs-sanitizer-memtag", @@ -213,6 +214,7 @@ "only-apple", "only-arm", "only-arm64ec", + "only-armv7-unknown-linux-gnueabihf", "only-avr", "only-beta", "only-bpf",
diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 168d5e9..e9f3d6c 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs
@@ -47,6 +47,11 @@ pub(super) fn handle_needs( ignore_reason: "ignored on targets without kernel address sanitizer", }, Need { + name: "needs-sanitizer-khwasan", + condition: cache.sanitizer_khwasan, + ignore_reason: "ignored on targets without kernel hardware-assisted address sanitizer", + }, + Need { name: "needs-sanitizer-leak", condition: cache.sanitizer_leak, ignore_reason: "ignored on targets without leak sanitizer", @@ -332,6 +337,7 @@ pub(super) struct CachedNeedsConditions { sanitizer_dataflow: bool, sanitizer_kcfi: bool, sanitizer_kasan: bool, + sanitizer_khwasan: bool, sanitizer_leak: bool, sanitizer_memory: bool, sanitizer_thread: bool, @@ -359,6 +365,7 @@ pub(super) fn load(config: &Config) -> Self { sanitizer_dataflow: sanitizers.contains(&Sanitizer::Dataflow), sanitizer_kcfi: sanitizers.contains(&Sanitizer::Kcfi), sanitizer_kasan: sanitizers.contains(&Sanitizer::KernelAddress), + sanitizer_khwasan: sanitizers.contains(&Sanitizer::KernelHwaddress), sanitizer_leak: sanitizers.contains(&Sanitizer::Leak), sanitizer_memory: sanitizers.contains(&Sanitizer::Memory), sanitizer_thread: sanitizers.contains(&Sanitizer::Thread),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b584d14..da4ec44 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs
@@ -1919,8 +1919,9 @@ fn make_compile_args( compiler.args(&["-A", "unused", "-W", "unused_attributes"]); } - // Allow tests to use internal features. + // Allow tests to use internal and incomplete features. compiler.args(&["-A", "internal_features"]); + compiler.args(&["-A", "incomplete_features"]); // Allow tests to have unused parens and braces. // Add #![deny(unused_parens, unused_braces)] to the test file if you want to
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 6534902..8dfac2e 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -191,7 +191,7 @@ fn run_debuginfo_gdb_test(&self) { let mut stdout = BufReader::new(adb.stdout.take().unwrap()); let mut line = String::new(); loop { - line.truncate(0); + line.clear(); stdout.read_line(&mut line).unwrap(); if line.starts_with("Listening on port 5039") { break;
diff --git a/src/tools/enzyme b/src/tools/enzyme index 0b86a67..3244024 160000 --- a/src/tools/enzyme +++ b/src/tools/enzyme
@@ -1 +1 @@ -Subproject commit 0b86a6759e5f250d6691a94a4a779a44d846e25b +Subproject commit 324402444ac48874d8ebd3ac767330bdc7cb1c06
diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 4eeba30..9129562 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml
@@ -58,7 +58,7 @@ env: HOST_TARGET: ${{ matrix.host_target }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: install multiarch if: ${{ matrix.multiarch != '' }} run: | @@ -105,7 +105,7 @@ name: style checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ./.github/workflows/setup - name: rustfmt @@ -121,7 +121,7 @@ name: bootstrap build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # Deliberately skipping `./.github/workflows/setup` as we do our own setup - name: Add cache for cargo id: cache @@ -156,7 +156,7 @@ name: coverage report runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ./.github/workflows/setup - name: coverage run: ./miri test --coverage @@ -191,7 +191,7 @@ pull-requests: write if: ${{ github.event_name == 'schedule' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 256 # get a bit more of the history - name: install josh-sync
diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index 852ea26..ad8b2b0 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md
@@ -171,8 +171,8 @@ ``` Note that you will only get `info`, `warn` or `error` messages if you use a prebuilt compiler. -In order to get `debug` and `trace` level messages, you need to build miri with a locally built -compiler that has `debug=true` set in `bootstrap.toml`. +In order to get `debug` and `trace` level messages, you need to build miri with a [locally built +compiler](#advanced-topic-building-miri-against-a-locally-compiled-rustc) that has `debug=true` set in `bootstrap.toml`. #### Debugging error messages @@ -320,6 +320,33 @@ ./x.py run miri --stage 1 --args src/tools/miri/tests/pass/hello.rs ``` +## Advanced topic: Building Miri against a locally compiled rustc + +Very rarely, it can be necessary to work with an out-of-tree Miri but build it against a rustc that +was locally compiled. (Usually, you should instead work on the Miri that's in the Rust tree, as +described in the previous subsection.) + +This requires a fully bootstrapped build: + +```sh +# Build rustc, then build rustc with that rustc. This can take a while. +./x build library --stage 3 +``` + +You also need to set up a linked toolchain with rustup: + +```sh +rustup toolchain link stage2 build/host/stage2 +``` + +Then in the Miri folder, you can set this as the current toolchain and build against it: + +```sh +rustup override set stage2 +# Prevent `./miri` from reseting the toolchain. +export MIRI_AUTO_OPS=no +``` + ## Advanced topic: Syncing with the rustc repo We use the [`josh-sync`](https://github.com/rust-lang/josh-sync) tool to transmit changes between the
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 97f385a..f51cd96 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md
@@ -476,8 +476,9 @@ but reports to the program that it did actually write. This is useful when you are not interested in the actual program's output, but only want to see Miri's errors and warnings. -* `-Zmiri-recursive-validation` is a *highly experimental* flag that makes validity checking - recurse below references. +* `-Zmiri-recursive-validation` is a *highly experimental* flag that makes validity checking recurse + *one level* below references. The in-memory value is treated as-if it was inside a + `MaybeDangling`, i.e., nested references do not even have to be dereferenceable. * `-Zmiri-preemption-rate` configures the probability that at the end of a basic block, the active thread will be preempted. The default is `0.01` (i.e., 1%). Setting this to `0` disables preemption. Note that even without preemption, the schedule is still non-deterministic:
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index 45be05f..977728f 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -230,9 +230,9 @@ [[package]] name = "rustc-build-sysroot" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b881c015c729b43105bbd3702a9bdecee28fafaa21126d1d62e454ec011a4b7" +checksum = "eec3905e8201688412f6f4b1f6c86d38b3ee6578f59ba85f41330a3af61e8365" dependencies = [ "anyhow", "rustc_version", @@ -339,11 +339,11 @@ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -392,45 +392,42 @@ [[package]] name = "toml" -version = "0.8.23" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" dependencies = [ "indexmap", - "serde", + "serde_core", "serde_spanned", "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", + "toml_parser", + "toml_writer", "winnow", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_datetime" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "unicode-ident" @@ -489,12 +486,9 @@ [[package]] name = "winnow" -version = "0.7.13" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" [[package]] name = "wit-bindgen"
diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml index e8da7f2..568bb29 100644 --- a/src/tools/miri/cargo-miri/Cargo.toml +++ b/src/tools/miri/cargo-miri/Cargo.toml
@@ -18,7 +18,7 @@ rustc_version = "0.4" serde_json = "1.0.40" cargo_metadata = "0.23" -rustc-build-sysroot = "0.5.10" +rustc-build-sysroot = "0.5.12" # Enable some feature flags that dev-dependencies need but dependencies # do not. This makes `./miri install` after `./miri build` faster.
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 6c0bcea..9bacbbc 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh
@@ -28,6 +28,7 @@ export RUSTFLAGS="-D warnings" export CARGO_INCREMENTAL=0 export CARGO_EXTRA_FLAGS="--locked" +export CARGO_UNSTABLE_BUILD_DIR_NEW_LAYOUT=true # Determine configuration for installed build (used by test-cargo-miri and `./miri bench`). # We use the default set of features for this.
diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 86f6253..d469502 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs
@@ -80,7 +80,7 @@ fn auto_actions() -> Result<()> { // `toolchain` goes first as it could affect the others if auto_toolchain { - Self::toolchain(vec![])?; + Self::toolchain(None, vec![])?; } if auto_fmt { Self::fmt(vec![])?; @@ -121,15 +121,18 @@ pub fn exec(self) -> Result<()> { Command::Clippy { features, flags } => Self::clippy(features, flags), Command::Bench { target, no_install, save_baseline, load_baseline, benches } => Self::bench(target, no_install, save_baseline, load_baseline, benches), - Command::Toolchain { flags } => Self::toolchain(flags), + Command::Toolchain { commit, flags } => Self::toolchain(commit, flags), Command::Squash => Self::squash(), } } - fn toolchain(flags: Vec<String>) -> Result<()> { + fn toolchain(new_commit: Option<String>, flags: Vec<String>) -> Result<()> { let sh = Shell::new()?; sh.change_dir(miri_dir()?); - let new_commit = sh.read_file("rust-version")?.trim().to_owned(); + let new_commit = match new_commit { + Some(c) => c, + None => sh.read_file("rust-version")?.trim().to_owned(), + }; let current_commit = { let rustc_info = cmd!(sh, "rustc +miri --version -v").read(); if let Ok(rustc_info) = rustc_info {
diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index e307014..419c128 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs
@@ -138,6 +138,9 @@ pub enum Command { /// The `rust-version` file is used to determine the commit that will be intsalled. /// `rustup-toolchain-install-master` must be installed for this to work. Toolchain { + /// Overwrite the commit to install. + #[arg(long)] + commit: Option<String>, /// Flags that are passed through to `rustup-toolchain-install-master`. #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, @@ -157,8 +160,8 @@ fn add_remainder(&mut self, remainder: Vec<String>) -> Result<()> { | Self::Build { flags, .. } | Self::Check { flags, .. } | Self::Doc { flags, .. } - | Self::Fmt { flags } - | Self::Toolchain { flags } + | Self::Fmt { flags, .. } + | Self::Toolchain { flags, .. } | Self::Clippy { flags, .. } | Self::Run { flags, .. } | Self::Test { flags, .. } => {
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index e281dad..85571d9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version
@@ -1 +1 @@ -fd0c901b00ee1e08a250039cdb90258603497e20 +116458d0a5ae01cd517cabd2d1aee7f5457018ab
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index d6d6449..ee74e06 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs
@@ -656,64 +656,10 @@ fn yield_active_thread(&mut self) { // We should only switch stacks between steps. self.yield_active_thread = true; } - - /// Get the wait time for the next timeout, or `None` if no timeout is pending. - fn next_callback_wait_time(&self, clock: &MonotonicClock) -> Option<Duration> { - self.threads - .iter() - .filter_map(|t| { - match &t.state { - ThreadState::Blocked { timeout: Some(timeout), .. } => - Some(timeout.get_wait_time(clock)), - _ => None, - } - }) - .min() - } } impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {} trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { - /// Execute a timeout callback on the callback's thread. - #[inline] - fn run_timeout_callback(&mut self) -> InterpResult<'tcx> { - let this = self.eval_context_mut(); - let mut found_callback = None; - // Find a blocked thread that has timed out. - for (id, thread) in this.machine.threads.threads.iter_enumerated_mut() { - match &thread.state { - ThreadState::Blocked { timeout: Some(timeout), .. } - if timeout.get_wait_time(&this.machine.monotonic_clock) == Duration::ZERO => - { - let old_state = mem::replace(&mut thread.state, ThreadState::Enabled); - let ThreadState::Blocked { callback, .. } = old_state else { unreachable!() }; - found_callback = Some((id, callback)); - // Run the fallback (after the loop because borrow-checking). - break; - } - _ => {} - } - } - if let Some((thread, callback)) = found_callback { - // This back-and-forth with `set_active_thread` is here because of two - // design decisions: - // 1. Make the caller and not the callback responsible for changing - // thread. - // 2. Make the scheduler the only place that can change the active - // thread. - let old_thread = this.machine.threads.set_active_thread_id(thread); - callback.call(this, UnblockKind::TimedOut)?; - this.machine.threads.set_active_thread_id(old_thread); - } - // found_callback can remain None if the computer's clock - // was shifted after calling the scheduler and before the call - // to get_ready_callback (see issue - // https://github.com/rust-lang/miri/issues/1763). In this case, - // just do nothing, which effectively just returns to the - // scheduler. - interp_ok(()) - } - #[inline] fn run_on_stack_empty(&mut self) -> InterpResult<'tcx, Poll<()>> { let this = self.eval_context_mut(); @@ -790,19 +736,12 @@ fn schedule(&mut self) -> InterpResult<'tcx, SchedulingAction> { this.poll_and_unblock(Some(Duration::ZERO))?; } - let thread_manager = &this.machine.threads; - let clock = &this.machine.monotonic_clock; - // We also check timeouts before running any other thread, to ensure that timeouts // "in the past" fire before any other thread can take an action. This ensures that for // `pthread_cond_timedwait`, "an error is returned if [...] the absolute time specified by // abstime has already been passed at the time of the call". // <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html> - let potential_sleep_time = thread_manager.next_callback_wait_time(clock); - if potential_sleep_time == Some(Duration::ZERO) { - // The timeout exceeded for some thread so we unblock the thread and execute its timeout callback. - this.run_timeout_callback()?; - } + let potential_sleep_time = this.unblock_expired_timeouts()?; let thread_manager = &mut this.machine.threads; let rng = this.machine.rng.get_mut(); @@ -868,6 +807,71 @@ fn schedule(&mut self) -> InterpResult<'tcx, SchedulingAction> { throw_machine_stop!(TerminationInfo::GlobalDeadlock); } } + + /// Poll for I/O events until either an I/O event happened or the timeout expired. + /// The different timeout values are described in [`BlockingIoManager::poll`]. + fn poll_and_unblock(&mut self, timeout: Option<Duration>) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let ready = match this.machine.blocking_io.poll(timeout) { + Ok(ready) => ready, + // We can ignore errors originating from interrupts; that's just a spurious wakeup. + Err(e) if e.kind() == io::ErrorKind::Interrupted => return interp_ok(()), + // For other errors we panic. On Linux and BSD hosts this should only be + // reachable when a system resource error (e.g. ENOMEM or ENOSPC) occurred. + Err(e) => panic!("unexpected error while polling: {e}"), + }; + + ready.into_iter().try_for_each(|thread_id| this.unblock_thread(thread_id, BlockReason::IO)) + } + + /// Find all threads with expired timeouts, unblock them and execute their timeout callbacks. + /// + /// This method returns the minimum duration until the next thread timeout expires. + /// If all ready threads have no timeout set, [`None`] is returned. + fn unblock_expired_timeouts(&mut self) -> InterpResult<'tcx, Option<Duration>> { + let this = self.eval_context_mut(); + let clock = &this.machine.monotonic_clock; + + let mut min_wait_time = Option::<Duration>::None; + let mut callbacks = Vec::new(); + + for (id, thread) in this.machine.threads.threads.iter_enumerated_mut() { + match &thread.state { + ThreadState::Blocked { timeout: Some(timeout), .. } => { + let wait_time = timeout.get_wait_time(clock); + if wait_time.is_zero() { + // The timeout expired for this thread. + let old_state = mem::replace(&mut thread.state, ThreadState::Enabled); + let ThreadState::Blocked { callback, .. } = old_state else { + unreachable!() + }; + // Add callback to list to be run after this loop because of borrow-checking. + callbacks.push((id, callback)); + } else { + // Update `min_wait_time` to contain the smallest duration until + // the next timeout expires. + min_wait_time = Some(wait_time.min(min_wait_time.unwrap_or(Duration::MAX))); + } + } + _ => {} + } + } + + for (thread, callback) in callbacks { + // This back-and-forth with `set_active_thread` is here because of two + // design decisions: + // 1. Make the caller and not the callback responsible for changing + // thread. + // 2. Make the scheduler the only place that can change the active + // thread. + let old_thread = this.machine.threads.set_active_thread_id(thread); + callback.call(this, UnblockKind::TimedOut)?; + this.machine.threads.set_active_thread_id(old_thread); + } + + interp_ok(min_wait_time) + } } // Public interface to thread management. @@ -1348,21 +1352,4 @@ fn run_threads(&mut self) -> InterpResult<'tcx, !> { } } } - - /// Poll for I/O events until either an I/O event happened or the timeout expired. - /// The different timeout values are described in [`BlockingIoManager::poll`]. - fn poll_and_unblock(&mut self, timeout: Option<Duration>) -> InterpResult<'tcx> { - let this = self.eval_context_mut(); - - let ready = match this.machine.blocking_io.poll(timeout) { - Ok(ready) => ready, - // We can ignore errors originating from interrupts; that's just a spurious wakeup. - Err(e) if e.kind() == io::ErrorKind::Interrupted => return interp_ok(()), - // For other errors we panic. On Linux and BSD hosts this should only be - // reachable when a system resource error (e.g. ENOMEM or ENOSPC) occurred. - Err(e) => panic!("{e}"), - }; - - ready.into_iter().try_for_each(|thread_id| this.unblock_thread(thread_id, BlockReason::IO)) - } }
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index d8224f1..566a775 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs
@@ -569,7 +569,7 @@ pub struct MiriMachine<'tcx> { pub(crate) user_relevant_crates: Vec<CrateNum>, /// Mapping extern static names to their pointer. - extern_statics: FxHashMap<Symbol, StrictPointer>, + pub(crate) extern_statics: FxHashMap<Symbol, StrictPointer>, /// The random number generator used for resolving non-determinism. /// Needs to be queried by ptr_to_int, hence needs interior mutability.
diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs index d06b02a..6a914d5 100644 --- a/src/tools/miri/src/shims/aarch64.rs +++ b/src/tools/miri/src/shims/aarch64.rs
@@ -4,6 +4,7 @@ use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use crate::shims::math::compute_crc32; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -58,6 +59,93 @@ fn emulate_aarch64_intrinsic( this.write_immediate(*res_lane, &dest)?; } } + + // Wrapping pairwise addition. + // + // Concatenates the two input vectors and adds adjacent elements. For input vectors `v` + // and `w` this computes `[v0 + v1, v2 + v3, ..., w0 + w1, w2 + w3, ...]`, using + // wrapping addition for `+`. + // + // Used by `vpadd_{s8, u8, s16, u16, s32, u32}`. + name if name.starts_with("neon.addp.") => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(left_len, dest_len); + + assert_eq!(left.layout, right.layout); + assert_eq!(left.layout, dest.layout); + + assert!(dest_len.is_multiple_of(2)); + let half_len = dest_len.strict_div(2); + + for lane_idx in 0..dest_len { + // The left and right vectors are concatenated. + let (src, src_pair_idx) = if lane_idx < half_len { + (&left, lane_idx) + } else { + (&right, lane_idx.strict_sub(half_len)) + }; + // Convert "pair index" into "index of first element of the pair". + let i = src_pair_idx.strict_mul(2); + + let lhs = this.read_immediate(&this.project_index(src, i)?)?; + let rhs = this.read_immediate(&this.project_index(src, i.strict_add(1))?)?; + + // Wrapping addition on the element type. + let sum = this.binary_op(BinOp::Add, &lhs, &rhs)?; + + let dst_lane = this.project_index(&dest, lane_idx)?; + this.write_immediate(*sum, &dst_lane)?; + } + } + + // Widening pairwise addition. + // + // Takes a single input vector, and an output vector with half as many lanes and double + // the element width. Takes adjacent pairs of elements, widens both, and then adds them + // together. + // + // Used by `vpaddl_{u8, u16, u32}` and `vpaddlq_{u8, u16, u32}`. + name if name.starts_with("neon.uaddlp.") => { + let [src] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (src, src_len) = this.project_to_simd(src)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + // Operates pairwise, so src has twice as many lanes. + assert_eq!(src_len, dest_len.strict_mul(2)); + + let src_elem_size = src.layout.field(this, 0).size; + let dest_elem_size = dest.layout.field(this, 0).size; + + // Widens, so dest elements must be exactly twice as wide. + assert_eq!(dest_elem_size.bytes(), src_elem_size.bytes().strict_mul(2)); + + for dest_idx in 0..dest_len { + let src_idx = dest_idx.strict_mul(2); + + let a_scalar = this.read_scalar(&this.project_index(&src, src_idx)?)?; + let b_scalar = + this.read_scalar(&this.project_index(&src, src_idx.strict_add(1))?)?; + + let a_val = a_scalar.to_uint(src_elem_size)?; + let b_val = b_scalar.to_uint(src_elem_size)?; + + // Use addition on u128 to simulate widening addition for the destination type. + // This cannot wrap since the element type is at most u64. + let sum = a_val.strict_add(b_val); + + let dst_lane = this.project_index(&dest, dest_idx)?; + this.write_scalar(Scalar::from_uint(sum, dest_elem_size), &dst_lane)?; + } + } + // Vector table lookup: each index selects a byte from the 16-byte table, out-of-range -> 0. // Used to implement vtbl1_u8 function. // LLVM does not have a portable shuffle that takes non-const indices @@ -85,6 +173,47 @@ fn emulate_aarch64_intrinsic( this.write_scalar(val, &this.project_index(&dest, i)?)?; } } + // Used to implement the __crc32{b,h,w,x} and __crc32c{b,h,w,x} functions. + // Polynomial 0x04C11DB7 (standard CRC-32): + // https://developer.arm.com/documentation/ddi0602/latest/Base-Instructions/CRC32B--CRC32H--CRC32W--CRC32X--CRC32-checksum- + // Polynomial 0x1EDC6F41 (CRC-32C / Castagnoli): + // https://developer.arm.com/documentation/ddi0602/latest/Base-Instructions/CRC32CB--CRC32CH--CRC32CW--CRC32CX--CRC32C-checksum- + "crc32b" | "crc32h" | "crc32w" | "crc32x" | "crc32cb" | "crc32ch" | "crc32cw" + | "crc32cx" => { + this.expect_target_feature_for_intrinsic(link_name, "crc")?; + // The polynomial constants below include the leading 1 bit + // (e.g. 0x104C11DB7 instead of 0x04C11DB7) which the ARM docs + // omit but the polynomial division algorithm requires. + let (bit_size, polynomial): (u32, u128) = match unprefixed_name { + "crc32b" => (8, 0x104C11DB7), + "crc32h" => (16, 0x104C11DB7), + "crc32w" => (32, 0x104C11DB7), + "crc32x" => (64, 0x104C11DB7), + "crc32cb" => (8, 0x11EDC6F41), + "crc32ch" => (16, 0x11EDC6F41), + "crc32cw" => (32, 0x11EDC6F41), + "crc32cx" => (64, 0x11EDC6F41), + _ => unreachable!(), + }; + + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let left = this.read_scalar(left)?; + let right = this.read_scalar(right)?; + + // The CRC accumulator is always u32. The data argument is u32 for + // b/h/w variants and u64 for the x variant, per the LLVM intrinsic + // definitions (all b/h/w take i32, only x takes i64). + // https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAArch64.td + // If the higher bits are non-zero, `compute_crc32` will panic. We should probably + // raise a proper error instead, but outside stdarch nobody can trigger this anyway. + let crc = left.to_u32()?; + let data = + if bit_size == 64 { right.to_u64()? } else { u64::from(right.to_u32()?) }; + + let result = compute_crc32(crc, data, bit_size, polynomial); + this.write_scalar(Scalar::from_u32(result), dest)?; + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn)
diff --git a/src/tools/miri/src/shims/math.rs b/src/tools/miri/src/shims/math.rs index ef185aa..1da7fbb 100644 --- a/src/tools/miri/src/shims/math.rs +++ b/src/tools/miri/src/shims/math.rs
@@ -245,3 +245,51 @@ fn emulate_foreign_item_inner( interp_ok(EmulateItemResult::NeedsReturn) } } + +/// Compute a CRC32 checksum using the given polynomial. +/// +/// `bit_size` is the number of relevant data bits (8, 16, 32, or 64). +/// Only the low `bit_size` bits of `data` are used; higher bits must be zero. +/// `polynomial` includes the leading 1 bit (e.g. `0x11EDC6F41` for CRC32C). +/// +/// Following hardware CRC conventions, `crc` and `data` bits are assumed to be reversed, +/// and output bits will be equally reversed. +pub(crate) fn compute_crc32(crc: u32, data: u64, bit_size: u32, polynomial: u128) -> u32 { + assert!( + bit_size == 64 || data < 1u64.strict_shl(bit_size), + "crc32: `data` is larger than {bit_size} bits" + ); + // Bit-reverse inputs to match hardware CRC conventions. + let crc = u128::from(crc.reverse_bits()); + // Reverse all 64 bits of `data`, then shift right by `64 - bit_size`. This + // discards the (now-reversed) higher bits, leaving only the reversed low + // `bit_size` bits in the lowest positions (with zeros above). + let v = u128::from(data.reverse_bits() >> (64u32.strict_sub(bit_size))); + + // Perform polynomial division modulo 2. + // The algorithm for the division is an adapted version of the + // schoolbook division algorithm used for normal integer or polynomial + // division. In this context, the quotient is not calculated, since + // only the remainder is needed. + // + // The algorithm works as follows: + // 1. Pull down digits until division can be performed. In the context of division + // modulo 2 it means locating the most significant digit of the dividend and shifting + // the divisor such that the position of the divisors most significand digit and the + // dividends most significand digit match. + // 2. Perform a division and determine the remainder. Since it is arithmetic modulo 2, + // this operation is a simple bitwise exclusive or. + // 3. Repeat steps 1. and 2. until the full remainder is calculated. This is the case + // once the degree of the remainder polynomial is smaller than the degree of the + // divisor polynomial. In other words, the number of leading zeros of the remainder + // is larger than the number of leading zeros of the divisor. It is important to + // note that standard arithmetic comparison is not applicable here: + // 0b10011 / 0b11111 = 0b01100 is a valid division, even though the dividend is + // smaller than the divisor. + let mut dividend = (crc << bit_size) ^ (v << 32); + while dividend.leading_zeros() <= polynomial.leading_zeros() { + dividend ^= (polynomial << polynomial.leading_zeros()) >> dividend.leading_zeros(); + } + + u32::try_from(dividend).unwrap().reverse_bits() +}
diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 6a281dd..b302a07 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs
@@ -396,8 +396,9 @@ fn ty_to_ffitype(&self, layout: TyAndLayout<'tcx>) -> Result<FfiType, Ty<'tcx>> // matches what codegen does. This does mean that we support some types whose ABI is not // stable, but that's fine -- we are anyway quite conservative in native-lib mode. if let BackendRepr::Scalar(s) = layout.backend_repr { - // Simple sanity-check: this cannot be `repr(C)`. - assert!(!layout.ty.ty_adt_def().is_some_and(|adt| adt.repr().c())); + // Simple sanity-check: this cannot be a `repr(C)` struct or union. (It could be a + // repr(C) enum. Those indeed behave like integers in the ABI.) + assert!(!layout.ty.ty_adt_def().is_some_and(|adt| !adt.is_enum() && adt.repr().c())); return Ok(match s.primitive() { Primitive::Int(Integer::I8, /* signed */ true) => FfiType::i8(), Primitive::Int(Integer::I16, /* signed */ true) => FfiType::i16(),
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index f2e16e7..3651bc1 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -633,6 +633,16 @@ fn emulate_foreign_item_inner( let result = this.getsockname(socket, address, address_len)?; this.write_scalar(result, dest)?; } + "getpeername" => { + let [socket, address, address_len] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *mut _, *mut _) -> i32), + link_name, + abi, + args, + )?; + let result = this.getpeername(socket, address, address_len)?; + this.write_scalar(result, dest)?; + } // Time "gettimeofday" => { @@ -727,11 +737,14 @@ fn emulate_foreign_item_inner( this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let name = this.read_c_str(symbol)?; - if let Ok(name) = str::from_utf8(name) - && is_dyn_sym(name, &this.tcx.sess.target.os) - { + let Ok(name) = str::from_utf8(name) else { + throw_unsup_format!("dlsym: non UTF-8 symbol name not supported") + }; + if is_dyn_sym(name, &this.tcx.sess.target.os) { let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name))); this.write_pointer(ptr, dest)?; + } else if let Some(&ptr) = this.machine.extern_statics.get(&Symbol::intern(name)) { + this.write_pointer(ptr, dest)?; } else { this.write_null(dest)?; }
diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs index 8cf4464..7c46dd5 100644 --- a/src/tools/miri/src/shims/unix/freebsd/sync.rs +++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs
@@ -215,8 +215,17 @@ fn read_umtx_time(&mut self, ut: &MPlaceTy<'tcx>) -> InterpResult<'tcx, Option<U let Some(duration) = this.read_timespec(×pec_place)? else { return interp_ok(None) }; let flags_place = this.project_field(ut, FieldIdx::from_u32(1))?; - let flags = this.read_scalar(&flags_place)?.to_u32()?; - let abs_time_flag = flags == abs_time; + let mut flags = this.read_scalar(&flags_place)?.to_u32()?; + + let abs_time_flag = if flags & abs_time != 0 { + flags &= !abs_time; + true + } else { + false + }; + if flags != 0 { + throw_unsup_format!("unsupported `_umtx_time` flags: {:#x}", flags); + } let clock_id_place = this.project_field(ut, FieldIdx::from_u32(2))?; let clock_id = this.read_scalar(&clock_id_place)?;
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 9873af8..5adc593 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -364,6 +364,9 @@ fn open( this.machine.emit_diagnostic(NonHaltingDiagnostic::FileInProcOpened); } + // We will "subtract" supported flags from this and at the end check that no bits are left. + let mut flag = flag; + let mut options = OpenOptions::new(); let o_rdonly = this.eval_libc_i32("O_RDONLY"); @@ -379,6 +382,7 @@ fn open( // Now we check the access mode let access_mode = flag & 0b11; + flag &= !access_mode; if access_mode == o_rdonly { writable = false; @@ -390,23 +394,20 @@ fn open( } else { throw_unsup_format!("unsupported access mode {:#x}", access_mode); } - // We need to check that there aren't unsupported options in `flag`. For this we try to - // reproduce the content of `flag` in the `mirror` variable using only the supported - // options. - let mut mirror = access_mode; let o_append = this.eval_libc_i32("O_APPEND"); if flag & o_append == o_append { + flag &= !o_append; options.append(true); - mirror |= o_append; } let o_trunc = this.eval_libc_i32("O_TRUNC"); if flag & o_trunc == o_trunc { + flag &= !o_trunc; options.truncate(true); - mirror |= o_trunc; } let o_creat = this.eval_libc_i32("O_CREAT"); if flag & o_creat == o_creat { + flag &= !o_creat; // Get the mode. On macOS, the argument type `mode_t` is actually `u16`, but // C integer promotion rules mean that on the ABI level, it gets passed as `u32` // (see https://github.com/rust-lang/rust/issues/71915). @@ -430,11 +431,9 @@ fn open( } } - mirror |= o_creat; - let o_excl = this.eval_libc_i32("O_EXCL"); if flag & o_excl == o_excl { - mirror |= o_excl; + flag &= !o_excl; options.create_new(true); } else { options.create(true); @@ -442,9 +441,9 @@ fn open( } let o_cloexec = this.eval_libc_i32("O_CLOEXEC"); if flag & o_cloexec == o_cloexec { + flag &= !o_cloexec; // We do not need to do anything for this flag because `std` already sets it. // (Technically we do not support *not* setting this flag, but we ignore that.) - mirror |= o_cloexec; } if this.tcx.sess.target.os == Os::Linux { let o_tmpfile = this.eval_libc_i32("O_TMPFILE"); @@ -456,6 +455,7 @@ fn open( let o_nofollow = this.eval_libc_i32("O_NOFOLLOW"); if flag & o_nofollow == o_nofollow { + flag &= !o_nofollow; #[cfg(unix)] { use std::os::unix::fs::OpenOptionsExt; @@ -472,13 +472,11 @@ fn open( return this.set_last_error_and_return_i32(LibcError("ELOOP")); } } - mirror |= o_nofollow; } - // If `flag` is not equal to `mirror`, there is an unsupported option enabled in `flag`, - // then we throw an error. - if flag != mirror { - throw_unsup_format!("unsupported flags {:#x}", flag & !mirror); + // If `flag` has any bits left set, those are not supported. + if flag != 0 { + throw_unsup_format!("unsupported flags {:#x}", flag); } // Reject if isolation is enabled.
diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index f9b3ca4..8f2ab69 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs
@@ -620,6 +620,48 @@ fn getsockname( Err(e) => this.set_last_error_and_return_i32(e), } } + + fn getpeername( + &mut self, + socket: &OpTy<'tcx>, + address: &OpTy<'tcx>, + address_len: &OpTy<'tcx>, + ) -> InterpResult<'tcx, Scalar> { + let this = self.eval_context_mut(); + + let socket = this.read_scalar(socket)?.to_i32()?; + let address_ptr = this.read_pointer(address)?; + let address_len_ptr = this.read_pointer(address_len)?; + + // Get the file handle + let Some(fd) = this.machine.fds.get(socket) else { + return this.set_last_error_and_return_i32(LibcError("EBADF")); + }; + + let Some(socket) = fd.downcast::<Socket>() else { + // Man page specifies to return ENOTSOCK if `fd` is not a socket. + return this.set_last_error_and_return_i32(LibcError("ENOTSOCK")); + }; + + assert!(this.machine.communicate(), "cannot have `Socket` with isolation enabled!"); + + let state = socket.state.borrow(); + + let SocketState::Connected(stream) = &*state else { + // We can only read the peer address of connected sockets. + return this.set_last_error_and_return_i32(LibcError("ENOTCONN")); + }; + + let address = match stream.peer_addr() { + Ok(address) => address, + Err(e) => return this.set_last_error_and_return_i32(e), + }; + + match this.write_socket_address(&address, address_ptr, address_len_ptr, "getpeername")? { + Ok(_) => interp_ok(Scalar::from_i32(0)), + Err(e) => this.set_last_error_and_return_i32(e), + } + } } impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {}
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 2d1a153..16e269c 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -451,6 +451,16 @@ fn emulate_foreign_item_inner( this.SetFilePointerEx(file, distance_to_move, new_file_pointer, move_method)?; this.write_scalar(res, dest)?; } + "MoveFileExW" => { + let [existing_name, new_name, flags] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _, *const _, u32) -> winapi::BOOL), + link_name, + abi, + args, + )?; + let res = this.MoveFileExW(existing_name, new_name, flags)?; + this.write_scalar(res, dest)?; + } // Allocation "HeapAlloc" => {
diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index e5a98e8..1ee93cf 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs
@@ -490,6 +490,36 @@ fn FlushFileBuffers( } } + fn MoveFileExW( + &mut self, + existing_name: &OpTy<'tcx>, + new_name: &OpTy<'tcx>, + flags: &OpTy<'tcx>, + ) -> InterpResult<'tcx, Scalar> { + let this = self.eval_context_mut(); + + let existing_name = this.read_path_from_wide_str(this.read_pointer(existing_name)?)?; + let new_name = this.read_path_from_wide_str(this.read_pointer(new_name)?)?; + + let flags = this.read_scalar(flags)?.to_u32()?; + + // Flag to indicate whether we should replace an existing file. + // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefileexw + let movefile_replace_existing = this.eval_windows_u32("c", "MOVEFILE_REPLACE_EXISTING"); + + if flags != movefile_replace_existing { + throw_unsup_format!("MoveFileExW: Unsupported `dwFlags` value {}", flags); + } + + match std::fs::rename(existing_name, new_name) { + Ok(_) => interp_ok(this.eval_windows("c", "TRUE")), + Err(e) => { + this.set_last_error(e)?; + interp_ok(this.eval_windows("c", "FALSE")) + } + } + } + fn DeleteFileW( &mut self, file_name: &OpTy<'tcx>, // LPCWSTR
diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 7c0f9c5..6b0e672 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs
@@ -5,6 +5,7 @@ use rustc_target::callconv::FnAbi; use rustc_target::spec::Arch; +use crate::shims::math::compute_crc32; use crate::*; /// A bitmask constant for scrutinizing the immediate byte provided @@ -445,46 +446,19 @@ fn emulate_x86_sse42_intrinsic( // The 64-bit version will only consider the lower 32 bits, // while the upper 32 bits get discarded. #[expect(clippy::as_conversions)] - u128::from((left.to_u64()? as u32).reverse_bits()) + (left.to_u64()? as u32) } else { - u128::from(left.to_u32()?.reverse_bits()) + left.to_u32()? }; - let v = match bit_size { - 8 => u128::from(right.to_u8()?.reverse_bits()), - 16 => u128::from(right.to_u16()?.reverse_bits()), - 32 => u128::from(right.to_u32()?.reverse_bits()), - 64 => u128::from(right.to_u64()?.reverse_bits()), + let data = match bit_size { + 8 => u64::from(right.to_u8()?), + 16 => u64::from(right.to_u16()?), + 32 => u64::from(right.to_u32()?), + 64 => right.to_u64()?, _ => unreachable!(), }; - // Perform polynomial division modulo 2. - // The algorithm for the division is an adapted version of the - // schoolbook division algorithm used for normal integer or polynomial - // division. In this context, the quotient is not calculated, since - // only the remainder is needed. - // - // The algorithm works as follows: - // 1. Pull down digits until division can be performed. In the context of division - // modulo 2 it means locating the most significant digit of the dividend and shifting - // the divisor such that the position of the divisors most significand digit and the - // dividends most significand digit match. - // 2. Perform a division and determine the remainder. Since it is arithmetic modulo 2, - // this operation is a simple bitwise exclusive or. - // 3. Repeat steps 1. and 2. until the full remainder is calculated. This is the case - // once the degree of the remainder polynomial is smaller than the degree of the - // divisor polynomial. In other words, the number of leading zeros of the remainder - // is larger than the number of leading zeros of the divisor. It is important to - // note that standard arithmetic comparison is not applicable here: - // 0b10011 / 0b11111 = 0b01100 is a valid division, even though the dividend is - // smaller than the divisor. - let mut dividend = (crc << bit_size) ^ (v << 32); - const POLYNOMIAL: u128 = 0x11EDC6F41; - while dividend.leading_zeros() <= POLYNOMIAL.leading_zeros() { - dividend ^= - (POLYNOMIAL << POLYNOMIAL.leading_zeros()) >> dividend.leading_zeros(); - } - - let result = u32::try_from(dividend).unwrap().reverse_bits(); + let result = compute_crc32(crc, data, bit_size, 0x11EDC6F41); let result = if bit_size == 64 { Scalar::from_u64(u64::from(result)) } else {
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs index 6fec650..0245376 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs
@@ -5,6 +5,7 @@ use std::{mem, ptr}; extern "C" fn thread_start() -> *mut libc::c_void { + //~^ERROR: calling a function with more arguments than it expected panic!() } @@ -16,7 +17,6 @@ fn main() { mem::transmute(thread_start); assert_eq!( libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), - //~^ERROR: calling a function with more arguments than it expected 0 ); assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr index 979a1a8..e3509a2 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr
@@ -1,14 +1,17 @@ error: Undefined Behavior: calling a function with more arguments than it expected --> tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs:LL:CC | -LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code +LL | extern "C" fn thread_start() -> *mut libc::c_void { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = 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: this is on thread `unnamed-ID` - = note: this error occurred while pushing a call frame onto an empty stack - = note: the span indicates which code caused the function to be called, but may not be the literal call site +note: the current function got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs:LL:CC + | +LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs index cb55b0f..28fdb1d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs
@@ -5,6 +5,7 @@ use std::{mem, ptr}; extern "C" fn thread_start(_null: *mut libc::c_void, _x: i32) -> *mut libc::c_void { + //~^ERROR: calling a function with fewer arguments than it requires panic!() } @@ -16,7 +17,6 @@ fn main() { mem::transmute(thread_start); assert_eq!( libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), - //~^ERROR: calling a function with fewer arguments than it requires 0 ); assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr index e8ad65a..d6504f6 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr
@@ -1,14 +1,17 @@ error: Undefined Behavior: calling a function with fewer arguments than it requires --> tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs:LL:CC | -LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code +LL | extern "C" fn thread_start(_null: *mut libc::c_void, _x: i32) -> *mut libc::c_void { + | ^^ Undefined Behavior occurred here | = 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: this is on thread `unnamed-ID` - = note: this error occurred while pushing a call frame onto an empty stack - = note: the span indicates which code caused the function to be called, but may not be the literal call site +note: the current function got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs:LL:CC + | +LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error
diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs index 5c80f64..b1929e3 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs
@@ -7,7 +7,7 @@ fn main() { let t = thread::spawn(|| unsafe { // Access the environment in another thread without taking the env lock. // This represents some C code that queries the environment. - libc::getenv(b"TZ\0".as_ptr().cast()); //~ERROR: Data race detected + libc::getenv(c"TZ".as_ptr()); //~ERROR: Data race detected }); // Meanwhile, the main thread uses the "safe" Rust env accessor. env::set_var("MY_RUST_VAR", "Ferris");
diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr index 635091cc..b4cd31b 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC --> tests/fail-dep/libc/env-set_var-data-race.rs:LL:CC | -LL | libc::getenv(b"TZ/0".as_ptr().cast()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (2) just happened here +LL | libc::getenv(c"TZ".as_ptr()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (2) just happened here | help: and (1) occurred earlier here --> tests/fail-dep/libc/env-set_var-data-race.rs:LL:CC @@ -19,7 +19,7 @@ | _____________^ LL | | // Access the environment in another thread without taking the env lock. LL | | // This represents some C code that queries the environment. -LL | | libc::getenv(b"TZ/0".as_ptr().cast()); +LL | | libc::getenv(c"TZ".as_ptr()); LL | | }); | |______^
diff --git a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs index 2c676f1..abdafe2 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs +++ b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs
@@ -6,6 +6,6 @@ fn main() { } fn test_mkstemp_immutable_arg() { - let s: *mut libc::c_char = b"fooXXXXXX\0" as *const _ as *mut _; + let s: *mut libc::c_char = c"fooXXXXXX".as_ptr().cast_mut(); let _fd = unsafe { libc::mkstemp(s) }; //~ ERROR: Undefined Behavior: writing to alloc1 which is read-only }
diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs index 457f32e..29548c1 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs
@@ -6,7 +6,6 @@ fn main() { } fn test_file_open_missing_needed_mode() { - let name = b"missing_arg.txt\0"; - let name_ptr = name.as_ptr().cast::<libc::c_char>(); - let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: not enough variadic arguments + let name = c"missing_arg.txt".as_ptr(); + let _fd = unsafe { libc::open(name, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: not enough variadic arguments }
diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr index a85fae9..186ca4c 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: not enough variadic arguments for `open(pathname, O_CREAT, ...)`: got 0, expected at least 1 --> tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC | -LL | let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | let _fd = unsafe { libc::open(name, libc::O_CREAT) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = 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-dep/libc/libc-read-and-uninit-premature-eof.stderr b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr index 9d5e119..214b626 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [3]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type [u8; 4]: at [3], encountered uninitialized memory, but expected an integer --> tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs:LL:CC | LL | buf.assume_init();
diff --git a/src/tools/miri/tests/fail/branchless-select-i128-pointer.rs b/src/tools/miri/tests/fail/branchless-select-i128-pointer.rs index 7147813..b425916 100644 --- a/src/tools/miri/tests/fail/branchless-select-i128-pointer.rs +++ b/src/tools/miri/tests/fail/branchless-select-i128-pointer.rs
@@ -14,7 +14,7 @@ fn main() { // However, it drops provenance when transmuting to TwoPtrs, so this is UB. let val = unsafe { transmute::<_, &str>( - //~^ ERROR: constructing invalid value: encountered a dangling reference + //~^ ERROR: encountered a dangling reference !mask & transmute::<_, TwoPtrs>("false !") | mask & transmute::<_, TwoPtrs>("true !"), )
diff --git a/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr b/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr index abcaf90..83dc2dd 100644 --- a/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr +++ b/src/tools/miri/tests/fail/branchless-select-i128-pointer.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference ($HEX[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &str: encountered a dangling reference ($HEX[noalloc] has no provenance) --> tests/fail/branchless-select-i128-pointer.rs:LL:CC | LL | / transmute::<_, &str>(
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 afc2cb2..4f06a1a 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr
@@ -2,7 +2,7 @@ --> tests/fail/dangling_pointers/dangling_primitive.rs:LL:CC | LL | dbg!(*ptr); - | ^^^^^^^^^^ Undefined Behavior occurred here + | ^^^^ Undefined Behavior occurred here | = 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_dangling_box.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr index 0ae38c3..6467131 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling box (0x18[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<i32>: encountered a dangling box (0x18[noalloc] has no provenance) --> tests/fail/dangling_pointers/deref_dangling_box.rs:LL:CC | LL | let _val = unsafe { addr_of_mut!(**outer) };
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 index c10dc19..5520947 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (0x18[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &mut i32: encountered a dangling reference (0x18[noalloc] has no provenance) --> tests/fail/dangling_pointers/deref_dangling_ref.rs:LL:CC | LL | let _val = unsafe { addr_of_mut!(**outer) };
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 74102f7..df82e08 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error: Undefined Behavior: constructing invalid value of type &SliceWithHead: encountered a dangling reference (going beyond the bounds of its allocation) --> tests/fail/dangling_pointers/dyn_size.rs:LL:CC | LL | let _ptr = unsafe { &*ptr };
diff --git a/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr b/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr index 65ad97f..86a695f 100644 --- a/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr +++ b/src/tools/miri/tests/fail/dyn-upcast-nop-wrong-trait.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug + std::marker::Send + std::marker::Sync`, but encountered `std::fmt::Display` +error: Undefined Behavior: constructing invalid value of type *const dyn std::fmt::Debug + std::marker::Send + std::marker::Sync: wrong trait in wide pointer vtable: expected `std::fmt::Debug + std::marker::Send + std::marker::Sync`, but encountered `std::fmt::Display` --> tests/fail/dyn-upcast-nop-wrong-trait.rs:LL:CC | LL | let ptr: *const (dyn fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) };
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs index b6cda60..1fb597f 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs
@@ -21,8 +21,6 @@ fn main() { // This specifically uses a type with scalar representation to tempt Miri to use the // efficient way of storing local variables (outside adressable memory). Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) - //~[stack]^ ERROR: not granting access - //~[tree]| ERROR: /read access .* forbidden/ } after_call = { Return() @@ -32,6 +30,8 @@ fn main() { #[expect(unused_variables, unused_assignments)] fn callee(x: S, mut y: S) { + //~[stack]^ ERROR: not granting access + //~[tree]| ERROR: /read access .* forbidden/ // With the setup above, if `x` and `y` are both moved, // then writing to `y` will change the value stored in `x`! y.0 = 0;
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr index a86c68c..14df4eb 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.stack.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC | -LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn callee(x: S, mut y: S) { + | ^^^^^ Undefined Behavior occurred here | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -14,8 +14,13 @@ help: <TAG> is this argument --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC | -LL | y.0 = 0; - | ^^^^^^^ +LL | fn callee(x: S, mut y: S) { + | ^ + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_locals_alias.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/function_calls/arg_inplace_locals_alias.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr index d62adee..7012c4f 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.tree.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: read access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC | -LL | Call(_unit = callee(Move(non_copy), Move(non_copy)), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn callee(x: S, mut y: S) { + | ^^^^^ Undefined Behavior occurred here | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information @@ -17,14 +17,19 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC | -LL | y.0 = 0; - | ^^^^^^^ +LL | fn callee(x: S, mut y: S) { + | ^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC | -LL | y.0 = 0; - | ^^^^^^^ +LL | fn callee(x: S, mut y: S) { + | ^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_locals_alias.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_locals_alias.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/function_calls/arg_inplace_locals_alias_ret.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs index 3cb8ee2..b3d43ca 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs
@@ -20,8 +20,6 @@ fn main() { // This specifically uses a type with scalar representation to tempt Miri to use the // efficient way of storing local variables (outside adressable memory). Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue()) - //~[stack]^ ERROR: not granting access - //~[tree]| ERROR: /reborrow .* forbidden/ } after_call = { Return() @@ -30,5 +28,7 @@ fn main() { } fn callee(x: S) -> S { + //~[stack]^ ERROR: not granting access + //~[tree]| ERROR: /reborrow .* forbidden/ x }
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr index 491d01c..21fcfb9 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC | -LL | Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn callee(x: S) -> S { + | ^ Undefined Behavior occurred here | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -14,8 +14,13 @@ help: <TAG> is this argument --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC | -LL | x - | ^ +LL | fn callee(x: S) -> S { + | ^ + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_locals_alias_ret.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/function_calls/arg_inplace_locals_alias_ret.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr index 3c1038d..e4d4e87 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr
@@ -1,8 +1,8 @@ error: Undefined Behavior: reborrow through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC | -LL | Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn callee(x: S) -> S { + | ^ Undefined Behavior occurred here | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information @@ -17,14 +17,19 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC | -LL | x - | ^ +LL | fn callee(x: S) -> S { + | ^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC | -LL | x - | ^ +LL | fn callee(x: S) -> S { + | ^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_locals_alias_ret.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/function_calls/arg_inplace_mutate.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr index 952f227..c754acd 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
@@ -19,8 +19,8 @@ help: <TAG> is this argument --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC | -LL | unsafe { ptr.write(S(0)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn callee(x: S, ptr: *mut S) { + | ^ = note: stack backtrace: 0: callee at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr index 095dc7e..c210d5c 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
@@ -22,13 +22,13 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC | -LL | unsafe { ptr.write(S(0)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn callee(x: S, ptr: *mut S) { + | ^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC | -LL | unsafe { ptr.write(S(0)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn callee(x: S, ptr: *mut S) { + | ^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference = note: stack backtrace: 0: callee
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr index d625d1d..b7eb3c5 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
@@ -19,8 +19,8 @@ help: <TAG> is this argument --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | -LL | x.0 = 0; - | ^^^^^^^ +LL | fn change_arg(mut x: S, ptr: *mut S) { + | ^^^^^ = note: stack backtrace: 0: change_arg at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr index a01c040..e79cf08 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
@@ -22,13 +22,13 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | -LL | x.0 = 0; - | ^^^^^^^ +LL | fn change_arg(mut x: S, ptr: *mut S) { + | ^^^^^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | -LL | x.0 = 0; - | ^^^^^^^ +LL | fn change_arg(mut x: S, ptr: *mut S) { + | ^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference = note: stack backtrace: 0: change_arg
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.rs b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.rs index a108944..81fa672 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.rs +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.rs
@@ -1,9 +1,9 @@ #[no_mangle] -fn foo() {} +fn foo() {} //~ ERROR: calling a function with more arguments than it expected fn main() { extern "Rust" { fn foo(_: i32); } - unsafe { foo(1) } //~ ERROR: calling a function with more arguments than it expected + unsafe { foo(1) } }
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr index 75c060e..4c481e8 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_wrong_arguments.stderr
@@ -1,11 +1,16 @@ error: Undefined Behavior: calling a function with more arguments than it expected --> tests/fail/function_calls/exported_symbol_wrong_arguments.rs:LL:CC | -LL | unsafe { foo(1) } - | ^^^^^^ Undefined Behavior occurred here +LL | fn foo() {} + | ^^^^^^^^ Undefined Behavior occurred here | = 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: stack backtrace: + 0: foo + at tests/fail/function_calls/exported_symbol_wrong_arguments.rs:LL:CC + 1: main + at tests/fail/function_calls/exported_symbol_wrong_arguments.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/function_calls/return_pointer_aliasing_read.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr index 73c562c..5cf0fd4 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr
@@ -19,8 +19,8 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | unsafe { ptr.read() }; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ = note: stack backtrace: 0: myfun at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr index 0dc1378..cc5f4a8 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr
@@ -22,13 +22,13 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | unsafe { ptr.read() }; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | -LL | unsafe { ptr.read() }; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference = note: stack backtrace: 0: myfun
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr index 6654ddc..133aa8c 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr
@@ -19,8 +19,8 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ = note: stack backtrace: 0: myfun at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr index 6472dfd..fb87eea 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr
@@ -22,13 +22,13 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference = note: stack backtrace: 0: myfun
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr index 79f4d2c..07ed6d1 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr
@@ -19,8 +19,8 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | become myfun2(ptr) - | ^^^^^^^^^^^^^^^^^^ +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^ = note: stack backtrace: 0: myfun2 at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr index 82b898d..e3c5d6b 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr
@@ -22,13 +22,13 @@ help: the protected tag <TAG> was created here, in the initial state Reserved --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun2(ptr: *mut i32) -> i32 { + | ^^^ help: the protected tag <TAG> later transitioned to Unique due to a child write access at offsets [0x0..0x4] --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | -LL | unsafe { ptr.write(0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn myfun2(ptr: *mut i32) -> i32 { + | ^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference = note: stack backtrace: 0: myfun2
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr index 364a4b4..88d5694 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
@@ -7,7 +7,7 @@ --> tests/fail/function_calls/return_pointer_on_unwind.rs:LL:CC | LL | dbg!(x.0); - | ^^^^^^^^^ Undefined Behavior occurred here + | ^^^ Undefined Behavior occurred here | = 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/abi_mismatch_array_vs_struct.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs index 26f2e73..beb0f72 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs
@@ -12,10 +12,10 @@ struct S( type A = [i32; 4]; fn main() { - fn f(_: S) {} + fn f(_: S) {} //~ ERROR: type S passing argument of type [i32; 4] // These two types have the same size but are still not compatible. let g = unsafe { std::mem::transmute::<fn(S), fn(A)>(f) }; - g(Default::default()) //~ ERROR: type S passing argument of type [i32; 4] + g(Default::default()) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr index 56e69e8..62ba807 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type S passing argument of type [i32; 4] --> tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs:LL:CC | -LL | g(Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn f(_: S) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_array_vs_struct.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/function_pointers/abi_mismatch_int_vs_float.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.rs index 0cca4a1..a40e5b4 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.rs
@@ -1,7 +1,7 @@ fn main() { - fn f(_: f32) {} + fn f(_: f32) {} //~ ERROR: type f32 passing argument of type i32 let g = unsafe { std::mem::transmute::<fn(f32), fn(i32)>(f) }; - g(42) //~ ERROR: type f32 passing argument of type i32 + g(42) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr index cbef9d2..8147d00 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type f32 passing argument of type i32 --> tests/fail/function_pointers/abi_mismatch_int_vs_float.rs:LL:CC | -LL | g(42) - | ^^^^^ Undefined Behavior occurred here +LL | fn f(_: f32) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_int_vs_float.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_int_vs_float.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/function_pointers/abi_mismatch_raw_pointer.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.rs index 053a4a5..8c2d064 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.rs
@@ -1,7 +1,7 @@ fn main() { - fn f(_: *const [i32]) {} + fn f(_: *const [i32]) {} //~ ERROR: type *const [i32] passing argument of type *const i32 let g = unsafe { std::mem::transmute::<fn(*const [i32]), fn(*const i32)>(f) }; - g(&42 as *const i32) //~ ERROR: type *const [i32] passing argument of type *const i32 + g(&42 as *const i32) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr index cd14ea1..f9195a8 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type *const [i32] passing argument of type *const i32 --> tests/fail/function_pointers/abi_mismatch_raw_pointer.rs:LL:CC | -LL | g(&42 as *const i32) - | ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn f(_: *const [i32]) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_raw_pointer.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_raw_pointer.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/function_pointers/abi_mismatch_repr_C.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs index f3dffcc..79485a2 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs
@@ -7,10 +7,10 @@ struct S2(i32); fn callee(_s: S2) {} +//~^ ERROR: type S2 passing argument of type S1 fn main() { let fnptr: fn(S2) = callee; let fnptr: fn(S1) = unsafe { std::mem::transmute(fnptr) }; fnptr(S1(NonZero::new(1).unwrap())); - //~^ ERROR: type S2 passing argument of type S1 }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr index 0e52dc0..3e4be1e 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type S2 passing argument of type S1 --> tests/fail/function_pointers/abi_mismatch_repr_C.rs:LL:CC | -LL | fnptr(S1(NonZero::new(1).unwrap())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn callee(_s: S2) {} + | ^^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: callee + at tests/fail/function_pointers/abi_mismatch_repr_C.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_repr_C.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/function_pointers/abi_mismatch_return_type.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.rs index 05b645c..3f9c42a 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.rs
@@ -1,9 +1,10 @@ fn main() { fn f() -> u32 { + //~^ERROR: type u32 passing return place of type () 42 } let g = unsafe { std::mem::transmute::<fn() -> u32, fn()>(f) }; - g() //~ ERROR: type u32 passing return place of type () + g() }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr index ba94090..9f20618 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function with return type u32 passing return place of type () --> tests/fail/function_pointers/abi_mismatch_return_type.rs:LL:CC | -LL | g() - | ^^^ Undefined Behavior occurred here +LL | fn f() -> u32 { + | ^^^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_return_type.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_return_type.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/function_pointers/abi_mismatch_simple.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.rs index ca43c06..0b06496 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.rs
@@ -1,7 +1,7 @@ fn main() { - fn f(_: (i32, i32)) {} + fn f(_: (i32, i32)) {} //~ ERROR: type (i32, i32) passing argument of type i32 let g = unsafe { std::mem::transmute::<fn((i32, i32)), fn(i32)>(f) }; - g(42) //~ ERROR: type (i32, i32) passing argument of type i32 + g(42) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr index ab9c0e7..b85ac39 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type (i32, i32) passing argument of type i32 --> tests/fail/function_pointers/abi_mismatch_simple.rs:LL:CC | -LL | g(42) - | ^^^^^ Undefined Behavior occurred here +LL | fn f(_: (i32, i32)) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_simple.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_simple.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/function_pointers/abi_mismatch_too_few_args.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.rs index 920fb51..fc9a107 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.rs
@@ -1,7 +1,7 @@ fn main() { - fn f(_: (i32, i32)) {} + fn f(_: (i32, i32)) {} //~ ERROR: calling a function with fewer arguments than it requires let g = unsafe { std::mem::transmute::<fn((i32, i32)), fn()>(f) }; - g() //~ ERROR: calling a function with fewer arguments than it requires + g() }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr index 06e6ccb..271ec64 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_few_args.stderr
@@ -1,11 +1,16 @@ error: Undefined Behavior: calling a function with fewer arguments than it requires --> tests/fail/function_pointers/abi_mismatch_too_few_args.rs:LL:CC | -LL | g() - | ^^^ Undefined Behavior occurred here +LL | fn f(_: (i32, i32)) {} + | ^ Undefined Behavior occurred here | = 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: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_too_few_args.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_too_few_args.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/function_pointers/abi_mismatch_too_many_args.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.rs index c0e96a4..744c528 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.rs
@@ -1,7 +1,7 @@ fn main() { - fn f() {} + fn f() {} //~ ERROR: calling a function with more arguments than it expected let g = unsafe { std::mem::transmute::<fn(), fn(i32)>(f) }; - g(42) //~ ERROR: calling a function with more arguments than it expected + g(42) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr index d343eb8..1721f0f 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_too_many_args.stderr
@@ -1,11 +1,16 @@ error: Undefined Behavior: calling a function with more arguments than it expected --> tests/fail/function_pointers/abi_mismatch_too_many_args.rs:LL:CC | -LL | g(42) - | ^^^^^ Undefined Behavior occurred here +LL | fn f() {} + | ^^^^^^ Undefined Behavior occurred here | = 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: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_too_many_args.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_too_many_args.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/function_pointers/abi_mismatch_vector.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.rs index dedcaac..ed5b469 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.rs
@@ -2,10 +2,10 @@ use std::simd; fn main() { - fn f(_: simd::u32x8) {} + fn f(_: simd::u32x8) {} //~ ERROR: type std::simd::Simd<u32, 8> passing argument of type std::simd::Simd<u64, 4> // These two vector types have the same size but are still not compatible. let g = unsafe { std::mem::transmute::<fn(simd::u32x8), fn(simd::u64x4)>(f) }; - g(Default::default()) //~ ERROR: type std::simd::Simd<u32, 8> passing argument of type std::simd::Simd<u64, 4> + g(Default::default()) }
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr index 1176589..59823fa 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type std::simd::Simd<u32, 8> passing argument of type std::simd::Simd<u64, 4> --> tests/fail/function_pointers/abi_mismatch_vector.rs:LL:CC | -LL | g(Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn f(_: simd::u32x8) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: main::f + at tests/fail/function_pointers/abi_mismatch_vector.rs:LL:CC + 1: main + at tests/fail/function_pointers/abi_mismatch_vector.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/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 6cdcd11..e366aa9 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered 0x02, but expected a boolean +error: Undefined Behavior: constructing invalid value of type [bool; 100]: at [0], encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | LL | typed_swap_nonoverlapping(a, b);
diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr index 223f743..58e2030 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean +error: Undefined Behavior: constructing invalid value of type bool: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | LL | typed_swap_nonoverlapping(a, b);
diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr index 59e3920..b5bf8d7 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0x03, but expected a boolean +error: Undefined Behavior: constructing invalid value of type bool: encountered 0x03, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | LL | typed_swap_nonoverlapping(a, b);
diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr index d0f7cc1..47acb43 100644 --- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr +++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a value of the never type `!` +error: Undefined Behavior: constructing invalid value of type !: encountered a value of the never type `!` --> tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC | LL | let _ = unsafe { std::mem::uninitialized::<!>() };
diff --git a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr index 1646721..ab6f913 100644 --- a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a null function pointer +error: Undefined Behavior: constructing invalid value of type fn(): encountered a null function pointer --> tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC | LL | let _ = unsafe { std::mem::zeroed::<fn()>() };
diff --git a/src/tools/miri/tests/fail/issue-miri-1112.stderr b/src/tools/miri/tests/fail/issue-miri-1112.stderr index 0c5c6a9..9873591 100644 --- a/src/tools/miri/tests/fail/issue-miri-1112.stderr +++ b/src/tools/miri/tests/fail/issue-miri-1112.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered $HEX[ALLOC]<TAG>, but expected a vtable pointer +error: Undefined Behavior: constructing invalid value of type *mut FunnyPointer: encountered $HEX[ALLOC]<TAG>, but expected a vtable pointer --> tests/fail/issue-miri-1112.rs:LL:CC | LL | let obj = std::mem::transmute::<FatPointer, *mut FunnyPointer>(obj);
diff --git a/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr index cbb74df..9bbbc1b 100644 --- a/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr +++ b/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) +error: Undefined Behavior: constructing invalid value of type &u32: encountered a dangling reference (use-after-free) --> tests/fail/match/closures/deref-in-pattern.rs:LL:CC | LL | let _ = || {
diff --git a/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr index b8ca045..ab50f9b 100644 --- a/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr +++ b/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) +error: Undefined Behavior: constructing invalid value of type &u32: encountered a dangling reference (use-after-free) --> tests/fail/match/closures/partial-pattern.rs:LL:CC | LL | let _ = || {
diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr index 6f097c3..8a3448f 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance0.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference ($HEX[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference ($HEX[noalloc] has no provenance) --> tests/fail/provenance/int_copy_looses_provenance0.rs:LL:CC | LL | let _val = unsafe { *ptr.read() };
diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr index f3d1d8c..d4fb5b5 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance1.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference ($HEX[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference ($HEX[noalloc] has no provenance) --> tests/fail/provenance/int_copy_looses_provenance1.rs:LL:CC | LL | let _val = unsafe { *ptr.read() };
diff --git a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr index 8374232..bdeb8a4 100644 --- a/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr +++ b/src/tools/miri/tests/fail/provenance/int_copy_looses_provenance2.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference ($HEX[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference ($HEX[noalloc] has no provenance) --> tests/fail/provenance/int_copy_looses_provenance2.rs:LL:CC | LL | let _val = unsafe { *ptr.read() };
diff --git a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs index 3629e43..1e10f68 100644 --- a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs +++ b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs
@@ -1,4 +1,5 @@ unsafe extern "C" fn ctor() -> i32 { + //~^ERROR: calling a function with return type i32 passing return place of type () 0 } @@ -30,7 +31,6 @@ macro_rules! ctor { )] #[used] static $ident: unsafe extern "C" fn() -> i32 = $ctor; - //~^ERROR: calling a function with return type i32 passing return place of type () }; }
diff --git a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr index 1b4cd23..4e474db 100644 --- a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr +++ b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr
@@ -1,18 +1,21 @@ error: Undefined Behavior: calling a function with return type i32 passing return place of type () --> tests/fail/shims/ctor_wrong_ret_type.rs:LL:CC | -LL | static $ident: unsafe extern "C" fn() -> i32 = $ctor; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code -... -LL | ctor! { CTOR = ctor } - | --------------------- in this macro invocation +LL | unsafe extern "C" fn ctor() -> i32 { + | ^^^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri - = note: this error occurred while pushing a call frame onto an empty stack - = note: the span indicates which code caused the function to be called, but may not be the literal call site +note: the current function got called indirectly due to this code + --> tests/fail/shims/ctor_wrong_ret_type.rs:LL:CC + | +LL | static $ident: unsafe extern "C" fn() -> i32 = $ctor; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | ctor! { CTOR = ctor } + | --------------------- in this macro invocation = note: this error originates in the macro `ctor` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error
diff --git a/src/tools/miri/tests/fail/storage-live-resets-var.stderr b/src/tools/miri/tests/fail/storage-live-resets-var.stderr index b3dd4ea..418e5f5 100644 --- a/src/tools/miri/tests/fail/storage-live-resets-var.stderr +++ b/src/tools/miri/tests/fail/storage-live-resets-var.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type i32: encountered uninitialized memory, but expected an integer --> tests/fail/storage-live-resets-var.rs:LL:CC | LL | _val2 = val;
diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs index 36bd1e9..e747bfd 100644 --- a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs
@@ -2,16 +2,14 @@ #![allow(incomplete_features)] fn main() { - // FIXME(explicit_tail_calls): - // the error should point to `become g(x)`, - // but tail calls mess up the backtrace it seems like... f(0); - //~^ error: type i32 passing argument of type u32 } fn f(x: u32) { let g = unsafe { std::mem::transmute::<fn(i32), fn(u32)>(g) }; - become g(x); + become g(x); // FIXME ideally this should also be involved in the error somehow, + // but by the time we pass the argument, `f`'s stackframe has already been popped. } fn g(_: i32) {} +//~^ error: type i32 passing argument of type u32
diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr index f5eccae..9c10db8 100644 --- a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr
@@ -1,13 +1,18 @@ error: Undefined Behavior: calling a function whose parameter #1 has type i32 passing argument of type u32 --> tests/fail/tail_calls/signature-mismatch-arg.rs:LL:CC | -LL | f(0); - | ^^^^ Undefined Behavior occurred here +LL | fn g(_: i32) {} + | ^ Undefined Behavior occurred here | = 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: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: stack backtrace: + 0: g + at tests/fail/tail_calls/signature-mismatch-arg.rs:LL:CC + 1: main + at tests/fail/tail_calls/signature-mismatch-arg.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/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index 2b98a2f..ea4b495 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,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +error: Undefined Behavior: constructing invalid value of type &mut PartialDrop: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | LL | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
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 0be5ef9..7c85a3b 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +error: Undefined Behavior: constructing invalid value of type &dyn std::fmt::Debug: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> tests/fail/unaligned_pointers/dyn_alignment.rs:LL:CC | LL | let _ptr = &*ptr;
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.rs b/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.rs index 92917c8..38ec7a7 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.rs
@@ -10,6 +10,6 @@ fn main() { unsafe { let unaligned = MaybeDangling::new(a.as_ptr().byte_add(1)); transmute::<MaybeDangling<*const u16>, MaybeDangling<&u16>>(unaligned) - //~^ ERROR: Undefined Behavior: constructing invalid value: encountered an unaligned reference + //~^ ERROR: encountered an unaligned reference }; }
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.stderr b/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.stderr index 9a50a03..190976c 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/maybe_dangling_unalighed.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +error: Undefined Behavior: constructing invalid value of type std::mem::MaybeDangling<&u16>: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> tests/fail/unaligned_pointers/maybe_dangling_unalighed.rs:LL:CC | LL | transmute::<MaybeDangling<*const u16>, MaybeDangling<&u16>>(unaligned)
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 2f30793..d8252e5 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,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +error: Undefined Behavior: constructing invalid value of type &i32: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC | LL | mem::transmute(x)
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 index dfd6c14..8527317 100644 --- 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
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +error: Undefined Behavior: constructing invalid value of type &u32: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs:LL:CC | LL | let _x = unsafe { &*x };
diff --git a/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr b/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr index 2b0dbd3..cf22b56 100644 --- a/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-struct-in-union.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .bytes[2]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type Bar: at .bytes[2], encountered uninitialized memory, but expected an integer --> tests/fail/uninit/padding-struct-in-union.rs:LL:CC | LL | let _val = unsafe { (foobar.foo, foobar.bar) };
diff --git a/src/tools/miri/tests/fail/uninit/padding-union.stderr b/src/tools/miri/tests/fail/uninit/padding-union.stderr index 30d0862..7851bb6 100644 --- a/src/tools/miri/tests/fail/uninit/padding-union.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-union.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [1]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type [u8; 4]: at [1], encountered uninitialized memory, but expected an integer --> tests/fail/uninit/padding-union.rs:LL:CC | LL | let _val = *c;
diff --git a/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr b/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr index e8deb57..d4048bb 100644 --- a/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit-after-aggregate-assign.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [1]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type [u8; 4]: at [1], encountered uninitialized memory, but expected an integer --> tests/fail/uninit/uninit-after-aggregate-assign.rs:LL:CC | LL | _val = *sptr2; // should hence be UB
diff --git a/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr b/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr index b470e79..3de7f6c 100644 --- a/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr +++ b/src/tools/miri/tests/fail/validity/box-custom-alloc-dangling-ptr.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling box (0x4[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<i32, MyAlloc>: encountered a dangling box (0x4[noalloc] has no provenance) --> tests/fail/validity/box-custom-alloc-dangling-ptr.rs:LL:CC | LL | std::mem::transmute(b)
diff --git a/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr b/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr index d7594ab..f2fa738 100644 --- a/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr +++ b/src/tools/miri/tests/fail/validity/box-custom-alloc-invalid-alloc.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .1.my_alloc_field1: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<i32, MyAlloc>: at .1.my_alloc_field1, encountered uninitialized memory, but expected an integer --> tests/fail/validity/box-custom-alloc-invalid-alloc.rs:LL:CC | LL | std::mem::transmute(b)
diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs index 6ab7356..8657e3a 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs
@@ -5,9 +5,9 @@ fn main() { // from raw ptr to reference. This is ABI-compatible, so it's not the call that // should fail, but validation should. fn f(_x: &i32) {} + //~^ ERROR: encountered a null reference let g: fn(*const i32) = unsafe { std::mem::transmute(f as fn(&i32)) }; g(0usize as *const i32) - //~^ ERROR: encountered a null reference }
diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr index 02e0ebe..1859ec5 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_arg.stderr
@@ -1,11 +1,16 @@ -error: Undefined Behavior: constructing invalid value: encountered a null reference +error: Undefined Behavior: constructing invalid value of type &i32: encountered a null reference --> tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs:LL:CC | -LL | g(0usize as *const i32) - | ^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn f(_x: &i32) {} + | ^^ Undefined Behavior occurred here | = 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: stack backtrace: + 0: main::f + at tests/fail/validity/cast_fn_ptr_invalid_callee_arg.rs:LL:CC + 1: main + at tests/fail/validity/cast_fn_ptr_invalid_callee_arg.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/validity/cast_fn_ptr_invalid_callee_ret.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr index 6fc1bc0..26db49e 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value of type std::num::NonZero<u32>: at .0.0, encountered 0, but expected something greater or equal to 1 --> tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs:LL:CC | LL | f();
diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs index 7ca26bf..0635fdd 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs
@@ -6,6 +6,7 @@ use std::ptr; fn f(c: u32) { + //~^ERROR: expected something greater or equal to 1 println!("{c}"); } @@ -20,7 +21,7 @@ fn call(f: fn(NonZero<u32>)) { let tmp = ptr::addr_of!(c); let ptr = tmp as *const NonZero<u32>; // The call site now is a `NonZero<u32>` to `u32` transmute. - Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) //~ERROR: expected something greater or equal to 1 + Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) } retblock = { Return()
diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr index 3b23a6c..fa67150 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr
@@ -1,15 +1,17 @@ -error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value of type std::num::NonZero<u32>: at .0.0, encountered 0, but expected something greater or equal to 1 --> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC | -LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | fn f(c: u32) { + | ^ Undefined Behavior occurred here | = 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: stack backtrace: - 0: call + 0: f at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC - 1: main + 1: call + at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC + 2: main at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.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/validity/cast_fn_ptr_invalid_caller_ret.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr index 03d6637..d922532 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_ret.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a null reference +error: Undefined Behavior: constructing invalid value of type &i32: encountered a null reference --> tests/fail/validity/cast_fn_ptr_invalid_caller_ret.rs:LL:CC | LL | let _x = g();
diff --git a/src/tools/miri/tests/fail/validity/dangling_ref1.stderr b/src/tools/miri/tests/fail/validity/dangling_ref1.stderr index 05467c4..0020c64 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref1.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref1.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (0x10[noalloc] has no provenance) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference (0x10[noalloc] has no provenance) --> tests/fail/validity/dangling_ref1.rs:LL:CC | LL | let _x: &i32 = unsafe { mem::transmute(16usize) };
diff --git a/src/tools/miri/tests/fail/validity/dangling_ref2.stderr b/src/tools/miri/tests/fail/validity/dangling_ref2.stderr index eb1b6e2..a1c8de2 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref2.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref2.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference (going beyond the bounds of its allocation) --> tests/fail/validity/dangling_ref2.rs:LL:CC | LL | let _x: &i32 = unsafe { mem::transmute(ptr) };
diff --git a/src/tools/miri/tests/fail/validity/dangling_ref3.stderr b/src/tools/miri/tests/fail/validity/dangling_ref3.stderr index ec2238c..0bf2598 100644 --- a/src/tools/miri/tests/fail/validity/dangling_ref3.stderr +++ b/src/tools/miri/tests/fail/validity/dangling_ref3.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) +error: Undefined Behavior: constructing invalid value of type &i32: encountered a dangling reference (use-after-free) --> tests/fail/validity/dangling_ref3.rs:LL:CC | LL | let _x: &i32 = unsafe { mem::transmute(dangling()) };
diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr index 383c13cc..9df01f0 100644 --- a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>` +error: Undefined Behavior: constructing invalid value of type &dyn Trait<for<'a> fn(&'a ())>: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>` --> tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC | LL | let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
diff --git a/src/tools/miri/tests/fail/validity/invalid_bool.stderr b/src/tools/miri/tests/fail/validity/invalid_bool.stderr index b667449..a403c8d 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_bool.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean +error: Undefined Behavior: constructing invalid value of type bool: encountered 0x02, but expected a boolean --> tests/fail/validity/invalid_bool.rs:LL:CC | LL | let _b = unsafe { std::mem::transmute::<u8, bool>(2) };
diff --git a/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr index 800bc4f..86767c6 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_bool_uninit.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a boolean +error: Undefined Behavior: constructing invalid value of type [bool; 1]: at [0], encountered uninitialized memory, but expected a boolean --> tests/fail/validity/invalid_bool_uninit.rs:LL:CC | LL | let _b = unsafe { MyUninit { init: () }.uninit };
diff --git a/src/tools/miri/tests/fail/validity/invalid_char.stderr b/src/tools/miri/tests/fail/validity/invalid_char.stderr index 7f57988..cb81038 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered $HEX, but expected a valid unicode scalar value (in `0..=$HEX` but not in `$HEX..=$HEX`) +error: Undefined Behavior: constructing invalid value of type char: encountered $HEX, but expected a valid unicode scalar value (in `0..=$HEX` but not in `$HEX..=$HEX`) --> tests/fail/validity/invalid_char.rs:LL:CC | LL | let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } {
diff --git a/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr index de8c1f3..78acda6 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_uninit.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a unicode scalar value +error: Undefined Behavior: constructing invalid value of type [char; 1]: at [0], encountered uninitialized memory, but expected a unicode scalar value --> tests/fail/validity/invalid_char_uninit.rs:LL:CC | LL | let _b = unsafe { MyUninit { init: () }.uninit };
diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_tag.rs b/src/tools/miri/tests/fail/validity/invalid_enum_tag.rs index fa115e1..9ef4a30 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_tag.rs +++ b/src/tools/miri/tests/fail/validity/invalid_enum_tag.rs
@@ -7,5 +7,5 @@ pub enum Foo { } fn main() { - let _f = unsafe { std::mem::transmute::<i32, Foo>(42) }; //~ ERROR: constructing invalid value at .<enum-tag>: encountered 0x0000002a, but expected a valid enum tag + let _f = unsafe { std::mem::transmute::<i32, Foo>(42) }; //~ ERROR: constructing invalid value of type Foo: at .<enum-tag>, encountered 0x0000002a, but expected a valid enum tag }
diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr index d7f2991..bd182df 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_tag.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .<enum-tag>: encountered $HEX, but expected a valid enum tag +error: Undefined Behavior: constructing invalid value of type Foo: at .<enum-tag>, encountered $HEX, but expected a valid enum tag --> tests/fail/validity/invalid_enum_tag.rs:LL:CC | LL | let _f = unsafe { std::mem::transmute::<i32, Foo>(42) };
diff --git a/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr b/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr index 20b2234..6750dcb 100644 --- a/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_fnptr_null.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a null function pointer +error: Undefined Behavior: constructing invalid value of type fn(): encountered a null function pointer --> tests/fail/validity/invalid_fnptr_null.rs:LL:CC | LL | let _b: fn() = unsafe { std::mem::transmute(0usize) };
diff --git a/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr b/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr index 513b90b..60994e2 100644 --- a/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_fnptr_uninit.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a function pointer +error: Undefined Behavior: constructing invalid value of type [fn(); 1]: at [0], encountered uninitialized memory, but expected a function pointer --> tests/fail/validity/invalid_fnptr_uninit.rs:LL:CC | LL | let _b = unsafe { MyUninit { init: () }.uninit };
diff --git a/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr b/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr index a3c7815..cb3c098 100644 --- a/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_wide_raw.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered null pointer, but expected a vtable pointer +error: Undefined Behavior: constructing invalid value of type *mut dyn main::T: encountered null pointer, but expected a vtable pointer --> tests/fail/validity/invalid_wide_raw.rs:LL:CC | LL | dbg!(S { x: unsafe { std::mem::transmute((0usize, 0usize)) } });
diff --git a/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr b/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr index 0ca8bc9..c905f3a 100644 --- a/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr +++ b/src/tools/miri/tests/fail/validity/match_binder_checks_validity1.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a value of uninhabited type `main::Void` +error: Undefined Behavior: constructing invalid value of type main::Void: encountered a value of uninhabited type `main::Void` --> tests/fail/validity/match_binder_checks_validity1.rs:LL:CC | LL | _x => println!("hi from the void!"),
diff --git a/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr b/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr index 281314e..02caf64 100644 --- a/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr +++ b/src/tools/miri/tests/fail/validity/match_binder_checks_validity2.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0x03, but expected a boolean +error: Undefined Behavior: constructing invalid value of type bool: encountered 0x03, but expected a boolean --> tests/fail/validity/match_binder_checks_validity2.rs:LL:CC | LL | _x => println!("hi from the void!"),
diff --git a/src/tools/miri/tests/fail/validity/maybe_dangling_null.rs b/src/tools/miri/tests/fail/validity/maybe_dangling_null.rs index 21dba86..9b3c80b 100644 --- a/src/tools/miri/tests/fail/validity/maybe_dangling_null.rs +++ b/src/tools/miri/tests/fail/validity/maybe_dangling_null.rs
@@ -9,5 +9,5 @@ fn main() { let null = MaybeDangling::new(null()); unsafe { transmute::<MaybeDangling<*const u8>, MaybeDangling<&u8>>(null) }; - //~^ ERROR: Undefined Behavior: constructing invalid value: encountered a null reference + //~^ ERROR: encountered a null reference }
diff --git a/src/tools/miri/tests/fail/validity/maybe_dangling_null.stderr b/src/tools/miri/tests/fail/validity/maybe_dangling_null.stderr index 6502347..041a6b1 100644 --- a/src/tools/miri/tests/fail/validity/maybe_dangling_null.stderr +++ b/src/tools/miri/tests/fail/validity/maybe_dangling_null.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a null reference +error: Undefined Behavior: constructing invalid value of type std::mem::MaybeDangling<&u8>: encountered a null reference --> tests/fail/validity/maybe_dangling_null.rs:LL:CC | LL | unsafe { transmute::<MaybeDangling<*const u8>, MaybeDangling<&u8>>(null) };
diff --git a/src/tools/miri/tests/fail/validity/nonzero.stderr b/src/tools/miri/tests/fail/validity/nonzero.stderr index e5fcdad..2b35240 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.stderr +++ b/src/tools/miri/tests/fail/validity/nonzero.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value of type NonZero<i32>: encountered 0, but expected something greater or equal to 1 --> tests/fail/validity/nonzero.rs:LL:CC | LL | let _x = Some(unsafe { NonZero(0) });
diff --git a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr b/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr index d658909..9cb6430 100644 --- a/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr +++ b/src/tools/miri/tests/fail/validity/recursive-validity-box-bool.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .<deref>: encountered 0x03, but expected a boolean +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<bool>: at .<deref>, encountered 0x03, but expected a boolean --> tests/fail/validity/recursive-validity-box-bool.rs:LL:CC | LL | let xref_wrong_type: Box<bool> = unsafe { std::mem::transmute(xref) };
diff --git a/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr b/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr index 1120726..933e48a 100644 --- a/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr +++ b/src/tools/miri/tests/fail/validity/recursive-validity-ref-bool.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .<deref>: encountered 0x03, but expected a boolean +error: Undefined Behavior: constructing invalid value of type &bool: at .<deref>, encountered 0x03, but expected a boolean --> tests/fail/validity/recursive-validity-ref-bool.rs:LL:CC | LL | let xref_wrong_type: &bool = unsafe { std::mem::transmute(xref) };
diff --git a/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr b/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr index f1a0591..645a978 100644 --- a/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr +++ b/src/tools/miri/tests/fail/validity/ref_to_uninhabited1.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a box pointing to uninhabited type ! +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<!>: encountered a box pointing to uninhabited type ! --> tests/fail/validity/ref_to_uninhabited1.rs:LL:CC | LL | let x: Box<!> = transmute(&mut 42);
diff --git a/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr b/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr index 4d25de4..37b265a 100644 --- a/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr +++ b/src/tools/miri/tests/fail/validity/ref_to_uninhabited2.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered a reference pointing to uninhabited type (i32, Void) +error: Undefined Behavior: constructing invalid value of type &(i32, Void): encountered a reference pointing to uninhabited type (i32, Void) --> tests/fail/validity/ref_to_uninhabited2.rs:LL:CC | LL | let _x: &(i32, Void) = transmute(&42);
diff --git a/src/tools/miri/tests/fail/validity/too-big-slice.stderr b/src/tools/miri/tests/fail/validity/too-big-slice.stderr index 9d4c347..7377d20 100644 --- a/src/tools/miri/tests/fail/validity/too-big-slice.stderr +++ b/src/tools/miri/tests/fail/validity/too-big-slice.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error: Undefined Behavior: constructing invalid value of type &[u8]: encountered invalid reference metadata: slice is bigger than largest supported object --> tests/fail/validity/too-big-slice.rs:LL:CC | LL | ... let _x: &[u8] = mem::transmute((ptr, usize::MAX));
diff --git a/src/tools/miri/tests/fail/validity/too-big-unsized.stderr b/src/tools/miri/tests/fail/validity/too-big-unsized.stderr index 6c07308..0fc6339 100644 --- a/src/tools/miri/tests/fail/validity/too-big-unsized.stderr +++ b/src/tools/miri/tests/fail/validity/too-big-unsized.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered invalid reference metadata: total size is bigger than largest supported object +error: Undefined Behavior: constructing invalid value of type &MySlice: encountered invalid reference metadata: total size is bigger than largest supported object --> tests/fail/validity/too-big-unsized.rs:LL:CC | LL | ... let _x: &MySlice = mem::transmute((ptr, isize::MAX as usize));
diff --git a/src/tools/miri/tests/fail/validity/transmute_through_ptr.rs b/src/tools/miri/tests/fail/validity/transmute_through_ptr.rs index 60b3bdd..b49c774 100644 --- a/src/tools/miri/tests/fail/validity/transmute_through_ptr.rs +++ b/src/tools/miri/tests/fail/validity/transmute_through_ptr.rs
@@ -14,6 +14,6 @@ fn main() { let mut x = Bool::True; evil(&mut x); let y = x; // reading this ought to be enough to trigger validation - //~^ ERROR: constructing invalid value at .<enum-tag>: encountered 0x0000002c, but expected a valid enum tag + //~^ ERROR: constructing invalid value of type Bool: at .<enum-tag>, encountered 0x0000002c, but expected a valid enum tag println!("{:?}", y); // make sure it is used (and not optimized away) }
diff --git a/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr b/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr index 998ff79..d531df6 100644 --- a/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr +++ b/src/tools/miri/tests/fail/validity/transmute_through_ptr.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .<enum-tag>: encountered $HEX, but expected a valid enum tag +error: Undefined Behavior: constructing invalid value of type Bool: at .<enum-tag>, encountered $HEX, but expected a valid enum tag --> tests/fail/validity/transmute_through_ptr.rs:LL:CC | LL | let y = x; // reading this ought to be enough to trigger validation
diff --git a/src/tools/miri/tests/fail/validity/uninhabited_variant.stderr b/src/tools/miri/tests/fail/validity/uninhabited_variant.stderr index 76ee250..8f120cb 100644 --- a/src/tools/miri/tests/fail/validity/uninhabited_variant.stderr +++ b/src/tools/miri/tests/fail/validity/uninhabited_variant.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error: Undefined Behavior: constructing invalid value of type E: at .<enum-tag>, encountered an uninhabited enum variant --> tests/fail/validity/uninhabited_variant.rs:LL:CC | LL | std::mem::transmute::<u32, E>(1);
diff --git a/src/tools/miri/tests/fail/validity/uninit_float.stderr b/src/tools/miri/tests/fail/validity/uninit_float.stderr index 7f3c94a..82e0b20 100644 --- a/src/tools/miri/tests/fail/validity/uninit_float.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_float.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a floating point number +error: Undefined Behavior: constructing invalid value of type [f32; 1]: at [0], encountered uninitialized memory, but expected a floating point number --> tests/fail/validity/uninit_float.rs:LL:CC | LL | let _val: [f32; 1] = unsafe { std::mem::uninitialized() };
diff --git a/src/tools/miri/tests/fail/validity/uninit_integer.stderr b/src/tools/miri/tests/fail/validity/uninit_integer.stderr index a80396f..038ffde 100644 --- a/src/tools/miri/tests/fail/validity/uninit_integer.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_integer.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type [usize; 1]: at [0], encountered uninitialized memory, but expected an integer --> tests/fail/validity/uninit_integer.rs:LL:CC | LL | let _val = unsafe { std::mem::MaybeUninit::<[usize; 1]>::uninit().assume_init() };
diff --git a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr index 946d74d..ecfca66 100644 --- a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a raw pointer +error: Undefined Behavior: constructing invalid value of type [*const u8; 1]: at [0], encountered uninitialized memory, but expected a raw pointer --> tests/fail/validity/uninit_raw_ptr.rs:LL:CC | LL | let _val = unsafe { std::mem::MaybeUninit::<[*const u8; 1]>::uninit().assume_init() };
diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr index ea77d11..74d8a46 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-assoc-type.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<Assoc = bool>`, but encountered `Trait<Assoc = u8>` +error: Undefined Behavior: constructing invalid value of type std::boxed::Box<dyn Trait<Assoc = bool>>: wrong trait in wide pointer vtable: expected `Trait<Assoc = bool>`, but encountered `Trait<Assoc = u8>` --> tests/fail/validity/wrong-dyn-trait-assoc-type.rs:LL:CC | LL | let v: Box<dyn Trait<Assoc = bool>> = unsafe { std::mem::transmute(v) };
diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr index f9e2f15..9273e39 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait-generic.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<u32>`, but encountered `Trait<i32>` +error: Undefined Behavior: constructing invalid value of type *const dyn Trait<u32>: wrong trait in wide pointer vtable: expected `Trait<u32>`, but encountered `Trait<i32>` --> tests/fail/validity/wrong-dyn-trait-generic.rs:LL:CC | LL | let _y: *const dyn Trait<u32> = unsafe { mem::transmute(x) };
diff --git a/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr b/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr index 47efd0b..6ca55c2 100644 --- a/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr +++ b/src/tools/miri/tests/fail/validity/wrong-dyn-trait.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `std::fmt::Debug`, but encountered `std::marker::Send` +error: Undefined Behavior: constructing invalid value of type *const dyn std::fmt::Debug: wrong trait in wide pointer vtable: expected `std::fmt::Debug`, but encountered `std::marker::Send` --> tests/fail/validity/wrong-dyn-trait.rs:LL:CC | LL | let _y: *const dyn fmt::Debug = unsafe { mem::transmute(x) };
diff --git a/src/tools/miri/tests/native-lib/fail/invalid_retval.rs b/src/tools/miri/tests/native-lib/fail/invalid_retval.rs index 4967866..e4bcbeb 100644 --- a/src/tools/miri/tests/native-lib/fail/invalid_retval.rs +++ b/src/tools/miri/tests/native-lib/fail/invalid_retval.rs
@@ -9,6 +9,6 @@ fn main() { unsafe { - u8_id(2); //~ ERROR: invalid value: encountered 0x02, but expected a boolean + u8_id(2); //~ ERROR: encountered 0x02, but expected a boolean } }
diff --git a/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr b/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr index 9db2982..b3b99cc 100644 --- a/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr +++ b/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean +error: Undefined Behavior: constructing invalid value of type bool: encountered 0x02, but expected a boolean --> tests/native-lib/fail/invalid_retval.rs:LL:CC | LL | u8_id(2);
diff --git a/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr b/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr index 9833b65..83e8170 100644 --- a/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr +++ b/src/tools/miri/tests/native-lib/fail/uninit_struct.stderr
@@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .part_1.high: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value of type ComplexStruct: at .part_1.high, encountered uninitialized memory, but expected an integer --> tests/native-lib/fail/uninit_struct.rs:LL:CC | LL | unsafe { pass_struct_complex(*arg.as_ptr(), 0, 0, 0) };
diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs index 57def78..03f14dc 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs
@@ -176,7 +176,7 @@ struct Triple { } extern "C" { - fn swap_ptr_triple_dangling(t_ptr: *const Triple); + fn swap_ptr_triple_dangling(t_ptr: *mut Triple); } let x = 101; @@ -184,9 +184,9 @@ struct Triple { let ptr = Box::as_ptr(&b); drop(b); let z = 121; - let triple = Triple { ptr0: &raw const x, ptr1: ptr, ptr2: &raw const z }; + let mut triple = Triple { ptr0: &raw const x, ptr1: ptr, ptr2: &raw const z }; - unsafe { swap_ptr_triple_dangling(&triple) } + unsafe { swap_ptr_triple_dangling(&mut triple) } assert_eq!(unsafe { *triple.ptr2 }, x); }
diff --git a/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs index 231df67..07584ba 100644 --- a/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs +++ b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs
@@ -1,3 +1,10 @@ +#[allow(unused)] +#[repr(C)] +enum CEnum { + A, + B, +} + extern "C" { fn add_one_int(x: i32) -> i32; fn add_int16(x: i16) -> i16; @@ -19,6 +26,7 @@ fn test_stack_spill( fn get_unsigned_int() -> u32; fn add_float(x: f32) -> f32; fn printer(); + fn scalar_enum(e: CEnum) -> u8; } fn main() { @@ -43,5 +51,8 @@ fn main() { // test void function that prints from C printer(); + + // test passing enums with scalar layout + assert_eq!(scalar_enum(CEnum::B), 1); } }
diff --git a/src/tools/miri/tests/native-lib/scalar_arguments.c b/src/tools/miri/tests/native-lib/scalar_arguments.c index 720f198..19ca940 100644 --- a/src/tools/miri/tests/native-lib/scalar_arguments.c +++ b/src/tools/miri/tests/native-lib/scalar_arguments.c
@@ -4,6 +4,11 @@ // See comments in build_native_lib() #define EXPORT __attribute__((visibility("default"))) +enum cenum { + cenum_a, + cenum_b, +}; + EXPORT int32_t add_one_int(int32_t x) { return 2 + x; } @@ -38,6 +43,10 @@ return x; } +EXPORT uint8_t scalar_enum(enum cenum e) { + return (uint8_t)e; +} + // To test that functions not marked with EXPORT cannot be called by Miri. int32_t not_exported(void) { return 0;
diff --git a/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs index 91cf24a..44e96957 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs
@@ -8,7 +8,7 @@ fn main() { unsafe { thread::spawn(|| { // Access the environment in another thread without taking the env lock - let s = libc::getenv("MIRI_ENV_VAR_TEST\0".as_ptr().cast()); + let s = libc::getenv(c"MIRI_ENV_VAR_TEST".as_ptr()); if s.is_null() { panic!("null"); }
diff --git a/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs b/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs index 9e5627c..70fa6c1 100644 --- a/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs +++ b/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs
@@ -7,8 +7,8 @@ type GetEntropyFn = unsafe extern "C" fn(*mut u8, libc::size_t) -> libc::c_int; fn main() { - let name = "getentropy\0"; - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr() as *const _) as usize }; + let name = c"getentropy"; + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize }; // If the GC does not account for the extra_fn_ptr entry that this dlsym just added, this GC // run will delete our entry for the base addr of the function pointer we will transmute to, // and the call through the function pointer will report UB.
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index f5e9a56..9dc1af1 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
@@ -54,29 +54,23 @@ fn main() { fn test_file_open_unix_allow_two_args() { let path = utils::prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]); + let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>(); - let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY) }; + let _fd = unsafe { libc::open(name.as_ptr(), libc::O_RDONLY) }; } fn test_file_open_unix_needs_three_args() { let path = utils::prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]); + let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>(); - let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT, 0o666) }; + let _fd = unsafe { libc::open(name.as_ptr(), libc::O_CREAT, 0o666) }; } fn test_file_open_unix_extra_third_arg() { let path = utils::prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]); + let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>(); - let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 42) }; + let _fd = unsafe { libc::open(name.as_ptr(), libc::O_RDONLY, 42) }; } fn test_dup_stdout_stderr() { @@ -92,12 +86,10 @@ fn test_dup_stdout_stderr() { fn test_dup() { let bytes = b"dup and dup2"; let path = utils::prepare_with_content("miri_test_libc_dup.txt", bytes); + let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>(); unsafe { - let fd = libc::open(name_ptr, libc::O_RDONLY); + let fd = libc::open(name.as_ptr(), libc::O_RDONLY); let new_fd = libc::dup(fd); let new_fd2 = libc::dup2(fd, 8); @@ -519,7 +511,7 @@ fn test_read_and_uninit() { { // We test that libc::read initializes its buffer. let path = utils::prepare_with_content("pass-libc-read-and-uninit.txt", &[1u8, 2, 3]); - let cpath = CString::new(path.clone().into_os_string().into_encoded_bytes()).unwrap(); + let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); unsafe { let fd = libc::open(cpath.as_ptr(), libc::O_RDONLY); assert_ne!(fd, -1); @@ -528,8 +520,8 @@ fn test_read_and_uninit() { let buf = buf.assume_init(); assert_eq!(buf, 1); assert_eq!(libc::close(fd), 0); + assert_eq!(libc::unlink(cpath.as_ptr()), 0); } - remove_file(&path).unwrap(); } { // We test that if we requested to read 4 bytes, but actually read 3 bytes, then @@ -567,17 +559,15 @@ fn test_nofollow_not_symlink() { #[cfg(target_os = "macos")] fn test_ioctl() { let path = utils::prepare_with_content("miri_test_libc_ioctl.txt", &[]); + let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>(); unsafe { // 100 surely is an invalid FD. assert_eq!(libc::ioctl(100, libc::FIOCLEX), -1); let errno = std::io::Error::last_os_error().raw_os_error().unwrap(); assert_eq!(errno, libc::EBADF); - let fd = libc::open(name_ptr, libc::O_RDONLY); + let fd = libc::open(name.as_ptr(), libc::O_RDONLY); assert_eq!(libc::ioctl(fd, libc::FIOCLEX), 0); } }
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs index d1c0085..36ed470 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
@@ -63,15 +63,22 @@ fn test_sigrt() { } fn test_dlsym() { - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"notasymbol\0".as_ptr().cast()) }; + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c"notasymbol".as_ptr()) }; assert!(addr as usize == 0); - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"isatty\0".as_ptr().cast()) }; + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c"isatty".as_ptr()) }; assert!(addr as usize != 0); let isatty: extern "C" fn(i32) -> i32 = unsafe { transmute(addr) }; assert_eq!(isatty(999), 0); let errno = std::io::Error::last_os_error().raw_os_error().unwrap(); assert_eq!(errno, libc::EBADF); + + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c"environ".as_ptr()) }; + assert!(addr as usize != 0); + extern "C" { + static mut environ: *const *const u8; + } + assert!(addr as usize == &raw const environ as usize); } fn test_getuid() {
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs index e3c14e6..8dd00e6 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs
@@ -38,6 +38,9 @@ fn main() { test_getsockname_ipv4_random_port(); test_getsockname_ipv4_unbound(); test_getsockname_ipv6(); + + test_getpeername_ipv4(); + test_getpeername_ipv6(); } fn test_socket_close() { @@ -183,7 +186,6 @@ fn test_listen() { /// - Connecting when the server is already accepting /// - Accepting when there is already an incoming connection fn test_accept_connect() { - // Create a new non-blocking server socket. let server_sockfd = unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; let client_sockfd = @@ -379,6 +381,132 @@ fn test_getsockname_ipv6() { assert_eq!(addr.sin6_addr.s6_addr, sock_addr.sin6_addr.s6_addr); } +/// Test the `getpeername` syscall on an IPv4 socket. +/// For a connected socket, the `getpeername` syscall should +/// return the same address as the socket was connected to. +fn test_getpeername_ipv4() { + let server_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + let addr = net::ipv4_sock_addr(net::IPV4_LOCALHOST, 0); + unsafe { + errno_check(libc::bind( + server_sockfd, + (&addr as *const libc::sockaddr_in).cast::<libc::sockaddr>(), + size_of::<libc::sockaddr_in>() as libc::socklen_t, + )); + } + + unsafe { + errno_check(libc::listen(server_sockfd, 16)); + } + + // Retrieve actual listener address because we used a randomized port. + let (_, server_addr) = + sockname(|storage, len| unsafe { libc::getsockname(server_sockfd, storage, len) }).unwrap(); + + let LibcSocketAddr::V4(addr) = server_addr else { + // We bound an IPv4 address so we also expect + // an IPv4 address to be returned. + panic!() + }; + + // Spawn the server thread. + let server_thread = thread::spawn(move || { + let (_peerfd, _peer_addr) = + sockname(|storage, len| unsafe { libc::accept(server_sockfd, storage, len) }).unwrap(); + }); + + // Test connecting to an already accepting server. + unsafe { + errno_check(libc::connect( + client_sockfd, + (&addr as *const libc::sockaddr_in).cast::<libc::sockaddr>(), + size_of::<libc::sockaddr_in>() as libc::socklen_t, + )); + } + + let (_, peer_addr) = + sockname(|storage, len| unsafe { libc::getpeername(client_sockfd, storage, len) }).unwrap(); + + let LibcSocketAddr::V4(peer_addr) = peer_addr else { + // We connected to an IPv4 address so we also expect + // an IPv4 address to be returned. + panic!() + }; + + assert_eq!(addr.sin_family, peer_addr.sin_family); + assert_eq!(addr.sin_port, peer_addr.sin_port); + assert_eq!(addr.sin_addr.s_addr, peer_addr.sin_addr.s_addr); + + server_thread.join().unwrap(); +} + +/// Test the `getpeername` syscall on an IPv6 socket. +/// For a connected socket, the `getpeername` syscall should +/// return the same address as the socket was connected to. +fn test_getpeername_ipv6() { + let server_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET6, libc::SOCK_STREAM, 0)).unwrap() }; + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET6, libc::SOCK_STREAM, 0)).unwrap() }; + let addr = net::ipv6_sock_addr(net::IPV6_LOCALHOST, 0); + unsafe { + errno_check(libc::bind( + server_sockfd, + (&addr as *const libc::sockaddr_in6).cast::<libc::sockaddr>(), + size_of::<libc::sockaddr_in6>() as libc::socklen_t, + )); + } + + unsafe { + errno_check(libc::listen(server_sockfd, 16)); + } + + // Retrieve actual listener address because we used a randomized port. + let (_, server_addr) = + sockname(|storage, len| unsafe { libc::getsockname(server_sockfd, storage, len) }).unwrap(); + + let LibcSocketAddr::V6(addr) = server_addr else { + // We bound an IPv6 address so we also expect + // an IPv6 address to be returned. + panic!() + }; + + // Spawn the server thread. + let server_thread = thread::spawn(move || { + let (_peerfd, _peer_addr) = + sockname(|storage, len| unsafe { libc::accept(server_sockfd, storage, len) }).unwrap(); + }); + + // Test connecting to an already accepting server. + unsafe { + errno_check(libc::connect( + client_sockfd, + (&addr as *const libc::sockaddr_in6).cast::<libc::sockaddr>(), + size_of::<libc::sockaddr_in6>() as libc::socklen_t, + )); + } + + let (_, peer_addr) = + sockname(|storage, len| unsafe { libc::getpeername(client_sockfd, storage, len) }).unwrap(); + + let LibcSocketAddr::V6(peer_addr) = peer_addr else { + // We connected to an IPv6 address so we also expect + // an IPv6 address to be returned. + panic!() + }; + + assert_eq!(addr.sin6_family, peer_addr.sin6_family); + assert_eq!(addr.sin6_port, peer_addr.sin6_port); + assert_eq!(addr.sin6_flowinfo, peer_addr.sin6_flowinfo); + assert_eq!(addr.sin6_scope_id, peer_addr.sin6_scope_id); + assert_eq!(addr.sin6_addr.s6_addr, peer_addr.sin6_addr.s6_addr); + + server_thread.join().unwrap(); +} + /// Set a socket option. It's the caller's responsibility to ensure that `T` is /// associated with the given socket option. ///
diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs index 91639c5..79cb551 100644 --- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -22,7 +22,7 @@ FILE_ALLOCATION_INFO, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_BEGIN, FILE_CURRENT, FILE_END_OF_FILE_INFO, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, FileAllocationInfo, FileEndOfFileInfo, - FlushFileBuffers, GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, + FlushFileBuffers, GetFileInformationByHandle, MoveFileExW, OPEN_ALWAYS, OPEN_EXISTING, SetFileInformationByHandle, SetFilePointerEx, }; use windows_sys::Win32::System::IO::IO_STATUS_BLOCK; @@ -42,6 +42,7 @@ fn main() { test_set_file_info(); test_dup_handle(); test_flush_buffers(); + test_move_file(); } } @@ -376,6 +377,23 @@ unsafe fn test_flush_buffers() { } } +unsafe fn test_move_file() { + let tmp_dir = utils::tmp(); + + let temp = tmp_dir.join("test_move_file.txt"); + let temp_new = tmp_dir.join("test_move_file_new.txt"); + let mut file = fs::File::options().create(true).write(true).open(&temp).unwrap(); + file.write_all(b"Hello, World!\n").unwrap(); + + let from = to_wide_cstr(&temp); + let to = to_wide_cstr(&temp_new); + if MoveFileExW(from.as_ptr(), to.as_ptr(), 1) == 0 { + panic!("Failed to rename file from {} to {}", temp.display(), temp_new.display()); + } + + assert_eq!(fs::read_to_string(temp_new).unwrap(), "Hello, World!\n"); +} + fn to_wide_cstr(path: &Path) -> Vec<u16> { let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>(); raw_path.extend([0, 0]);
diff --git a/src/tools/miri/tests/pass/float_nan.rs b/src/tools/miri/tests/pass/float_nan.rs index 6b39c2db..4ec5a7e 100644 --- a/src/tools/miri/tests/pass/float_nan.rs +++ b/src/tools/miri/tests/pass/float_nan.rs
@@ -513,10 +513,10 @@ fn test_simd() { F32::from(unsafe { simd_div(f32x4::splat(0.0), f32x4::splat(0.0)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { - F32::from(unsafe { simd_fmin(f32x4::splat(nan), f32x4::splat(nan)) }[0]) + F32::from(unsafe { simd_minimum_number_nsz(f32x4::splat(nan), f32x4::splat(nan)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { - F32::from(unsafe { simd_fmax(f32x4::splat(nan), f32x4::splat(nan)) }[0]) + F32::from(unsafe { simd_maximum_number_nsz(f32x4::splat(nan), f32x4::splat(nan)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { F32::from(unsafe { simd_fma(f32x4::splat(nan), f32x4::splat(nan), f32x4::splat(nan)) }[0])
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index b4fd8e2..f81f62e 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -90,11 +90,11 @@ macro_rules! assert_eq { assert_eq!(simd_rem(a, b), f16x4::from_array([0.0, 0.0, 1.0, 2.0])); assert_eq!(simd_fabs(b), f16x4::from_array([1.0, 2.0, 3.0, 4.0])); assert_eq!( - simd_fmax(a, simd_mul(b, f16x4::splat(4.0))), + simd_maximum_number_nsz(a, simd_mul(b, f16x4::splat(4.0))), f16x4::from_array([10.0, 10.0, 12.0, 10.0]) ); assert_eq!( - simd_fmin(a, simd_mul(b, f16x4::splat(4.0))), + simd_minimum_number_nsz(a, simd_mul(b, f16x4::splat(4.0))), f16x4::from_array([4.0, 8.0, 10.0, -16.0]) ); @@ -134,13 +134,19 @@ macro_rules! assert_eq { assert_eq!(simd_reduce_min(b), -4.0f16); assert_eq!( - simd_fmax(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + simd_maximum_number_nsz( + f16x2::from_array([0.0, f16::NAN]), + f16x2::from_array([f16::NAN, 0.0]) + ), f16x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_max(f16x2::from_array([0.0, f16::NAN])), 0.0f16); assert_eq!(simd_reduce_max(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); assert_eq!( - simd_fmin(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + simd_minimum_number_nsz( + f16x2::from_array([0.0, f16::NAN]), + f16x2::from_array([f16::NAN, 0.0]) + ), f16x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_min(f16x2::from_array([0.0, f16::NAN])), 0.0f16); @@ -304,11 +310,11 @@ macro_rules! assert_eq { assert_eq!(simd_rem(a, b), f128x4::from_array([0.0, 0.0, 1.0, 2.0])); assert_eq!(simd_fabs(b), f128x4::from_array([1.0, 2.0, 3.0, 4.0])); assert_eq!( - simd_fmax(a, simd_mul(b, f128x4::splat(4.0))), + simd_maximum_number_nsz(a, simd_mul(b, f128x4::splat(4.0))), f128x4::from_array([10.0, 10.0, 12.0, 10.0]) ); assert_eq!( - simd_fmin(a, simd_mul(b, f128x4::splat(4.0))), + simd_minimum_number_nsz(a, simd_mul(b, f128x4::splat(4.0))), f128x4::from_array([4.0, 8.0, 10.0, -16.0]) ); @@ -348,13 +354,19 @@ macro_rules! assert_eq { assert_eq!(simd_reduce_min(b), -4.0f128); assert_eq!( - simd_fmax(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + simd_maximum_number_nsz( + f128x2::from_array([0.0, f128::NAN]), + f128x2::from_array([f128::NAN, 0.0]) + ), f128x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_max(f128x2::from_array([0.0, f128::NAN])), 0.0f128); assert_eq!(simd_reduce_max(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); assert_eq!( - simd_fmin(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + simd_minimum_number_nsz( + f128x2::from_array([0.0, f128::NAN]), + f128x2::from_array([f128::NAN, 0.0]) + ), f128x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_min(f128x2::from_array([0.0, f128::NAN])), 0.0f128);
diff --git a/src/tools/miri/tests/pass/no_std_miri_start.rs b/src/tools/miri/tests/pass/miri_start_no_std.rs similarity index 100% rename from src/tools/miri/tests/pass/no_std_miri_start.rs rename to src/tools/miri/tests/pass/miri_start_no_std.rs
diff --git a/src/tools/miri/tests/pass/no_std_miri_start.stdout b/src/tools/miri/tests/pass/miri_start_no_std.stdout similarity index 100% rename from src/tools/miri/tests/pass/no_std_miri_start.stdout rename to src/tools/miri/tests/pass/miri_start_no_std.stdout
diff --git a/src/tools/miri/tests/pass/miri_start_with_std.rs b/src/tools/miri/tests/pass/miri_start_with_std.rs new file mode 100644 index 0000000..510b9d4 --- /dev/null +++ b/src/tools/miri/tests/pass/miri_start_with_std.rs
@@ -0,0 +1,8 @@ +#![no_main] + +#[no_mangle] +fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { + let _b = Box::new(0); + println!("hello, world!"); + 0 +}
diff --git a/src/tools/miri/tests/pass/no_std_miri_start.stdout b/src/tools/miri/tests/pass/miri_start_with_std.stdout similarity index 100% copy from src/tools/miri/tests/pass/no_std_miri_start.stdout copy to src/tools/miri/tests/pass/miri_start_with_std.stdout
diff --git a/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-crc32.rs b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-crc32.rs new file mode 100644 index 0000000..849f99e --- /dev/null +++ b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-crc32.rs
@@ -0,0 +1,61 @@ +// We're testing aarch64 CRC32 target specific features +//@only-target: aarch64 +//@compile-flags: -C target-feature=+crc + +use std::arch::aarch64::*; +use std::arch::is_aarch64_feature_detected; + +fn main() { + assert!(is_aarch64_feature_detected!("crc")); + + unsafe { + test_crc32_standard(); + test_crc32c_castagnoli(); + } +} + +#[target_feature(enable = "crc")] +unsafe fn test_crc32_standard() { + // __crc32b: 8-bit input + assert_eq!(__crc32b(0x00000000, 0x01), 0x77073096); + assert_eq!(__crc32b(0xffffffff, 0x61), 0x174841bc); + assert_eq!(__crc32b(0x2aa1e72b, 0x2a), 0x772d9171); + + // __crc32h: 16-bit input + assert_eq!(__crc32h(0x00000000, 0x0001), 0x191b3141); + assert_eq!(__crc32h(0xffffffff, 0x1234), 0xf6b56fbf); + assert_eq!(__crc32h(0x8ecec3b5, 0x022b), 0x03a1db7c); + + // __crc32w: 32-bit input + assert_eq!(__crc32w(0x00000000, 0x00000001), 0xb8bc6765); + assert_eq!(__crc32w(0xffffffff, 0x12345678), 0x5092782d); + assert_eq!(__crc32w(0xae2912c8, 0x00845fed), 0xc5690dd4); + + // __crc32d: 64-bit input + assert_eq!(__crc32d(0x00000000, 0x0000000000000001), 0xccaa009e); + assert_eq!(__crc32d(0xffffffff, 0x123456789abcdef0), 0xe6ddf8b5); + assert_eq!(__crc32d(0x0badeafe, 0xc0febeefdadafefe), 0x61a45fba); +} + +#[target_feature(enable = "crc")] +unsafe fn test_crc32c_castagnoli() { + // __crc32cb: 8-bit input + assert_eq!(__crc32cb(0x00000000, 0x01), 0xf26b8303); + assert_eq!(__crc32cb(0xffffffff, 0x61), 0x3e2fbccf); + assert_eq!(__crc32cb(0x2aa1e72b, 0x2a), 0xf24122e4); + + // __crc32ch: 16-bit input + assert_eq!(__crc32ch(0x00000000, 0x0001), 0x13a29877); + assert_eq!(__crc32ch(0xffffffff, 0x1234), 0xf13f4cea); + assert_eq!(__crc32ch(0x8ecec3b5, 0x022b), 0x013bb2fb); + + // __crc32cw: 32-bit input + assert_eq!(__crc32cw(0x00000000, 0x00000001), 0xdd45aab8); + assert_eq!(__crc32cw(0xffffffff, 0x12345678), 0x4dece20c); + assert_eq!(__crc32cw(0xae2912c8, 0x00845fed), 0xffae2ed1); + + // __crc32cd: 64-bit input + assert_eq!(__crc32cd(0x00000000, 0x0000000000000001), 0x493c7d27); + assert_eq!(__crc32cd(0xffffffff, 0x123456789abcdef0), 0xd95b664b); + assert_eq!(__crc32cd(0x0badeafe, 0xc0febeefdadafefe), 0x5b44f54f); +}
diff --git a/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs index 6d3f153..884f8ef 100644 --- a/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs +++ b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs
@@ -12,6 +12,8 @@ fn main() { unsafe { test_vpmaxq_u8(); test_tbl1_v16i8_basic(); + test_vpadd(); + test_vpaddl(); } } @@ -65,3 +67,93 @@ fn test_tbl1_v16i8_basic() { assert_eq!(&got2_arr[3..16], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12][..]); } } +#[target_feature(enable = "neon")] +unsafe fn test_vpadd() { + let a = vld1_s8([1, 2, 3, 4, 5, 6, 7, 8].as_ptr()); + let b = vld1_s8([9, 10, -1, 2, i8::MIN, i8::MIN, i8::MAX, i8::MAX].as_ptr()); + let e = + [3i8, 7, 11, 15, 19, -1 + 2, i8::MIN.wrapping_add(i8::MIN), i8::MAX.wrapping_add(i8::MAX)]; + let mut r = [0i8; 8]; + vst1_s8(r.as_mut_ptr(), vpadd_s8(a, b)); + assert_eq!(r, e); + + let a = vld1_s16([1, 2, 3, 4].as_ptr()); + let b = vld1_s16([-1, 2, i16::MAX, i16::MAX].as_ptr()); + let e = [3i16, 7, -1 + 2, i16::MAX.wrapping_add(i16::MAX)]; + let mut r = [0i16; 4]; + vst1_s16(r.as_mut_ptr(), vpadd_s16(a, b)); + assert_eq!(r, e); + + let a = vld1_s32([1, 2].as_ptr()); + let b = vld1_s32([i32::MAX, i32::MAX].as_ptr()); + let e = [3i32, i32::MAX.wrapping_add(i32::MAX)]; + let mut r = [0i32; 2]; + vst1_s32(r.as_mut_ptr(), vpadd_s32(a, b)); + assert_eq!(r, e); + + let a = vld1_u8([1, 2, 3, 4, 5, 6, 7, 8].as_ptr()); + let b = vld1_u8([9, 10, 11, 12, 13, 14, u8::MAX, u8::MAX].as_ptr()); + let e = [3u8, 7, 11, 15, 19, 23, 27, 254]; + let mut r = [0u8; 8]; + vst1_u8(r.as_mut_ptr(), vpadd_u8(a, b)); + assert_eq!(r, e); + + let a = vld1_u16([1, 2, 3, 4].as_ptr()); + let b = vld1_u16([5, 6, u16::MAX, u16::MAX].as_ptr()); + let e = [3u16, 7, 11, 65534]; + let mut r = [0u16; 4]; + vst1_u16(r.as_mut_ptr(), vpadd_u16(a, b)); + assert_eq!(r, e); + + let a = vld1_u32([1, 2].as_ptr()); + let b = vld1_u32([u32::MAX, u32::MAX].as_ptr()); + let e = [3u32, u32::MAX.wrapping_add(u32::MAX)]; + let mut r = [0u32; 2]; + vst1_u32(r.as_mut_ptr(), vpadd_u32(a, b)); + assert_eq!(r, e); +} + +#[target_feature(enable = "neon")] +unsafe fn test_vpaddl() { + let a = vld1_u8([1, 2, 3, 4, 5, 6, u8::MAX, u8::MAX].as_ptr()); + let e = [3u16, 7, 11, 510]; + let mut r = [0u16; 4]; + vst1_u16(r.as_mut_ptr(), vpaddl_u8(a)); + assert_eq!(r, e); + + let a = vld1q_u8([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, u8::MAX, u8::MAX].as_ptr()); + let e = [3u16, 7, 11, 15, 19, 23, 27, 510]; + let mut r = [0u16; 8]; + vst1q_u16(r.as_mut_ptr(), vpaddlq_u8(a)); + assert_eq!(r, e); + + let a = vld1_u16([1, 2, u16::MAX, u16::MAX].as_ptr()); + let e = [3u32, 131070]; + let mut r = [0u32; 2]; + vst1_u32(r.as_mut_ptr(), vpaddl_u16(a)); + assert_eq!(r, e); + + let a = vld1q_u16([1, 2, 3, 4, 5, 6, u16::MAX, u16::MAX].as_ptr()); + let e = [3u32, 7, 11, 131070]; + let mut r = [0u32; 4]; + vst1q_u32(r.as_mut_ptr(), vpaddlq_u16(a)); + assert_eq!(r, e); + + let a = vld1_u32([1, 2].as_ptr()); + let e = [3u64]; + let mut r = [0u64; 1]; + vst1_u64(r.as_mut_ptr(), vpaddl_u32(a)); + assert_eq!(r, e); + + let a = vld1_u32([u32::MAX, u32::MAX].as_ptr()); + let e = [8589934590]; + let mut r = [0u64; 1]; + vst1_u64(r.as_mut_ptr(), vpaddl_u32(a)); + assert_eq!(r, e); + + let a = vld1q_u32([1, 2, u32::MAX, u32::MAX].as_ptr()); + let e = [3u64, 8589934590]; + let mut r = [0u64; 2]; + vst1q_u64(r.as_mut_ptr(), vpaddlq_u32(a)); + assert_eq!(r, e); +}
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 50b5dbf..e6c15c8 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -30,9 +30,9 @@ fn main() { test_file_clone(); test_file_set_len(); test_file_sync(); + test_rename(); // Windows file handling is very incomplete. if cfg!(not(windows)) { - test_rename(); test_directory(); test_canonicalize(); #[cfg(unix)]
diff --git a/src/tools/miri/tests/pass/shims/socket.rs b/src/tools/miri/tests/pass/shims/socket.rs index 2e63e00..852397a 100644 --- a/src/tools/miri/tests/pass/shims/socket.rs +++ b/src/tools/miri/tests/pass/shims/socket.rs
@@ -8,6 +8,7 @@ fn main() { test_create_ipv4_listener(); test_create_ipv6_listener(); test_accept_and_connect(); + test_peer_addr(); } fn test_create_ipv4_listener() { @@ -34,3 +35,22 @@ fn test_accept_and_connect() { handle.join().unwrap(); } + +/// Test whether the [`TcpStream::peer_addr`] of a connected socket +/// is the same address as the one the stream was connected to. +fn test_peer_addr() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + // Get local address with randomized port to know where + // we need to connect to. + let address = listener.local_addr().unwrap(); + + let handle = thread::spawn(move || { + let (_stream, _addr) = listener.accept().unwrap(); + }); + + let stream = TcpStream::connect(address).unwrap(); + let peer_addr = stream.peer_addr().unwrap(); + assert_eq!(address, peer_addr); + + handle.join().unwrap(); +}
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index 29d302b..9b54f62 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml
@@ -13,7 +13,7 @@ sysinfo = { version = "0.38.4", default-features = false, features = ["disk"] } fs_extra = "1" camino = "1" -tar = "0.4" +tar = "0.4.45" xz = { version = "0.1", package = "xz2" } serde_json = "1" glob = "0.3"
diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index b4d3028..cc8edfc 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs
@@ -211,12 +211,12 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf let mut args = Vec::new(); while t!(reader.read_until(0, &mut arg)) > 1 { args.push(t!(str::from_utf8(&arg[..arg.len() - 1])).to_string()); - arg.truncate(0); + arg.clear(); } // Next we'll get a bunch of env vars in pairs delimited by 0s as well let mut env = Vec::new(); - arg.truncate(0); + arg.clear(); while t!(reader.read_until(0, &mut arg)) > 1 { let key_len = arg.len() - 1; let val_len = t!(reader.read_until(0, &mut arg)) - 1; @@ -227,7 +227,7 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf let val = t!(str::from_utf8(val)).to_string(); env.push((key, val)); } - arg.truncate(0); + arg.clear(); } // The section of code from here down to where we drop the lock is going to
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml index 6e2be7f..abb9b52 100644 --- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml +++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -16,7 +16,7 @@ runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 04de6d1..c27d84f 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -30,8 +30,8 @@ outputs: typescript: ${{ steps.filter.outputs.typescript }} steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@1441771bbfdd59dcd748680ee64ebd8faab1a242 + - uses: actions/checkout@v6 + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 id: filter with: filters: | @@ -45,7 +45,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} @@ -88,7 +88,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} @@ -136,7 +136,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust toolchain run: | @@ -164,7 +164,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust toolchain run: | @@ -180,7 +180,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 # Note that clippy output is currently dependent on whether rust-src is installed, # https://github.com/rust-lang/rust-clippy/issues/14625 @@ -202,7 +202,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust toolchain run: | @@ -226,12 +226,7 @@ strategy: matrix: - target: - [ - powerpc-unknown-linux-gnu, - x86_64-unknown-linux-musl, - wasm32-unknown-unknown, - ] + target: [powerpc-unknown-linux-gnu, x86_64-unknown-linux-musl, wasm32-unknown-unknown] include: # The rust-analyzer binary is not expected to compile on WASM, but the IDE # crate should @@ -240,7 +235,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Rust toolchain run: | @@ -268,10 +263,10 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Nodejs - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 @@ -327,7 +322,7 @@ run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }}
diff --git a/src/tools/rust-analyzer/.github/workflows/coverage.yaml b/src/tools/rust-analyzer/.github/workflows/coverage.yaml index bd4edba..9460c6a 100644 --- a/src/tools/rust-analyzer/.github/workflows/coverage.yaml +++ b/src/tools/rust-analyzer/.github/workflows/coverage.yaml
@@ -13,7 +13,7 @@ coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Rust toolchain run: | @@ -34,9 +34,9 @@ - name: Generate code coverage run: cargo llvm-cov --workspace --lcov --output-path lcov.info - + - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: lcov.info fail_ci_if_error: false
diff --git a/src/tools/rust-analyzer/.github/workflows/fuzz.yml b/src/tools/rust-analyzer/.github/workflows/fuzz.yml index 7acfcbe..af0e035 100644 --- a/src/tools/rust-analyzer/.github/workflows/fuzz.yml +++ b/src/tools/rust-analyzer/.github/workflows/fuzz.yml
@@ -2,10 +2,10 @@ on: schedule: # Once a week - - cron: '0 0 * * 0' + - cron: "0 0 * * 0" push: paths: - - '.github/workflows/fuzz.yml' + - ".github/workflows/fuzz.yml" # Allow manual trigger workflow_dispatch: @@ -27,7 +27,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 1
diff --git a/src/tools/rust-analyzer/.github/workflows/metrics.yaml b/src/tools/rust-analyzer/.github/workflows/metrics.yaml index 860837d..a482235 100644 --- a/src/tools/rust-analyzer/.github/workflows/metrics.yaml +++ b/src/tools/rust-analyzer/.github/workflows/metrics.yaml
@@ -23,7 +23,7 @@ rustup component add --toolchain beta rust-src - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Cache cargo uses: actions/cache@v4 @@ -45,7 +45,7 @@ key: ${{ runner.os }}-target-${{ github.sha }} - name: Upload build metrics - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: build-${{ github.sha }} path: target/build.json @@ -66,7 +66,7 @@ rustup component add --toolchain beta rust-src - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Restore target cache uses: actions/cache@v4 @@ -78,7 +78,7 @@ run: cargo xtask metrics "${{ matrix.names }}" - name: Upload metrics - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.names }}-${{ github.sha }} path: target/${{ matrix.names }}.json @@ -89,35 +89,35 @@ needs: [build_metrics, other_metrics] steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download build metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: build-${{ github.sha }} - name: Download self metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: self-${{ github.sha }} - name: Download ripgrep-13.0.0 metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: ripgrep-13.0.0-${{ github.sha }} - name: Download webrender-2022 metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: webrender-2022-${{ github.sha }} - name: Download diesel-1.4.8 metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: diesel-1.4.8-${{ github.sha }} - name: Download hyper-0.14.18 metrics - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: hyper-0.14.18-${{ github.sha }}
diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml index f2c8b63..762b7bd 100644 --- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml +++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
@@ -14,7 +14,7 @@ runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index 2891411..b35614f 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -70,12 +70,12 @@ steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: ${{ env.FETCH_DEPTH }} - name: Install Node.js toolchain - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 @@ -143,7 +143,7 @@ run: target/${{ matrix.target }}/release/rust-analyzer analysis-stats --with-deps --no-sysroot --no-test $(rustc --print sysroot)/lib/rustlib/src/rust/library/std -q - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: dist-${{ matrix.target }} path: ./dist @@ -166,7 +166,7 @@ run: apk add --no-cache git clang lld musl-dev nodejs npm - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: ${{ env.FETCH_DEPTH }} @@ -189,7 +189,7 @@ - run: rm -rf editors/code/server - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: dist-x86_64-unknown-linux-musl path: ./dist @@ -201,7 +201,7 @@ needs: ["dist", "dist-x86_64-unknown-linux-musl"] steps: - name: Install Nodejs - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 @@ -212,46 +212,46 @@ - run: 'echo "TAG: $TAG"' - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: ${{ env.FETCH_DEPTH }} - run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV - run: 'echo "HEAD_SHA: $HEAD_SHA"' - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-aarch64-apple-darwin path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-x86_64-apple-darwin path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-x86_64-unknown-linux-gnu path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-x86_64-unknown-linux-musl path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-aarch64-unknown-linux-gnu path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-arm-unknown-linux-gnueabihf path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-x86_64-pc-windows-msvc path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-i686-pc-windows-msvc path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: dist-aarch64-pc-windows-msvc path: dist
diff --git a/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml index 0cc7ce7..03fd083 100644 --- a/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml +++ b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml
@@ -1,8 +1,8 @@ name: rustdoc on: push: - branches: - - master + branches: + - master env: CARGO_INCREMENTAL: 0 @@ -10,6 +10,7 @@ RUSTFLAGS: "-D warnings -W unreachable-pub" RUSTDOCFLAGS: "-D warnings" RUSTUP_MAX_RETRIES: 10 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true jobs: rustdoc: @@ -17,19 +18,19 @@ runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v6 - - name: Install Rust toolchain - run: rustup update --no-self-update stable + - name: Install Rust toolchain + run: rustup update --no-self-update stable - - name: Build Documentation - run: cargo doc --all --no-deps --document-private-items + - name: Build Documentation + run: cargo doc --all --no-deps --document-private-items - - name: Deploy Docs - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: gh-pages - publish_dir: ./target/doc - force_orphan: true + - name: Deploy Docs + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: gh-pages + publish_dir: ./target/doc + force_orphan: true
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index f31dda4..5370127 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock
@@ -2315,6 +2315,7 @@ "ide-db", "ide-ssr", "indexmap", + "intern", "itertools 0.14.0", "load-cargo", "lsp-server 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/src/tools/rust-analyzer/README.md b/src/tools/rust-analyzer/README.md index 6d2a673..06d63a2 100644 --- a/src/tools/rust-analyzer/README.md +++ b/src/tools/rust-analyzer/README.md
@@ -20,6 +20,8 @@ [Architecture](https://rust-analyzer.github.io/book/contributing/architecture.html) in the manual. +[](https://app.codecov.io/github/rust-lang/rust-analyzer/tree/master) + ## Quick Start https://rust-analyzer.github.io/book/installation.html
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index 0b8f656..e3e1aac 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs
@@ -894,7 +894,7 @@ pub fn query_generic_params( def: GenericDefId, ) -> &(ArenaMap<LocalLifetimeParamId, AttrFlags>, ArenaMap<LocalTypeOrConstParamId, AttrFlags>) { - let generic_params = GenericParams::new(db, def); + let generic_params = GenericParams::of(db, def); let params_count_excluding_self = generic_params.len() - usize::from(generic_params.trait_self_param().is_some()); if params_count_excluding_self == 0 {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index b0b652a..5d5d435 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -4,28 +4,18 @@ EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind, db::ExpandDatabase, }; -use la_arena::ArenaMap; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, - EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, - FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, - MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, - ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, - TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, + AnonConstId, AnonConstLoc, AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, + EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, + ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, Macro2Id, Macro2Loc, MacroExpander, + MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, + StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, + UnionLoc, UseId, UseLoc, attrs::AttrFlags, - expr_store::{ - Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, - }, - hir::generics::GenericParams, - import_map::ImportMap, item_tree::{ItemTree, file_item_tree_query}, nameres::crate_def_map, - signatures::{ - ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature, - StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, - }, visibility::{self, Visibility}, }; @@ -62,6 +52,9 @@ pub trait InternDatabase: RootQueryDb { fn intern_static(&self, loc: StaticLoc) -> StaticId; #[salsa::interned] + fn intern_anon_const(&self, loc: AnonConstLoc) -> AnonConstId; + + #[salsa::interned] fn intern_trait(&self, loc: TraitLoc) -> TraitId; #[salsa::interned] @@ -102,145 +95,8 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { #[salsa::invoke(macro_def)] fn macro_def(&self, m: MacroId) -> MacroDefId; - // region:data - - #[salsa::tracked] - fn trait_signature(&self, trait_: TraitId) -> Arc<TraitSignature> { - self.trait_signature_with_source_map(trait_).0 - } - - #[salsa::tracked] - fn impl_signature(&self, impl_: ImplId) -> Arc<ImplSignature> { - self.impl_signature_with_source_map(impl_).0 - } - - #[salsa::tracked] - fn struct_signature(&self, struct_: StructId) -> Arc<StructSignature> { - self.struct_signature_with_source_map(struct_).0 - } - - #[salsa::tracked] - fn union_signature(&self, union_: UnionId) -> Arc<UnionSignature> { - self.union_signature_with_source_map(union_).0 - } - - #[salsa::tracked] - fn enum_signature(&self, e: EnumId) -> Arc<EnumSignature> { - self.enum_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn const_signature(&self, e: ConstId) -> Arc<ConstSignature> { - self.const_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn static_signature(&self, e: StaticId) -> Arc<StaticSignature> { - self.static_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn function_signature(&self, e: FunctionId) -> Arc<FunctionSignature> { - self.function_signature_with_source_map(e).0 - } - - #[salsa::tracked] - fn type_alias_signature(&self, e: TypeAliasId) -> Arc<TypeAliasSignature> { - self.type_alias_signature_with_source_map(e).0 - } - - #[salsa::invoke(TraitSignature::query)] - fn trait_signature_with_source_map( - &self, - trait_: TraitId, - ) -> (Arc<TraitSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(ImplSignature::query)] - fn impl_signature_with_source_map( - &self, - impl_: ImplId, - ) -> (Arc<ImplSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(StructSignature::query)] - fn struct_signature_with_source_map( - &self, - struct_: StructId, - ) -> (Arc<StructSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(UnionSignature::query)] - fn union_signature_with_source_map( - &self, - union_: UnionId, - ) -> (Arc<UnionSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(EnumSignature::query)] - fn enum_signature_with_source_map( - &self, - e: EnumId, - ) -> (Arc<EnumSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(ConstSignature::query)] - fn const_signature_with_source_map( - &self, - e: ConstId, - ) -> (Arc<ConstSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(StaticSignature::query)] - fn static_signature_with_source_map( - &self, - e: StaticId, - ) -> (Arc<StaticSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(FunctionSignature::query)] - fn function_signature_with_source_map( - &self, - e: FunctionId, - ) -> (Arc<FunctionSignature>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(TypeAliasSignature::query)] - fn type_alias_signature_with_source_map( - &self, - e: TypeAliasId, - ) -> (Arc<TypeAliasSignature>, Arc<ExpressionStoreSourceMap>); - - // endregion:data - - #[salsa::invoke(Body::body_with_source_map_query)] - #[salsa::lru(512)] - fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); - - #[salsa::invoke(Body::body_query)] - fn body(&self, def: DefWithBodyId) -> Arc<Body>; - - #[salsa::invoke(ExprScopes::expr_scopes_query)] - fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; - - #[salsa::transparent] - #[salsa::invoke(GenericParams::new)] - fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; - - #[salsa::transparent] - #[salsa::invoke(GenericParams::generic_params_and_store)] - fn generic_params_and_store( - &self, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>); - - #[salsa::transparent] - #[salsa::invoke(GenericParams::generic_params_and_store_and_source_map)] - fn generic_params_and_store_and_source_map( - &self, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>); - - #[salsa::invoke(ImportMap::import_map_query)] - fn import_map(&self, krate: Crate) -> Arc<ImportMap>; - // region:visibilities - #[salsa::invoke(visibility::field_visibilities_query)] - fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>; - #[salsa::invoke(visibility::assoc_visibility_query)] fn assoc_visibility(&self, def: AssocItemId) -> Visibility;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 1ce4c88..ca52362 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
@@ -9,10 +9,7 @@ #[cfg(test)] mod tests; -use std::{ - ops::{Deref, Index}, - sync::LazyLock, -}; +use std::ops::{Deref, Index}; use cfg::{CfgExpr, CfgOptions}; use either::Either; @@ -23,11 +20,10 @@ use span::{Edition, SyntaxContext}; use syntax::{AstPtr, SyntaxNodePtr, ast}; use thin_vec::ThinVec; -use triomphe::Arc; use tt::TextRange; use crate::{ - BlockId, SyntheticSyntax, + AdtId, BlockId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, db::DefDatabase, expr_store::path::Path, hir::{ @@ -35,6 +31,7 @@ PatId, RecordFieldPat, RecordSpread, Statement, }, nameres::{DefMap, block_def_map}, + signatures::VariantFields, type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId}, }; @@ -94,9 +91,26 @@ pub(crate) fn is_root(self) -> bool { pub type LifetimePtr = AstPtr<ast::Lifetime>; pub type LifetimeSource = InFile<LifetimePtr>; +/// Describes where a const expression originated from. +/// +/// Used by signature/body inference to determine the expected type for each +/// const expression root. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum RootExprOrigin { + /// Array length expression: `[T; <expr>]` — expected type is `usize`. + ArrayLength, + /// Const parameter default value: `const N: usize = <expr>`. + ConstParam(crate::hir::generics::LocalTypeOrConstParamId), + /// Const generic argument in a path: `SomeType::<{ <expr> }>` or `some_fn::<{ <expr> }>()`. + /// Determining the expected type requires path resolution, so it is deferred. + GenericArgsPath, + /// The root expression of a body. + BodyRoot, +} + // We split the store into types-only and expressions, because most stores (e.g. generics) // don't store any expressions and this saves memory. Same thing for the source map. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] struct ExpressionOnlyStore { exprs: Arena<Expr>, pats: Arena<Pat>, @@ -113,9 +127,12 @@ struct ExpressionOnlyStore { /// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer /// to variables and have hygiene (some refer to items, we don't know at this stage). ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, + + /// Maps expression roots to their origin. + expr_roots: SmallVec<[(ExprId, RootExprOrigin); 1]>, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ExpressionStore { expr_only: Option<Box<ExpressionOnlyStore>>, pub types: Arena<TypeRef>, @@ -226,6 +243,7 @@ pub struct ExpressionStoreBuilder { pub types: Arena<TypeRef>, block_scopes: Vec<BlockId>, ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, + pub inference_roots: Option<SmallVec<[(ExprId, RootExprOrigin); 1]>>, // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected). @@ -297,6 +315,7 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) { mut bindings, mut binding_owners, mut ident_hygiene, + inference_roots: mut expr_roots, mut types, mut lifetimes, @@ -356,6 +375,9 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) { let store = { let expr_only = if has_exprs { + if let Some(const_expr_origins) = &mut expr_roots { + const_expr_origins.shrink_to_fit(); + } Some(Box::new(ExpressionOnlyStore { exprs, pats, @@ -364,6 +386,7 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) { binding_owners, block_scopes: block_scopes.into_boxed_slice(), ident_hygiene, + expr_roots: expr_roots.unwrap_or_default(), })) } else { None @@ -404,13 +427,108 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) { } impl ExpressionStore { - pub fn empty_singleton() -> (Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) { - static EMPTY: LazyLock<(Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>)> = - LazyLock::new(|| { - let (store, source_map) = ExpressionStoreBuilder::default().finish(); - (Arc::new(store), Arc::new(source_map)) - }); - EMPTY.clone() + pub fn of(db: &dyn DefDatabase, def: ExpressionStoreOwnerId) -> &ExpressionStore { + match def { + ExpressionStoreOwnerId::Signature(def) => { + use crate::signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, + StaticSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, + }; + match def { + GenericDefId::AdtId(AdtId::EnumId(id)) => &EnumSignature::of(db, id).store, + GenericDefId::AdtId(AdtId::StructId(id)) => &StructSignature::of(db, id).store, + GenericDefId::AdtId(AdtId::UnionId(id)) => &UnionSignature::of(db, id).store, + GenericDefId::ConstId(id) => &ConstSignature::of(db, id).store, + GenericDefId::FunctionId(id) => &FunctionSignature::of(db, id).store, + GenericDefId::ImplId(id) => &ImplSignature::of(db, id).store, + GenericDefId::StaticId(id) => &StaticSignature::of(db, id).store, + GenericDefId::TraitId(id) => &TraitSignature::of(db, id).store, + GenericDefId::TypeAliasId(id) => &TypeAliasSignature::of(db, id).store, + } + } + ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store, + ExpressionStoreOwnerId::VariantFields(variant_id) => { + &VariantFields::of(db, variant_id).store + } + } + } + + pub fn with_source_map( + db: &dyn DefDatabase, + def: ExpressionStoreOwnerId, + ) -> (&ExpressionStore, &ExpressionStoreSourceMap) { + match def { + ExpressionStoreOwnerId::Signature(def) => { + use crate::signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, + StaticSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, + }; + match def { + GenericDefId::AdtId(AdtId::EnumId(id)) => { + let sig = EnumSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::AdtId(AdtId::StructId(id)) => { + let sig = StructSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::AdtId(AdtId::UnionId(id)) => { + let sig = UnionSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::ConstId(id) => { + let sig = ConstSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::FunctionId(id) => { + let sig = FunctionSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::ImplId(id) => { + let sig = ImplSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::StaticId(id) => { + let sig = StaticSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::TraitId(id) => { + let sig = TraitSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + GenericDefId::TypeAliasId(id) => { + let sig = TypeAliasSignature::with_source_map(db, id); + (&sig.0.store, &sig.1) + } + } + } + ExpressionStoreOwnerId::Body(body) => { + let (store, sm) = Body::with_source_map(db, body); + (&store.store, &sm.store) + } + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let (store, sm) = VariantFields::with_source_map(db, variant_id); + (&store.store, sm) + } + } + } + + /// Returns all expression root `ExprId`s found in this store. + pub fn expr_roots(&self) -> impl Iterator<Item = ExprId> { + self.const_expr_origins().iter().map(|&(id, _)| id) + } + + /// Like [`Self::signature_const_expr_roots`], but also returns the origin + /// of each expression. + pub fn expr_roots_with_origins(&self) -> impl Iterator<Item = (ExprId, RootExprOrigin)> { + self.const_expr_origins().iter().map(|&(id, origin)| (id, origin)) + } + + /// Returns the map of const expression roots to their origins. + pub fn const_expr_origins(&self) -> &[(ExprId, RootExprOrigin)] { + self.expr_only.as_ref().map_or(&[], |it| &it.expr_roots) } /// Returns an iterator over all block expressions in this store that define inner items.
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs index c955393..0c83203 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs
@@ -29,8 +29,6 @@ pub struct Body { /// empty. pub params: Box<[PatId]>, pub self_param: Option<BindingId>, - /// The `ExprId` of the actual body expression. - pub body_expr: ExprId, } impl ops::Deref for Body { @@ -68,11 +66,10 @@ fn deref(&self) -> &Self::Target { } } +#[salsa::tracked] impl Body { - pub(crate) fn body_with_source_map_query( - db: &dyn DefDatabase, - def: DefWithBodyId, - ) -> (Arc<Body>, Arc<BodySourceMap>) { + #[salsa::tracked(lru = 512, returns(ref))] + pub fn with_source_map(db: &dyn DefDatabase, def: DefWithBodyId) -> (Arc<Body>, BodySourceMap) { let _p = tracing::info_span!("body_with_source_map_query").entered(); let mut params = None; @@ -99,18 +96,25 @@ pub(crate) fn body_with_source_map_query( DefWithBodyId::VariantId(v) => { let s = v.lookup(db); let src = s.source(db); - src.map(|it| it.expr()) + src.map(|it| it.const_arg()?.expr()) } } }; let module = def.module(db); let (body, source_map) = lower_body(db, def, file_id, module, params, body, is_async_fn); - (Arc::new(body), Arc::new(source_map)) + (Arc::new(body), source_map) } - pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { - db.body_with_source_map(def).0 + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> { + Self::with_source_map(db, def).0.clone() + } +} + +impl Body { + pub fn root_expr(&self) -> ExprId { + self.store.expr_roots().next().unwrap() } pub fn pretty_print(
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs index d34ec9b..2fffa02 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs
@@ -14,7 +14,6 @@ use span::{AstIdMap, SyntaxContext}; use syntax::ast::HasAttrs; use syntax::{AstNode, Parse, ast}; -use triomphe::Arc; use tt::TextRange; use crate::{ @@ -23,21 +22,21 @@ }; #[derive(Debug)] -pub(super) struct Expander { +pub(super) struct Expander<'db> { span_map: SpanMap, current_file_id: HirFileId, - ast_id_map: Arc<AstIdMap>, + ast_id_map: &'db AstIdMap, /// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached. recursion_depth: u32, recursion_limit: usize, } -impl Expander { +impl<'db> Expander<'db> { pub(super) fn new( - db: &dyn DefDatabase, + db: &'db dyn DefDatabase, current_file_id: HirFileId, - def_map: &DefMap, - ) -> Expander { + def_map: &'db DefMap, + ) -> Expander<'db> { let recursion_limit = def_map.recursion_limit() as usize; let recursion_limit = if cfg!(test) { // Without this, `body::tests::your_stack_belongs_to_me` stack-overflows in debug @@ -77,12 +76,12 @@ pub(super) fn is_cfg_enabled( pub(super) fn enter_expand<T: ast::AstNode>( &mut self, - db: &dyn DefDatabase, + db: &'db dyn DefDatabase, macro_call: ast::MacroCall, krate: Crate, resolver: impl Fn(&ModPath) -> Option<MacroId>, eager_callback: EagerCallBackFn<'_>, - ) -> Result<ExpandResult<Option<(Mark, Option<Parse<T>>)>>, UnresolvedMacro> { + ) -> Result<ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>>, UnresolvedMacro> { // FIXME: within_limit should support this, instead of us having to extract the error let mut unresolved_macro_err = None; @@ -130,13 +129,13 @@ pub(super) fn enter_expand<T: ast::AstNode>( pub(super) fn enter_expand_id<T: ast::AstNode>( &mut self, - db: &dyn DefDatabase, + db: &'db dyn DefDatabase, call_id: MacroCallId, - ) -> ExpandResult<Option<(Mark, Option<Parse<T>>)>> { + ) -> ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>> { self.within_limit(db, |_this| ExpandResult::ok(Some(call_id))) } - pub(super) fn exit(&mut self, Mark { file_id, span_map, ast_id_map, mut bomb }: Mark) { + pub(super) fn exit(&mut self, Mark { file_id, span_map, ast_id_map, mut bomb }: Mark<'db>) { self.span_map = span_map; self.current_file_id = file_id; self.ast_id_map = ast_id_map; @@ -162,9 +161,9 @@ pub(super) fn current_file_id(&self) -> HirFileId { fn within_limit<F, T: ast::AstNode>( &mut self, - db: &dyn DefDatabase, + db: &'db dyn DefDatabase, op: F, - ) -> ExpandResult<Option<(Mark, Option<Parse<T>>)>> + ) -> ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>> where F: FnOnce(&mut Self) -> ExpandResult<Option<MacroCallId>>, { @@ -219,7 +218,7 @@ fn within_limit<F, T: ast::AstNode>( #[inline] pub(super) fn ast_id_map(&self) -> &AstIdMap { - &self.ast_id_map + self.ast_id_map } #[inline] @@ -229,9 +228,9 @@ pub(super) fn span_map(&self) -> SpanMapRef<'_> { } #[derive(Debug)] -pub(super) struct Mark { +pub(super) struct Mark<'db> { file_id: HirFileId, span_map: SpanMap, - ast_id_map: Arc<AstIdMap>, + ast_id_map: &'db AstIdMap, bomb: DropBomb, }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 1cecd19..74006c6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -18,6 +18,7 @@ }; use intern::{Symbol, sym}; use rustc_hash::FxHashMap; +use smallvec::smallvec; use stdx::never; use syntax::{ AstNode, AstPtr, SyntaxNodePtr, @@ -28,7 +29,6 @@ }, }; use thin_vec::ThinVec; -use triomphe::Arc; use tt::TextRange; use crate::{ @@ -39,7 +39,7 @@ expr_store::{ Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr, - PatPtr, TypePtr, + PatPtr, RootExprOrigin, TypePtr, expander::Expander, lower::generics::ImplTraitLowerFn, path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path}, @@ -53,6 +53,7 @@ item_tree::FieldsShape, lang_item::{LangItemTarget, LangItems}, nameres::{DefMap, LocalDefMap, MacroSubNs, block_def_map}, + signatures::StructSignature, type_ref::{ ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef, @@ -79,7 +80,7 @@ pub(super) fn lower_body( let mut self_param = None; let mut source_map_self_param = None; let mut params = vec![]; - let mut collector = ExprCollector::new(db, module, current_file_id); + let mut collector = ExprCollector::body(db, module, current_file_id); let skip_body = AttrFlags::query( db, @@ -117,9 +118,10 @@ pub(super) fn lower_body( params = (0..count).map(|_| collector.missing_pat()).collect(); }; let body_expr = collector.missing_expr(); + collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]); let (store, source_map) = collector.store.finish(); return ( - Body { store, params: params.into_boxed_slice(), self_param, body_expr }, + Body { store, params: params.into_boxed_slice(), self_param }, BodySourceMap { self_param: source_map_self_param, store: source_map }, ); } @@ -173,10 +175,11 @@ pub(super) fn lower_body( } }, ); + collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]); let (store, source_map) = collector.store.finish(); ( - Body { store, params: params.into_boxed_slice(), self_param, body_expr }, + Body { store, params: params.into_boxed_slice(), self_param }, BodySourceMap { self_param: source_map_self_param, store: source_map }, ) } @@ -186,7 +189,7 @@ pub(crate) fn lower_type_ref( module: ModuleId, type_ref: InFile<Option<ast::Type>>, ) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId) { - let mut expr_collector = ExprCollector::new(db, module, type_ref.file_id); + let mut expr_collector = ExprCollector::signature(db, module, type_ref.file_id); let type_ref = expr_collector.lower_type_ref_opt(type_ref.value, &mut ExprCollector::impl_trait_allocator); let (store, source_map) = expr_collector.store.finish(); @@ -200,13 +203,13 @@ pub(crate) fn lower_generic_params( file_id: HirFileId, param_list: Option<ast::GenericParamList>, where_clause: Option<ast::WhereClause>, -) -> (Arc<ExpressionStore>, Arc<GenericParams>, ExpressionStoreSourceMap) { - let mut expr_collector = ExprCollector::new(db, module, file_id); +) -> (ExpressionStore, GenericParams, ExpressionStoreSourceMap) { + let mut expr_collector = ExprCollector::signature(db, module, file_id); let mut collector = generics::GenericParamsCollector::new(def); collector.lower(&mut expr_collector, param_list, where_clause); let params = collector.finish(); let (store, source_map) = expr_collector.store.finish(); - (Arc::new(store), params, source_map) + (store, params, source_map) } pub(crate) fn lower_impl( @@ -214,8 +217,8 @@ pub(crate) fn lower_impl( module: ModuleId, impl_syntax: InFile<ast::Impl>, impl_id: ImplId, -) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId, Option<TraitRef>, Arc<GenericParams>) { - let mut expr_collector = ExprCollector::new(db, module, impl_syntax.file_id); +) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId, Option<TraitRef>, GenericParams) { + let mut expr_collector = ExprCollector::signature(db, module, impl_syntax.file_id); let self_ty = expr_collector.lower_type_ref_opt_disallow_impl_trait(impl_syntax.value.self_ty()); let trait_ = impl_syntax.value.trait_().and_then(|it| match &it { @@ -242,8 +245,8 @@ pub(crate) fn lower_trait( module: ModuleId, trait_syntax: InFile<ast::Trait>, trait_id: TraitId, -) -> (ExpressionStore, ExpressionStoreSourceMap, Arc<GenericParams>) { - let mut expr_collector = ExprCollector::new(db, module, trait_syntax.file_id); +) -> (ExpressionStore, ExpressionStoreSourceMap, GenericParams) { + let mut expr_collector = ExprCollector::signature(db, module, trait_syntax.file_id); let mut collector = generics::GenericParamsCollector::with_self_param( &mut expr_collector, trait_id.into(), @@ -264,14 +267,9 @@ pub(crate) fn lower_type_alias( module: ModuleId, alias: InFile<ast::TypeAlias>, type_alias_id: TypeAliasId, -) -> ( - ExpressionStore, - ExpressionStoreSourceMap, - Arc<GenericParams>, - Box<[TypeBound]>, - Option<TypeRefId>, -) { - let mut expr_collector = ExprCollector::new(db, module, alias.file_id); +) -> (ExpressionStore, ExpressionStoreSourceMap, GenericParams, Box<[TypeBound]>, Option<TypeRefId>) +{ + let mut expr_collector = ExprCollector::signature(db, module, alias.file_id); let bounds = alias .value .type_bound_list() @@ -307,13 +305,13 @@ pub(crate) fn lower_function( ) -> ( ExpressionStore, ExpressionStoreSourceMap, - Arc<GenericParams>, + GenericParams, Box<[TypeRefId]>, Option<TypeRefId>, bool, bool, ) { - let mut expr_collector = ExprCollector::new(db, module, fn_.file_id); + let mut expr_collector = ExprCollector::signature(db, module, fn_.file_id); let mut collector = generics::GenericParamsCollector::new(function_id.into()); collector.lower(&mut expr_collector, fn_.value.generic_param_list(), fn_.value.where_clause()); let mut params = vec![]; @@ -419,7 +417,7 @@ pub(crate) fn lower_function( pub struct ExprCollector<'db> { db: &'db dyn DefDatabase, cfg_options: &'db CfgOptions, - expander: Expander, + expander: Expander<'db>, def_map: &'db DefMap, local_def_map: &'db LocalDefMap, module: ModuleId, @@ -532,7 +530,20 @@ fn check_is_used(&mut self, ec: &mut ExprCollector<'_>, id: BindingId) { } impl<'db> ExprCollector<'db> { - pub fn new( + /// Creates a collector for a signature store, this will populate `const_expr_origins` to any + /// top level const arg roots. + pub fn signature( + db: &dyn DefDatabase, + module: ModuleId, + current_file_id: HirFileId, + ) -> ExprCollector<'_> { + let mut this = Self::body(db, module, current_file_id); + this.store.inference_roots = Some(Default::default()); + this + } + + /// Creates a collector for a bidy store. + pub fn body( db: &dyn DefDatabase, module: ModuleId, current_file_id: HirFileId, @@ -577,7 +588,10 @@ pub(crate) fn span_map(&self) -> SpanMapRef<'_> { self.expander.span_map() } - pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId { + pub(in crate::expr_store) fn lower_lifetime_ref( + &mut self, + lifetime: ast::Lifetime, + ) -> LifetimeRefId { // FIXME: Keyword check? let lifetime_ref = match &*lifetime.text() { "" | "'" => LifetimeRef::Error, @@ -588,7 +602,10 @@ pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId { self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime)) } - pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRefId { + pub(in crate::expr_store) fn lower_lifetime_ref_opt( + &mut self, + lifetime: Option<ast::Lifetime>, + ) -> LifetimeRefId { match lifetime { Some(lifetime) => self.lower_lifetime_ref(lifetime), None => self.alloc_lifetime_ref_desugared(LifetimeRef::Placeholder), @@ -596,7 +613,7 @@ pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> Lif } /// Converts an `ast::TypeRef` to a `hir::TypeRef`. - pub fn lower_type_ref( + pub(in crate::expr_store) fn lower_type_ref( &mut self, node: ast::Type, impl_trait_lower_fn: ImplTraitLowerFn<'_>, @@ -621,6 +638,9 @@ pub fn lower_type_ref( } ast::Type::ArrayType(inner) => { let len = self.lower_const_arg_opt(inner.const_arg()); + if let Some(const_expr_origins) = &mut self.store.inference_roots { + const_expr_origins.push((len.expr, RootExprOrigin::ArrayLength)); + } TypeRef::Array(ArrayType { ty: self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn), len, @@ -810,7 +830,7 @@ fn alloc_path(&mut self, path: Path, node: TypePtr) -> PathId { /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). - pub fn lower_generic_args_from_fn_path( + pub(in crate::expr_store) fn lower_generic_args_from_fn_path( &mut self, args: Option<ast::ParenthesizedArgList>, ret_type: Option<ast::RetType>, @@ -905,6 +925,9 @@ pub(super) fn lower_generic_args( } ast::GenericArg::ConstArg(arg) => { let arg = self.lower_const_arg(arg); + if let Some(const_expr_origins) = &mut self.store.inference_roots { + const_expr_origins.push((arg.expr, RootExprOrigin::GenericArgsPath)); + } args.push(GenericArg::Const(arg)) } } @@ -1045,17 +1068,30 @@ fn lower_type_bound( } fn lower_const_arg_opt(&mut self, arg: Option<ast::ConstArg>) -> ConstRef { - ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) } + let const_expr_origins = self.store.inference_roots.take(); + let r = ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) }; + self.store.inference_roots = const_expr_origins; + r } - fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef { - ConstRef { expr: self.collect_expr_opt(arg.expr()) } + pub fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef { + let const_expr_origins = self.store.inference_roots.take(); + let r = ConstRef { expr: self.collect_expr_opt(arg.expr()) }; + self.store.inference_roots = const_expr_origins; + r } fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr()) } + pub(in crate::expr_store) fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { + match expr { + Some(expr) => self.collect_expr(expr), + None => self.missing_expr(), + } + } + /// Returns `None` if and only if the expression is `#[cfg]`d out. fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> { let syntax_ptr = AstPtr::new(&expr); @@ -2065,13 +2101,6 @@ fn collect_macro_call<T, U>( } } - pub fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { - match expr { - Some(expr) => self.collect_expr(expr), - None => self.missing_expr(), - } - } - fn collect_macro_as_stmt( &mut self, statements: &mut Vec<Statement>, @@ -2332,7 +2361,7 @@ fn collect_pat(&mut self, pat: ast::Pat, binding_list: &mut BindingList) -> PatI } Some(ModuleDefId::AdtId(AdtId::StructId(s))) // FIXME: This can cause a cycle if the user is writing invalid code - if self.db.struct_signature(s).shape != FieldsShape::Record => + if StructSignature::of(self.db, s).shape != FieldsShape::Record => { (None, Pat::Path(name.into())) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs index c570df4..5ffc4f5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
@@ -3,15 +3,12 @@ //! generic parameters. See also the `Generics` type and the `generics_of` query //! in rustc. -use std::sync::LazyLock; - use either::Either; use hir_expand::name::{AsName, Name}; use intern::sym; use la_arena::Arena; use syntax::ast::{self, HasName, HasTypeBounds}; use thin_vec::ThinVec; -use triomphe::Arc; use crate::{ GenericDefId, TypeOrConstParamId, TypeParamId, @@ -84,28 +81,16 @@ pub(crate) fn collect_impl_trait<R>( ) } - pub(crate) fn finish(self) -> Arc<GenericParams> { - let Self { mut lifetimes, mut type_or_consts, mut where_predicates, parent: _ } = self; - - if lifetimes.is_empty() && type_or_consts.is_empty() && where_predicates.is_empty() { - static EMPTY: LazyLock<Arc<GenericParams>> = LazyLock::new(|| { - Arc::new(GenericParams { - lifetimes: Arena::new(), - type_or_consts: Arena::new(), - where_predicates: Box::default(), - }) - }); - return Arc::clone(&EMPTY); - } + pub(crate) fn finish(self) -> GenericParams { + let Self { mut lifetimes, mut type_or_consts, where_predicates, parent: _ } = self; lifetimes.shrink_to_fit(); type_or_consts.shrink_to_fit(); - where_predicates.shrink_to_fit(); - Arc::new(GenericParams { + GenericParams { type_or_consts, lifetimes, where_predicates: where_predicates.into_boxed_slice(), - }) + } } fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericParamList) { @@ -141,12 +126,17 @@ fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericP const_param.ty(), &mut ExprCollector::impl_trait_error_allocator, ); - let param = ConstParamData { - name, - ty, - default: const_param.default_val().map(|it| ec.lower_const_arg(it)), - }; - let _idx = self.type_or_consts.alloc(param.into()); + let default = const_param.default_val().map(|it| ec.lower_const_arg(it)); + let param = ConstParamData { name, ty, default }; + let idx = self.type_or_consts.alloc(param.into()); + if let Some(default) = default + && let Some(const_expr_origins) = &mut ec.store.inference_roots + { + const_expr_origins.push(( + default.expr, + crate::expr_store::RootExprOrigin::ConstParam(idx), + )); + } } ast::GenericParam::LifetimeParam(lifetime_param) => { let lifetime = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path/tests.rs index f507841..6819eb3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/path/tests.rs
@@ -21,7 +21,7 @@ fn lower_path(path: ast::Path) -> (TestDB, ExpressionStore, Option<Path>) { let (db, file_id) = TestDB::with_single_file(""); let krate = db.fetch_test_crate(); let mut ctx = - ExprCollector::new(&db, crate_def_map(&db, krate).root_module_id(), file_id.into()); + ExprCollector::signature(&db, crate_def_map(&db, krate).root_module_id(), file_id.into()); let lowered_path = ctx.lower_path(path, &mut ExprCollector::impl_trait_allocator); let (store, _) = ctx.store.finish(); (db, store, lowered_path)
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs index 35f3cd1..9c9c4db 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
@@ -105,7 +105,7 @@ pub fn print_body_hir( p.buf.push(')'); p.buf.push(' '); } - p.print_expr(body.body_expr); + p.print_expr(body.root_expr()); if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) { p.buf.push(';'); } @@ -168,8 +168,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi match owner { GenericDefId::AdtId(id) => match id { AdtId::StructId(id) => { - let signature = db.struct_signature(id); - print_struct(db, id, &signature, edition) + let signature = StructSignature::of(db, id); + print_struct(db, id, signature, edition) } AdtId::UnionId(id) => { format!("unimplemented {id:?}") @@ -180,8 +180,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi }, GenericDefId::ConstId(id) => format!("unimplemented {id:?}"), GenericDefId::FunctionId(id) => { - let signature = db.function_signature(id); - print_function(db, id, &signature, edition) + let signature = FunctionSignature::of(db, id); + print_function(db, id, signature, edition) } GenericDefId::ImplId(id) => format!("unimplemented {id:?}"), GenericDefId::StaticId(id) => format!("unimplemented {id:?}"), @@ -1212,7 +1212,7 @@ pub(crate) fn print_generic_arg(&mut self, arg: &GenericArg) { } pub(crate) fn print_type_param(&mut self, param: TypeParamId) { - let generic_params = self.db.generic_params(param.parent()); + let generic_params = GenericParams::of(self.db, param.parent()); match generic_params[param.local_id()].name() { Some(name) => w!(self, "{}", name.display(self.db, self.edition)), @@ -1221,7 +1221,7 @@ pub(crate) fn print_type_param(&mut self, param: TypeParamId) { } pub(crate) fn print_lifetime_param(&mut self, param: LifetimeParamId) { - let generic_params = self.db.generic_params(param.parent); + let generic_params = GenericParams::of(self.db, param.parent); w!(self, "{}", generic_params[param.local_id].name.display(self.db, self.edition)) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs index 1952dae..40ae0b7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/scope.rs
@@ -1,13 +1,16 @@ //! Name resolution for expressions. use hir_expand::{MacroDefId, name::Name}; use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx}; -use triomphe::Arc; use crate::{ - BlockId, DefWithBodyId, + BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, VariantId, db::DefDatabase, expr_store::{Body, ExpressionStore, HygieneId}, - hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement}, + hir::{ + Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement, + generics::GenericParams, + }, + signatures::VariantFields, }; pub type ScopeId = Idx<ScopeData>; @@ -50,12 +53,45 @@ pub struct ScopeData { entries: IdxRange<ScopeEntry>, } +#[salsa::tracked] impl ExprScopes { - pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> { - let body = db.body(def); - let mut scopes = ExprScopes::new_body(&body); + #[salsa::tracked(returns(ref))] + pub fn body_expr_scopes(db: &dyn DefDatabase, def: DefWithBodyId) -> ExprScopes { + let body = Body::of(db, def); + let mut scopes = ExprScopes::new_body(body); scopes.shrink_to_fit(); - Arc::new(scopes) + scopes + } + + #[salsa::tracked(returns(ref))] + pub fn sig_expr_scopes(db: &dyn DefDatabase, def: GenericDefId) -> ExprScopes { + let (_, store) = GenericParams::with_store(db, def); + let roots = store.expr_roots(); + let mut scopes = ExprScopes::new_store(store, roots); + scopes.shrink_to_fit(); + scopes + } + + #[salsa::tracked(returns(ref))] + pub fn variant_scopes(db: &dyn DefDatabase, def: VariantId) -> ExprScopes { + let fields = VariantFields::of(db, def); + let roots = fields.store.expr_roots(); + let mut scopes = ExprScopes::new_store(&fields.store, roots); + scopes.shrink_to_fit(); + scopes + } +} + +impl ExprScopes { + #[inline] + pub fn of(db: &dyn DefDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &ExprScopes { + match def.into() { + ExpressionStoreOwnerId::Body(def) => Self::body_expr_scopes(db, def), + ExpressionStoreOwnerId::Signature(def) => Self::sig_expr_scopes(db, def), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::variant_scopes(db, variant_id) + } + } } pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { @@ -115,7 +151,23 @@ fn new_body(body: &Body) -> ExprScopes { scopes.add_bindings(body, root, self_param, body.binding_hygiene(self_param)); } scopes.add_params_bindings(body, root, &body.params); - compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root); + compute_expr_scopes(body.root_expr(), body, &mut scopes, &mut root); + scopes + } + + fn new_store(store: &ExpressionStore, roots: impl IntoIterator<Item = ExprId>) -> ExprScopes { + let mut scopes = ExprScopes { + scopes: Arena::default(), + scope_entries: Arena::default(), + scope_by_expr: ArenaMap::with_capacity( + store.expr_only.as_ref().map_or(0, |it| it.exprs.len()), + ), + }; + let root = scopes.root_scope(); + for root_expr in roots { + let mut scope = scopes.new_scope(root); + compute_expr_scopes(root_expr, store, &mut scopes, &mut scope); + } scopes } @@ -327,7 +379,10 @@ mod tests { use test_utils::{assert_eq_text, extract_offset}; use crate::{ - FunctionId, ModuleDefId, db::DefDatabase, nameres::crate_def_map, test_db::TestDB, + DefWithBodyId, FunctionId, ModuleDefId, + expr_store::{Body, scope::ExprScopes}, + nameres::crate_def_map, + test_db::TestDB, }; fn find_function(db: &TestDB, file_id: FileId) -> FunctionId { @@ -363,8 +418,8 @@ fn do_check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &[&str]) let marker: ast::PathExpr = find_node_at_offset(&file_syntax, offset).unwrap(); let function = find_function(&db, file_id); - let scopes = db.expr_scopes(function.into()); - let (_body, source_map) = db.body_with_source_map(function.into()); + let scopes = ExprScopes::of(&db, DefWithBodyId::from(function)); + let (_body, source_map) = Body::with_source_map(&db, function.into()); let expr_id = source_map .node_expr(InFile { file_id: editioned_file_id.into(), value: &marker.into() }) @@ -522,8 +577,8 @@ fn do_check_local_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected let function = find_function(&db, file_id); - let scopes = db.expr_scopes(function.into()); - let (_, source_map) = db.body_with_source_map(function.into()); + let scopes = ExprScopes::body_expr_scopes(&db, DefWithBodyId::from(function)); + let (_, source_map) = Body::with_source_map(&db, function.into()); let expr_scope = { let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs index 8f857ae..985cd96 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs
@@ -4,11 +4,10 @@ use expect_test::{Expect, expect}; use la_arena::RawIdx; use test_fixture::WithFixture; -use triomphe::Arc; use super::super::*; -fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) { +fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, DefWithBodyId) { let db = TestDB::with_files(ra_fixture); let krate = db.fetch_test_crate(); @@ -24,8 +23,27 @@ fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, } let fn_def = fn_def.unwrap().into(); - let body = db.body(fn_def); - (db, body, fn_def) + Body::of(&db, fn_def); + (db, fn_def) +} + +fn pretty_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { + let db = TestDB::with_files(ra_fixture); + + let krate = db.fetch_test_crate(); + let def_map = crate_def_map(&db, krate); + let mut fn_def = None; + 'outer: for (_, module) in def_map.modules() { + for decl in module.scope.declarations() { + if let ModuleDefId::FunctionId(it) = decl { + fn_def = Some(it); + break 'outer; + } + } + } + let fn_def = fn_def.unwrap().into(); + + expect.assert_eq(&Body::of(&db, fn_def).pretty_print(&db, fn_def, Edition::CURRENT)); } fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { @@ -144,7 +162,7 @@ fn outer() { #[test] fn desugar_for_loop() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: iterator fn main() { @@ -154,9 +172,7 @@ fn main() { } } "#, - ); - - expect![[r#" + expect![[r#" fn main() { match builtin#lang(into_iter)( 0..10, @@ -173,13 +189,13 @@ fn main() { } }, } - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ); } #[test] fn desugar_builtin_format_args_before_1_89_0() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt_before_1_89_0 fn main() { @@ -188,9 +204,7 @@ fn main() { builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!"); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -256,13 +270,13 @@ fn main() { } }, ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn desugar_builtin_format_args_before_1_93_0() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt_before_1_93_0 fn main() { @@ -271,9 +285,7 @@ fn main() { builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!"); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -339,13 +351,13 @@ fn main() { ) } }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn desugar_builtin_format_args() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: fmt fn main() { @@ -356,9 +368,7 @@ fn main() { builtin#format_args("hello world", orphan = ()); } "#, - ); - - expect![[r#" + expect![[r#" fn main() { let are = "are"; let count = 10; @@ -392,13 +402,13 @@ fn main() { "hello world", ) }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn test_macro_hygiene() { - let (db, body, def) = lower( + pretty_print( r##" //- minicore: fmt, from //- /main.rs @@ -428,10 +438,7 @@ pub(crate) fn new(message: impl Into<core::fmt::Arguments>) -> SsrError { } } "##, - ); - - assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]); - expect![[r#" + expect![[r#" fn main() { _ = ra_test_fixture::error::SsrError::new( { @@ -449,13 +456,13 @@ fn main() { } }, ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn regression_10300() { - let (db, body, def) = lower( + pretty_print( r#" //- minicore: concat, panic, fmt_before_1_89_0 mod private { @@ -472,16 +479,7 @@ fn f(a: i32, b: u32) -> String { m!(); } "#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" + expect![[r#" fn f(a, b) { { core::panicking::panic_fmt( @@ -497,8 +495,8 @@ fn f(a, b) { ), ); }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] @@ -507,7 +505,7 @@ fn destructuring_assignment_tuple_macro() { // but in destructuring assignment it is valid, because `m!()()` is a valid expression, and destructuring // assignments start their lives as expressions. So we have to do the same. - let (db, body, def) = lower( + pretty_print( r#" struct Bar(); @@ -519,25 +517,16 @@ fn foo() { m!()() = Bar(); } "#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" + expect![[r#" fn foo() { Bar() = Bar(); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn shadowing_record_variant() { - let (_, body, _) = lower( + let (db, def) = lower( r#" enum A { B { field: i32 }, @@ -550,6 +539,7 @@ fn f() { } "#, ); + let body = Body::of(&db, def); assert_eq!(body.assert_expr_only().bindings.len(), 1, "should have a binding for `B`"); assert_eq!( body[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(), @@ -560,39 +550,35 @@ fn f() { #[test] fn regression_pretty_print_bind_pat() { - let (db, body, owner) = lower( + pretty_print( r#" fn foo() { let v @ u = 123; } "#, - ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - - expect![[r#" + expect![[r#" fn foo() { let v @ u = 123; - }"#]] - .assert_eq(&printed); + }"#]], + ); } #[test] fn skip_skips_body() { - let (db, body, owner) = lower( + pretty_print( r#" #[rust_analyzer::skip] async fn foo(a: (), b: i32) -> u32 { 0 + 1 + b() } "#, + expect!["fn foo(�, �) �"], ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - expect!["fn foo(�, �) �"].assert_eq(&printed); } #[test] fn range_bounds_are_hir_exprs() { - let (_, body, _) = lower( + let (db, body) = lower( r#" pub const L: i32 = 6; mod x { @@ -607,6 +593,7 @@ const fn f(x: i32) -> i32 { }"#, ); + let body = Body::of(&db, body); let mtch_arms = body .assert_expr_only() .exprs @@ -635,7 +622,7 @@ const fn f(x: i32) -> i32 { #[test] fn print_hir_precedences() { - let (db, body, def) = lower( + pretty_print( r#" fn main() { _ = &(1 - (2 - 3) + 4 * 5 * (6 + 7)); @@ -646,9 +633,7 @@ fn main() { let _ = &mut (*r as i32) } "#, - ); - - expect![[r#" + expect![[r#" fn main() { _ = &((1 - (2 - 3)) + (4 * 5) * (6 + 7)); _ = 1 + 2 < 3 && true && 4 < 5 && (a || b || c) || d && e; @@ -656,24 +641,22 @@ fn main() { break a && b || (return) || (return 2); let r = &2; let _ = &mut (*r as i32); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) } #[test] fn async_fn_weird_param_patterns() { - let (db, body, def) = lower( + pretty_print( r#" async fn main(&self, param1: i32, ref mut param2: i32, _: i32, param4 @ _: i32, 123: i32) {} "#, - ); - - expect![[r#" + expect![[r#" fn main(self, param1, mut param2, mut <ra@gennew>0, param4 @ _, mut <ra@gennew>1) async { let ref mut param2 = param2; let _ = <ra@gennew>0; let 123 = <ra@gennew>1; {} - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) + }"#]], + ) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs index f1db00c..5e0184d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs
@@ -2,6 +2,7 @@ GenericDefId, ModuleDefId, expr_store::pretty::{print_function, print_struct}, nameres::crate_def_map, + signatures::{FunctionSignature, StructSignature}, test_db::TestDB, }; use expect_test::{Expect, expect}; @@ -41,7 +42,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe out += &print_struct( &db, struct_id, - &db.struct_signature(struct_id), + StructSignature::of(&db, struct_id), Edition::CURRENT, ); } @@ -53,7 +54,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe out += &print_function( &db, function_id, - &db.function_signature(function_id), + FunctionSignature::of(&db, function_id), Edition::CURRENT, ) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 5d1cac8..8308203 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -14,6 +14,7 @@ use crate::{ FindPathConfig, ModuleDefId, ModuleId, db::DefDatabase, + import_map::ImportMap, item_scope::ItemInNs, nameres::DefMap, visibility::{Visibility, VisibilityExplicitness}, @@ -426,7 +427,7 @@ fn find_in_dep( best_choice: &mut Option<Choice>, dep: Crate, ) { - let import_map = ctx.db.import_map(dep); + let import_map = ImportMap::of(ctx.db, dep); let Some(import_info_for) = import_map.import_info_for(item) else { return; };
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs index 022f8ad..43dd7d1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs
@@ -5,12 +5,15 @@ use la_arena::{Arena, Idx, RawIdx}; use stdx::impl_from; use thin_vec::ThinVec; -use triomphe::Arc; use crate::{ AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId, db::DefDatabase, expr_store::{ExpressionStore, ExpressionStoreSourceMap}, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature, + StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, + }, type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId}, }; @@ -142,7 +145,7 @@ pub enum GenericParamDataRef<'a> { } /// Data about the generic parameters of a function, struct, impl, etc. -#[derive(Clone, PartialEq, Eq, Debug, Hash)] +#[derive(PartialEq, Eq, Debug, Hash, Default)] pub struct GenericParams { pub(crate) type_or_consts: Arena<TypeOrConstParamData>, pub(crate) lifetimes: Arena<LifetimeParamData>, @@ -174,12 +177,10 @@ pub enum WherePredicate { ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound }, } -static EMPTY: LazyLock<Arc<GenericParams>> = LazyLock::new(|| { - Arc::new(GenericParams { - type_or_consts: Arena::default(), - lifetimes: Arena::default(), - where_predicates: Box::default(), - }) +static EMPTY: LazyLock<GenericParams> = LazyLock::new(|| GenericParams { + type_or_consts: Arena::default(), + lifetimes: Arena::default(), + where_predicates: Box::default(), }); impl GenericParams { @@ -187,112 +188,94 @@ impl GenericParams { pub const SELF_PARAM_ID_IN_SELF: la_arena::Idx<TypeOrConstParamData> = LocalTypeOrConstParamId::from_raw(RawIdx::from_u32(0)); - pub fn new(db: &dyn DefDatabase, def: GenericDefId) -> Arc<GenericParams> { + pub fn of(db: &dyn DefDatabase, def: GenericDefId) -> &GenericParams { + Self::with_store(db, def).0 + } + + pub fn with_store( + db: &dyn DefDatabase, + def: GenericDefId, + ) -> (&GenericParams, &ExpressionStore) { match def { - GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature(it).generic_params.clone(), - GenericDefId::AdtId(AdtId::StructId(it)) => { - db.struct_signature(it).generic_params.clone() + GenericDefId::AdtId(AdtId::EnumId(id)) => { + let sig = EnumSignature::of(db, id); + (&sig.generic_params, &sig.store) } - GenericDefId::AdtId(AdtId::UnionId(it)) => { - db.union_signature(it).generic_params.clone() + GenericDefId::AdtId(AdtId::StructId(id)) => { + let sig = StructSignature::of(db, id); + (&sig.generic_params, &sig.store) } - GenericDefId::ConstId(_) => EMPTY.clone(), - GenericDefId::FunctionId(function_id) => { - db.function_signature(function_id).generic_params.clone() + GenericDefId::AdtId(AdtId::UnionId(id)) => { + let sig = UnionSignature::of(db, id); + (&sig.generic_params, &sig.store) } - GenericDefId::ImplId(impl_id) => db.impl_signature(impl_id).generic_params.clone(), - GenericDefId::StaticId(_) => EMPTY.clone(), - GenericDefId::TraitId(trait_id) => db.trait_signature(trait_id).generic_params.clone(), - GenericDefId::TypeAliasId(type_alias_id) => { - db.type_alias_signature(type_alias_id).generic_params.clone() + GenericDefId::ConstId(id) => { + let sig = ConstSignature::of(db, id); + (&EMPTY, &sig.store) + } + GenericDefId::FunctionId(id) => { + let sig = FunctionSignature::of(db, id); + (&sig.generic_params, &sig.store) + } + GenericDefId::ImplId(id) => { + let sig = ImplSignature::of(db, id); + (&sig.generic_params, &sig.store) + } + GenericDefId::StaticId(id) => { + let sig = StaticSignature::of(db, id); + (&EMPTY, &sig.store) + } + GenericDefId::TraitId(id) => { + let sig = TraitSignature::of(db, id); + (&sig.generic_params, &sig.store) + } + GenericDefId::TypeAliasId(id) => { + let sig = TypeAliasSignature::of(db, id); + (&sig.generic_params, &sig.store) } } } - pub fn generic_params_and_store( + pub fn with_source_map( db: &dyn DefDatabase, def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>) { + ) -> (&GenericParams, &ExpressionStore, &ExpressionStoreSourceMap) { match def { GenericDefId::AdtId(AdtId::EnumId(id)) => { - let sig = db.enum_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = EnumSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::AdtId(AdtId::StructId(id)) => { - let sig = db.struct_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = StructSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::AdtId(AdtId::UnionId(id)) => { - let sig = db.union_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = UnionSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::ConstId(id) => { - let sig = db.const_signature(id); - (EMPTY.clone(), sig.store.clone()) + let (sig, sm) = ConstSignature::with_source_map(db, id); + (&EMPTY, &sig.store, sm) } GenericDefId::FunctionId(id) => { - let sig = db.function_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = FunctionSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::ImplId(id) => { - let sig = db.impl_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = ImplSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::StaticId(id) => { - let sig = db.static_signature(id); - (EMPTY.clone(), sig.store.clone()) + let (sig, sm) = StaticSignature::with_source_map(db, id); + (&EMPTY, &sig.store, sm) } GenericDefId::TraitId(id) => { - let sig = db.trait_signature(id); - (sig.generic_params.clone(), sig.store.clone()) + let (sig, sm) = TraitSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } GenericDefId::TypeAliasId(id) => { - let sig = db.type_alias_signature(id); - (sig.generic_params.clone(), sig.store.clone()) - } - } - } - - pub fn generic_params_and_store_and_source_map( - db: &dyn DefDatabase, - def: GenericDefId, - ) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) { - match def { - GenericDefId::AdtId(AdtId::EnumId(id)) => { - let (sig, sm) = db.enum_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::AdtId(AdtId::StructId(id)) => { - let (sig, sm) = db.struct_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::AdtId(AdtId::UnionId(id)) => { - let (sig, sm) = db.union_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::ConstId(id) => { - let (sig, sm) = db.const_signature_with_source_map(id); - (EMPTY.clone(), sig.store.clone(), sm) - } - GenericDefId::FunctionId(id) => { - let (sig, sm) = db.function_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::ImplId(id) => { - let (sig, sm) = db.impl_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::StaticId(id) => { - let (sig, sm) = db.static_signature_with_source_map(id); - (EMPTY.clone(), sig.store.clone(), sm) - } - GenericDefId::TraitId(id) => { - let (sig, sm) = db.trait_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) - } - GenericDefId::TypeAliasId(id) => { - let (sig, sm) = db.type_alias_signature_with_source_map(id); - (sig.generic_params.clone(), sig.store.clone(), sm) + let (sig, sm) = TypeAliasSignature::with_source_map(db, id); + (&sig.generic_params, &sig.store, sm) } } }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 6c5d226..0014e1a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
@@ -10,7 +10,6 @@ use smallvec::SmallVec; use span::Edition; use stdx::format_to; -use triomphe::Arc; use crate::{ AssocItemId, AttrDefId, Complete, FxIndexMap, ModuleDefId, ModuleId, TraitId, @@ -63,6 +62,14 @@ enum IsTraitAssocItem { type ImportMapIndex = FxIndexMap<ItemInNs, (SmallVec<[ImportInfo; 1]>, IsTraitAssocItem)>; +#[salsa::tracked] +impl ImportMap { + #[salsa::tracked(returns(ref))] + pub fn of(db: &dyn DefDatabase, krate: Crate) -> Self { + Self::import_map_query_impl(db, krate) + } +} + impl ImportMap { pub fn dump(&self, db: &dyn DefDatabase) -> String { let mut out = String::new(); @@ -76,7 +83,7 @@ pub fn dump(&self, db: &dyn DefDatabase) -> String { out } - pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc<Self> { + fn import_map_query_impl(db: &dyn DefDatabase, krate: Crate) -> Self { let _p = tracing::info_span!("import_map_query").entered(); let map = Self::collect_import_map(db, krate); @@ -120,7 +127,7 @@ pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc<Self> } let importables = importables.into_iter().map(|(item, _, idx)| (item, idx)).collect(); - Arc::new(ImportMap { item_to_info_map: map, fst: builder.into_map(), importables }) + ImportMap { item_to_info_map: map, fst: builder.into_map(), importables } } pub fn import_info_for(&self, item: ItemInNs) -> Option<&[ImportInfo]> { @@ -424,7 +431,7 @@ pub fn search_dependencies( let _p = tracing::info_span!("search_dependencies", ?query).entered(); let import_maps: Vec<_> = - krate.data(db).dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect(); + krate.data(db).dependencies.iter().map(|dep| ImportMap::of(db, dep.crate_id)).collect(); let mut op = fst::map::OpBuilder::new(); @@ -458,7 +465,7 @@ pub fn search_dependencies( fn search_maps( _db: &dyn DefDatabase, - import_maps: &[Arc<ImportMap>], + import_maps: &[&ImportMap], mut stream: fst::map::Union<'_>, query: &Query, ) -> FxHashSet<(ItemInNs, Complete)> { @@ -467,7 +474,7 @@ fn search_maps( for &IndexedValue { index: import_map_idx, value } in indexed_values { let end = (value & 0xFFFF_FFFF) as usize; let start = (value >> 32) as usize; - let ImportMap { item_to_info_map, importables, .. } = &*import_maps[import_map_idx]; + let ImportMap { item_to_info_map, importables, .. } = import_maps[import_map_idx]; let importables = &importables[start..end]; let iter = importables @@ -546,9 +553,9 @@ fn check_search( .into_iter() .filter_map(|(dependency, _)| { let dependency_krate = dependency.krate(&db)?; - let dependency_imports = db.import_map(dependency_krate); + let dependency_imports = ImportMap::of(&db, dependency_krate); - let (path, mark) = match assoc_item_path(&db, &dependency_imports, dependency) { + let (path, mark) = match assoc_item_path(&db, dependency_imports, dependency) { Some(assoc_item_path) => (assoc_item_path, "a"), None => ( render_path(&db, &dependency_imports.import_info_for(dependency)?[0]), @@ -618,7 +625,7 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let cdata = &krate.extra_data(&db); let name = cdata.display_name.as_ref()?; - let map = db.import_map(krate); + let map = ImportMap::of(&db, krate); Some(format!("{name}:\n{}\n", map.fmt_for_test(&db))) })
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 9825dbf..e7ab2b3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -192,45 +192,22 @@ pub(crate) fn file_item_tree_query( } } -#[salsa_macros::tracked(returns(deref))] +#[salsa_macros::tracked(returns(ref))] pub(crate) fn block_item_tree_query( db: &dyn DefDatabase, block: BlockId, krate: Crate, -) -> Arc<ItemTree> { +) -> ItemTree { let _p = tracing::info_span!("block_item_tree_query", ?block).entered(); - static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new(); - let loc = block.lookup(db); let block = loc.ast_id.to_node(db); let ctx = lower::Ctx::new(db, loc.ast_id.file_id, krate); let mut item_tree = ctx.lower_block(&block); - let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree; - if small_data.is_empty() - && big_data.is_empty() - && top_level.is_empty() - && attrs.is_empty() - && top_attrs.is_empty() - && vis.arena.is_empty() - { - EMPTY - .get_or_init(|| { - Arc::new(ItemTree { - top_level: Box::new([]), - attrs: FxHashMap::default(), - small_data: FxHashMap::default(), - big_data: FxHashMap::default(), - top_attrs: AttrsOrCfg::empty(), - vis: ItemVisibilities { arena: ThinVec::new() }, - }) - }) - .clone() - } else { - item_tree.shrink_to_fit(); - Arc::new(item_tree) - } + item_tree.shrink_to_fit(); + item_tree } + /// The item tree of a source file. #[derive(Debug, Default, Eq, PartialEq)] pub struct ItemTree {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 31c6ef8..31e409d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -16,7 +16,6 @@ AstNode, ast::{self, HasModuleItem, HasName}, }; -use triomphe::Arc; use crate::{ db::DefDatabase, @@ -29,20 +28,20 @@ }, }; -pub(super) struct Ctx<'a> { - pub(super) db: &'a dyn DefDatabase, +pub(super) struct Ctx<'db> { + pub(super) db: &'db dyn DefDatabase, tree: ItemTree, - source_ast_id_map: Arc<AstIdMap>, + source_ast_id_map: &'db AstIdMap, span_map: OnceCell<SpanMap>, file: HirFileId, - cfg_options: OnceCell<&'a CfgOptions>, + cfg_options: OnceCell<&'db CfgOptions>, krate: Crate, top_level: Vec<ModItemId>, visibilities: FxIndexSet<RawVisibility>, } -impl<'a> Ctx<'a> { - pub(super) fn new(db: &'a dyn DefDatabase, file: HirFileId, krate: Crate) -> Self { +impl<'db> Ctx<'db> { + pub(super) fn new(db: &'db dyn DefDatabase, file: HirFileId, krate: Crate) -> Self { Self { db, tree: ItemTree::default(), @@ -57,7 +56,7 @@ pub(super) fn new(db: &'a dyn DefDatabase, file: HirFileId, krate: Crate) -> Sel } #[inline] - pub(super) fn cfg_options(&self) -> &'a CfgOptions { + pub(super) fn cfg_options(&self) -> &'db CfgOptions { self.cfg_options.get_or_init(|| self.krate.cfg_options(self.db)) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index de674be..9a7fbc8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -49,7 +49,6 @@ use intern::{Interned, Symbol}; pub use rustc_abi as layout; use thin_vec::ThinVec; -use triomphe::Arc; pub use crate::signatures::LocalFieldId; @@ -86,14 +85,19 @@ builtin_type::BuiltinType, db::DefDatabase, expr_store::ExpressionStoreSourceMap, - hir::generics::{GenericParams, LocalLifetimeParamId, LocalTypeOrConstParamId}, + hir::{ + ExprId, + generics::{GenericParams, LocalLifetimeParamId, LocalTypeOrConstParamId}, + }, nameres::{ LocalDefMap, assoc::{ImplItems, TraitItems}, block_def_map, crate_def_map, crate_local_def_map, diagnostics::DefDiagnostics, }, - signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields}, + signatures::{ + ConstSignature, EnumVariants, InactiveEnumVariantCode, StaticSignature, VariantFields, + }, }; type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>; @@ -255,14 +259,15 @@ fn module(&self, db: &dyn DefDatabase) -> ModuleId { impl StructId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -271,14 +276,15 @@ pub fn fields_with_source_map( impl UnionId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -306,6 +312,19 @@ pub fn enum_variants_with_diagnostics( pub type StaticLoc = AssocItemLoc<ast::Static>; impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); +/// An anonymous const expression that appears in a type position (e.g., array lengths, +/// const generic arguments like `{ N + 1 }`). Unlike named constants, these don't have +/// their own `Body` — their expressions live in the parent's signature `ExpressionStore`. +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub struct AnonConstLoc { + /// The owner store containing this expression. + pub owner: ExpressionStoreOwnerId, + /// The ExprId within the owner's ExpressionStore that is the root + /// of this anonymous const expression. + pub expr: ExprId, +} +impl_intern!(AnonConstId, AnonConstLoc, intern_anon_const, lookup_intern_anon_const); + pub type TraitLoc = ItemLoc<ast::Trait>; impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); @@ -377,14 +396,15 @@ pub struct EnumVariantLoc { impl EnumVariantId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self.into()) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self.into()); + (&r.0, &r.1) } } @@ -706,46 +726,47 @@ fn from(value: DefWithBodyId) -> Self { pub enum GeneralConstId { ConstId(ConstId), StaticId(StaticId), + AnonConstId(AnonConstId), } -impl_from!(ConstId, StaticId for GeneralConstId); +impl_from!(ConstId, StaticId, AnonConstId for GeneralConstId); impl GeneralConstId { - pub fn generic_def(self, _db: &dyn DefDatabase) -> Option<GenericDefId> { + pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> { match self { GeneralConstId::ConstId(it) => Some(it.into()), GeneralConstId::StaticId(it) => Some(it.into()), + GeneralConstId::AnonConstId(it) => Some(it.lookup(db).owner.generic_def(db)), } } pub fn name(self, db: &dyn DefDatabase) -> String { match self { GeneralConstId::StaticId(it) => { - db.static_signature(it).name.display(db, Edition::CURRENT).to_string() + StaticSignature::of(db, it).name.display(db, Edition::CURRENT).to_string() } GeneralConstId::ConstId(const_id) => { - db.const_signature(const_id).name.as_ref().map_or_else( + ConstSignature::of(db, const_id).name.as_ref().map_or_else( || "_".to_owned(), |name| name.display(db, Edition::CURRENT).to_string(), ) } + GeneralConstId::AnonConstId(_) => "{anon const}".to_owned(), } } } -/// The defs which have a body (have root expressions for type inference). +/// The defs which have a body. #[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum DefWithBodyId { + /// A function body. FunctionId(FunctionId), + /// A static item initializer. StaticId(StaticId), + /// A const item initializer ConstId(ConstId), + /// An enum variant discrimiant VariantId(EnumVariantId), - // /// All fields of a variant are inference roots - // VariantId(VariantId), - // /// The signature can contain inference roots in a bunch of places - // /// like const parameters or const arguments in paths - // This should likely be kept on its own with a separate query - // GenericDefId(GenericDefId), } impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); @@ -814,6 +835,62 @@ pub enum GenericDefId { for GenericDefId ); +/// Owner of an expression store - either a body or a signature. +/// This is used for queries that operate on expression stores generically, +/// such as `expr_scopes`. +// NOTE: This type cannot be `salsa::Supertype` as its variants are overlapping. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord /* !salsa::Supertype */)] +pub enum ExpressionStoreOwnerId { + Signature(GenericDefId), + /// A body, something with a root expression. + /// + /// An enum variant's body is considered its discriminant initializer. + Body(DefWithBodyId), + VariantFields(VariantId), +} + +impl ExpressionStoreOwnerId { + // FIXME: Check callers of this, this method likely can be removed + pub fn as_def_with_body(self) -> Option<DefWithBodyId> { + if let Self::Body(v) = self { Some(v) } else { None } + } + + pub fn generic_def(self, db: &dyn DefDatabase) -> GenericDefId { + match self { + ExpressionStoreOwnerId::Signature(generic_def_id) => generic_def_id, + ExpressionStoreOwnerId::Body(def_with_body_id) => match def_with_body_id { + DefWithBodyId::FunctionId(id) => GenericDefId::FunctionId(id), + DefWithBodyId::StaticId(id) => GenericDefId::StaticId(id), + DefWithBodyId::ConstId(id) => GenericDefId::ConstId(id), + DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(), + }, + ExpressionStoreOwnerId::VariantFields(variant_id) => match variant_id { + VariantId::EnumVariantId(it) => it.lookup(db).parent.into(), + VariantId::StructId(it) => it.into(), + VariantId::UnionId(it) => it.into(), + }, + } + } +} + +impl From<GenericDefId> for ExpressionStoreOwnerId { + fn from(id: GenericDefId) -> Self { + ExpressionStoreOwnerId::Signature(id) + } +} + +impl From<DefWithBodyId> for ExpressionStoreOwnerId { + fn from(id: DefWithBodyId) -> Self { + ExpressionStoreOwnerId::Body(id) + } +} + +impl From<VariantId> for ExpressionStoreOwnerId { + fn from(id: VariantId) -> Self { + ExpressionStoreOwnerId::VariantFields(id) + } +} + impl GenericDefId { pub fn file_id_and_params_of( self, @@ -954,7 +1031,9 @@ fn from(vid: VariantId) -> Self { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa_macros::Supertype, salsa::Update, +)] pub enum VariantId { EnumVariantId(EnumVariantId), StructId(StructId), @@ -964,14 +1043,15 @@ pub enum VariantId { impl VariantId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self) + VariantFields::of(db, self) } pub fn fields_with_source_map( self, db: &dyn DefDatabase, - ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) { - VariantFields::query(db, self) + ) -> (&VariantFields, &ExpressionStoreSourceMap) { + let r = VariantFields::with_source_map(db, self); + (&r.0, &r.1) } pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId { @@ -1172,6 +1252,16 @@ fn module(&self, db: &dyn DefDatabase) -> ModuleId { } } +impl HasModule for ExpressionStoreOwnerId { + fn module(&self, db: &dyn DefDatabase) -> ModuleId { + match self { + ExpressionStoreOwnerId::Signature(def) => def.module(db), + ExpressionStoreOwnerId::Body(def) => def.module(db), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.module(db), + } + } +} + impl HasModule for GenericDefId { fn module(&self, db: &dyn DefDatabase) -> ModuleId { match self {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 8ee93dc..8317c56 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -45,6 +45,7 @@ use crate::{ AdtId, Lookup, ModuleDefId, db::DefDatabase, + expr_store::Body, nameres::{DefMap, ModuleSource, crate_def_map}, src::HasSource, test_db::TestDB, @@ -276,7 +277,7 @@ fn resolve_macro_call_id( _ => continue, }; - let (body, sm) = db.body_with_source_map(body); + let (body, sm) = Body::with_source_map(db, body); if let Some(it) = body .blocks(db) .find_map(|block| resolve_macro_call_id(db, block.1, ast_id, ast_ptr))
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs index 9d2b210..f5a852b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs
@@ -17,7 +17,6 @@ ast::{self, HasModuleItem, HasName}, }; use thin_vec::ThinVec; -use triomphe::Arc; use crate::{ AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId, @@ -133,14 +132,14 @@ pub fn macro_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId } } -struct AssocItemCollector<'a> { - db: &'a dyn DefDatabase, +struct AssocItemCollector<'db> { + db: &'db dyn DefDatabase, module_id: ModuleId, - def_map: &'a DefMap, - local_def_map: &'a LocalDefMap, - ast_id_map: Arc<AstIdMap>, + def_map: &'db DefMap, + local_def_map: &'db LocalDefMap, + ast_id_map: &'db AstIdMap, span_map: SpanMap, - cfg_options: &'a CfgOptions, + cfg_options: &'db CfgOptions, file_id: HirFileId, diagnostics: Vec<DefDiagnostic>, container: ItemContainerId, @@ -150,9 +149,9 @@ struct AssocItemCollector<'a> { macro_calls: ThinVec<(AstId<ast::Item>, MacroCallId)>, } -impl<'a> AssocItemCollector<'a> { +impl<'db> AssocItemCollector<'db> { fn new( - db: &'a dyn DefDatabase, + db: &'db dyn DefDatabase, module_id: ModuleId, container: ItemContainerId, file_id: HirFileId,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index 7fedfa0..5b75c07 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -166,15 +166,15 @@ fn no() {} [ "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "EnumVariants::of_", @@ -183,7 +183,7 @@ fn no() {} expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "EnumVariants::of_", @@ -224,21 +224,21 @@ pub struct S {} [ "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "decl_macro_expander_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", ] @@ -246,12 +246,12 @@ pub struct S {} expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "macro_arg_shim", "parse_macro_expansion_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", ] "#]], @@ -282,26 +282,26 @@ fn f() { foo } [ "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "crate_local_def_map", "proc_macros_for_crate_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "expand_proc_macro_shim", "macro_arg_shim", @@ -311,13 +311,13 @@ fn f() { foo } expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "macro_arg_shim", "expand_proc_macro_shim", "parse_macro_expansion_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", ] "#]], @@ -406,38 +406,38 @@ pub struct S {} [ "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "crate_local_def_map", "proc_macros_for_crate_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "decl_macro_expander_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", "decl_macro_expander_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "expand_proc_macro_shim", "macro_arg_shim", @@ -447,7 +447,7 @@ pub struct S {} expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "macro_arg_shim", @@ -523,29 +523,29 @@ fn quux() { 1$0 } [ "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "decl_macro_expander_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "macro_def_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_macro_expansion_shim", "macro_arg_shim", ] @@ -572,7 +572,7 @@ fn quux() { 92 } expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "macro_arg_shim", @@ -610,7 +610,7 @@ impl Tr for () {} expect![[r#" [ "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", ] @@ -630,7 +630,7 @@ impl Tr for () {} expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", ]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index d32e53f..bb292ac 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -13,14 +13,13 @@ use smallvec::{SmallVec, smallvec}; use span::SyntaxContext; use syntax::ast::HasName; -use triomphe::Arc; use crate::{ - AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, - ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId, - ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, - ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UseId, VariantId, + AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, + ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, + GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, + MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UseId, VariantId, builtin_type::BuiltinType, db::DefDatabase, expr_store::{ @@ -36,6 +35,7 @@ lang_item::LangItemTarget, nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map}, per_ns::PerNs, + signatures::ImplSignature, src::HasSource, type_ref::LifetimeRef, visibility::{RawVisibility, Visibility}, @@ -65,13 +65,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } #[derive(Clone)] -struct ExprScope { - owner: DefWithBodyId, - expr_scopes: Arc<ExprScopes>, +struct ExprScope<'db> { + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, } -impl fmt::Debug for ExprScope { +impl fmt::Debug for ExprScope<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ExprScope") .field("owner", &self.owner) @@ -86,9 +86,9 @@ enum Scope<'db> { BlockScope(ModuleItemMap<'db>), /// Brings the generic parameters of an item into scope as well as the `Self` type alias / /// generic for ADTs and impls. - GenericParams { def: GenericDefId, params: Arc<GenericParams> }, + GenericParams { def: GenericDefId, params: &'db GenericParams }, /// Local bindings - ExprScope(ExprScope), + ExprScope(ExprScope<'db>), /// Macro definition inside bodies that affects all paths after it in the same block. MacroDefScope(MacroDefId), } @@ -653,7 +653,7 @@ pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> { match scope { Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()), &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => { - let impl_data = db.impl_signature(impl_); + let impl_data = ImplSignature::of(db, impl_); if let Some(target_trait) = impl_data.target_trait && let Some(TypeNs::TraitId(trait_)) = self .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path]) @@ -724,19 +724,19 @@ pub fn generic_def(&self) -> Option<GenericDefId> { pub fn generic_params(&self) -> Option<&GenericParams> { self.scopes().find_map(|scope| match scope { - Scope::GenericParams { params, .. } => Some(&**params), + &Scope::GenericParams { params, .. } => Some(params), _ => None, }) } - pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> { + pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, GenericDefId)> { self.scopes().filter_map(|scope| match scope { - Scope::GenericParams { params, def } => Some((&**params, def)), + &Scope::GenericParams { params, def } => Some((params, def)), _ => None, }) } - pub fn body_owner(&self) -> Option<DefWithBodyId> { + pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwnerId> { self.scopes().find_map(|scope| match scope { Scope::ExprScope(it) => Some(it.owner), _ => None, @@ -854,25 +854,30 @@ pub fn rename_will_conflict_with_renamed( pub fn update_to_inner_scope( &mut self, db: &'db dyn DefDatabase, - owner: DefWithBodyId, + owner: impl Into<ExpressionStoreOwnerId>, + expr_id: ExprId, + ) -> UpdateGuard { + self.update_to_inner_scope_(db, owner.into(), expr_id) + } + + fn update_to_inner_scope_( + &mut self, + db: &'db dyn DefDatabase, + owner: ExpressionStoreOwnerId, expr_id: ExprId, ) -> UpdateGuard { #[inline(always)] fn append_expr_scope<'db>( db: &'db dyn DefDatabase, resolver: &mut Resolver<'db>, - owner: DefWithBodyId, - expr_scopes: &Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) { if let Some(macro_id) = expr_scopes.macro_def(scope_id) { resolver.scopes.push(Scope::MacroDefScope(**macro_id)); } - resolver.scopes.push(Scope::ExprScope(ExprScope { - owner, - expr_scopes: expr_scopes.clone(), - scope_id, - })); + resolver.scopes.push(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); let local_def_map = block.lookup(db).module.only_local_def_map(db); @@ -890,21 +895,20 @@ fn append_expr_scope<'db>( let start = self.scopes.len(); let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_))); match innermost_scope { - Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => { - let expr_scopes = expr_scopes.clone(); + Some(&Scope::ExprScope(ExprScope { scope_id, expr_scopes, owner })) => { let scope_chain = expr_scopes .scope_chain(expr_scopes.scope_for(expr_id)) .take_while(|&it| it != scope_id); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } _ => { - let expr_scopes = db.expr_scopes(owner); + let expr_scopes = ExprScopes::of(db, owner); let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id)); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } } @@ -1016,7 +1020,7 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) { }) }); } - &Scope::GenericParams { ref params, def: parent } => { + &Scope::GenericParams { params, def: parent } => { if let GenericDefId::ImplId(impl_) = parent { acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_)); } else if let GenericDefId::AdtId(adt) = parent { @@ -1026,7 +1030,7 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) { for (local_id, param) in params.iter_type_or_consts() { if let Some(name) = ¶m.name() { let id = TypeOrConstParamId { parent, local_id }; - let data = &db.generic_params(parent)[local_id]; + let data = &GenericParams::of(db, parent)[local_id]; acc.add( name, ScopeDef::GenericParam(match data { @@ -1060,20 +1064,21 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) { pub fn resolver_for_scope( db: &dyn DefDatabase, - owner: DefWithBodyId, + owner: impl Into<ExpressionStoreOwnerId> + HasResolver, scope_id: Option<ScopeId>, ) -> Resolver<'_> { - let r = owner.resolver(db); - let scopes = db.expr_scopes(owner); - resolver_for_scope_(db, scopes, scope_id, r, owner) + let store_owner = owner.into(); + let r = store_owner.resolver(db); + let scopes = ExprScopes::of(db, store_owner); + resolver_for_scope_(db, scopes, scope_id, r, store_owner) } fn resolver_for_scope_<'db>( db: &'db dyn DefDatabase, - scopes: Arc<ExprScopes>, + scopes: &'db ExprScopes, scope_id: Option<ScopeId>, mut r: Resolver<'db>, - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, ) -> Resolver<'db> { let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); r.scopes.reserve(scope_chain.len()); @@ -1093,7 +1098,7 @@ fn resolver_for_scope_<'db>( r = r.push_scope(Scope::MacroDefScope(**macro_id)); } - r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); + r = r.push_expr_scope(owner, scopes, scope); } r } @@ -1109,7 +1114,7 @@ fn push_generic_params_scope( db: &'db dyn DefDatabase, def: GenericDefId, ) -> Resolver<'db> { - let params = db.generic_params(def); + let params = GenericParams::of(db, def); self.push_scope(Scope::GenericParams { def, params }) } @@ -1124,8 +1129,8 @@ fn push_block_scope( fn push_expr_scope( self, - owner: DefWithBodyId, - expr_scopes: Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) -> Resolver<'db> { self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) @@ -1409,6 +1414,16 @@ fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { } } +impl HasResolver for ExpressionStoreOwnerId { + fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { + match self { + ExpressionStoreOwnerId::Signature(def) => def.resolver(db), + ExpressionStoreOwnerId::Body(def) => def.resolver(db), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.resolver(db), + } + } +} + impl HasResolver for EnumVariantId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { self.lookup(db).parent.resolver(db)
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs index 37c8f76..6d70427 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
@@ -24,7 +24,7 @@ attrs::AttrFlags, db::DefDatabase, expr_store::{ - ExpressionStore, ExpressionStoreSourceMap, + Body, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreSourceMap, lower::{ ExprCollector, lower_function, lower_generic_params, lower_trait, lower_type_alias, }, @@ -32,7 +32,7 @@ hir::{ExprId, PatId, generics::GenericParams}, item_tree::{FieldsShape, RawVisibility, visibility_from_ast}, src::HasSource, - type_ref::{TraitRef, TypeBound, TypeRefId}, + type_ref::{ConstRef, TraitRef, TypeBound, TypeRefId}, }; #[inline] @@ -43,8 +43,8 @@ fn as_name_opt(name: Option<ast::Name>) -> Name { #[derive(Debug, PartialEq, Eq)] pub struct StructSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub flags: StructFlags, pub shape: FieldsShape, } @@ -71,8 +71,18 @@ pub struct StructFlags: u8 { } } +#[salsa::tracked] impl StructSignature { - pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: StructId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: StructId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let InFile { file_id, value: source } = loc.source(db); let attrs = AttrFlags::query(db, id.into()); @@ -115,10 +125,12 @@ pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionSt shape, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } +} +impl StructSignature { #[inline] pub fn repr(&self, db: &dyn DefDatabase, id: StructId) -> Option<ReprOptions> { if self.flags.contains(StructFlags::HAS_REPR) { @@ -141,13 +153,23 @@ fn adt_shape(adt_kind: ast::StructKind) -> FieldsShape { #[derive(Debug, PartialEq, Eq)] pub struct UnionSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub flags: StructFlags, } +#[salsa::tracked] impl UnionSignature { - pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: UnionId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: UnionId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let attrs = AttrFlags::query(db, id.into()); let mut flags = StructFlags::empty(); @@ -177,7 +199,7 @@ pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionSto flags, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } } @@ -195,13 +217,23 @@ pub struct EnumFlags: u8 { #[derive(Debug, PartialEq, Eq)] pub struct EnumSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub flags: EnumFlags, } +#[salsa::tracked] impl EnumSignature { - pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: EnumId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: EnumId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let attrs = AttrFlags::query(db, id.into()); let mut flags = EnumFlags::empty(); @@ -229,10 +261,12 @@ pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStor flags, name: as_name_opt(source.name()), }), - Arc::new(source_map), + source_map, ) } +} +impl EnumSignature { pub fn variant_body_type(db: &dyn DefDatabase, id: EnumId) -> IntegerType { match AttrFlags::repr(db, id.into()) { Some(ReprOptions { int: Some(builtin), .. }) => builtin, @@ -256,14 +290,24 @@ pub struct ConstFlags: u8 { #[derive(Debug, PartialEq, Eq)] pub struct ConstSignature { pub name: Option<Name>, - // generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + // generic_params: GenericParams, + pub store: ExpressionStore, pub type_ref: TypeRefId, pub flags: ConstFlags, } +#[salsa::tracked] impl ConstSignature { - pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: ConstId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: ConstId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -282,15 +326,17 @@ pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionSto ( Arc::new(ConstSignature { - store: Arc::new(store), + store, type_ref, flags, name: source.value.name().map(|it| it.as_name()), }), - Arc::new(source_map), + source_map, ) } +} +impl ConstSignature { pub fn has_body(&self) -> bool { self.flags.contains(ConstFlags::HAS_BODY) } @@ -312,13 +358,24 @@ pub struct StaticFlags: u8 { pub struct StaticSignature { pub name: Name, - // generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + // generic_params: GenericParams, + pub store: ExpressionStore, pub type_ref: TypeRefId, pub flags: StaticFlags, } + +#[salsa::tracked] impl StaticSignature { - pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: StaticId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: StaticId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -351,12 +408,12 @@ pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionSt ( Arc::new(StaticSignature { - store: Arc::new(store), + store, type_ref, flags, name: as_name_opt(source.value.name()), }), - Arc::new(source_map), + source_map, ) } } @@ -372,15 +429,25 @@ pub struct ImplFlags: u8 { #[derive(Debug, PartialEq, Eq)] pub struct ImplSignature { - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub self_ty: TypeRefId, pub target_trait: Option<TraitRef>, pub flags: ImplFlags, } +#[salsa::tracked] impl ImplSignature { - pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: ImplId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: ImplId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = ImplFlags::empty(); @@ -399,17 +466,13 @@ pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStor crate::expr_store::lower::lower_impl(db, loc.container, src, id); ( - Arc::new(ImplSignature { - store: Arc::new(store), - generic_params, - self_ty, - target_trait, - flags, - }), - Arc::new(source_map), + Arc::new(ImplSignature { store, generic_params, self_ty, target_trait, flags }), + source_map, ) } +} +impl ImplSignature { #[inline] pub fn is_negative(&self) -> bool { self.flags.contains(ImplFlags::NEGATIVE) @@ -439,13 +502,23 @@ pub struct TraitFlags: u16 { #[derive(Debug, PartialEq, Eq)] pub struct TraitSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub flags: TraitFlags, } +#[salsa::tracked] impl TraitSignature { - pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: TraitId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( + db: &dyn DefDatabase, + id: TraitId, + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = TraitFlags::empty(); @@ -483,10 +556,7 @@ pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionSto let name = as_name_opt(source.value.name()); let (store, source_map, generic_params) = lower_trait(db, loc.container, source, id); - ( - Arc::new(TraitSignature { store: Arc::new(store), generic_params, flags, name }), - Arc::new(source_map), - ) + (Arc::new(TraitSignature { store, generic_params, flags, name }), source_map) } } @@ -516,19 +586,26 @@ pub struct FnFlags: u16 { #[derive(Debug, PartialEq, Eq)] pub struct FunctionSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub params: Box<[TypeRefId]>, pub ret_type: Option<TypeRefId>, pub abi: Option<Symbol>, pub flags: FnFlags, } +#[salsa::tracked] impl FunctionSignature { - pub fn query( + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: FunctionId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( db: &dyn DefDatabase, id: FunctionId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let module = loc.container.module(db); @@ -589,17 +666,19 @@ pub fn query( ( Arc::new(FunctionSignature { generic_params, - store: Arc::new(store), + store, params, ret_type, abi, flags, name, }), - Arc::new(source_map), + source_map, ) } +} +impl FunctionSignature { pub fn has_body(&self) -> bool { self.flags.contains(FnFlags::HAS_BODY) } @@ -656,7 +735,7 @@ pub fn legacy_const_generics_indices<'db>( } pub fn is_intrinsic(db: &dyn DefDatabase, id: FunctionId) -> bool { - let data = db.function_signature(id); + let data = FunctionSignature::of(db, id); data.flags.contains(FnFlags::RUSTC_INTRINSIC) // Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used || match &data.abi { @@ -683,18 +762,25 @@ pub struct TypeAliasFlags: u8 { #[derive(Debug, PartialEq, Eq)] pub struct TypeAliasSignature { pub name: Name, - pub generic_params: Arc<GenericParams>, - pub store: Arc<ExpressionStore>, + pub generic_params: GenericParams, + pub store: ExpressionStore, pub bounds: Box<[TypeBound]>, pub ty: Option<TypeRefId>, pub flags: TypeAliasFlags, } +#[salsa::tracked] impl TypeAliasSignature { - pub fn query( + #[salsa::tracked(returns(deref))] + pub fn of(db: &dyn DefDatabase, id: TypeAliasId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() + } + + #[salsa::tracked(returns(ref))] + pub fn with_source_map( db: &dyn DefDatabase, id: TypeAliasId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let loc = id.lookup(db); let mut flags = TypeAliasFlags::empty(); @@ -714,28 +800,21 @@ pub fn query( lower_type_alias(db, loc.container.module(db), source, id); ( - Arc::new(TypeAliasSignature { - store: Arc::new(store), - generic_params, - flags, - bounds, - name, - ty, - }), - Arc::new(source_map), + Arc::new(TypeAliasSignature { store, generic_params, flags, bounds, name, ty }), + source_map, ) } } #[derive(Debug, PartialEq, Eq)] pub struct FunctionBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub parameters: Box<[PatId]>, } #[derive(Debug, PartialEq, Eq)] pub struct SimpleBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, } pub type StaticBody = SimpleBody; pub type ConstBody = SimpleBody; @@ -743,7 +822,7 @@ pub struct SimpleBody { #[derive(Debug, PartialEq, Eq)] pub struct VariantFieldsBody { - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub fields: Box<[Option<ExprId>]>, } @@ -754,7 +833,7 @@ pub struct FieldData { pub type_ref: TypeRefId, pub visibility: RawVisibility, pub is_unsafe: bool, - pub default_value: Option<ExprId>, + pub default_value: Option<ConstRef>, } pub type LocalFieldId = Idx<FieldData>; @@ -762,17 +841,17 @@ pub struct FieldData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct VariantFields { fields: Arena<FieldData>, - pub store: Arc<ExpressionStore>, + pub store: ExpressionStore, pub shape: FieldsShape, } #[salsa::tracked] impl VariantFields { - #[salsa::tracked(returns(clone))] - pub(crate) fn query( + #[salsa::tracked(returns(ref))] + pub fn with_source_map( db: &dyn DefDatabase, id: VariantId, - ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) { + ) -> (Arc<Self>, ExpressionStoreSourceMap) { let (shape, result) = match id { VariantId::EnumVariantId(id) => { let loc = id.lookup(db); @@ -809,20 +888,26 @@ pub(crate) fn query( } }; match result { - Some((fields, store, source_map)) => ( - Arc::new(VariantFields { fields, store: Arc::new(store), shape }), - Arc::new(source_map), - ), + Some((fields, store, source_map)) => { + (Arc::new(VariantFields { fields, store, shape }), source_map) + } None => { - let (store, source_map) = ExpressionStore::empty_singleton(); - (Arc::new(VariantFields { fields: Arena::default(), store, shape }), source_map) + let source_map = ExpressionStoreSourceMap::default(); + ( + Arc::new(VariantFields { + fields: Arena::default(), + store: ExpressionStoreBuilder::default().finish().0, + shape, + }), + source_map, + ) } } } #[salsa::tracked(returns(deref))] - pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> { - Self::query(db, id).0 + pub fn of(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> { + Self::with_source_map(db, id).0.clone() } } @@ -873,7 +958,7 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>( override_visibility: Option<Option<ast::Visibility>>, ) -> Option<(Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap)> { let cfg_options = module.krate(db).cfg_options(db); - let mut col = ExprCollector::new(db, module, fields.file_id); + let mut col = ExprCollector::signature(db, module, fields.file_id); let override_visibility = override_visibility.map(|vis| { LazyCell::new(|| { let span_map = db.span_map(fields.file_id); @@ -907,9 +992,9 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>( // Check if field has default value (only for record fields) let default_value = ast::RecordField::cast(field.syntax().clone()) - .and_then(|rf| rf.eq_token().is_some().then_some(rf.expr())) + .and_then(|rf| rf.eq_token().is_some().then_some(rf.default_val())) .flatten() - .map(|expr| col.collect_expr_opt(Some(expr))); + .map(|expr| col.lower_const_arg(expr)); arena.alloc(FieldData { name, type_ref, visibility, is_unsafe, default_value }); idx += 1; @@ -1014,9 +1099,9 @@ pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool { } // The outer if condition is whether this variant has const ctor or not if !matches!(variant.shape, FieldsShape::Unit) { - let body = db.body(v.into()); + let body = Body::of(db, v.into()); // A variant with explicit discriminant - if !matches!(body[body.body_expr], crate::hir::Expr::Missing) { + if !matches!(body[body.root_expr()], crate::hir::Expr::Missing) { return false; } }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs index 6fe016f..e33fd95 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
@@ -7,7 +7,7 @@ use crate::{ AstIdLoc, GenericDefId, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, - UseId, VariantId, attrs::AttrFlags, db::DefDatabase, + UseId, VariantId, attrs::AttrFlags, db::DefDatabase, hir::generics::GenericParams, }; pub trait HasSource { @@ -76,7 +76,7 @@ fn child_source( &self, db: &dyn DefDatabase, ) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> { - let generic_params = db.generic_params(*self); + let generic_params = GenericParams::of(db, *self); let mut idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx); let (file_id, generic_params_list) = self.file_id_and_params_of(db); @@ -110,7 +110,7 @@ fn child_source( &self, db: &dyn DefDatabase, ) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> { - let generic_params = db.generic_params(*self); + let generic_params = GenericParams::of(db, *self); let idx_iter = generic_params.iter_lt().map(|(idx, _)| idx); let (file_id, generic_params_list) = self.file_id_and_params_of(db);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index e8377fd..0d260279 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
@@ -15,6 +15,7 @@ use crate::{ Lookup, ModuleDefId, ModuleId, db::DefDatabase, + expr_store::{Body, scope::ExprScopes}, nameres::{DefMap, ModuleSource, block_def_map, crate_def_map}, src::HasSource, }; @@ -284,8 +285,8 @@ fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option< // Find the innermost block expression that has a `DefMap`. let (def_with_body, file_id) = fn_def?; let def_with_body = def_with_body.into(); - let source_map = self.body_with_source_map(def_with_body).1; - let scopes = self.expr_scopes(def_with_body); + let source_map = &Body::with_source_map(self, def_with_body).1; + let scopes = ExprScopes::body_expr_scopes(self, def_with_body); let root_syntax_node = self.parse(file_id).syntax_node(); let scope_iter =
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index cb5eed1..81a61ec 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
@@ -6,11 +6,11 @@ use hir_expand::{InFile, Lookup}; use la_arena::ArenaMap; use syntax::ast::{self, HasVisibility}; -use triomphe::Arc; use crate::{ AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, - db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + db::DefDatabase, nameres::DefMap, resolver::HasResolver, signatures::VariantFields, + src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -277,23 +277,26 @@ pub(crate) fn min( } } -/// Resolve visibility of all specific fields of a struct or union variant. -pub(crate) fn field_visibilities_query( - db: &dyn DefDatabase, - variant_id: VariantId, -) -> Arc<ArenaMap<LocalFieldId, Visibility>> { - let variant_fields = variant_id.fields(db); - let fields = variant_fields.fields(); - if fields.is_empty() { - return Arc::default(); +#[salsa::tracked] +impl VariantFields { + /// Resolve visibility of all specific fields of a struct or union variant. + #[salsa::tracked(returns(ref))] + pub fn field_visibilities( + db: &dyn DefDatabase, + variant_id: VariantId, + ) -> ArenaMap<LocalFieldId, Visibility> { + let variant_fields = variant_id.fields(db); + let fields = variant_fields.fields(); + if fields.is_empty() { + return ArenaMap::default(); + } + let resolver = variant_id.module(db).resolver(db); + let mut res = ArenaMap::with_capacity(fields.len()); + for (field_id, field_data) in fields.iter() { + res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility)); + } + res } - let resolver = variant_id.module(db).resolver(db); - let mut res = ArenaMap::default(); - for (field_id, field_data) in fields.iter() { - res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility)); - } - res.shrink_to_fit(); - Arc::new(res) } pub fn visibility_from_ast(
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 363465f..020731c 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
@@ -58,8 +58,8 @@ pub trait ExpandDatabase: RootQueryDb { fn proc_macros_for_crate(&self, krate: Crate) -> Option<Arc<CrateProcMacros>>; #[salsa::invoke(ast_id_map)] - #[salsa::lru(1024)] - fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; + #[salsa::transparent] + fn ast_id_map(&self, file_id: HirFileId) -> &AstIdMap; #[salsa::transparent] fn resolve_span(&self, span: Span) -> FileRange; @@ -334,8 +334,9 @@ pub fn expand_speculative( Some((node.syntax_node(), token)) } -fn ast_id_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> triomphe::Arc<AstIdMap> { - triomphe::Arc::new(AstIdMap::from_source(&db.parse_or_expand(file_id))) +#[salsa::tracked(lru = 1024, returns(ref))] +fn ast_id_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> AstIdMap { + AstIdMap::from_source(&db.parse_or_expand(file_id)) } /// Main public API -- parses a hir file, not caring whether it's a real
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs index 5a93c2b..92629b7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs
@@ -80,7 +80,7 @@ pub(crate) fn generics_of<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplI pub fn generic_params_count(db: &dyn HirDatabase, id: BuiltinDeriveImplId) -> usize { let loc = id.loc(db); - let adt_params = GenericParams::new(db, loc.adt.into()); + let adt_params = GenericParams::of(db, loc.adt.into()); let extra_params_count = match loc.trait_ { BuiltinDeriveImplTrait::Copy | BuiltinDeriveImplTrait::Clone @@ -128,12 +128,12 @@ pub fn impl_trait<'db>( )) } BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { - let generic_params = GenericParams::new(db, loc.adt.into()); + let generic_params = GenericParams::of(db, loc.adt.into()); let interner = DbInterner::new_no_crate(db); let args = GenericArgs::identity_for_item(interner, loc.adt.into()); let self_ty = Ty::new_adt(interner, loc.adt, args); let Some((pointee_param_idx, _, new_param_ty)) = - coerce_pointee_params(interner, loc, &generic_params, trait_id) + coerce_pointee_params(interner, loc, generic_params, trait_id) else { // Malformed derive. return EarlyBinder::bind(TraitRef::new( @@ -152,7 +152,7 @@ pub fn impl_trait<'db>( #[salsa::tracked(returns(ref))] pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPredicates { let loc = impl_.loc(db); - let generic_params = GenericParams::new(db, loc.adt.into()); + let generic_params = GenericParams::of(db, loc.adt.into()); let interner = DbInterner::new_with(db, loc.module(db).krate(db)); let adt_predicates = GenericPredicates::query(db, loc.adt.into()); let trait_id = loc @@ -168,7 +168,7 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> | BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::Eq | BuiltinDeriveImplTrait::PartialEq => { - simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id) + simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id) } BuiltinDeriveImplTrait::Default => { if matches!(loc.adt, AdtId::EnumId(_)) { @@ -178,12 +178,12 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> .store(), )) } else { - simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id) + simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id) } } BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { let Some((pointee_param_idx, pointee_param_id, new_param_ty)) = - coerce_pointee_params(interner, loc, &generic_params, trait_id) + coerce_pointee_params(interner, loc, generic_params, trait_id) else { // Malformed derive. return GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 07e9f70..928396c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -5,10 +5,11 @@ use base_db::Crate; use hir_def::{ - ConstId, EnumVariantId, GeneralConstId, HasModule, StaticId, + ConstId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericDefId, HasModule, + StaticId, attrs::AttrFlags, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, - expr_store::Body, + expr_store::{Body, ExpressionStore}, hir::{Expr, ExprId, Literal}, }; use hir_expand::Lookup; @@ -235,6 +236,7 @@ pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u let ec = db.const_eval_static(id).ok()?; try_const_usize(db, ec) } + GeneralConstId::AnonConstId(_) => None, }, ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().memory, false))), ConstKind::Error(_) => None, @@ -258,6 +260,7 @@ pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option< let ec = db.const_eval_static(id).ok()?; try_const_isize(db, &ec) } + GeneralConstId::AnonConstId(_) => None, }, ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().memory, true))), ConstKind::Error(_) => None, @@ -271,9 +274,9 @@ pub(crate) fn const_eval_discriminant_variant( ) -> Result<i128, ConstEvalError> { let interner = DbInterner::new_no_crate(db); let def = variant_id.into(); - let body = db.body(def); + let body = Body::of(db, def); let loc = variant_id.lookup(db); - if matches!(body[body.body_expr], Expr::Missing) { + if matches!(body[body.root_expr()], Expr::Missing) { let prev_idx = loc.index.checked_sub(1); let value = match prev_idx { Some(prev_idx) => { @@ -292,7 +295,7 @@ pub(crate) fn const_eval_discriminant_variant( let mir_body = db.monomorphized_mir_body( def, GenericArgs::empty(interner).store(), - ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) } .store(), )?; let c = interpret_mir(db, mir_body, false, None)?.0?; @@ -309,23 +312,23 @@ pub(crate) fn const_eval_discriminant_variant( // and make this function private. See the fixme comment on `InferenceContext::resolve_all`. pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'db>) -> Const<'db> { let infer = ctx.fixme_resolve_all_clone(); - fn has_closure(body: &Body, expr: ExprId) -> bool { - if matches!(body[expr], Expr::Closure { .. }) { + fn has_closure(store: &ExpressionStore, expr: ExprId) -> bool { + if matches!(store[expr], Expr::Closure { .. }) { return true; } let mut r = false; - body.walk_child_exprs(expr, |idx| r |= has_closure(body, idx)); + store.walk_child_exprs(expr, |idx| r |= has_closure(store, idx)); r } - if has_closure(ctx.body, expr) { + if has_closure(ctx.store, expr) { // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic. return Const::error(ctx.interner()); } - if let Expr::Path(p) = &ctx.body[expr] { + if let Expr::Path(p) = &ctx.store[expr] { let mut ctx = TyLoweringContext::new( ctx.db, &ctx.resolver, - ctx.body, + ctx.store, ctx.generic_def, LifetimeElisionKind::Infer, ); @@ -333,7 +336,9 @@ fn has_closure(body: &Body, expr: ExprId) -> bool { return c; } } - if let Ok(mir_body) = lower_body_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr) + if let Some(body_owner) = ctx.owner.as_def_with_body() + && let Ok(mir_body) = + lower_body_to_mir(ctx.db, body_owner, Body::of(ctx.db, body_owner), &infer, expr) && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None) { return result; @@ -370,8 +375,12 @@ pub(crate) fn const_eval_query<'db>( let body = db.monomorphized_mir_body( def.into(), subst, - ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) } - .store(), + ParamEnvAndCrate { + param_env: db + .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))), + krate: def.krate(db), + } + .store(), )?; let c = interpret_mir(db, body, false, trait_env.as_ref().map(|env| env.as_ref()))?.0?; Ok(c.store()) @@ -407,7 +416,8 @@ pub(crate) fn const_eval_static_query<'db>( def.into(), GenericArgs::empty(interner).store(), ParamEnvAndCrate { - param_env: db.trait_environment_for_body(def.into()), + param_env: db + .trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))), krate: def.krate(db), } .store(),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 5f6bcb4..31cf864 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
@@ -1,5 +1,5 @@ use base_db::RootQueryDb; -use hir_def::db::DefDatabase; +use hir_def::signatures::ConstSignature; use hir_expand::EditionedFileId; use rustc_apfloat::{ Float, @@ -131,7 +131,11 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEv .declarations() .find_map(|x| match x { hir_def::ModuleDefId::ConstId(x) => { - if db.const_signature(x).name.as_ref()?.display(db, file_id.edition(db)).to_string() + if ConstSignature::of(db, x) + .name + .as_ref()? + .display(db, file_id.edition(db)) + .to_string() == "GOAL" { Some(x)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 70474fc..a0fb753 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
@@ -5,9 +5,9 @@ use either::Either; use hir_def::{ AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, - FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, - TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod, db::DefDatabase, hir::ExprId, - layout::TargetDataLayout, + ExpressionStoreOwnerId, FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, + StaticId, TraitId, TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod, + db::DefDatabase, hir::ExprId, layout::TargetDataLayout, }; use la_arena::ArenaMap; use salsa::plumbing::AsId; @@ -178,13 +178,9 @@ fn callable_item_signature<'db>( def: CallableDefId, ) -> EarlyBinder<'db, PolyFnSig<'db>>; - #[salsa::invoke(crate::lower::trait_environment_for_body_query)] - #[salsa::transparent] - fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>; - #[salsa::invoke(crate::lower::trait_environment)] #[salsa::transparent] - fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>; + fn trait_environment<'db>(&'db self, def: ExpressionStoreOwnerId) -> ParamEnv<'db>; #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)] #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)] @@ -240,7 +236,7 @@ pub struct InternedOpaqueTyId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct InternedClosure(pub DefWithBodyId, pub ExprId); +pub struct InternedClosure(pub ExpressionStoreOwnerId, pub ExprId); #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] #[derive(PartialOrd, Ord)] @@ -249,7 +245,7 @@ pub struct InternedClosureId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId); +pub struct InternedCoroutine(pub ExpressionStoreOwnerId, pub ExprId); #[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] #[derive(PartialOrd, Ord)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 0931b85..89d8c0e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -17,8 +17,17 @@ use hir_def::{ AdtId, ConstId, EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, - ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags, - db::DefDatabase, hir::Pat, item_tree::FieldsShape, signatures::StaticFlags, src::HasSource, + ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + attrs::AttrFlags, + db::DefDatabase, + expr_store::Body, + hir::Pat, + item_tree::FieldsShape, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, StaticFlags, StaticSignature, + StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, + }, + src::HasSource, }; use hir_expand::{ HirFileId, @@ -178,7 +187,7 @@ fn validate_module(&mut self, module_id: ModuleId) { fn validate_trait(&mut self, trait_id: TraitId) { // Check the trait name. - let data = self.db.trait_signature(trait_id); + let data = TraitSignature::of(self.db, trait_id); self.create_incorrect_case_diagnostic_for_item_name( trait_id, &data.name, @@ -197,7 +206,7 @@ fn validate_func(&mut self, func: FunctionId) { // Check the function name. // Skipped if function is an associated item of a trait implementation. if !self.is_trait_impl_container(container) { - let data = self.db.function_signature(func); + let data = FunctionSignature::of(self.db, func); // Don't run the lint on extern "[not Rust]" fn items with the // #[no_mangle] attribute. @@ -223,7 +232,7 @@ fn validate_func(&mut self, func: FunctionId) { /// Check incorrect names for patterns inside the function body. /// This includes function parameters except for trait implementation associated functions. fn validate_func_body(&mut self, func: FunctionId) { - let body = self.db.body(func.into()); + let body = Body::of(self.db, func.into()); let edition = self.edition(func); let mut pats_replacements = body .pats() @@ -250,7 +259,7 @@ fn validate_func_body(&mut self, func: FunctionId) { return; } - let source_map = self.db.body_with_source_map(func.into()).1; + let source_map = &Body::with_source_map(self.db, func.into()).1; for (id, replacement) in pats_replacements { let Ok(source_ptr) = source_map.pat_syntax(id) else { continue; @@ -292,7 +301,7 @@ fn edition(&self, id: impl HasModule) -> span::Edition { fn validate_struct(&mut self, struct_id: StructId) { // Check the structure name. - let data = self.db.struct_signature(struct_id); + let data = StructSignature::of(self.db, struct_id); // rustc implementation excuses repr(C) since C structs predominantly don't // use camel case. @@ -385,7 +394,7 @@ fn validate_struct_fields(&mut self, struct_id: StructId) { fn validate_union(&mut self, union_id: UnionId) { // Check the union name. - let data = self.db.union_signature(union_id); + let data = UnionSignature::of(self.db, union_id); // rustc implementation excuses repr(C) since C unions predominantly don't // use camel case. @@ -473,7 +482,7 @@ fn validate_union_fields(&mut self, union_id: UnionId) { fn validate_enum(&mut self, enum_id: EnumId) { // Check the enum name. - let data = self.db.enum_signature(enum_id); + let data = EnumSignature::of(self.db, enum_id); // rustc implementation excuses repr(C) since C structs predominantly don't // use camel case. @@ -644,7 +653,7 @@ fn validate_const(&mut self, const_id: ConstId) { return; } - let data = self.db.const_signature(const_id); + let data = ConstSignature::of(self.db, const_id); let Some(name) = &data.name else { return; }; @@ -657,7 +666,7 @@ fn validate_const(&mut self, const_id: ConstId) { } fn validate_static(&mut self, static_id: StaticId) { - let data = self.db.static_signature(static_id); + let data = StaticSignature::of(self.db, static_id); if data.flags.contains(StaticFlags::EXTERN) { cov_mark::hit!(extern_static_incorrect_case_ignored); return; @@ -683,7 +692,7 @@ fn validate_type_alias(&mut self, type_alias_id: TypeAliasId) { } // Check the type alias name. - let data = self.db.type_alias_signature(type_alias_id); + let data = TypeAliasSignature::of(self.db, type_alias_id); self.create_incorrect_case_diagnostic_for_item_name( type_alias_id, &data.name,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 4e1bb6f..33d9dd5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -21,7 +21,7 @@ ast::{self, UnaryOp}, }; use tracing::debug; -use triomphe::Arc; + use typed_arena::Arena; use crate::{ @@ -76,9 +76,9 @@ pub fn collect( validate_lints: bool, ) -> Vec<BodyValidationDiagnostic> { let _p = tracing::info_span!("BodyValidationDiagnostic::collect").entered(); - let infer = InferenceResult::for_body(db, owner); - let body = db.body(owner); - let env = db.trait_environment_for_body(owner); + let infer = InferenceResult::of(db, owner); + let body = Body::of(db, owner); + let env = db.trait_environment(owner.into()); let interner = DbInterner::new_with(db, owner.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::typeck_for_body(interner, owner.into())); @@ -98,7 +98,7 @@ pub fn collect( struct ExprValidator<'db> { owner: DefWithBodyId, - body: Arc<Body>, + body: &'db Body, infer: &'db InferenceResult, env: ParamEnv<'db>, diagnostics: Vec<BodyValidationDiagnostic>, @@ -116,10 +116,10 @@ fn validate_body(&mut self) { let db = self.db(); let mut filter_map_next_checker = None; // we'll pass &mut self while iterating over body.exprs, so they need to be disjoint - let body = Arc::clone(&self.body); + let body = self.body; if matches!(self.owner, DefWithBodyId::FunctionId(_)) { - self.check_for_trailing_return(body.body_expr, &body); + self.check_for_trailing_return(body.root_expr(), body); } for (id, expr) in body.exprs() { @@ -141,7 +141,7 @@ fn validate_body(&mut self) { self.validate_call(id, expr, &mut filter_map_next_checker); } Expr::Closure { body: body_expr, .. } => { - self.check_for_trailing_return(*body_expr, &body); + self.check_for_trailing_return(*body_expr, body); } Expr::If { .. } => { self.check_for_unnecessary_else(id, expr); @@ -240,7 +240,7 @@ fn validate_match(&mut self, match_expr: ExprId, scrutinee_expr: ExprId, arms: & .as_reference() .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty) .unwrap_or(false)) - && types_of_subpatterns_do_match(arm.pat, &self.body, self.infer) + && types_of_subpatterns_do_match(arm.pat, self.body, self.infer) { // If we had a NotUsefulMatchArm diagnostic, we could // check the usefulness of each pattern as we added it @@ -388,7 +388,7 @@ fn lower_pattern<'a>( pat: PatId, have_errors: &mut bool, ) -> DeconstructedPat<'a, 'db> { - let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, &self.body); + let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, self.body); let pattern = patcx.lower_pattern(pat); let pattern = cx.lower_pat(&pattern); if !patcx.errors.is_empty() { @@ -451,7 +451,7 @@ fn check_for_unnecessary_else(&mut self, id: ExprId, expr: &Expr) { && last_then_expr_ty.is_never() { // Only look at sources if the then branch diverges and we have an else branch. - let source_map = self.db().body_with_source_map(self.owner).1; + let source_map = &Body::with_source_map(self.db(), self.owner).1; let Ok(source_ptr) = source_map.expr_syntax(id) else { return; };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs index 8e6101e..f559c26 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -14,6 +14,7 @@ expr_store::{Body, path::Path}, hir::PatId, item_tree::FieldsShape, + signatures::{StructSignature, UnionSignature}, }; use hir_expand::name::Name; use rustc_type_ir::inherent::IntoKind; @@ -340,12 +341,12 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError> VariantId::StructId(s) => write!( f, "{}", - f.db.struct_signature(s).name.display(f.db, f.edition()) + StructSignature::of(f.db, s).name.display(f.db, f.edition()) )?, VariantId::UnionId(u) => write!( f, "{}", - f.db.union_signature(u).name.display(f.db, f.edition()) + UnionSignature::of(f.db, u).name.display(f.db, f.edition()) )?, };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index eda7e7e..bc3d9bb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -4,6 +4,7 @@ use hir_def::{ EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId, attrs::AttrFlags, + signatures::VariantFields, }; use intern::sym; use rustc_pattern_analysis::{ @@ -363,7 +364,8 @@ fn ctor_sub_tys( let adt = adt_def.def_id().0; let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap(); - let visibilities = LazyCell::new(|| self.db.field_visibilities(variant)); + let visibilities = + LazyCell::new(|| VariantFields::field_visibilities(self.db, variant)); self.list_variant_fields(*ty, variant) .map(move |(fid, ty)| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index 21f2637..09c6481 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -5,11 +5,12 @@ use either::Either; use hir_def::{ - AdtId, CallableDefId, DefWithBodyId, FieldId, FunctionId, VariantId, - expr_store::{Body, path::Path}, + AdtId, CallableDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId, + VariantId, + expr_store::{Body, ExpressionStore, path::Path}, hir::{AsmOperand, Expr, ExprId, ExprOrPatId, InlineAsmKind, Pat, PatId, Statement, UnaryOp}, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, - signatures::StaticFlags, + signatures::{FunctionSignature, StaticFlags, StaticSignature}, type_ref::Rawness, }; use rustc_type_ir::inherent::IntoKind; @@ -34,15 +35,15 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe let _p = tracing::info_span!("missing_unsafe").entered(); let is_unsafe = match def { - DefWithBodyId::FunctionId(it) => db.function_signature(it).is_unsafe(), + DefWithBodyId::FunctionId(it) => FunctionSignature::of(db, it).is_unsafe(), DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => { false } }; let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() }; - let body = db.body(def); - let infer = InferenceResult::for_body(db, def); + let body = Body::of(db, def); + let infer = InferenceResult::of(db, def); let mut callback = |diag| match diag { UnsafeDiagnostic::UnsafeOperation { node, inside_unsafe_block, reason } => { if inside_unsafe_block == InsideUnsafeBlock::No { @@ -55,8 +56,8 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe } } }; - let mut visitor = UnsafeVisitor::new(db, infer, &body, def, &mut callback); - visitor.walk_expr(body.body_expr); + let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut callback); + visitor.walk_expr(body.root_expr()); if !is_unsafe { // Unsafety in function parameter patterns (that can only be union destructuring) @@ -109,8 +110,8 @@ pub fn unsafe_operations_for_body( callback(node); } }; - let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback); - visitor.walk_expr(body.body_expr); + let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut visitor_callback); + visitor.walk_expr(body.root_expr()); for ¶m in &body.params { visitor.walk_pat(param); } @@ -119,8 +120,8 @@ pub fn unsafe_operations_for_body( pub fn unsafe_operations( db: &dyn HirDatabase, infer: &InferenceResult, - def: DefWithBodyId, - body: &Body, + def: ExpressionStoreOwnerId, + body: &ExpressionStore, current: ExprId, callback: &mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock), ) { @@ -137,9 +138,9 @@ pub fn unsafe_operations( struct UnsafeVisitor<'db> { db: &'db dyn HirDatabase, infer: &'db InferenceResult, - body: &'db Body, + body: &'db ExpressionStore, resolver: Resolver<'db>, - def: DefWithBodyId, + def: ExpressionStoreOwnerId, inside_unsafe_block: InsideUnsafeBlock, inside_assignment: bool, inside_union_destructure: bool, @@ -156,13 +157,16 @@ impl<'db> UnsafeVisitor<'db> { fn new( db: &'db dyn HirDatabase, infer: &'db InferenceResult, - body: &'db Body, - def: DefWithBodyId, + body: &'db ExpressionStore, + def: ExpressionStoreOwnerId, unsafe_expr_cb: &'db mut dyn FnMut(UnsafeDiagnostic), ) -> Self { let resolver = def.resolver(db); let def_target_features = match def { - DefWithBodyId::FunctionId(func) => TargetFeatures::from_fn(db, func), + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) + | ExpressionStoreOwnerId::Signature(GenericDefId::FunctionId(func)) => { + TargetFeatures::from_fn(db, func) + } _ => TargetFeatures::default(), }; let krate = resolver.krate(); @@ -431,7 +435,7 @@ fn mark_unsafe_path(&mut self, node: ExprOrPatId, path: &Path) { let hygiene = self.body.expr_or_pat_path_hygiene(node); let value_or_partial = self.resolver.resolve_path_in_value_ns(self.db, path, hygiene); if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial { - let static_data = self.db.static_signature(id); + let static_data = StaticSignature::of(self.db, id); if static_data.flags.contains(StaticFlags::MUTABLE) { self.on_unsafe_op(node, UnsafetyReason::MutableStatic); } else if static_data.flags.contains(StaticFlags::EXTERN)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 4e77e8b..d680588 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -10,15 +10,18 @@ use base_db::{Crate, FxIndexMap}; use either::Either; use hir_def::{ - FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, ModuleDefId, - ModuleId, TraitId, + ExpressionStoreOwnerId, FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, + Lookup, ModuleDefId, ModuleId, TraitId, expr_store::{ExpressionStore, path::Path}, find_path::{self, PrefixKind}, - hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate}, + hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_scope::ItemInNs, item_tree::FieldsShape, lang_item::LangItems, - signatures::VariantFields, + signatures::{ + EnumSignature, FunctionSignature, StructSignature, TraitSignature, TypeAliasSignature, + UnionSignature, VariantFields, + }, type_ref::{ ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef, @@ -671,7 +674,9 @@ fn write_projection<'db>( write!( f, ">::{}", - f.db.type_alias_signature(alias.def_id.expect_type_alias()).name.display(f.db, f.edition()) + TypeAliasSignature::of(f.db, alias.def_id.expect_type_alias()) + .name + .display(f.db, f.edition()) )?; let proj_params = &alias.args.as_slice()[trait_ref.args.len()..]; hir_fmt_generics(f, proj_params, None, None) @@ -853,7 +858,7 @@ fn render_const_scalar_inner<'db>( } TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id().0 { hir_def::AdtId::StructId(s) => { - let data = f.db.struct_signature(s); + let data = StructSignature::of(f.db, s); write!(f, "&{}", data.name.display(f.db, f.edition()))?; Ok(()) } @@ -911,14 +916,16 @@ fn render_const_scalar_inner<'db>( }; match def { hir_def::AdtId::StructId(s) => { - let data = f.db.struct_signature(s); + let data = StructSignature::of(f.db, s); write!(f, "{}", data.name.display(f.db, f.edition()))?; let field_types = f.db.field_types(s.into()); render_variant_after_name( s.fields(f.db), f, field_types, - f.db.trait_environment(def.into()), + f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + def, + ))), &layout, args, b, @@ -926,7 +933,7 @@ fn render_const_scalar_inner<'db>( ) } hir_def::AdtId::UnionId(u) => { - write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition())) + write!(f, "{}", UnionSignature::of(f.db, u).name.display(f.db, f.edition())) } hir_def::AdtId::EnumId(e) => { let Ok(target_data_layout) = f.db.target_data_layout(f.krate()) else { @@ -950,7 +957,9 @@ fn render_const_scalar_inner<'db>( var_id.fields(f.db), f, field_types, - f.db.trait_environment(def.into()), + f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + def, + ))), var_layout, args, b, @@ -1152,11 +1161,13 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) write!(f, "fn ")?; f.start_location_link(def.into()); match def { - CallableDefId::FunctionId(ff) => { - write!(f, "{}", db.function_signature(ff).name.display(f.db, f.edition()))? - } + CallableDefId::FunctionId(ff) => write!( + f, + "{}", + FunctionSignature::of(db, ff).name.display(f.db, f.edition()) + )?, CallableDefId::StructId(s) => { - write!(f, "{}", db.struct_signature(s).name.display(f.db, f.edition()))? + write!(f, "{}", StructSignature::of(db, s).name.display(f.db, f.edition()))? } CallableDefId::EnumVariantId(e) => { let loc = e.lookup(db); @@ -1235,9 +1246,11 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) match f.display_kind { DisplayKind::Diagnostics | DisplayKind::Test => { let name = match def_id { - hir_def::AdtId::StructId(it) => db.struct_signature(it).name.clone(), - hir_def::AdtId::UnionId(it) => db.union_signature(it).name.clone(), - hir_def::AdtId::EnumId(it) => db.enum_signature(it).name.clone(), + hir_def::AdtId::StructId(it) => { + StructSignature::of(db, it).name.clone() + } + hir_def::AdtId::UnionId(it) => UnionSignature::of(db, it).name.clone(), + hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it).name.clone(), }; write!(f, "{}", name.display(f.db, f.edition()))?; } @@ -1272,7 +1285,7 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) write_projection(f, &alias_ty, trait_bounds_need_parens)? } TyKind::Foreign(alias) => { - let type_alias = db.type_alias_signature(alias.0); + let type_alias = TypeAliasSignature::of(db, alias.0); f.start_location_link(alias.0.into()); write!(f, "{}", type_alias.name.display(f.db, f.edition()))?; f.end_location_link(); @@ -1336,8 +1349,8 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) } let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe); let sig = sig.skip_binder(); - let InternedClosure(def, _) = db.lookup_intern_closure(id); - let infer = InferenceResult::for_body(db, def); + let InternedClosure(owner, _) = db.lookup_intern_closure(id); + let infer = InferenceResult::of(db, owner); let (_, kind) = infer.closure_info(id); match f.closure_style { ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?, @@ -1526,7 +1539,7 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>) let InternedCoroutine(owner, expr_id) = coroutine_id.0.loc(db); let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } = subst.split_coroutine_args(); - let body = db.body(owner); + let body = ExpressionStore::of(db, owner); let expr = &body[expr_id]; match expr { hir_def::hir::Expr::Closure { @@ -1867,7 +1880,7 @@ fn write_bounds_like_dyn_trait<'db>( // existential) here, which is the only thing that's // possible in actual Rust, and hence don't print it f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?; + write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?; f.end_location_link(); if is_fn_trait { if let [_self, params @ ..] = trait_ref.trait_ref.args.as_slice() @@ -1930,7 +1943,7 @@ fn write_bounds_like_dyn_trait<'db>( angle_open = true; } let assoc_ty_id = projection.def_id().expect_type_alias(); - let type_alias = f.db.type_alias_signature(assoc_ty_id); + let type_alias = TypeAliasSignature::of(f.db, assoc_ty_id); f.start_location_link(assoc_ty_id.into()); write!(f, "{}", type_alias.name.display(f.db, f.edition()))?; f.end_location_link(); @@ -2021,7 +2034,7 @@ impl<'db> HirDisplay<'db> for TraitRef<'db> { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { let trait_ = self.def_id.0; f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?; + write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?; f.end_location_link(); let substs = self.args.as_slice(); hir_fmt_generic_args(f, &substs[1..], None, Some(self.self_ty())) @@ -2128,7 +2141,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Res LifetimeRef::Placeholder => write!(f, "'_"), LifetimeRef::Error => write!(f, "'{{error}}"), &LifetimeRef::Param(lifetime_param_id) => { - let generic_params = f.db.generic_params(lifetime_param_id.parent); + let generic_params = GenericParams::of(f.db, lifetime_param_id.parent); write!( f, "{}", @@ -2144,7 +2157,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Res match &store[*self] { TypeRef::Never => write!(f, "!")?, TypeRef::TypeParam(param) => { - let generic_params = f.db.generic_params(param.parent()); + let generic_params = GenericParams::of(f.db, param.parent()); match generic_params[param.local_id()].name() { Some(name) => write!(f, "{}", name.display(f.db, f.edition()))?, None => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 9d6869e..ddc4e4c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
@@ -1,6 +1,9 @@ //! Utilities for computing drop info about types. -use hir_def::{AdtId, signatures::StructFlags}; +use hir_def::{ + AdtId, + signatures::{StructFlags, StructSignature}, +}; use rustc_hash::FxHashSet; use rustc_type_ir::inherent::{AdtDef, IntoKind}; use stdx::never; @@ -73,8 +76,7 @@ fn has_drop_glue_impl<'db>( } match adt_id { AdtId::StructId(id) => { - if db - .struct_signature(id) + if StructSignature::of(db, id) .flags .intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA) { @@ -132,9 +134,9 @@ fn has_drop_glue_impl<'db>( TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited), TyKind::Closure(closure_id, subst) => { let owner = db.lookup_intern_closure(closure_id.0).0; - let infer = InferenceResult::for_body(db, owner); + let infer = InferenceResult::of(db, owner); let (captures, _) = infer.closure_info(closure_id.0); - let env = db.trait_environment_for_body(owner); + let env = db.trait_environment(owner); captures .iter() .map(|capture| has_drop_glue_impl(infcx, capture.ty(db, subst), env, visited))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 59cfd3f..4c300af 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
@@ -4,8 +4,10 @@ use hir_def::{ AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId, - nameres::crate_def_map, signatures::TraitFlags, + TypeOrConstParamId, TypeParamId, + hir::generics::{GenericParams, LocalTypeOrConstParamId}, + nameres::crate_def_map, + signatures::{FunctionSignature, TraitFlags, TraitSignature}, }; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -298,7 +300,7 @@ fn dyn_compatibility_violation_for_assoc_item<F>( if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) { ControlFlow::Continue(()) } else { - let generic_params = db.generic_params(item.into()); + let generic_params = GenericParams::of(db, item.into()); if !generic_params.is_empty() { cb(DynCompatibilityViolation::GAT(it)) } else { @@ -318,7 +320,7 @@ fn virtual_call_violations_for_method<F>( where F: FnMut(MethodViolationCode) -> ControlFlow<()>, { - let func_data = db.function_signature(func); + let func_data = FunctionSignature::of(db, func); if !func_data.has_self_param() { cb(MethodViolationCode::StaticMethod)?; } @@ -349,7 +351,7 @@ fn virtual_call_violations_for_method<F>( cb(mvc)?; } - let generic_params = db.generic_params(func.into()); + let generic_params = GenericParams::of(db, func.into()); if generic_params.len_type_or_consts() > 0 { cb(MethodViolationCode::Generic)?; } @@ -371,7 +373,7 @@ fn virtual_call_violations_for_method<F>( trait_ref: pred_trait_ref, polarity: PredicatePolarity::Positive, }) = pred - && let trait_data = db.trait_signature(pred_trait_ref.def_id.0) + && let trait_data = TraitSignature::of(db, pred_trait_ref.def_id.0) && trait_data.flags.contains(TraitFlags::AUTO) && let rustc_type_ir::TyKind::Param(ParamTy { index: 0, .. }) = pred_trait_ref.self_ty().kind()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs index 5c9b06e..a70f98a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs
@@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use hir_def::db::DefDatabase; +use hir_def::signatures::TraitSignature; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::ToSmolStr; use test_fixture::WithFixture; @@ -40,8 +40,7 @@ fn check_dyn_compatibility<'a>( .declarations() .filter_map(|def| { if let hir_def::ModuleDefId::TraitId(trait_id) = def { - let name = db - .trait_signature(trait_id) + let name = TraitSignature::of(&db, trait_id) .name .display_no_db(file_id.edition(&db)) .to_smolstr();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs index b1500bc..822942e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
@@ -20,24 +20,23 @@ }, }; use itertools::chain; -use triomphe::Arc; -pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics { +pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics<'_> { let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def))); - let (params, store) = db.generic_params_and_store(def); + let (params, store) = GenericParams::with_store(db, def); let has_trait_self_param = params.trait_self_param().is_some(); Generics { def, params, parent_generics, has_trait_self_param, store } } #[derive(Clone, Debug)] -pub struct Generics { +pub struct Generics<'db> { def: GenericDefId, - params: Arc<GenericParams>, - store: Arc<ExpressionStore>, - parent_generics: Option<Box<Generics>>, + params: &'db GenericParams, + store: &'db ExpressionStore, + parent_generics: Option<Box<Generics<'db>>>, has_trait_self_param: bool, } -impl<T> ops::Index<T> for Generics +impl<T> ops::Index<T> for Generics<'_> where GenericParams: ops::Index<T>, { @@ -47,13 +46,13 @@ fn index(&self, index: T) -> &Self::Output { } } -impl Generics { +impl<'db> Generics<'db> { pub(crate) fn def(&self) -> GenericDefId { self.def } pub(crate) fn store(&self) -> &ExpressionStore { - &self.store + self.store } pub(crate) fn where_predicates(&self) -> impl Iterator<Item = &WherePredicate> { @@ -97,7 +96,7 @@ pub(crate) fn iter_parents_with_store( ) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &ExpressionStore)> + '_ { self.iter_parent() - .zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(&*it.store))) + .zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(it.store))) } /// Iterate over the params without parent params. @@ -185,7 +184,7 @@ fn find_type_or_const_param(&self, param: TypeOrConstParamId) -> Option<usize> { if param.parent == self.def { let idx = param.local_id.into_raw().into_u32() as usize; debug_assert!( - idx <= self.params.len_type_or_consts(), + idx < self.params.len_type_or_consts(), "idx: {} len: {}", idx, self.params.len_type_or_consts() @@ -219,7 +218,7 @@ fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<usize> { } } - pub(crate) fn parent_generics(&self) -> Option<&Generics> { + pub(crate) fn parent_generics(&self) -> Option<&Generics<'db>> { self.parent_generics.as_deref() } } @@ -243,7 +242,7 @@ pub(crate) fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Opt } fn from_toc_id<'a>( - it: &'a Generics, + it: &'a Generics<'a>, ) -> impl Fn( (LocalTypeOrConstParamId, &'a TypeOrConstParamData), ) -> (GenericParamId, GenericParamDataRef<'a>) { @@ -263,7 +262,7 @@ fn from_toc_id<'a>( } fn from_lt_id<'a>( - it: &'a Generics, + it: &'a Generics<'a>, ) -> impl Fn((LocalLifetimeParamId, &'a LifetimeParamData)) -> (GenericParamId, GenericParamDataRef<'a>) { move |(local_id, p): (_, _)| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 991acda..d14e9d6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -33,14 +33,15 @@ use base_db::Crate; use either::Either; use hir_def::{ - AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, - ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, - expr_store::{Body, ExpressionStore, HygieneId, path::Path}, + AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, + FunctionId, GenericDefId, GenericParamId, ItemContainerId, LocalFieldId, Lookup, TraitId, + TupleFieldId, TupleId, TypeAliasId, TypeOrConstParamId, VariantId, + expr_store::{Body, ExpressionStore, HygieneId, RootExprOrigin, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::LangItems, layout::Integer, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, - signatures::{ConstSignature, EnumSignature, StaticSignature}, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, type_ref::{ConstRef, LifetimeRefId, TypeRef, TypeRefId}, }; use hir_expand::{mod_path::ModPath, name::Name}; @@ -104,19 +105,18 @@ pub fn infer_query_with_inspect<'db>( ) -> InferenceResult { let _p = tracing::info_span!("infer_query").entered(); let resolver = def.resolver(db); - let body = db.body(def); - let mut ctx = InferenceContext::new(db, def, &body, resolver); + let body = Body::of(db, def); + let mut ctx = + InferenceContext::new(db, ExpressionStoreOwnerId::Body(def), &body.store, resolver); if let Some(inspect) = inspect { ctx.table.infer_ctxt.attach_obligation_inspector(inspect); } match def { - DefWithBodyId::FunctionId(f) => { - ctx.collect_fn(f); - } - DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)), - DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)), + DefWithBodyId::FunctionId(f) => ctx.collect_fn(f, body.self_param, &body.params), + DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)), + DefWithBodyId::StaticId(s) => ctx.collect_static(StaticSignature::of(db, s)), DefWithBodyId::VariantId(v) => { ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) { hir_def::layout::IntegerType::Pointer(signed) => match signed { @@ -143,10 +143,113 @@ pub fn infer_query_with_inspect<'db>( } } - ctx.infer_body(); + ctx.infer_body(body.root_expr()); - ctx.infer_mut_body(); + ctx.infer_mut_body(body.root_expr()); + infer_finalize(ctx) +} + +fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult { + InferenceResult { + has_errors: true, + ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) + } +} + +/// Infer types for all const expressions in an item's signature. +/// +/// This handles const expressions that appear in type positions within a generic +/// item's signature, such as array lengths (`[T; N]`) and const generic arguments +/// (`Foo<{ expr }>`). Each root expression is inferred independently within +/// a shared `InferenceContext`, accumulating results into a single `InferenceResult`. +fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { + let _p = tracing::info_span!("infer_signature_query").entered(); + let store = ExpressionStore::of(db, def.into()); + let mut roots = store.expr_roots_with_origins().peekable(); + let Some(_) = roots.peek() else { + return InferenceResult::new(crate::next_solver::default_types(db).types.error); + }; + + let resolver = def.resolver(db); + let owner = ExpressionStoreOwnerId::Signature(def); + + let mut ctx = InferenceContext::new(db, owner, store, resolver); + + for (root_expr, origin) in roots { + let expected = match origin { + // Array lengths are always `usize`. + RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize), + // Const parameter default: look up the param's declared type. + RootExprOrigin::ConstParam(local_id) => Expectation::has_type(db.const_param_ty_ns( + ConstParamId::from_unchecked(TypeOrConstParamId { parent: def, local_id }), + )), + // Path const generic args: determining the expected type requires + // path resolution. + // FIXME + RootExprOrigin::GenericArgsPath => Expectation::None, + RootExprOrigin::BodyRoot => Expectation::None, + }; + ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes); + } + + infer_finalize(ctx) +} + +fn infer_variant_fields_query(db: &dyn HirDatabase, def: VariantId) -> InferenceResult { + let _p = tracing::info_span!("infer_variant_fields_query").entered(); + let store = ExpressionStore::of(db, def.into()); + let mut roots = store.expr_roots_with_origins().peekable(); + let Some(_) = roots.peek() else { + return InferenceResult::new(crate::next_solver::default_types(db).types.error); + }; + + let resolver = def.resolver(db); + let owner = ExpressionStoreOwnerId::VariantFields(def); + + let mut ctx = InferenceContext::new(db, owner, store, resolver); + + for (root_expr, origin) in roots { + let expected = match origin { + // Array lengths are always `usize`. + RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize), + // unreachable + RootExprOrigin::ConstParam(_) => Expectation::None, + // Path const generic args: determining the expected type requires + // path resolution. + // FIXME + RootExprOrigin::GenericArgsPath => Expectation::None, + RootExprOrigin::BodyRoot => Expectation::None, + }; + ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes); + } + + infer_finalize(ctx) +} + +fn infer_signature_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _: GenericDefId, +) -> InferenceResult { + InferenceResult { + has_errors: true, + ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) + } +} + +fn infer_variant_fields_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _: VariantId, +) -> InferenceResult { + InferenceResult { + has_errors: true, + ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) + } +} + +fn infer_finalize(mut ctx: InferenceContext<'_, '_>) -> InferenceResult { ctx.handle_opaque_type_uses(); ctx.type_inference_fallback(); @@ -171,14 +274,6 @@ pub fn infer_query_with_inspect<'db>( ctx.resolve_all() } - -fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult { - InferenceResult { - has_errors: true, - ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) - } -} - /// Binding modes inferred for patterns. /// <https://doc.rust-lang.org/reference/patterns.html#binding-modes> #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] @@ -552,12 +647,39 @@ pub struct InferenceResult { #[salsa::tracked] impl InferenceResult { #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)] - pub fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { + fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { infer_query(db, def) } + + /// Infer types for all const expressions in an item's signature. + /// + /// Returns an `InferenceResult` containing type information for array lengths, + /// const generic arguments, and other const expressions appearing in type + /// positions within the item's signature. + #[salsa::tracked(returns(ref), cycle_result = infer_signature_cycle_result)] + fn for_signature(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { + infer_signature_query(db, def) + } + + #[salsa::tracked(returns(ref), cycle_result = infer_variant_fields_cycle_result)] + fn for_variant_fields(db: &dyn HirDatabase, def: VariantId) -> InferenceResult { + infer_variant_fields_query(db, def) + } } impl InferenceResult { + pub fn of(db: &dyn HirDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &InferenceResult { + match def.into() { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + Self::for_signature(db, generic_def_id) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Self::for_body(db, def_with_body_id), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::for_variant_fields(db, variant_id) + } + } + } + fn new(error_ty: Ty<'_>) -> Self { Self { method_resolutions: Default::default(), @@ -754,8 +876,8 @@ pub fn binding_ty<'db>(&self, id: BindingId) -> Ty<'db> { #[derive(Clone, Debug)] pub(crate) struct InferenceContext<'body, 'db> { pub(crate) db: &'db dyn HirDatabase, - pub(crate) owner: DefWithBodyId, - pub(crate) body: &'body Body, + pub(crate) owner: ExpressionStoreOwnerId, + pub(crate) store: &'body ExpressionStore, /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext /// and resolve the path via its methods. This will ensure proper error reporting. pub(crate) resolver: Resolver<'db>, @@ -855,11 +977,21 @@ fn find_continuable<'a, 'db>( impl<'body, 'db> InferenceContext<'body, 'db> { fn new( db: &'db dyn HirDatabase, - owner: DefWithBodyId, - body: &'body Body, + owner: ExpressionStoreOwnerId, + store: &'body ExpressionStore, resolver: Resolver<'db>, ) -> Self { - let trait_env = db.trait_environment_for_body(owner); + let trait_env = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + db.trait_environment(ExpressionStoreOwnerId::from(generic_def_id)) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => { + db.trait_environment(ExpressionStoreOwnerId::Body(def_with_body_id)) + } + ExpressionStoreOwnerId::VariantFields(variant_id) => { + db.trait_environment(ExpressionStoreOwnerId::VariantFields(variant_id)) + } + }; let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner)); let types = crate::next_solver::default_types(db); InferenceContext { @@ -878,13 +1010,8 @@ fn new( return_coercion: None, db, owner, - generic_def: match owner { - DefWithBodyId::FunctionId(it) => it.into(), - DefWithBodyId::StaticId(it) => it.into(), - DefWithBodyId::ConstId(it) => it.into(), - DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(), - }, - body, + generic_def: owner.generic_def(db), + store, traits_in_scope: resolver.traits_in_scope(db), resolver, diverges: Diverges::Maybe, @@ -908,7 +1035,9 @@ fn krate(&self) -> Crate { fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) { let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| { let target_features = match self.owner { - DefWithBodyId::FunctionId(id) => TargetFeatures::from_fn(self.db, id), + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => { + TargetFeatures::from_fn(self.db, id) + } _ => TargetFeatures::default(), }; let target_feature_is_safe = match &self.krate().workspace_data(self.db).target { @@ -1102,12 +1231,12 @@ fn collect_static(&mut self, data: &StaticSignature) { self.return_ty = return_ty; } - fn collect_fn(&mut self, func: FunctionId) { - let data = self.db.function_signature(func); + fn collect_fn(&mut self, func: FunctionId, self_param: Option<BindingId>, params: &[PatId]) { + let data = FunctionSignature::of(self.db, func); let mut param_tys = self.with_ty_lowering( &data.store, InferenceTyDiagnosticSource::Signature, - LifetimeElisionKind::for_fn_params(&data), + LifetimeElisionKind::for_fn_params(data), |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(), ); @@ -1130,13 +1259,13 @@ fn collect_fn(&mut self, func: FunctionId) { param_tys.push(va_list_ty); } let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.next_ty_var())); - if let Some(self_param) = self.body.self_param + if let Some(self_param) = self_param && let Some(ty) = param_tys.next() { let ty = self.process_user_written_ty(ty); self.write_binding_ty(self_param, ty); } - for (ty, pat) in param_tys.zip(&*self.body.params) { + for (ty, pat) in param_tys.zip(params) { let ty = self.process_user_written_ty(ty); self.infer_top_pat(*pat, ty, None); @@ -1170,12 +1299,12 @@ pub(crate) fn infcx(&self) -> &InferCtxt<'db> { &self.table.infer_ctxt } - fn infer_body(&mut self) { + fn infer_body(&mut self, body_expr: ExprId) { match self.return_coercion { - Some(_) => self.infer_return(self.body.body_expr), + Some(_) => self.infer_return(body_expr), None => { _ = self.infer_expr_coerce( - self.body.body_expr, + body_expr, &Expectation::has_type(self.return_ty), ExprIsRead::Yes, ) @@ -1282,7 +1411,7 @@ fn with_body_ty_lowering<R>( f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R, ) -> R { self.with_ty_lowering( - self.body, + self.store, InferenceTyDiagnosticSource::Body, LifetimeElisionKind::Infer, f, @@ -1324,7 +1453,7 @@ fn make_ty( pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> { self.make_ty( type_ref, - self.body, + self.store, InferenceTyDiagnosticSource::Body, LifetimeElisionKind::Infer, ) @@ -1332,7 +1461,7 @@ pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> { pub(crate) fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Const<'db> { let const_ = self.with_ty_lowering( - self.body, + self.store, InferenceTyDiagnosticSource::Body, LifetimeElisionKind::Infer, |ctx| ctx.lower_const(const_ref, ty), @@ -1342,7 +1471,7 @@ pub(crate) fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Co pub(crate) fn make_path_as_body_const(&mut self, path: &Path, ty: Ty<'db>) -> Const<'db> { let const_ = self.with_ty_lowering( - self.body, + self.store, InferenceTyDiagnosticSource::Body, LifetimeElisionKind::Infer, |ctx| ctx.lower_path_as_const(path, ty), @@ -1356,7 +1485,7 @@ fn err_ty(&self) -> Ty<'db> { pub(crate) fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> { let lt = self.with_ty_lowering( - self.body, + self.store, InferenceTyDiagnosticSource::Body, LifetimeElisionKind::Infer, |ctx| ctx.lower_lifetime(lifetime_ref), @@ -1571,7 +1700,7 @@ fn resolve_variant( let mut ctx = TyLoweringContext::new( self.db, &self.resolver, - &self.body.store, + self.store, &self.diagnostics, InferenceTyDiagnosticSource::Body, self.generic_def,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index fc38361..e5ee734 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -1,6 +1,10 @@ //! Type cast logic. Basically coercion + additional casts. -use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags}; +use hir_def::{ + AdtId, + hir::ExprId, + signatures::{TraitFlags, TraitSignature}, +}; use rustc_ast_ir::Mutability; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -383,8 +387,7 @@ fn check_ptr_ptr_cast( .chain( elaborate::supertrait_def_ids(ctx.interner(), src_principal) .filter(|trait_| { - ctx.db - .trait_signature(trait_.0) + TraitSignature::of(ctx.db, trait_.0) .flags .contains(TraitFlags::AUTO) }),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index 5a3eba1..ce0ccfe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs
@@ -4,14 +4,15 @@ use base_db::Crate; use hir_def::{ - DefWithBodyId, FieldId, HasModule, VariantId, - expr_store::path::Path, + ExpressionStoreOwnerId, FieldId, HasModule, VariantId, + expr_store::{Body, ExpressionStore, path::Path}, hir::{ Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId, RecordSpread, Statement, UnaryOp, }, item_tree::FieldsShape, resolver::ValueNs, + signatures::VariantFields, }; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; @@ -179,9 +180,26 @@ pub fn kind(&self) -> CaptureKind { } /// Converts the place to a name that can be inserted into source code. - pub fn place_to_name(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); - let mut result = body[self.place.local].name.as_str().to_owned(); + pub fn place_to_name(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String { + let krate = owner.krate(db); + let edition = krate.data(db).edition; + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } + }; for proj in &self.place.projections { match proj { HirPlaceProjection::Deref => {} @@ -213,11 +231,30 @@ pub fn place_to_name(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> Strin result } - pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); + pub fn display_place_source_code( + &self, + owner: ExpressionStoreOwnerId, + db: &dyn HirDatabase, + ) -> String { let krate = owner.krate(db); let edition = krate.data(db).edition; - let mut result = body[self.place.local].name.display(db, edition).to_string(); + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } + }; for proj in &self.place.projections { match proj { // In source code autoderef kicks in. @@ -258,11 +295,26 @@ pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDataba result } - pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { - let body = db.body(owner); + pub fn display_place(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String { let krate = owner.krate(db); let edition = krate.data(db).edition; - let mut result = body[self.place.local].name.display(db, edition).to_string(); + let mut result = match owner { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::of(db, generic_def_id.into())[self.place.local] + .name + .display(db, edition) + .to_string() + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id) + [self.place.local] + .name + .display(db, edition) + .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } + }; let mut field_need_paren = false; for proj in &self.place.projections { match proj { @@ -346,7 +398,7 @@ fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace> { if path.type_anchor().is_some() { return None; } - let hygiene = self.body.expr_or_pat_path_hygiene(id); + let hygiene = self.store.expr_or_pat_path_hygiene(id); self.resolver.resolve_path_in_value_ns_fully(self.db, path, hygiene).and_then(|result| { match result { ValueNs::LocalBinding(binding) => { @@ -365,7 +417,7 @@ fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace> { /// Changes `current_capture_span_stack` to contain the stack of spans for this expr. fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option<HirPlace> { self.current_capture_span_stack.clear(); - match &self.body[tgt_expr] { + match &self.store[tgt_expr] { Expr::Path(p) => { let resolver_guard = self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr); @@ -416,7 +468,7 @@ fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut trunca let mut actual_truncate_to = 0; for &span in &*span_stack { actual_truncate_to += 1; - if !span.is_ref_span(self.body) { + if !span.is_ref_span(self.store) { remained -= 1; if remained == 0 { break; @@ -424,7 +476,7 @@ fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut trunca } } if actual_truncate_to < span_stack.len() - && span_stack[actual_truncate_to].is_ref_span(self.body) + && span_stack[actual_truncate_to].is_ref_span(self.store) { // Include the ref operator if there is one, we will fix it later (in `strip_captures_ref_span()`) if it's incorrect. actual_truncate_to += 1; @@ -533,7 +585,7 @@ fn walk_expr(&mut self, tgt_expr: ExprId) { } fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) { - match &self.body[tgt_expr] { + match &self.store[tgt_expr] { Expr::OffsetOf(_) => (), Expr::InlineAsm(e) => e.operands.iter().for_each(|(_, op)| match op { AsmOperand::In { expr, .. } @@ -733,7 +785,7 @@ fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) { self.consume_with_pat(rhs_place, target); self.inside_assignment = false; } - None => self.body.walk_pats(target, &mut |pat| match &self.body[pat] { + None => self.store.walk_pats(target, &mut |pat| match &self.store[pat] { Pat::Path(path) => self.mutate_path_pat(path, pat), &Pat::Expr(expr) => { let place = self.place_of_expr(expr); @@ -775,7 +827,7 @@ fn walk_pat_inner( update_result: &mut impl FnMut(CaptureKind), mut for_mut: BorrowKind, ) { - match &self.body[p] { + match &self.store[p] { Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing @@ -819,13 +871,13 @@ fn walk_pat_inner( if self.result.pat_adjustments.get(&p).is_some_and(|it| !it.is_empty()) { for_mut = BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }; } - self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut)); + self.store.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut)); } fn is_upvar(&self, place: &HirPlace) -> bool { if let Some(c) = self.current_closure { let InternedClosure(_, root) = self.db.lookup_intern_closure(c); - return self.body.is_binding_upvar(place.local, root); + return self.store.is_binding_upvar(place.local, root); } false } @@ -858,7 +910,7 @@ fn restrict_precision_for_unsafe(&mut self) { if ty.is_raw_ptr() || ty.is_union() { capture.kind = CaptureKind::ByRef(BorrowKind::Shared); self.truncate_capture_spans(capture, 0); - capture.place.projections.truncate(0); + capture.place.projections.clear(); continue; } for (i, p) in capture.place.projections.iter().enumerate() { @@ -866,7 +918,7 @@ fn restrict_precision_for_unsafe(&mut self) { &self.table.infer_ctxt, self.table.param_env, ty, - self.owner.module(self.db).krate(self.db), + self.owner.krate(self.db), ); if ty.is_raw_ptr() || ty.is_union() { capture.kind = CaptureKind::ByRef(BorrowKind::Shared); @@ -938,7 +990,7 @@ fn consume_with_pat(&mut self, mut place: HirPlace, tgt_pat: PatId) { self.current_capture_span_stack .extend((0..adjustments_count).map(|_| MirSpan::PatId(tgt_pat))); 'reset_span_stack: { - match &self.body[tgt_pat] { + match &self.store[tgt_pat] { Pat::Missing | Pat::Wild => (), Pat::Tuple { args, ellipsis } => { let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize)); @@ -1089,7 +1141,7 @@ fn closure_kind(&self) -> FnTrait { fn analyze_closure(&mut self, closure: InternedClosureId) -> FnTrait { let InternedClosure(_, root) = self.db.lookup_intern_closure(closure); self.current_closure = Some(closure); - let Expr::Closure { body, capture_by, .. } = &self.body[root] else { + let Expr::Closure { body, capture_by, .. } = &self.store[root] else { unreachable!("Closure expression id is always closure"); }; self.consume_expr(*body); @@ -1133,7 +1185,7 @@ fn strip_captures_ref_span(&mut self) { for capture in &mut captures { if matches!(capture.kind, CaptureKind::ByValue) { for span_stack in &mut capture.span_stacks { - if span_stack[span_stack.len() - 1].is_ref_span(self.body) { + if span_stack[span_stack.len() - 1].is_ref_span(self.store) { span_stack.truncate(span_stack.len() - 1); } } @@ -1149,7 +1201,7 @@ pub(crate) fn infer_closures(&mut self) { let kind = self.analyze_closure(closure); for (derefed_callee, callee_ty, params, expr) in exprs { - if let &Expr::Call { callee, .. } = &self.body[expr] { + if let &Expr::Call { callee, .. } = &self.store[expr] { let mut adjustments = self.result.expr_adjustments.remove(&callee).unwrap_or_default().into_vec(); self.write_fn_trait_method_resolution(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index e79868f..47a7049 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
@@ -1718,6 +1718,9 @@ fn fold_region(&mut self, r: Region<'db>) -> Region<'db> { fn is_capturing_closure(db: &dyn HirDatabase, closure: InternedClosureId) -> bool { let InternedClosure(owner, expr) = closure.loc(db); - upvars_mentioned(db, owner) + let Some(body_owner) = owner.as_def_with_body() else { + return false; + }; + upvars_mentioned(db, body_owner) .is_some_and(|upvars| upvars.get(&expr).is_some_and(|upvars| !upvars.is_empty())) }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 45b181e..dc57b1d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -11,6 +11,7 @@ InlineAsmKind, LabelId, Literal, Pat, PatId, RecordSpread, Statement, UnaryOp, }, resolver::ValueNs, + signatures::{FunctionSignature, VariantFields}, }; use hir_def::{FunctionId, hir::ClosureKind}; use hir_expand::name::Name; @@ -155,7 +156,7 @@ pub(super) fn expr_guaranteed_to_constitute_read_for_never( /// it is matching against. This is used to determine whether we should /// perform `NeverToAny` coercions. fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool { - match &self.body[pat] { + match &self.store[pat] { // Does not constitute a read. Pat::Wild => false, @@ -197,25 +198,25 @@ fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool { // FIXME(tschottdorf): this is problematic as the HIR is being scraped, but // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848. fn contains_explicit_ref_binding(&self, pat: PatId) -> bool { - if let Pat::Bind { id, .. } = self.body[pat] - && matches!(self.body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) + if let Pat::Bind { id, .. } = self.store[pat] + && matches!(self.store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) { return true; } let mut result = false; - self.body.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat)); + self.store.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat)); result } fn is_syntactic_place_expr(&self, expr: ExprId) -> bool { - match &self.body[expr] { + match &self.store[expr] { // Lang item paths cannot currently be local variables or statics. Expr::Path(Path::LangItem(_, _)) => false, Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(), Expr::Path(path) => self .resolver - .resolve_path_in_value_ns_fully(self.db, path, self.body.expr_path_hygiene(expr)) + .resolve_path_in_value_ns_fully(self.db, path, self.store.expr_path_hygiene(expr)) .is_none_or(|res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))), Expr::Underscore => true, Expr::UnaryOp { op: UnaryOp::Deref, .. } => true, @@ -311,7 +312,7 @@ fn infer_expr_inner( ) -> Ty<'db> { self.db.unwind_if_revision_cancelled(); - let expr = &self.body[tgt_expr]; + let expr = &self.store[tgt_expr]; tracing::trace!(?expr); let ty = match expr { Expr::Missing => self.err_ty(), @@ -608,7 +609,7 @@ fn infer_expr_inner( Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); for field in fields.iter() { let field_def = { match variant_data.field(&field.name) { @@ -717,7 +718,7 @@ fn infer_expr_inner( // instantiations in RHS can be coerced to it. Note that this // cannot happen in destructuring assignments because of how // they are desugared. - let lhs_ty = match &self.body[target] { + let lhs_ty = match &self.store[target] { // LHS of assignment doesn't constitute reads. &Pat::Expr(expr) => { Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No)) @@ -728,7 +729,7 @@ fn infer_expr_inner( let resolution = self.resolver.resolve_path_in_value_ns_fully( self.db, path, - self.body.pat_path_hygiene(target), + self.store.pat_path_hygiene(target), ); self.resolver.reset_to_guard(resolver_guard); @@ -1351,7 +1352,7 @@ fn infer_expr_array(&mut self, array: &Array, expected: &Expectation<'db>) -> Ty ExprIsRead::Yes, ); let usize = self.types.types.usize; - let len = match self.body[repeat] { + let len = match self.store[repeat] { Expr::Underscore => { self.write_expr_ty(repeat, usize); self.table.next_const_var() @@ -1491,7 +1492,7 @@ fn infer_block( } else { ExprIsRead::No }; - let ty = if contains_explicit_ref_binding(this.body, *pat) { + let ty = if contains_explicit_ref_binding(this.store, *pat) { this.infer_expr( *expr, &Expectation::has_type(decl_ty), @@ -1624,7 +1625,8 @@ fn lookup_field( }, _ => return None, }; - let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id] + let is_visible = VariantFields::field_visibilities(self.db, field_id.parent) + [field_id.local_id] .is_visible_from(self.db, self.resolver.module()); if !is_visible { if private_field.is_none() { @@ -2117,7 +2119,7 @@ pub(in super::super) fn check_call_arguments( // the return value of an argument-position async block to an argument-position // closure wrapped in a block. // See <https://github.com/rust-lang/rust/issues/112225>. - let is_closure = if let Expr::Closure { closure_kind, .. } = self.body[*arg] { + let is_closure = if let Expr::Closure { closure_kind, .. } = self.store[*arg] { !matches!(closure_kind, ClosureKind::Coroutine(_)) } else { false @@ -2194,7 +2196,7 @@ fn check_legacy_const_generics(&mut self, callee: Ty<'db>, args: &[ExprId]) -> B _ => return Default::default(), }; - let data = self.db.function_signature(func); + let data = FunctionSignature::of(self.db, func); let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func) else { return Default::default();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index 45fa141..bfe43fc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
@@ -14,8 +14,8 @@ }; impl<'db> InferenceContext<'_, 'db> { - pub(crate) fn infer_mut_body(&mut self) { - self.infer_mut_expr(self.body.body_expr, Mutability::Not); + pub(crate) fn infer_mut_body(&mut self, body_expr: ExprId) { + self.infer_mut_expr(body_expr, Mutability::Not); } fn infer_mut_expr(&mut self, tgt_expr: ExprId, mut mutability: Mutability) { @@ -52,7 +52,7 @@ fn infer_mut_expr(&mut self, tgt_expr: ExprId, mut mutability: Mutability) { } fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) { - match &self.body[tgt_expr] { + match &self.store[tgt_expr] { Expr::Missing => (), Expr::InlineAsm(e) => { e.operands.iter().for_each(|(_, op)| match op { @@ -173,7 +173,7 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi self.infer_mut_expr(*rhs, Mutability::Not); } &Expr::Assignment { target, value } => { - self.body.walk_pats(target, &mut |pat| match self.body[pat] { + self.store.walk_pats(target, &mut |pat| match self.store[pat] { Pat::Expr(expr) => self.infer_mut_expr(expr, Mutability::Mut), Pat::ConstBlock(block) => self.infer_mut_expr(block, Mutability::Not), _ => {} @@ -220,8 +220,8 @@ fn pat_iter_bound_mutability(&self, mut pat: impl Iterator<Item = PatId>) -> Mut /// `let (ref x0, ref x1) = *it;` we should use `Deref`. fn pat_bound_mutability(&self, pat: PatId) -> Mutability { let mut r = Mutability::Not; - self.body.walk_bindings_in_pat(pat, |b| { - if self.body[b].mode == BindingAnnotation::RefMut { + self.store.walk_bindings_in_pat(pat, |b| { + if self.store[b].mode == BindingAnnotation::RefMut { r = Mutability::Mut; } });
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index 87fd0da..8033680 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -3,9 +3,10 @@ use std::{cmp, iter}; use hir_def::{ - HasModule, - expr_store::{Body, path::Path}, + HasModule as _, + expr_store::{ExpressionStore, path::Path}, hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId}, + signatures::VariantFields, }; use hir_expand::name::Name; use rustc_ast_ir::Mutability; @@ -60,7 +61,7 @@ pub(super) fn infer_tuple_struct_pat_like( Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); let (pre, post) = match ellipsis { Some(idx) => subs.split_at(idx as usize), @@ -129,7 +130,7 @@ pub(super) fn infer_record_pat_like( Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); let substs = ty.as_adt().map(TupleExt::tail); @@ -260,14 +261,14 @@ fn infer_pat( ) -> Ty<'db> { let mut expected = self.table.structurally_resolve_type(expected); - if matches!(&self.body[pat], Pat::Ref { .. }) || self.inside_assignment { + if matches!(&self.store[pat], Pat::Ref { .. }) || self.inside_assignment { cov_mark::hit!(match_ergonomics_ref); // When you encounter a `&pat` pattern, reset to Move. // This is so that `w` is by value: `let (_, &w) = &(1, &2);` // Destructuring assignments also reset the binding mode and // don't do match ergonomics. default_bm = BindingMode::Move; - } else if self.is_non_ref_pat(self.body, pat) { + } else if self.is_non_ref_pat(self.store, pat) { let mut pat_adjustments = Vec::new(); while let TyKind::Ref(_lifetime, inner, mutability) = expected.kind() { pat_adjustments.push(expected.store()); @@ -289,7 +290,7 @@ fn infer_pat( let default_bm = default_bm; let expected = expected; - let ty = match &self.body[pat] { + let ty = match &self.store[pat] { Pat::Tuple { args, ellipsis } => { self.infer_tuple_pat_like(pat, expected, default_bm, *ellipsis, args, decl) } @@ -485,7 +486,7 @@ fn infer_bind_pat( expected: Ty<'db>, decl: Option<DeclContext>, ) -> Ty<'db> { - let Binding { mode, .. } = self.body[binding]; + let Binding { mode, .. } = self.store[binding]; let mode = if mode == BindingAnnotation::Unannotated { default_bm } else { @@ -569,7 +570,7 @@ fn infer_slice_pat( fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db> { // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`. - if let Expr::Literal(Literal::ByteString(_)) = self.body[expr] + if let Expr::Literal(Literal::ByteString(_)) = self.store[expr] && let TyKind::Ref(_, inner, _) = expected.kind() { let inner = self.table.try_structurally_resolve_type(inner); @@ -590,14 +591,14 @@ fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db> { self.infer_expr(expr, &Expectation::has_type(expected), ExprIsRead::Yes) } - fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bool { - match &body[pat] { + fn is_non_ref_pat(&mut self, store: &hir_def::expr_store::ExpressionStore, pat: PatId) -> bool { + match &store[pat] { Pat::Tuple { .. } | Pat::TupleStruct { .. } | Pat::Record { .. } | Pat::Range { .. } | Pat::Slice { .. } => true, - Pat::Or(pats) => pats.iter().all(|p| self.is_non_ref_pat(body, *p)), + Pat::Or(pats) => pats.iter().all(|p| self.is_non_ref_pat(store, *p)), Pat::Path(path) => { // A const is a reference pattern, but other value ns things aren't (see #16131). let resolved = self.resolve_value_path_inner(path, pat.into(), true); @@ -605,7 +606,7 @@ fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bo } Pat::ConstBlock(..) => false, Pat::Lit(expr) => !matches!( - body[*expr], + store[*expr], Expr::Literal(Literal::String(..) | Literal::CString(..) | Literal::ByteString(..)) ), Pat::Wild @@ -670,10 +671,10 @@ fn pat_is_irrefutable(&self, decl_ctxt: Option<DeclContext>) -> bool { } } -pub(super) fn contains_explicit_ref_binding(body: &Body, pat_id: PatId) -> bool { +pub(super) fn contains_explicit_ref_binding(store: &ExpressionStore, pat_id: PatId) -> bool { let mut res = false; - body.walk_pats(pat_id, &mut |pat| { - res |= matches!(body[pat], Pat::Bind { id, .. } if matches!(body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)); + store.walk_pats(pat_id, &mut |pat| { + res |= matches!(store[pat], Pat::Bind { id, .. } if matches!(store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)); }); res }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 40c6fdf..71d68cc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -4,6 +4,7 @@ AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, expr_store::path::{Path, PathSegment}, resolver::{ResolveValueResult, TypeNs, ValueNs}, + signatures::{ConstSignature, FunctionSignature}, }; use hir_expand::name::Name; use rustc_type_ir::inherent::{SliceLike, Ty as _}; @@ -136,7 +137,7 @@ pub(super) fn resolve_value_path_inner( let mut ctx = TyLoweringContext::new( self.db, &self.resolver, - self.body, + self.store, &self.diagnostics, InferenceTyDiagnosticSource::Body, self.generic_def, @@ -159,7 +160,7 @@ pub(super) fn resolve_value_path_inner( let ty = self.table.process_user_written_ty(ty); self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))? } else { - let hygiene = self.body.expr_or_pat_path_hygiene(id); + let hygiene = self.store.expr_or_pat_path_hygiene(id); // FIXME: report error, unresolved first path segment let value_or_partial = path_ctx.resolve_path_in_value_ns(hygiene)?; @@ -263,7 +264,7 @@ fn resolve_trait_assoc_item( trait_.trait_items(self.db).items.iter().map(|(_name, id)| *id).find_map(|item| { match item { AssocItemId::FunctionId(func) => { - if segment.name == &self.db.function_signature(func).name { + if segment.name == &FunctionSignature::of(self.db, func).name { Some(CandidateId::FunctionId(func)) } else { None @@ -271,7 +272,7 @@ fn resolve_trait_assoc_item( } AssocItemId::ConstId(konst) => { - if self.db.const_signature(konst).name.as_ref() == Some(segment.name) { + if ConstSignature::of(self.db, konst).name.as_ref() == Some(segment.name) { Some(CandidateId::ConstId(konst)) } else { None
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index 2057159..d093412 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -3,7 +3,7 @@ use std::fmt; use base_db::Crate; -use hir_def::{AdtId, DefWithBodyId, GenericParamId}; +use hir_def::{AdtId, ExpressionStoreOwnerId, GenericParamId}; use hir_expand::name::Name; use intern::sym; use rustc_hash::FxHashSet; @@ -147,7 +147,7 @@ pub(crate) fn new( db: &'db dyn HirDatabase, trait_env: ParamEnv<'db>, krate: Crate, - owner: Option<DefWithBodyId>, + owner: Option<ExpressionStoreOwnerId>, ) -> Self { let interner = DbInterner::new_with(db, krate); let typing_mode = match owner {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index 402e9ce..74d6612 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
@@ -1,7 +1,9 @@ //! Type inhabitedness logic. use std::ops::ControlFlow::{self, Break, Continue}; -use hir_def::{AdtId, EnumVariantId, ModuleId, VariantId, visibility::Visibility}; +use hir_def::{ + AdtId, EnumVariantId, ModuleId, VariantId, signatures::VariantFields, visibility::Visibility, +}; use rustc_hash::FxHashSet; use rustc_type_ir::{ TypeSuperVisitable, TypeVisitable, TypeVisitor, @@ -151,7 +153,11 @@ fn visit_variant( let is_enum = matches!(variant, VariantId::EnumVariantId(..)); let field_tys = self.db().field_types(variant); - let field_vis = if is_enum { None } else { Some(self.db().field_visibilities(variant)) }; + let field_vis = if is_enum { + None + } else { + Some(VariantFields::field_visibilities(self.db(), variant)) + }; for (fid, _) in fields.iter() { self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].get(), subst)?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs index 18feb0f..ae53276 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs
@@ -1,13 +1,17 @@ //! Functions to detect special lang items -use hir_def::{AdtId, TraitId, lang_item::LangItems, signatures::StructFlags}; +use hir_def::{ + AdtId, TraitId, + lang_item::LangItems, + signatures::{StructFlags, StructSignature}, +}; use intern::{Symbol, sym}; use crate::db::HirDatabase; pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool { let AdtId::StructId(id) = adt else { return false }; - db.struct_signature(id).flags.contains(StructFlags::IS_BOX) + StructSignature::of(db, id).flags.contains(StructFlags::IS_BOX) } pub fn lang_items_for_bin_op(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 5251004..5433212 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -333,7 +333,7 @@ pub fn layout_of_ty_query( } TyKind::Closure(id, args) => { let def = db.lookup_intern_closure(id.0); - let infer = InferenceResult::for_body(db, def.0); + let infer = InferenceResult::of(db, def.0); let (captures, _) = infer.closure_info(id.0); let fields = captures .iter()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index d249591..6090ddf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -5,7 +5,7 @@ use hir_def::{ AdtId, VariantId, attrs::AttrFlags, - signatures::{StructFlags, VariantFields}, + signatures::{StructFlags, StructSignature, VariantFields}, }; use rustc_abi::{Integer, ReprOptions, TargetDataLayout}; use rustc_index::IndexVec; @@ -41,7 +41,7 @@ pub fn layout_of_adt_query( }; let (variants, repr, is_special_no_niche) = match def { AdtId::StructId(s) => { - let sig = db.struct_signature(s); + let sig = StructSignature::of(db, s); let mut r = SmallVec::<[_; 1]>::new(); r.push(handle_variant(s.into(), s.fields(db))?); (
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 8c91be1..484eceb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
@@ -1,6 +1,12 @@ use base_db::target::TargetData; use either::Either; -use hir_def::{HasModule, db::DefDatabase}; +use hir_def::{ + DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, HasModule, + expr_store::Body, + signatures::{ + EnumSignature, FunctionSignature, StructSignature, TypeAliasSignature, UnionSignature, + }, +}; use project_model::{Sysroot, toolchain_info::QueryConfig}; use rustc_hash::FxHashMap; use rustc_type_ir::inherent::GenericArgs as _; @@ -49,18 +55,15 @@ fn eval_goal( let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { - hir_def::AdtId::StructId(x) => db - .struct_signature(x) + hir_def::AdtId::StructId(x) => StructSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), - hir_def::AdtId::UnionId(x) => db - .union_signature(x) + hir_def::AdtId::UnionId(x) => UnionSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), - hir_def::AdtId::EnumId(x) => db - .enum_signature(x) + hir_def::AdtId::EnumId(x) => EnumSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(), @@ -68,8 +71,7 @@ fn eval_goal( (name == "Goal").then_some(Either::Left(x)) } hir_def::ModuleDefId::TypeAliasId(x) => { - let name = db - .type_alias_signature(x) + let name = TypeAliasSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(); @@ -90,10 +92,13 @@ fn eval_goal( ), Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(), }; - let param_env = db.trait_environment(match adt_or_type_alias_id { - Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), - Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), - }); + let param_env = db.trait_environment( + match adt_or_type_alias_id { + Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), + Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), + } + .into(), + ); let krate = match adt_or_type_alias_id { Either::Left(it) => it.krate(&db), Either::Right(it) => it.krate(&db), @@ -123,8 +128,7 @@ fn eval_expr( .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - let name = db - .function_signature(x) + let name = FunctionSignature::of(&db, x) .name .display_no_db(file_id.edition(&db)) .to_smolstr(); @@ -133,15 +137,16 @@ fn eval_expr( _ => None, }) .unwrap(); - let hir_body = db.body(function_id.into()); + let hir_body = Body::of(&db, function_id.into()); let b = hir_body .bindings() .find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal") .unwrap() .0; - let infer = InferenceResult::for_body(&db, function_id.into()); + let infer = InferenceResult::of(&db, DefWithBodyId::from(function_id)); let goal_ty = infer.type_of_binding[b].clone(); - let param_env = db.trait_environment(function_id.into()); + let param_env = + db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(function_id))); let krate = function_id.krate(&db); db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }.store()) }) @@ -379,6 +384,11 @@ impl Tr for S { #[test] fn simd_types() { + let size = 16; + #[cfg(not(target_arch = "s390x"))] + let align = 16; + #[cfg(target_arch = "s390x")] + let align = 8; check_size_and_align( r#" #[repr(simd)] @@ -386,8 +396,8 @@ fn simd_types() { struct Goal(SimdType); "#, "", - 16, - 16, + size, + align, ); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 8d87276..e6b8329 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -61,8 +61,8 @@ use std::{hash::Hash, ops::ControlFlow}; use hir_def::{ - CallableDefId, GenericDefId, TypeAliasId, TypeOrConstParamId, TypeParamId, - hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness, + CallableDefId, ExpressionStoreOwnerId, GenericDefId, TypeAliasId, TypeOrConstParamId, + TypeParamId, hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness, }; use hir_expand::name::Name; use indexmap::{IndexMap, map::Entry}; @@ -507,7 +507,7 @@ pub fn associated_type_shorthand_candidates( let mut dedup_map = FxHashSet::default(); let param_ty = Ty::new_param(interner, param, param_idx(db, param.into()).unwrap() as u32); // We use the ParamEnv and not the predicates because the ParamEnv elaborates bounds. - let param_env = db.trait_environment(def); + let param_env = db.trait_environment(ExpressionStoreOwnerId::from(def)); for clause in param_env.clauses { let ClauseKind::Trait(trait_clause) = clause.kind().skip_binder() else { continue }; if trait_clause.self_ty() != param_ty {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 49594f3..7259099 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -13,10 +13,10 @@ use arrayvec::ArrayVec; use either::Either; use hir_def::{ - AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, - FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, - LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, UnionId, VariantId, + AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, EnumId, EnumVariantId, + ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, + ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, + TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId, builtin_type::BuiltinType, expr_store::{ExpressionStore, HygieneId, path::Path}, hir::generics::{ @@ -26,7 +26,10 @@ item_tree::FieldsShape, lang_item::LangItems, resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs}, - signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, + signatures::{ + ConstSignature, FunctionSignature, ImplSignature, StaticSignature, StructSignature, + TraitFlags, TraitSignature, TypeAliasFlags, TypeAliasSignature, + }, type_ref::{ ConstRef, FnType, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, @@ -178,7 +181,7 @@ pub struct TyLoweringContext<'db, 'a> { resolver: &'a Resolver<'db>, store: &'a ExpressionStore, def: GenericDefId, - generics: OnceCell<Generics>, + generics: OnceCell<Generics<'db>>, in_binders: DebruijnIndex, impl_trait_mode: ImplTraitLoweringState, /// Tracks types with explicit `?Sized` bounds. @@ -279,11 +282,12 @@ pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> { } pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> { - let const_ref = &self.store[const_ref.expr]; - match const_ref { - hir_def::hir::Expr::Path(path) => { - self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type)) - } + let expr_id = const_ref.expr; + let expr = &self.store[expr_id]; + match expr { + hir_def::hir::Expr::Path(path) => self + .path_to_const(path) + .unwrap_or_else(|| Const::new(self.interner, ConstKind::Error(ErrorGuaranteed))), hir_def::hir::Expr::Literal(literal) => { intern_const_ref(self.db, literal, const_type, self.resolver.krate()) } @@ -300,20 +304,74 @@ pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) - self.resolver.krate(), ) } else { - unknown_const(const_type) + Const::new(self.interner, ConstKind::Error(ErrorGuaranteed)) } } // For unsigned integers, chars, bools, etc., negation is not meaningful - _ => unknown_const(const_type), + _ => Const::new(self.interner, ConstKind::Error(ErrorGuaranteed)), } } else { - unknown_const(const_type) + // Complex negation expression (e.g. `-N` where N is a const param) + self.lower_const_as_unevaluated(expr_id, const_type) } } - _ => unknown_const(const_type), + hir_def::hir::Expr::Underscore => { + Const::new(self.interner, ConstKind::Error(ErrorGuaranteed)) + } + // Any other complex expression becomes an unevaluated anonymous const. + _ => self.lower_const_as_unevaluated(expr_id, const_type), } } + /// Lower a complex const expression to an `UnevaluatedConst` backed by an `AnonConstId`. + /// + /// The `expected_ty_ref` is `None` for array lengths (implicitly `usize`) or + /// `Some(type_ref_id)` for const generic arguments where the expected type comes + /// from the const parameter declaration. + fn lower_const_as_unevaluated( + &mut self, + _expr: hir_def::hir::ExprId, + _expected_ty: Ty<'db>, + ) -> Const<'db> { + // /// Build the identity generic args for the current generic context. + // /// + // /// This maps each generic parameter to itself (as a `ParamTy`, `ParamConst`, + // /// or `EarlyParamRegion`), which is the correct substitution when creating + // /// an `UnevaluatedConst` during type lowering — the anon const inherits the + // /// parent's generics and they haven't been substituted yet. + // fn current_generic_args(&self) -> GenericArgs<'db> { + // let generics = self.generics(); + // let interner = self.interner; + // GenericArgs::new_from_iter( + // interner, + // generics.iter_id().enumerate().map(|(index, id)| match id { + // GenericParamId::TypeParamId(id) => { + // GenericArg::from(Ty::new_param(interner, id, index as u32)) + // } + // GenericParamId::ConstParamId(id) => GenericArg::from(Const::new_param( + // interner, + // ParamConst { id, index: index as u32 }, + // )), + // GenericParamId::LifetimeParamId(id) => GenericArg::from(Region::new_early_param( + // interner, + // EarlyParamRegion { id, index: index as u32 }, + // )), + // }), + // ) + // } + // let loc = AnonConstLoc { owner: self.def, expr }; + // let id = loc.intern(self.db); + // let args = self.current_generic_args(); + // Const::new( + // self.interner, + // ConstKind::Unevaluated(UnevaluatedConst::new( + // GeneralConstId::AnonConstId(id).into(), + // args, + // )), + // ) + Const::new(self.interner, ConstKind::Error(ErrorGuaranteed)) + } + pub(crate) fn path_to_const(&mut self, path: &Path) -> Option<Const<'db>> { match self.resolver.resolve_path_in_value_ns_fully(self.db, path, HygieneId::ROOT) { Some(ValueNs::GenericParam(p)) => { @@ -349,7 +407,7 @@ pub(crate) fn lower_path_as_const(&mut self, path: &Path, const_type: Ty<'db>) - self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type)) } - fn generics(&self) -> &Generics { + fn generics(&self) -> &Generics<'db> { self.generics.get_or_init(|| generics(self.db, self.def)) } @@ -727,7 +785,8 @@ fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty<'db> { match b.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); - let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO); + let is_auto = + TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO); if is_auto { auto_traits.push(t.def_id().0); } else { @@ -1111,7 +1170,7 @@ pub(crate) fn impl_trait_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> Option<(StoredEarlyBinder<(TraitId, StoredGenericArgs)>, Diagnostics)> { - let impl_data = db.impl_signature(impl_id); + let impl_data = ImplSignature::of(db, impl_id); let resolver = impl_id.resolver(db); let mut ctx = TyLoweringContext::new( db, @@ -1196,7 +1255,7 @@ pub(crate) fn return_type_impl_traits( def: hir_def::FunctionId, ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe - let data = db.function_signature(def); + let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); let mut ctx_ret = TyLoweringContext::new( db, @@ -1224,7 +1283,7 @@ pub(crate) fn type_alias_impl_traits( db: &dyn HirDatabase, def: hir_def::TypeAliasId, ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { - let data = db.type_alias_signature(def); + let data = TypeAliasSignature::of(db, def); let resolver = def.resolver(db); let mut ctx = TyLoweringContext::new( db, @@ -1314,7 +1373,7 @@ fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Store /// Build the declared type of a const. fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); - let data = db.const_signature(def); + let data = ConstSignature::of(db, def); let parent = def.loc(db).container; let mut ctx = TyLoweringContext::new( db, @@ -1330,7 +1389,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<Store /// Build the declared type of a static. fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); - let data = db.static_signature(def); + let data = StaticSignature::of(db, def); let mut ctx = TyLoweringContext::new( db, &resolver, @@ -1347,7 +1406,7 @@ fn type_for_struct_constructor( db: &dyn HirDatabase, def: StructId, ) -> Option<StoredEarlyBinder<StoredTy>> { - let struct_data = db.struct_signature(def); + let struct_data = StructSignature::of(db, def); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.into())), @@ -1422,7 +1481,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, t: TypeAliasId, ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { - let type_alias_data = db.type_alias_signature(t); + let type_alias_data = TypeAliasSignature::of(db, t); let mut diags = None; let resolver = t.resolver(db); let interner = DbInterner::new_no_crate(db); @@ -1485,7 +1544,7 @@ pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { let resolver = impl_id.resolver(db); - let impl_data = db.impl_signature(impl_id); + let impl_data = ImplSignature::of(db, impl_id); let mut ctx = TyLoweringContext::new( db, &resolver, @@ -1531,14 +1590,14 @@ pub(crate) fn const_param_ty_with_diagnostics_query<'db>( _: (), def: ConstParamId, ) -> (StoredTy, Diagnostics) { - let (parent_data, store) = db.generic_params_and_store(def.parent()); + let (parent_data, store) = GenericParams::with_store(db, def.parent()); let data = &parent_data[def.local_id()]; let resolver = def.parent().resolver(db); let interner = DbInterner::new_no_crate(db); let mut ctx = TyLoweringContext::new( db, &resolver, - &store, + store, def.parent(), LifetimeElisionKind::AnonymousReportError, ); @@ -1629,7 +1688,7 @@ fn supertraits_info(db: &dyn HirDatabase, trait_: TraitId) -> SupertraitsInfo { )); let resolver = trait_.resolver(db); - let signature = db.trait_signature(trait_); + let signature = TraitSignature::of(db, trait_); for pred in signature.generic_params.where_predicates() { let (WherePredicate::TypeBound { target, bound } | WherePredicate::ForLifetime { lifetimes: _, target, bound }) = pred @@ -1900,7 +1959,7 @@ pub fn type_alias_bounds_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> (TypeAliasBounds<StoredEarlyBinder<StoredClauses>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(type_alias); + let type_alias_data = TypeAliasSignature::of(db, type_alias); let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); let mut ctx = TyLoweringContext::new( db, @@ -2079,16 +2138,6 @@ pub fn explicit_implied_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { } } -pub(crate) fn trait_environment_for_body_query( - db: &dyn HirDatabase, - def: DefWithBodyId, -) -> ParamEnv<'_> { - let Some(def) = def.as_generic_def_id(db) else { - return ParamEnv::empty(); - }; - db.trait_environment(def) -} - pub(crate) fn param_env_from_predicates<'db>( interner: DbInterner<'db>, predicates: &'db GenericPredicates, @@ -2103,7 +2152,12 @@ pub(crate) fn param_env_from_predicates<'db>( ParamEnv { clauses } } -pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> { +pub(crate) fn trait_environment<'db>( + db: &'db dyn HirDatabase, + def: ExpressionStoreOwnerId, +) -> ParamEnv<'db> { + let def = def.generic_def(db); + return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; #[salsa::tracked(returns(ref))] @@ -2303,7 +2357,7 @@ fn implicit_trait_predicate<'db>( fn push_const_arg_has_type_predicates<'db>( db: &'db dyn HirDatabase, predicates: &mut Vec<Clause<'db>>, - generics: &Generics, + generics: &Generics<'db>, ) { let interner = DbInterner::new_no_crate(db); let const_params_offset = generics.len_parent() + generics.len_lifetimes_self(); @@ -2356,10 +2410,11 @@ pub(crate) fn generic_defaults_with_diagnostics_query( } let resolver = def.resolver(db); + let store_for_self = generic_params.store(); let mut ctx = TyLoweringContext::new( db, &resolver, - generic_params.store(), + store_for_self, def, LifetimeElisionKind::AnonymousReportError, ) @@ -2377,6 +2432,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query( }) .collect::<Vec<_>>(); ctx.diagnostics.clear(); // Don't include diagnostics from the parent. + ctx.store = store_for_self; defaults.extend(generic_params.iter_self().map(|(_id, p)| { let (result, has_default) = handle_generic_param(&mut ctx, idx, p); has_any_default |= has_default; @@ -2447,7 +2503,7 @@ pub(crate) fn callable_item_signature_query<'db>( } fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<StoredPolyFnSig> { - let data = db.function_signature(def); + let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); let mut ctx_params = TyLoweringContext::new( @@ -2455,7 +2511,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Sto &resolver, &data.store, def.into(), - LifetimeElisionKind::for_fn_params(&data), + LifetimeElisionKind::for_fn_params(data), ); let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr)); @@ -2533,7 +2589,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> { - let type_alias_data = db.type_alias_signature(type_alias); + let type_alias_data = TypeAliasSignature::of(db, type_alias); let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); let interner = DbInterner::new_no_crate(db); let mut ctx = TyLoweringContext::new( @@ -2555,7 +2611,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( .map_bound(|c| match c { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); - let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO); + let is_auto = TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO); if is_auto { Some(ExistentialPredicate::AutoTrait(t.def_id())) } else {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index 81a9441..889f079 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
@@ -14,7 +14,7 @@ GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance, }, resolver::{ResolveValueResult, TypeNs, ValueNs}, - signatures::TraitFlags, + signatures::{TraitFlags, TraitSignature}, type_ref::{TypeRef, TypeRefId}, }; use rustc_type_ir::{ @@ -625,10 +625,7 @@ pub(crate) fn substs_from_path_segment( GenericDefId::TraitId(trait_) => { // RTN is prohibited anyways if we got here. let is_rtn = args.parenthesized == GenericArgsParentheses::ReturnTypeNotation; - let is_fn_trait = self - .ctx - .db - .trait_signature(trait_) + let is_fn_trait = TraitSignature::of(self.ctx.db, trait_) .flags .contains(TraitFlags::RUSTC_PAREN_SUGAR); is_rtn || !is_fn_trait @@ -1024,7 +1021,7 @@ fn inferred_kind( fn check_generic_args_len<'db>( args_and_bindings: Option<&HirGenericArgs>, def: GenericDefId, - def_generics: &Generics, + def_generics: &Generics<'db>, infer_args: bool, lifetime_elision: &LifetimeElisionKind<'db>, lowering_assoc_type_generics: bool,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index ad4d79e..05b9ea5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -17,11 +17,12 @@ ImplId, ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, builtin_derive::BuiltinDeriveImplMethod, - expr_store::path::GenericArgs as HirGenericArgs, - hir::ExprId, + expr_store::{Body, path::GenericArgs as HirGenericArgs}, + hir::{ExprId, generics::GenericParams}, lang_item::LangItems, nameres::{DefMap, block_def_map, crate_def_map}, resolver::Resolver, + signatures::{ConstSignature, FunctionSignature}, }; use intern::{Symbol, sym}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -366,7 +367,7 @@ pub fn lookup_impl_const<'db>( }; let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), subs); - let const_signature = db.const_signature(const_id); + let const_signature = ConstSignature::of(db, const_id); let name = match const_signature.name.as_ref() { Some(name) => name, None => return (const_id, subs), @@ -396,7 +397,7 @@ pub fn is_dyn_method<'db>( let ItemContainerId::TraitId(trait_id) = func.loc(db).container else { return None; }; - let trait_params = db.generic_params(trait_id.into()).len(); + let trait_params = GenericParams::of(db, trait_id.into()).len(); let fn_params = fn_subst.len() - trait_params; let trait_ref = TraitRef::new_from_args( interner, @@ -432,14 +433,14 @@ pub(crate) fn lookup_impl_method_query<'db>( let ItemContainerId::TraitId(trait_id) = func.loc(db).container else { return (Either::Left(func), fn_subst); }; - let trait_params = db.generic_params(trait_id.into()).len(); + let trait_params = GenericParams::of(db, trait_id.into()).len(); let trait_ref = TraitRef::new_from_args( interner, trait_id.into(), GenericArgs::new_from_slice(&fn_subst[..trait_params]), ); - let name = &db.function_signature(func).name; + let name = &FunctionSignature::of(db, func).name; let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env.param_env, name).and_then( |(assoc, impl_args)| { @@ -623,7 +624,7 @@ fn collect( // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; for konst in module_data.scope.unnamed_consts() { - let body = db.body(konst.into()); + let body = Body::of(db, konst.into()); for (_, block_def_map) in body.blocks(db) { collect(db, block_def_map, map); } @@ -766,7 +767,7 @@ fn collect( // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; for konst in module_data.scope.unnamed_consts() { - let body = db.body(konst.into()); + let body = Body::of(db, konst.into()); for (_, block_def_map) in body.blocks(db) { collect(db, block_def_map, lang_items, map); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs index 0024ca1..ec58908 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs
@@ -456,7 +456,7 @@ fn report_missing_lifetime(&mut self, _def: GenericDefId, _expected_count: u32) substs_from_args_and_bindings( self.db(), - self.ctx.body, + self.ctx.store, generic_args, self.candidate.into(), true,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index fc2bd87..8c76bfb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs
@@ -5,7 +5,8 @@ use hir_def::{ AssocItemId, FunctionId, GenericParamId, ImplId, ItemContainerId, TraitId, - signatures::TraitFlags, + hir::generics::GenericParams, + signatures::{FunctionSignature, TraitFlags, TraitSignature}, }; use hir_expand::name::Name; use rustc_ast_ir::Mutability; @@ -1605,7 +1606,8 @@ fn consider_probe( // Some trait methods are excluded for arrays before 2021. // (`array.into_iter()` wants a slice iterator for compatibility.) if self_ty.is_array() && !self.ctx.edition.at_least_2021() { - let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0); + let trait_signature = + TraitSignature::of(self.db(), poly_trait_ref.def_id().0); if trait_signature .flags .contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH) @@ -1619,7 +1621,8 @@ fn consider_probe( if self_ty.boxed_ty().is_some_and(Ty::is_slice) && !self.ctx.edition.at_least_2024() { - let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0); + let trait_signature = + TraitSignature::of(self.db(), poly_trait_ref.def_id().0); if trait_signature .flags .contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH) @@ -1963,7 +1966,7 @@ fn has_applicable_self(&self, item: CandidateId) -> bool { // associated value (i.e., methods, constants). match item { CandidateId::FunctionId(id) if self.mode == Mode::MethodCall => { - self.db().function_signature(id).has_self_param() + FunctionSignature::of(self.db(), id).has_self_param() } _ => true, } @@ -2008,7 +2011,7 @@ fn xform_method_sig(&self, method: FunctionId, args: &[GenericArg<'db>]) -> FnSi // we are given do not include type/lifetime parameters for the // method yet. So create fresh variables here for those too, // if there are any. - let generics = self.db().generic_params(method.into()); + let generics = GenericParams::of(self.db(), method.into()); let xform_fn_sig = if generics.is_empty() { fn_sig.instantiate(self.interner(), args)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index bf17c78..a8865cd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -6,7 +6,7 @@ use either::Either; use hir_def::{ DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId, - expr_store::Body, + expr_store::ExpressionStore, hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId}, }; use la_arena::{Arena, ArenaMap, Idx, RawIdx}; @@ -1210,12 +1210,12 @@ pub enum MirSpan { } impl MirSpan { - pub fn is_ref_span(&self, body: &Body) -> bool { + pub fn is_ref_span(&self, store: &ExpressionStore) -> bool { match *self { - MirSpan::ExprId(expr) => matches!(body[expr], Expr::Ref { .. }), + MirSpan::ExprId(expr) => matches!(store[expr], Expr::Ref { .. }), // FIXME: Figure out if this is correct wrt. match ergonomics. MirSpan::BindingId(binding) => { - matches!(body[binding].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) + matches!(store[binding].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) } MirSpan::PatId(_) | MirSpan::SelfParam | MirSpan::Unknown => false, }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index dece61a..3ff2db1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
@@ -5,7 +5,7 @@ use std::iter; -use hir_def::{DefWithBodyId, HasModule}; +use hir_def::{DefWithBodyId, ExpressionStoreOwnerId, HasModule}; use la_arena::ArenaMap; use rustc_hash::FxHashMap; use rustc_type_ir::inherent::GenericArgs as _; @@ -99,7 +99,7 @@ pub fn borrowck_query( let _p = tracing::info_span!("borrowck_query").entered(); let module = def.module(db); let interner = DbInterner::new_with(db, module.krate(db)); - let env = db.trait_environment_for_body(def); + let env = db.trait_environment(ExpressionStoreOwnerId::from(def)); let mut res = vec![]; // This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`. let typing_mode = TypingMode::borrowck(interner, def.into()); @@ -121,11 +121,11 @@ fn make_fetch_closure_field<'db>( db: &'db dyn HirDatabase, ) -> impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db> + use<'db> { |c: InternedClosureId, subst: GenericArgs<'db>, f: usize| { - let InternedClosure(def, _) = db.lookup_intern_closure(c); - let infer = InferenceResult::for_body(db, def); + let InternedClosure(owner, _) = db.lookup_intern_closure(c); + let interner = DbInterner::new_no_crate(db); + let infer = InferenceResult::of(db, owner); let (captures, _) = infer.closure_info(c); let parent_subst = subst.as_closure().parent_args(); - let interner = DbInterner::new_no_crate(db); captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst) } }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index ec0723c..505db17 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -5,14 +5,17 @@ use base_db::{Crate, target::TargetLoadError}; use either::Either; use hir_def::{ - AdtId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, HasModule, ItemContainerId, - Lookup, StaticId, VariantId, - expr_store::HygieneId, + AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, + HasModule, ItemContainerId, Lookup, StaticId, VariantId, + expr_store::{Body, HygieneId}, item_tree::FieldsShape, lang_item::LangItems, layout::{TagEncoding, Variants}, resolver::{HasResolver, TypeNs, ValueNs}, - signatures::{StaticFlags, StructFlags}, + signatures::{ + EnumSignature, FunctionSignature, StaticFlags, StaticSignature, StructFlags, + StructSignature, TraitSignature, + }, }; use hir_expand::{InFile, mod_path::path, name::Name}; use intern::sym; @@ -386,7 +389,7 @@ pub fn pretty_print( for (func, span, def) in stack.iter().take(30).rev() { match func { Either::Left(func) => { - let function_name = db.function_signature(*func); + let function_name = FunctionSignature::of(db, *func); writeln!( f, "In function {} ({:?})", @@ -398,7 +401,7 @@ pub fn pretty_print( writeln!(f, "In {closure:?}")?; } } - let source_map = db.body_with_source_map(*def).1; + let source_map = &Body::with_source_map(db, *def).1; let span: InFile<SyntaxNodePtr> = match span { MirSpan::ExprId(e) => match source_map.expr_syntax(*e) { Ok(s) => s.map(|it| it.into()), @@ -441,7 +444,7 @@ pub fn pretty_print( )?; } MirEvalError::MirLowerError(func, err) => { - let function_name = db.function_signature(*func); + let function_name = FunctionSignature::of(db, *func); let self_ = match func.lookup(db).container { ItemContainerId::ImplId(impl_id) => Some({ db.impl_self_ty(impl_id) @@ -450,7 +453,10 @@ pub fn pretty_print( .to_string() }), ItemContainerId::TraitId(it) => Some( - db.trait_signature(it).name.display(db, display_target.edition).to_string(), + TraitSignature::of(db, it) + .name + .display(db, display_target.edition) + .to_string(), ), _ => None, }; @@ -660,7 +666,7 @@ pub fn new( db, random_state: oorandom::Rand64::new(0), param_env: trait_env.unwrap_or_else(|| ParamEnvAndCrate { - param_env: db.trait_environment_for_body(owner), + param_env: db.trait_environment(ExpressionStoreOwnerId::from(owner)), krate: crate_id, }), crate_id, @@ -730,8 +736,8 @@ fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem) -> Ty<'db> { self.param_env.param_env, ty, |c, subst, f| { - let InternedClosure(def, _) = self.db.lookup_intern_closure(c); - let infer = InferenceResult::for_body(self.db, def); + let InternedClosure(owner, _) = self.db.lookup_intern_closure(c); + let infer = InferenceResult::of(self.db, owner); let (captures, _) = infer.closure_info(c); let parent_subst = subst.as_closure().parent_args(); captures @@ -893,8 +899,8 @@ fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<'db, Ty<'db>> { OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?, OperandKind::Constant { konst: _, ty } => ty.as_ref(), &OperandKind::Static(s) => { - let ty = InferenceResult::for_body(self.db, s.into()) - .expr_ty(self.db.body(s.into()).body_expr); + let ty = InferenceResult::of(self.db, DefWithBodyId::from(s)) + .expr_ty(Body::of(self.db, s.into()).root_expr()); Ty::new_ref( self.interner(), Region::new_static(self.interner()), @@ -1954,6 +1960,9 @@ fn allocate_const_in_heap( MirEvalError::ConstEvalError(name, Box::new(e)) })? } + GeneralConstId::AnonConstId(_) => { + not_supported!("anonymous const evaluation") + } }; if let ConstKind::Value(value) = result_owner.kind() { break 'b value; @@ -2818,15 +2827,15 @@ fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<'db, Address> if let Some(o) = self.static_locations.get(&st) { return Ok(*o); }; - let static_data = self.db.static_signature(st); + let static_data = StaticSignature::of(self.db, st); let result = if !static_data.flags.contains(StaticFlags::EXTERN) { let konst = self.db.const_eval_static(st).map_err(|e| { MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e)) })?; self.allocate_const_in_heap(locals, konst)? } else { - let ty = InferenceResult::for_body(self.db, st.into()) - .expr_ty(self.db.body(st.into()).body_expr); + let ty = InferenceResult::of(self.db, DefWithBodyId::from(st)) + .expr_ty(Body::of(self.db, st.into()).root_expr()); let Some((size, align)) = self.size_align_of(ty, locals)? else { not_supported!("unsized extern static"); }; @@ -2849,7 +2858,7 @@ fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> { let edition = self.crate_id.data(self.db).edition; let name = format!( "{}::{}", - self.db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(self.db, loc.parent).name.display(db, edition), loc.parent .enum_variants(self.db) .variant_name_by_id(variant) @@ -2909,7 +2918,7 @@ fn run_drop_glue_deep( let id = adt_def.def_id().0; match id { AdtId::StructId(s) => { - let data = self.db.struct_signature(s); + let data = StructSignature::of(self.db, s); if data.flags.contains(StructFlags::IS_MANUALLY_DROP) { return Ok(()); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 76c8701..ff6c99ca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -45,7 +45,7 @@ pub(super) fn detect_and_exec_special_function( return Ok(false); } - let function_data = self.db.function_signature(def); + let function_data = FunctionSignature::of(self.db, def); let attrs = AttrFlags::query(self.db, def.into()); let is_intrinsic = FunctionSignature::is_intrinsic(self.db, def); @@ -152,8 +152,8 @@ fn exec_clone( not_supported!("wrong arg count for clone"); }; let addr = Address::from_bytes(arg.get(self)?)?; - let InternedClosure(closure_owner, _) = self.db.lookup_intern_closure(id.0); - let infer = InferenceResult::for_body(self.db, closure_owner); + let InternedClosure(owner, _) = self.db.lookup_intern_closure(id.0); + let infer = InferenceResult::of(self.db, owner); let (captures, _) = infer.closure_info(id.0); let layout = self.layout(self_ty)?; let db = self.db; @@ -840,7 +840,7 @@ fn exec_intrinsic( // cases. let [lhs, rhs] = args else { return Err(MirEvalError::InternalError( - "wrapping_add args are not provided".into(), + "ptr_guaranteed_cmp args are not provided".into(), )); }; let ans = lhs.get(self)? == rhs.get(self)?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index 61dd775..6bf966c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
@@ -1,4 +1,4 @@ -use hir_def::{HasModule, db::DefDatabase}; +use hir_def::{GenericDefId, HasModule, signatures::FunctionSignature}; use hir_expand::EditionedFileId; use span::Edition; use syntax::{TextRange, TextSize}; @@ -25,7 +25,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - if db.function_signature(x).name.display(db, Edition::CURRENT).to_string() + if FunctionSignature::of(db, x).name.display(db, Edition::CURRENT).to_string() == "main" { Some(x) @@ -41,7 +41,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), func_id.into(), GenericArgs::empty(interner).store(), crate::ParamEnvAndCrate { - param_env: db.trait_environment(func_id.into()), + param_env: db.trait_environment(GenericDefId::from(func_id).into()), krate: func_id.krate(db), } .store(),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 2e849bc..44785d9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -4,16 +4,17 @@ use base_db::Crate; use hir_def::{ - AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, GenericParamId, HasModule, - ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, + AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericParamId, + HasModule, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{ ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm, - Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, + Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, generics::GenericParams, }, item_tree::FieldsShape, lang_item::LangItems, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -185,7 +186,7 @@ pub fn pretty_print( } } MirLowerError::MissingFunctionDefinition(owner, it) => { - let body = db.body(*owner); + let body = Body::of(db, *owner); writeln!( f, "Missing function definition for {}", @@ -202,13 +203,13 @@ pub fn pretty_print( MirLowerError::GenericArgNotProvided(id, subst) => { let param_name = match *id { GenericParamId::TypeParamId(id) => { - db.generic_params(id.parent())[id.local_id()].name().cloned() + GenericParams::of(db, id.parent())[id.local_id()].name().cloned() } GenericParamId::ConstParamId(id) => { - db.generic_params(id.parent())[id.local_id()].name().cloned() + GenericParams::of(db, id.parent())[id.local_id()].name().cloned() } GenericParamId::LifetimeParamId(id) => { - Some(db.generic_params(id.parent)[id.local_id].name.clone()) + Some(GenericParams::of(db, id.parent)[id.local_id].name.clone()) } }; writeln!( @@ -307,7 +308,7 @@ fn new( closures: vec![], }; let resolver = owner.resolver(db); - let env = db.trait_environment_for_body(owner); + let env = db.trait_environment(ExpressionStoreOwnerId::from(owner)); let interner = DbInterner::new_with(db, resolver.krate()); // FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body? let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); @@ -472,7 +473,7 @@ fn lower_expr_to_place_without_adjust( if let DefWithBodyId::FunctionId(f) = self.owner { let assoc = f.lookup(self.db); if let ItemContainerId::TraitId(t) = assoc.container { - let name = &self.db.function_signature(f).name; + let name = &FunctionSignature::of(self.db, f).name; return Err(MirLowerError::TraitFunctionDefinition(t, name.clone())); } } @@ -1546,6 +1547,9 @@ fn lower_const_to_operand( MirLowerError::ConstEvalError(name.into(), Box::new(e)) })? } + GeneralConstId::AnonConstId(_) => { + return Err(MirLowerError::IncompleteExpr); + } } }; let ty = self @@ -1553,6 +1557,7 @@ fn lower_const_to_operand( .value_ty(match const_id { GeneralConstId::ConstId(id) => id.into(), GeneralConstId::StaticId(id) => id.into(), + GeneralConstId::AnonConstId(_) => unreachable!("handled above"), }) .unwrap() .instantiate(self.interner(), subst); @@ -1989,7 +1994,7 @@ fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> { let loc = variant.lookup(db); let name = format!( "{}::{}", - self.db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(db, loc.parent).name.display(db, edition), loc.parent .enum_variants(self.db) .variant_name_by_id(variant) @@ -2106,8 +2111,10 @@ pub fn mir_body_for_closure_query<'db>( closure: InternedClosureId, ) -> Result<'db, Arc<MirBody>> { let InternedClosure(owner, expr) = db.lookup_intern_closure(closure); - let body = db.body(owner); - let infer = InferenceResult::for_body(db, owner); + let body_owner = + owner.as_def_with_body().expect("MIR lowering should only happen for body-owned closures"); + let body = Body::of(db, body_owner); + let infer = InferenceResult::of(db, body_owner); let Expr::Closure { args, body: root, .. } = &body[expr] else { implementation_error!("closure expression is not closure"); }; @@ -2115,7 +2122,7 @@ pub fn mir_body_for_closure_query<'db>( implementation_error!("closure expression is not closure"); }; let (captures, kind) = infer.closure_info(closure); - let mut ctx = MirLowerCtx::new(db, owner, &body.store, infer); + let mut ctx = MirLowerCtx::new(db, body_owner, &body.store, infer); // 0 is return local ctx.result.locals.alloc(Local { ty: infer.expr_ty(*root).store() }); let closure_local = ctx.result.locals.alloc(Local { @@ -2138,7 +2145,7 @@ pub fn mir_body_for_closure_query<'db>( }); ctx.result.param_locals.push(closure_local); let sig = ctx.interner().signature_unclosure(substs.as_closure().sig(), Safety::Safe); - let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr); + let resolver_guard = ctx.resolver.update_to_inner_scope(db, body_owner, expr); let current = ctx.lower_params_and_bindings( args.iter().zip(sig.skip_binder().inputs().iter()).map(|(it, y)| (*it, *y)), None, @@ -2222,13 +2229,12 @@ pub fn mir_body_query<'db>( let edition = krate.data(db).edition; let detail = match def { DefWithBodyId::FunctionId(it) => { - db.function_signature(it).name.display(db, edition).to_string() + FunctionSignature::of(db, it).name.display(db, edition).to_string() } DefWithBodyId::StaticId(it) => { - db.static_signature(it).name.display(db, edition).to_string() + StaticSignature::of(db, it).name.display(db, edition).to_string() } - DefWithBodyId::ConstId(it) => db - .const_signature(it) + DefWithBodyId::ConstId(it) => ConstSignature::of(db, it) .name .clone() .unwrap_or_else(Name::missing) @@ -2243,9 +2249,9 @@ pub fn mir_body_query<'db>( } }; let _p = tracing::info_span!("mir_body_query", ?detail).entered(); - let body = db.body(def); - let infer = InferenceResult::for_body(db, def); - let mut result = lower_body_to_mir(db, def, &body, infer, body.body_expr)?; + let body = Body::of(db, def); + let infer = InferenceResult::of(db, def); + let mut result = lower_body_to_mir(db, def, body, infer, body.root_expr())?; result.shrink_to_fit(); Ok(Arc::new(result)) } @@ -2269,7 +2275,7 @@ pub fn lower_body_to_mir<'db>( // but this is currently also used for `X` in `[(); X]` which live in the same expression store root_expr: ExprId, ) -> Result<'db, MirBody> { - let is_root = root_expr == body.body_expr; + let is_root = root_expr == body.root_expr(); // Extract params and self_param only when lowering the body's root expression for a function. if is_root && let DefWithBodyId::FunctionId(fid) = owner { let callable_sig =
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index 96b90a3..4b654a0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -6,7 +6,11 @@ }; use either::Either; -use hir_def::{expr_store::Body, hir::BindingId}; +use hir_def::{ + expr_store::Body, + hir::BindingId, + signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature}, +}; use hir_expand::{Lookup, name::Name}; use la_arena::ArenaMap; @@ -38,19 +42,19 @@ macro_rules! wln { impl MirBody { pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { - let hir_body = db.body(self.owner); - let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target); + let hir_body = Body::of(db, self.owner); + let mut ctx = MirPrettyCtx::new(self, hir_body, db, display_target); ctx.for_body(|this| match ctx.body.owner { hir_def::DefWithBodyId::FunctionId(id) => { - let data = db.function_signature(id); + let data = FunctionSignature::of(db, id); w!(this, "fn {}() ", data.name.display(db, this.display_target.edition)); } hir_def::DefWithBodyId::StaticId(id) => { - let data = db.static_signature(id); + let data = StaticSignature::of(db, id); w!(this, "static {}: _ = ", data.name.display(db, this.display_target.edition)); } hir_def::DefWithBodyId::ConstId(id) => { - let data = db.const_signature(id); + let data = ConstSignature::of(db, id); w!( this, "const {}: _ = ", @@ -66,7 +70,7 @@ pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) w!( this, "enum {}::{} = ", - db.enum_signature(loc.parent).name.display(db, edition), + EnumSignature::of(db, loc.parent).name.display(db, edition), loc.parent .enum_variants(db) .variant_name_by_id(id)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs index aa6caef..00161d6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs
@@ -1,9 +1,13 @@ //! Definition of `SolverDefId` use hir_def::{ - AdtId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, EnumId, - EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, StaticId, StructId, TraitId, - TypeAliasId, UnionId, + AdtId, AnonConstId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, + EnumId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, + ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, StaticSignature, StructSignature, + TraitSignature, TypeAliasSignature, UnionSignature, + }, }; use rustc_type_ir::inherent; use stdx::impl_from; @@ -12,13 +16,13 @@ use super::DbInterner; -#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash)] pub enum Ctor { Struct(StructId), Enum(EnumVariantId), } -#[derive(PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash)] pub enum SolverDefId { AdtId(AdtId), ConstId(ConstId), @@ -26,13 +30,13 @@ pub enum SolverDefId { ImplId(ImplId), BuiltinDeriveImplId(BuiltinDeriveImplId), StaticId(StaticId), + AnonConstId(AnonConstId), TraitId(TraitId), TypeAliasId(TypeAliasId), InternedClosureId(InternedClosureId), InternedCoroutineId(InternedCoroutineId), InternedOpaqueTyId(InternedOpaqueTyId), EnumVariantId(EnumVariantId), - // FIXME(next-solver): Do we need the separation of `Ctor`? It duplicates some variants. Ctor(Ctor), } @@ -42,32 +46,33 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let db = interner.db; match *self { SolverDefId::AdtId(AdtId::StructId(id)) => { - f.debug_tuple("AdtId").field(&db.struct_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&StructSignature::of(db, id).name.as_str()).finish() } SolverDefId::AdtId(AdtId::EnumId(id)) => { - f.debug_tuple("AdtId").field(&db.enum_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&EnumSignature::of(db, id).name.as_str()).finish() } SolverDefId::AdtId(AdtId::UnionId(id)) => { - f.debug_tuple("AdtId").field(&db.union_signature(id).name.as_str()).finish() + f.debug_tuple("AdtId").field(&UnionSignature::of(db, id).name.as_str()).finish() } SolverDefId::ConstId(id) => f .debug_tuple("ConstId") - .field(&db.const_signature(id).name.as_ref().map_or("_", |name| name.as_str())) + .field(&ConstSignature::of(db, id).name.as_ref().map_or("_", |name| name.as_str())) .finish(), - SolverDefId::FunctionId(id) => { - f.debug_tuple("FunctionId").field(&db.function_signature(id).name.as_str()).finish() - } + SolverDefId::FunctionId(id) => f + .debug_tuple("FunctionId") + .field(&FunctionSignature::of(db, id).name.as_str()) + .finish(), SolverDefId::ImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), SolverDefId::BuiltinDeriveImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), SolverDefId::StaticId(id) => { - f.debug_tuple("StaticId").field(&db.static_signature(id).name.as_str()).finish() + f.debug_tuple("StaticId").field(&StaticSignature::of(db, id).name.as_str()).finish() } SolverDefId::TraitId(id) => { - f.debug_tuple("TraitId").field(&db.trait_signature(id).name.as_str()).finish() + f.debug_tuple("TraitId").field(&TraitSignature::of(db, id).name.as_str()).finish() } SolverDefId::TypeAliasId(id) => f .debug_tuple("TypeAliasId") - .field(&db.type_alias_signature(id).name.as_str()) + .field(&TypeAliasSignature::of(db, id).name.as_str()) .finish(), SolverDefId::InternedClosureId(id) => { f.debug_tuple("InternedClosureId").field(&id).finish() @@ -83,20 +88,21 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("EnumVariantId") .field(&format_args!( "\"{}::{}\"", - db.enum_signature(parent_enum).name.as_str(), + EnumSignature::of(db, parent_enum).name.as_str(), parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str() )) .finish() } + SolverDefId::AnonConstId(id) => f.debug_tuple("AnonConstId").field(&id).finish(), SolverDefId::Ctor(Ctor::Struct(id)) => { - f.debug_tuple("Ctor").field(&db.struct_signature(id).name.as_str()).finish() + f.debug_tuple("Ctor").field(&StructSignature::of(db, id).name.as_str()).finish() } SolverDefId::Ctor(Ctor::Enum(id)) => { let parent_enum = id.loc(db).parent; f.debug_tuple("Ctor") .field(&format_args!( "\"{}::{}\"", - db.enum_signature(parent_enum).name.as_str(), + EnumSignature::of(db, parent_enum).name.as_str(), parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str() )) .finish() @@ -112,6 +118,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { ImplId, BuiltinDeriveImplId, StaticId, + AnonConstId, TraitId, TypeAliasId, InternedClosureId, @@ -142,6 +149,7 @@ fn from(value: GeneralConstId) -> Self { match value { GeneralConstId::ConstId(const_id) => SolverDefId::ConstId(const_id), GeneralConstId::StaticId(static_id) => SolverDefId::StaticId(static_id), + GeneralConstId::AnonConstId(anon_const_id) => SolverDefId::AnonConstId(anon_const_id), } } } @@ -158,6 +166,28 @@ fn from(value: DefWithBodyId) -> Self { } } +impl From<VariantId> for SolverDefId { + #[inline] + fn from(value: VariantId) -> Self { + match value { + VariantId::EnumVariantId(id) => id.into(), + VariantId::StructId(id) => id.into(), + VariantId::UnionId(id) => id.into(), + } + } +} + +impl From<ExpressionStoreOwnerId> for SolverDefId { + #[inline] + fn from(value: ExpressionStoreOwnerId) -> Self { + match value { + ExpressionStoreOwnerId::Body(body_id) => body_id.into(), + ExpressionStoreOwnerId::Signature(sig_id) => sig_id.into(), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.into(), + } + } +} + impl TryFrom<SolverDefId> for AttrDefId { type Error = (); #[inline] @@ -176,7 +206,8 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> { SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) - | SolverDefId::InternedOpaqueTyId(_) => Err(()), + | SolverDefId::InternedOpaqueTyId(_) + | SolverDefId::AnonConstId(_) => Err(()), } } } @@ -199,6 +230,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> { | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) | SolverDefId::Ctor(Ctor::Struct(_)) + | SolverDefId::AnonConstId(_) | SolverDefId::AdtId(_) => return Err(()), }; Ok(id) @@ -222,6 +254,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> { | SolverDefId::InternedOpaqueTyId(_) | SolverDefId::EnumVariantId(_) | SolverDefId::BuiltinDeriveImplId(_) + | SolverDefId::AnonConstId(_) | SolverDefId::Ctor(_) => return Err(()), }) } @@ -343,6 +376,7 @@ fn from(value: GeneralConstIdWrapper) -> SolverDefId { match value.0 { GeneralConstId::ConstId(id) => SolverDefId::ConstId(id), GeneralConstId::StaticId(id) => SolverDefId::StaticId(id), + GeneralConstId::AnonConstId(id) => SolverDefId::AnonConstId(id), } } } @@ -353,6 +387,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> { match value { SolverDefId::ConstId(it) => Ok(Self(it.into())), SolverDefId::StaticId(it) => Ok(Self(it.into())), + SolverDefId::AnonConstId(it) => Ok(Self(it.into())), _ => Err(()), } }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs index 8f798b4..0e8218b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs
@@ -617,6 +617,7 @@ pub fn to_debuggable_error(&self, infcx: &InferCtxt<'db>) -> FulfillmentError<'d } mod wf { + use hir_def::signatures::ImplSignature; use hir_def::{GeneralConstId, ItemContainerId}; use rustc_type_ir::inherent::{ AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Term as _, @@ -1054,7 +1055,7 @@ fn visit_const(&mut self, c: Const<'db>) -> Self::Result { if let GeneralConstId::ConstId(uv_def) = uv.def.0 && let ItemContainerId::ImplId(impl_) = uv_def.loc(self.interner().db).container - && self.interner().db.impl_signature(impl_).target_trait.is_none() + && ImplSignature::of(self.interner().db, impl_).target_trait.is_none() { return; // Subtree is handled by above function } else {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs index a8288b4..f31de21 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs
@@ -55,7 +55,7 @@ pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics { let (parent, own_params) = match (def.try_into(), def) { (Ok(def), _) => ( parent_generic_def(db, def), - own_params_for_generic_params(def, &db.generic_params(def)), + own_params_for_generic_params(def, GenericParams::of(db, def)), ), (_, SolverDefId::InternedOpaqueTyId(id)) => { match db.lookup_intern_impl_trait_id(id) {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index e17bdac..5b81c76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs
@@ -10,11 +10,15 @@ use base_db::Crate; use hir_def::{ - AdtId, CallableDefId, DefWithBodyId, EnumVariantId, HasModule, ItemContainerId, StructId, - UnionId, VariantId, + AdtId, CallableDefId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, HasModule, + ItemContainerId, StructId, UnionId, VariantId, attrs::AttrFlags, + expr_store::{Body, ExpressionStore}, lang_item::LangItems, - signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags}, + signatures::{ + EnumSignature, FieldData, FnFlags, FunctionSignature, ImplFlags, ImplSignature, + StructFlags, StructSignature, TraitFlags, TraitSignature, UnionSignature, + }, }; use la_arena::Idx; use rustc_abi::{ReprFlags, ReprOptions}; @@ -548,7 +552,7 @@ pub fn new<'db>(def_id: AdtId, interner: DbInterner<'db>) -> Self { let db = interner.db(); let (flags, variants, repr) = match def_id { AdtId::StructId(struct_id) => { - let data = db.struct_signature(struct_id); + let data = StructSignature::of(db, struct_id); let flags = AdtFlags { is_enum: false, @@ -775,15 +779,15 @@ impl fmt::Debug for AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { crate::with_attached_db(|db| match self.inner().id { AdtId::StructId(struct_id) => { - let data = db.struct_signature(struct_id); + let data = StructSignature::of(db, struct_id); f.write_str(data.name.as_str()) } AdtId::UnionId(union_id) => { - let data = db.union_signature(union_id); + let data = UnionSignature::of(db, union_id); f.write_str(data.name.as_str()) } AdtId::EnumId(enum_id) => { - let data = db.enum_signature(enum_id); + let data = EnumSignature::of(db, enum_id); f.write_str(data.name.as_str()) } }) @@ -1193,7 +1197,8 @@ fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf { | SolverDefId::ImplId(_) | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::InternedClosureId(_) - | SolverDefId::InternedCoroutineId(_) => { + | SolverDefId::InternedCoroutineId(_) + | SolverDefId::AnonConstId(_) => { return VariancesOf::empty(self); } }; @@ -1230,7 +1235,7 @@ fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind { SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque, SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container { ItemContainerId::ImplId(impl_) - if self.db.impl_signature(impl_).target_trait.is_none() => + if ImplSignature::of(self.db, impl_).target_trait.is_none() => { AliasTyKind::Inherent } @@ -1249,7 +1254,7 @@ fn alias_term_kind( SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy, SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container { ItemContainerId::ImplId(impl_) - if self.db.impl_signature(impl_).target_trait.is_none() => + if ImplSignature::of(self.db, impl_).target_trait.is_none() => { AliasTermKind::InherentTy } @@ -1260,7 +1265,9 @@ fn alias_term_kind( }, // rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections // via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it. - SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst, + SolverDefId::ConstId(_) | SolverDefId::AnonConstId(_) => { + AliasTermKind::UnevaluatedConst + } _ => unimplemented!("Unexpected alias: {:?}", alias.def_id), } } @@ -1308,22 +1315,10 @@ fn parent(self, def_id: Self::DefId) -> Self::DefId { SolverDefId::TypeAliasId(it) => it.lookup(self.db()).container, SolverDefId::ConstId(it) => it.lookup(self.db()).container, SolverDefId::InternedClosureId(it) => { - return self - .db() - .lookup_intern_closure(it) - .0 - .as_generic_def_id(self.db()) - .unwrap() - .into(); + return self.db().lookup_intern_closure(it).0.generic_def(self.db()).into(); } SolverDefId::InternedCoroutineId(it) => { - return self - .db() - .lookup_intern_coroutine(it) - .0 - .as_generic_def_id(self.db()) - .unwrap() - .into(); + return self.db().lookup_intern_coroutine(it).0.generic_def(self.db()).into(); } SolverDefId::StaticId(_) | SolverDefId::AdtId(_) @@ -1332,7 +1327,8 @@ fn parent(self, def_id: Self::DefId) -> Self::DefId { | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::EnumVariantId(..) | SolverDefId::Ctor(..) - | SolverDefId::InternedOpaqueTyId(..) => panic!(), + | SolverDefId::InternedOpaqueTyId(..) + | SolverDefId::AnonConstId(_) => panic!(), }; match container { @@ -1361,8 +1357,8 @@ fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movabi // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let body = self.db.body(owner); - let expr = &body[expr_id]; + let store = ExpressionStore::of(self.db, owner); + let expr = &store[expr_id]; match *expr { hir_def::hir::Expr::Closure { closure_kind, .. } => match closure_kind { hir_def::hir::ClosureKind::Coroutine(movability) => match movability { @@ -1795,6 +1791,7 @@ fn for_each_relevant_impl( | SolverDefId::InternedCoroutineId(_) | SolverDefId::InternedOpaqueTyId(_) | SolverDefId::EnumVariantId(_) + | SolverDefId::AnonConstId(_) | SolverDefId::Ctor(_) => return None, }; module.block(self.db) @@ -1933,7 +1930,7 @@ fn has_item_definition(self, _def_id: Self::DefId) -> bool { fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool { match impl_def_id { - AnyImplId::ImplId(impl_id) => self.db.impl_signature(impl_id).is_default(), + AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(), AnyImplId::BuiltinDeriveImplId(_) => false, } } @@ -1960,7 +1957,7 @@ fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity { let AnyImplId::ImplId(impl_id) = impl_id else { return ImplPolarity::Positive; }; - let impl_data = self.db().impl_signature(impl_id); + let impl_data = ImplSignature::of(self.db(), impl_id); if impl_data.flags.contains(ImplFlags::NEGATIVE) { ImplPolarity::Negative } else { @@ -1969,12 +1966,12 @@ fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity { } fn trait_is_auto(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::AUTO) } fn trait_is_alias(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::ALIAS) } @@ -1983,7 +1980,7 @@ fn trait_is_dyn_compatible(self, trait_: Self::TraitId) -> bool { } fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool { - let trait_data = self.db().trait_signature(trait_.0); + let trait_data = TraitSignature::of(self.db(), trait_.0); trait_data.flags.contains(TraitFlags::FUNDAMENTAL) } @@ -2006,9 +2003,9 @@ fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool { // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let body = self.db.body(owner); + let store = ExpressionStore::of(self.db, owner); matches!( - body[expr_id], + store[expr_id], hir_def::hir::Expr::Closure { closure_kind: hir_def::hir::ClosureKind::Coroutine(_), .. @@ -2020,9 +2017,9 @@ fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool { // FIXME: Make this a query? I don't believe this can be accessed from bodies other than // the current infer query, except with revealed opaques - is it rare enough to not matter? let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db); - let body = self.db.body(owner); + let store = ExpressionStore::of(self.db, owner); matches!( - body[expr_id], + store[expr_id], hir_def::hir::Expr::Closure { closure_kind: hir_def::hir::ClosureKind::Async, .. } | hir_def::hir::Expr::Async { .. } ) @@ -2143,7 +2140,7 @@ fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Sel crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result); // Collect coroutines. - let body = self.db.body(def_id); + let body = Body::of(self.db, def_id); body.exprs().for_each(|(expr_id, expr)| { if matches!( expr, @@ -2154,8 +2151,10 @@ fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Sel .. } ) { - let coroutine = - InternedCoroutineId::new(self.db, InternedCoroutine(def_id, expr_id)); + let coroutine = InternedCoroutineId::new( + self.db, + InternedCoroutine(ExpressionStoreOwnerId::Body(def_id), expr_id), + ); result.push(coroutine.into()); } }); @@ -2184,7 +2183,7 @@ fn fn_is_const(self, id: Self::FunctionId) -> bool { CallableDefId::FunctionId(id) => id, _ => return false, }; - self.db().function_signature(id).flags.contains(FnFlags::CONST) + FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST) } fn impl_is_const(self, _def_id: Self::ImplId) -> bool { @@ -2232,11 +2231,11 @@ fn is_default_trait(self, def_id: Self::TraitId) -> bool { } fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool { - self.db().trait_signature(trait_.0).flags.contains(TraitFlags::COINDUCTIVE) + TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE) } fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool { - self.db().trait_signature(trait_.0).flags.contains(TraitFlags::UNSAFE) + TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE) } fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs index 998aab5..e0732b3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs
@@ -1,7 +1,6 @@ //! Things related to IR printing in the next-trait-solver. -use std::any::type_name_of_val; - +use hir_def::signatures::{TraitSignature, TypeAliasSignature}; use rustc_type_ir::{self as ty, ir_print::IrPrint}; use super::SolverDefId; @@ -16,7 +15,7 @@ fn print_debug(t: &ty::AliasTy<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std: crate::with_attached_db(|db| match t.def_id { SolverDefId::TypeAliasId(id) => fmt.write_str(&format!( "AliasTy({:?}[{:?}])", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args )), SolverDefId::InternedOpaqueTyId(id) => { @@ -36,7 +35,7 @@ fn print_debug(t: &ty::AliasTerm<Self>, fmt: &mut std::fmt::Formatter<'_>) -> st crate::with_attached_db(|db| match t.def_id { SolverDefId::TypeAliasId(id) => fmt.write_str(&format!( "AliasTerm({:?}[{:?}])", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args )), SolverDefId::InternedOpaqueTyId(id) => { @@ -60,13 +59,13 @@ fn print_debug(t: &ty::TraitRef<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std fmt.write_str(&format!( "{:?}: {}", self_ty, - db.trait_signature(trait_).name.as_str() + TraitSignature::of(db, trait_).name.as_str() )) } else { fmt.write_str(&format!( "{:?}: {}<{:?}>", self_ty, - db.trait_signature(trait_).name.as_str(), + TraitSignature::of(db, trait_).name.as_str(), trait_args )) } @@ -82,7 +81,10 @@ fn print_debug( t: &ty::TraitPredicate<Self>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + match t.polarity { + ty::PredicatePolarity::Positive => write!(fmt, "{:?}", t.trait_ref), + ty::PredicatePolarity::Negative => write!(fmt, "!{:?}", t.trait_ref), + } } } impl<'db> IrPrint<rustc_type_ir::HostEffectPredicate<Self>> for DbInterner<'db> { @@ -97,7 +99,11 @@ fn print_debug( t: &rustc_type_ir::HostEffectPredicate<Self>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + let prefix = match t.constness { + ty::BoundConstness::Const => "const", + ty::BoundConstness::Maybe => "[const]", + }; + write!(fmt, "{prefix} {:?}", t.trait_ref) } } impl<'db> IrPrint<ty::ExistentialTraitRef<Self>> for DbInterner<'db> { @@ -116,7 +122,7 @@ fn print_debug( let trait_ = t.def_id.0; fmt.write_str(&format!( "ExistentialTraitRef({:?}[{:?}])", - db.trait_signature(trait_).name.as_str(), + TraitSignature::of(db, trait_).name.as_str(), t.args )) }) @@ -141,7 +147,7 @@ fn print_debug( }; fmt.write_str(&format!( "ExistentialProjection(({:?}[{:?}]) -> {:?})", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.args, t.term )) @@ -167,7 +173,7 @@ fn print_debug( }; fmt.write_str(&format!( "ProjectionPredicate(({:?}[{:?}]) -> {:?})", - db.type_alias_signature(id).name.as_str(), + TypeAliasSignature::of(db, id).name.as_str(), t.projection_term.args, t.term )) @@ -183,7 +189,7 @@ fn print_debug( t: &ty::NormalizesTo<Self>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + write!(fmt, "NormalizesTo({} -> {:?})", t.alias, t.term) } } impl<'db> IrPrint<ty::SubtypePredicate<Self>> for DbInterner<'db> { @@ -198,7 +204,7 @@ fn print_debug( t: &ty::SubtypePredicate<Self>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + write!(fmt, "{:?} <: {:?}", t.a, t.b) } } impl<'db> IrPrint<ty::CoercePredicate<Self>> for DbInterner<'db> { @@ -210,7 +216,7 @@ fn print_debug( t: &ty::CoercePredicate<Self>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + write!(fmt, "CoercePredicate({:?} -> {:?})", t.a, t.b) } } impl<'db> IrPrint<ty::FnSig<Self>> for DbInterner<'db> { @@ -219,7 +225,9 @@ fn print(t: &ty::FnSig<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Re } fn print_debug(t: &ty::FnSig<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + let tys = t.inputs_and_output.as_slice(); + let (output, inputs) = tys.split_last().unwrap(); + write!(fmt, "fn({:?}) -> {:?}", inputs, output) } } @@ -235,6 +243,10 @@ fn print_debug( t: &rustc_type_ir::PatternKind<DbInterner<'db>>, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { - fmt.write_str(&format!("TODO: {:?}", type_name_of_val(t))) + match t { + ty::PatternKind::Range { start, end } => write!(fmt, "{:?}..={:?}", start, end), + ty::PatternKind::Or(list) => write!(fmt, "or({:?})", list), + ty::PatternKind::NotNull => fmt.write_str("!null"), + } } }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index 15d6e2e..848bb11 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs
@@ -1,6 +1,9 @@ //! Defining `SolverContext` for next-trait-solver. -use hir_def::{AssocItemId, GeneralConstId}; +use hir_def::{ + AssocItemId, GeneralConstId, + signatures::{ConstSignature, TypeAliasSignature}, +}; use rustc_next_trait_solver::delegate::SolverDelegate; use rustc_type_ir::{ AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags, @@ -18,7 +21,7 @@ }; use super::{ - DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span, + Const, DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span, infer::{DbInternerInferExt, InferCtxt, canonical::instantiate::CanonicalExt}, }; @@ -181,52 +184,53 @@ fn fetch_eligible_assoc_item( return Ok(None); }; let impl_items = impl_id.impl_items(self.0.interner.db()); - let id = - match trait_assoc_def_id { - SolverDefId::TypeAliasId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id - && *impl_assoc_name == trait_assoc_data.name - { - Some(impl_assoc_id) - } else { - None - } - }) - .or_else(|| { - if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None } - }) - .map(SolverDefId::TypeAliasId) - } - SolverDefId::ConstId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id); - let trait_assoc_name = trait_assoc_data - .name - .as_ref() - .expect("unnamed consts should not get passed to the solver"); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id - && impl_assoc_name == trait_assoc_name - { - Some(impl_assoc_id) - } else { - None - } - }) - .or_else(|| { + let id = match trait_assoc_def_id { + SolverDefId::TypeAliasId(trait_assoc_id) => { + let trait_assoc_data = TypeAliasSignature::of(self.0.interner.db, trait_assoc_id); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id + && *impl_assoc_name == trait_assoc_data.name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else(|| { + if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None } + }) + .map(SolverDefId::TypeAliasId) + } + SolverDefId::ConstId(trait_assoc_id) => { + let trait_assoc_data = ConstSignature::of(self.0.interner.db, trait_assoc_id); + let trait_assoc_name = trait_assoc_data + .name + .as_ref() + .expect("unnamed consts should not get passed to the solver"); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id + && impl_assoc_name == trait_assoc_name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else( + || { if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None } - }) - .map(SolverDefId::ConstId) - } - _ => panic!("Unexpected SolverDefId"), - }; + }, + ) + .map(SolverDefId::ConstId) + } + _ => panic!("Unexpected SolverDefId"), + }; Ok(id) } @@ -256,6 +260,11 @@ fn evaluate_const( let ec = self.cx().db.const_eval_static(c).ok()?; Some(ec) } + // TODO: Wire up const_eval_anon query in Phase 5. + // For now, return an error const so normalization resolves the + // unevaluated const to Error (matching the old behavior where + // complex expressions produced ConstKind::Error directly). + GeneralConstId::AnonConstId(_) => Some(Const::error(self.cx())), } }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index 1173028..192cdb7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs
@@ -4,7 +4,7 @@ use hir_def::{ AdtId, HasModule, TypeParamId, - hir::generics::{TypeOrConstParamData, TypeParamProvenance}, + hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance}, }; use hir_def::{TraitId, type_ref::Rawness}; use intern::{Interned, InternedRef, impl_internable}; @@ -690,7 +690,7 @@ pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'d ), TyKind::Param(param) => { // FIXME: We shouldn't use `param.id` here. - let generic_params = db.generic_params(param.id.parent()); + let generic_params = GenericParams::of(db, param.id.parent()); let param_data = &generic_params[param.id.local_id()]; match param_data { TypeOrConstParamData::TypeParamData(p) => match p.provenance { @@ -714,7 +714,7 @@ pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'d } TyKind::Coroutine(coroutine_id, _args) => { let InternedCoroutine(owner, _) = coroutine_id.0.loc(db); - let krate = owner.module(db).krate(db); + let krate = owner.krate(db); if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future { // This is only used by type walking. // Parameters will be walked outside, and projection predicate is not used.
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs index 27ae5e3..ce93a33 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs
@@ -1,7 +1,8 @@ //! Handling of opaque types, detection of defining scope and hidden type. use hir_def::{ - AssocItemId, AssocItemLoc, DefWithBodyId, FunctionId, HasModule, ItemContainerId, TypeAliasId, + AssocItemId, AssocItemLoc, DefWithBodyId, ExpressionStoreOwnerId, FunctionId, GenericDefId, + HasModule, ItemContainerId, TypeAliasId, signatures::ImplSignature, }; use hir_expand::name::Name; use la_arena::ArenaMap; @@ -55,7 +56,7 @@ pub(crate) fn opaque_types_defined_by( }; let extend_with_atpit_from_container = |container| match container { ItemContainerId::ImplId(impl_id) => { - if db.impl_signature(impl_id).target_trait.is_some() { + if ImplSignature::of(db, impl_id).target_trait.is_some() { extend_with_atpit_from_assoc_items(&impl_id.impl_items(db).items); } } @@ -94,7 +95,7 @@ pub(crate) fn rpit_hidden_types<'db>( db: &'db dyn HirDatabase, function: FunctionId, ) -> ArenaMap<ImplTraitIdx, StoredEarlyBinder<StoredTy>> { - let infer = InferenceResult::for_body(db, function.into()); + let infer = InferenceResult::of(db, DefWithBodyId::from(function)); let mut result = ArenaMap::new(); for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) { result.insert(opaque, StoredEarlyBinder::bind(hidden_type.store())); @@ -122,13 +123,14 @@ pub(crate) fn tait_hidden_types<'db>( let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); - let param_env = db.trait_environment(type_alias.into()); + let param_env = + db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(type_alias))); let defining_bodies = tait_defining_bodies(db, &loc); let mut result = ArenaMap::with_capacity(taits_count); for defining_body in defining_bodies { - let infer = InferenceResult::for_body(db, defining_body); + let infer = InferenceResult::of(db, defining_body); for (&opaque, hidden_type) in &infer.type_of_opaque { let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else { continue; @@ -195,7 +197,7 @@ fn tait_defining_bodies( }; match loc.container { ItemContainerId::ImplId(impl_id) => { - if db.impl_signature(impl_id).target_trait.is_some() { + if ImplSignature::of(db, impl_id).target_trait.is_some() { return from_assoc_items(&impl_id.impl_items(db).items); } }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/representability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/representability.rs index 7e40f2d..bae204c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/representability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/representability.rs
@@ -1,6 +1,6 @@ //! Detecting whether a type is infinitely-sized. -use hir_def::{AdtId, VariantId}; +use hir_def::{AdtId, VariantId, hir::generics::GenericParams}; use rustc_type_ir::inherent::{AdtDef, IntoKind}; use crate::{ @@ -88,7 +88,7 @@ fn representability_adt_ty<'db>( } fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> { - let generics = db.generic_params(def_id.into()); + let generics = GenericParams::of(db, def_id.into()); let mut params_in_repr = (0..generics.len_lifetimes() + generics.len_type_or_consts()) .map(|_| false) .collect::<Box<[bool]>>();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs index d97a355..90cbcfe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs
@@ -1,6 +1,9 @@ //! Impl specialization related things -use hir_def::{HasModule, ImplId, nameres::crate_def_map}; +use hir_def::{ + ExpressionStoreOwnerId, GenericDefId, HasModule, ImplId, nameres::crate_def_map, + signatures::ImplSignature, +}; use intern::sym; use tracing::debug; @@ -45,11 +48,13 @@ fn specializes_query( specializing_impl_def_id: ImplId, parent_impl_def_id: ImplId, ) -> bool { - let trait_env = db.trait_environment(specializing_impl_def_id.into()); + let trait_env = db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from( + specializing_impl_def_id, + ))); let interner = DbInterner::new_with(db, specializing_impl_def_id.krate(db)); - let specializing_impl_signature = db.impl_signature(specializing_impl_def_id); - let parent_impl_signature = db.impl_signature(parent_impl_def_id); + let specializing_impl_signature = ImplSignature::of(db, specializing_impl_def_id); + let parent_impl_signature = ImplSignature::of(db, parent_impl_def_id); // We determine whether there's a subset relationship by: //
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs index 2bd675b..29a933f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs
@@ -217,6 +217,7 @@ pub(crate) fn from_fn_no_implications(db: &'db dyn HirDatabase, owner: FunctionI ("relaxed-simd", &["simd128"]), // BPF ("alu32", &[]), + ("allows-misaligned-mem-access", &[]), // CSKY ("10e60", &["7e10"]), ("2e3", &["e2"]),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 67ab89f..430a570 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
@@ -16,9 +16,9 @@ use base_db::{Crate, SourceDatabase}; use expect_test::Expect; use hir_def::{ - AssocItemId, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax, - db::DefDatabase, - expr_store::{Body, BodySourceMap}, + AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId, + SyntheticSyntax, + expr_store::{Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap}, hir::{ExprId, Pat, PatId}, item_scope::ItemScope, nameres::DefMap, @@ -34,7 +34,6 @@ ast::{self, AstNode, HasName}, }; use test_fixture::WithFixture; -use triomphe::Arc; use crate::{ InferenceResult, @@ -146,15 +145,15 @@ fn check_impl( let mut unexpected_type_mismatches = String::new(); for (def, krate) in defs { let display_target = DisplayTarget::from_crate(&db, krate); - let (body, body_source_map) = db.body_with_source_map(def); - let inference_result = InferenceResult::for_body(&db, def); + let (body, body_source_map) = Body::with_source_map(&db, def); + let inference_result = InferenceResult::of(&db, def); for (pat, ty) in inference_result.type_of_pat.iter() { let mut ty = ty.as_ref(); if let Pat::Bind { id, .. } = body[pat] { ty = inference_result.type_of_binding[id].as_ref(); } - let node = match pat_node(&body_source_map, pat, &db) { + let node = match pat_node(body_source_map, pat, &db) { Some(value) => value, None => continue, }; @@ -171,7 +170,7 @@ fn check_impl( for (expr, ty) in inference_result.type_of_expr.iter() { let ty = ty.as_ref(); - let node = match expr_node(&body_source_map, expr, &db) { + let node = match expr_node(body_source_map, expr, &db) { Some(value) => value, None => continue, }; @@ -202,9 +201,9 @@ fn check_impl( for (expr_or_pat, mismatch) in inference_result.type_mismatches() { let Some(node) = (match expr_or_pat { hir_def::hir::ExprOrPatId::ExprId(expr) => { - expr_node(&body_source_map, expr, &db) + expr_node(body_source_map, expr, &db) } - hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db), + hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(body_source_map, pat, &db), }) else { continue; }; @@ -223,7 +222,7 @@ fn check_impl( } for (type_ref, ty) in inference_result.placeholder_types() { - let node = match type_node(&body_source_map, type_ref, &db) { + let node = match type_node(body_source_map, type_ref, &db) { Some(value) => value, None => continue, }; @@ -321,16 +320,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let mut buf = String::new(); let mut infer_def = |inference_result: &InferenceResult, - body: Arc<Body>, - body_source_map: Arc<BodySourceMap>, + store: &ExpressionStore, + source_map: &ExpressionStoreSourceMap, + self_param: Option<( + hir_def::hir::BindingId, + Option<InFile<hir_def::expr_store::SelfParamPtr>>, + )>, krate: Crate| { let display_target = DisplayTarget::from_crate(&db, krate); let mut types: Vec<(InFile<SyntaxNode>, Ty<'_>)> = Vec::new(); let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new(); - if let Some(self_param) = body.self_param { - let ty = &inference_result.type_of_binding[self_param]; - if let Some(syntax_ptr) = body_source_map.self_param_syntax() { + if let Some((binding_id, syntax_ptr)) = self_param { + let ty = &inference_result.type_of_binding[binding_id]; + if let Some(syntax_ptr) = syntax_ptr { let root = db.parse_or_expand(syntax_ptr.file_id); let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone()); types.push((node, ty.as_ref())); @@ -338,10 +341,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } for (pat, mut ty) in inference_result.type_of_pat.iter() { - if let Pat::Bind { id, .. } = body[pat] { + if let Pat::Bind { id, .. } = store[pat] { ty = &inference_result.type_of_binding[id]; } - let node = match body_source_map.pat_syntax(pat) { + let node = match source_map.pat_syntax(pat) { Ok(sp) => { let root = db.parse_or_expand(sp.file_id); sp.map(|ptr| ptr.to_node(&root).syntax().clone()) @@ -355,7 +358,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } for (expr, ty) in inference_result.type_of_expr.iter() { - let node = match body_source_map.expr_syntax(expr) { + let node = match source_map.expr_syntax(expr) { Ok(sp) => { let root = db.parse_or_expand(sp.file_id); sp.map(|ptr| ptr.to_node(&root).syntax().clone()) @@ -414,16 +417,56 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let def_map = module.def_map(&db); let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new(); + let mut generic_defs: Vec<(GenericDefId, Crate)> = Vec::new(); visit_module(&db, def_map, module, &mut |it| { - let def = match it { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::EnumVariantId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => return, - }; - defs.push((def, module.krate(&db))) + let krate = module.krate(&db); + match it { + ModuleDefId::FunctionId(it) => { + defs.push((it.into(), krate)); + generic_defs.push((it.into(), krate)); + } + ModuleDefId::EnumVariantId(it) => { + defs.push((it.into(), krate)); + } + ModuleDefId::ConstId(it) => { + defs.push((it.into(), krate)); + generic_defs.push((it.into(), krate)); + } + ModuleDefId::StaticId(it) => { + defs.push((it.into(), krate)); + generic_defs.push((it.into(), krate)); + } + ModuleDefId::AdtId(it) => { + generic_defs.push((it.into(), krate)); + } + ModuleDefId::TraitId(it) => { + generic_defs.push((it.into(), krate)); + } + ModuleDefId::TypeAliasId(it) => { + generic_defs.push((it.into(), krate)); + } + _ => {} + } }); + // Also collect impls + for impl_id in def_map[module].scope.impls() { + generic_defs.push((impl_id.into(), module.krate(&db))); + let impl_data = impl_id.impl_items(&db); + for &(_, item) in impl_data.items.iter() { + match item { + AssocItemId::FunctionId(it) => { + generic_defs.push((it.into(), module.krate(&db))); + } + AssocItemId::ConstId(it) => { + generic_defs.push((it.into(), module.krate(&db))); + } + AssocItemId::TypeAliasId(it) => { + generic_defs.push((it.into(), module.krate(&db))); + } + } + } + } + defs.sort_by_key(|(def, _)| match def { DefWithBodyId::FunctionId(it) => { let loc = it.lookup(&db); @@ -443,9 +486,22 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } }); for (def, krate) in defs { - let (body, source_map) = db.body_with_source_map(def); - let infer = InferenceResult::for_body(&db, def); - infer_def(infer, body, source_map, krate); + let (body, source_map) = Body::with_source_map(&db, def); + let infer = InferenceResult::of(&db, def); + let self_param = body.self_param.map(|id| (id, source_map.self_param_syntax())); + infer_def(infer, body, source_map, self_param, krate); + } + + // Also infer signature const expressions (array lengths, const generic args, etc.) + generic_defs.dedup(); + for (def, krate) in generic_defs { + let (store, source_map) = ExpressionStore::with_source_map(&db, def.into()); + // Skip if there are no const expressions in the signature + if store.const_expr_origins().is_empty() { + continue; + } + let infer = InferenceResult::of(&db, def); + infer_def(infer, store, source_map, None, krate); } buf.truncate(buf.trim_end().len()); @@ -465,14 +521,14 @@ pub(crate) fn visit_module( for &(_, item) in impl_data.items.iter() { match item { AssocItemId::FunctionId(it) => { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); } AssocItemId::ConstId(it) => { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); } AssocItemId::TypeAliasId(it) => { cb(it.into()); @@ -491,22 +547,22 @@ fn visit_scope( cb(decl); match decl { ModuleDefId::FunctionId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::ConstId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::StaticId(it) => { - let body = db.body(it.into()); - visit_body(db, &body, cb); + let body = Body::of(db, it.into()); + visit_body(db, body, cb); } ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => { it.enum_variants(db).variants.iter().for_each(|&(it, _, _)| { - let body = db.body(it.into()); + let body = Body::of(db, it.into()); cb(it.into()); - visit_body(db, &body, cb); + visit_body(db, body, cb); }); } ModuleDefId::TraitId(it) => { @@ -596,16 +652,14 @@ fn main() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { - InferenceResult::for_body( - &db, - match def { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::EnumVariantId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => return, - }, - ); + let body_def: DefWithBodyId = match def { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::EnumVariantId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => return, + }; + InferenceResult::of(&db, body_def); }); }); @@ -640,16 +694,14 @@ fn main() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { - InferenceResult::for_body( - &db, - match def { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::EnumVariantId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => return, - }, - ); + let body_def: DefWithBodyId = match def { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::EnumVariantId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => return, + }; + InferenceResult::of(&db, body_def); }); }) }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index f089120..9e68756 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs
@@ -1,5 +1,8 @@ use expect_test::{Expect, expect}; -use hir_def::db::DefDatabase; +use hir_def::{ + DefWithBodyId, + expr_store::{Body, ExpressionStore}, +}; use hir_expand::{HirFileId, files::InFileWrapper}; use itertools::Itertools; use span::TextRange; @@ -28,19 +31,20 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let mut captures_info = Vec::new(); for def in defs { - let def = match def { + let def: DefWithBodyId = match def { hir_def::ModuleDefId::FunctionId(it) => it.into(), hir_def::ModuleDefId::EnumVariantId(it) => it.into(), hir_def::ModuleDefId::ConstId(it) => it.into(), hir_def::ModuleDefId::StaticId(it) => it.into(), _ => continue, }; - let infer = InferenceResult::for_body(&db, def); + let infer = InferenceResult::of(&db, def); let db = &db; captures_info.extend(infer.closure_info.iter().flat_map( |(closure_id, (captures, _))| { let closure = db.lookup_intern_closure(*closure_id); - let source_map = db.body_with_source_map(closure.0).1; + let body_owner = closure.0; + let source_map = ExpressionStore::with_source_map(db, body_owner).1; let closure_text_range = source_map .expr_syntax(closure.1) .expect("failed to map closure to SyntaxNode") @@ -56,7 +60,8 @@ fn text_range<N: AstNode>( } // FIXME: Deduplicate this with hir::Local::sources(). - let (body, source_map) = db.body_with_source_map(closure.0); + let (body, source_map) = + Body::with_source_map(db, body_owner.as_def_with_body().unwrap()); let local_text_range = match body.self_param.zip(source_map.self_param_syntax()) { Some((param, source)) if param == capture.local() => { @@ -71,7 +76,7 @@ fn text_range<N: AstNode>( .map(|it| format!("{it:?}")) .join(", "), }; - let place = capture.display_place(closure.0, db); + let place = capture.display_place(body_owner, db); let capture_ty = capture .ty .get()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index faa7b80..e806999 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
@@ -24,7 +24,7 @@ fn foo() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -34,21 +34,21 @@ fn foo() -> i32 { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", + "ExprScopes::body_expr_scopes_", ] "#]], ); @@ -69,7 +69,7 @@ fn foo() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -77,14 +77,14 @@ fn foo() -> i32 { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", ] "#]], ); @@ -112,7 +112,7 @@ fn baz() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -122,41 +122,41 @@ fn baz() -> i32 { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", + "ExprScopes::body_expr_scopes_", ] "#]], ); @@ -182,7 +182,7 @@ fn baz() -> i32 { let crate_def_map = module.def_map(&db); visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { - InferenceResult::for_body(&db, it.into()); + InferenceResult::of(&db, DefWithBodyId::from(it)); } }); }, @@ -190,26 +190,26 @@ fn baz() -> i32 { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "InferenceResult::for_body_", - "expr_scopes_shim", + "ExprScopes::body_expr_scopes_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", ] "#]], ); @@ -242,7 +242,7 @@ fn bar() -> f32 { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", @@ -279,7 +279,7 @@ pub struct NewStruct { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "crate_local_def_map", @@ -317,7 +317,7 @@ fn bar() -> f32 { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", @@ -355,7 +355,7 @@ pub enum SomeEnum { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "crate_local_def_map", @@ -393,7 +393,7 @@ fn bar() -> f32 { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", @@ -428,7 +428,7 @@ fn bar() -> f32 { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "crate_local_def_map", @@ -470,7 +470,7 @@ pub struct SomeStruct { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", @@ -513,7 +513,7 @@ pub fn new(value: i32) -> Self { expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "crate_local_def_map", @@ -562,7 +562,7 @@ fn main() { }); for def in defs { - let _inference_result = InferenceResult::for_body(&db, def); + let _inference_result = InferenceResult::of(&db, def); } }, &[("trait_solve_shim", 0)], @@ -571,23 +571,23 @@ fn main() { "source_root_crates_shim", "crate_local_def_map", "file_item_tree_query", - "ast_id_map_shim", + "ast_id_map", "parse_shim", "real_span_map_shim", "TraitItems::query_with_diagnostics_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "AttrFlags::query_", "ImplItems::of_", "InferenceResult::for_body_", - "trait_signature_shim", - "trait_signature_with_source_map_shim", + "TraitSignature::of_", + "TraitSignature::with_source_map_", "AttrFlags::query_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "AttrFlags::query_", - "body_shim", - "body_with_source_map_shim", + "Body::of_", + "Body::with_source_map_", "trait_environment_query", "lang_items", "crate_lang_items", @@ -595,14 +595,14 @@ fn main() { "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", "InferenceResult::for_body_", - "function_signature_shim", - "function_signature_with_source_map_shim", + "FunctionSignature::of_", + "FunctionSignature::with_source_map_", "trait_environment_query", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", - "struct_signature_shim", - "struct_signature_with_source_map_shim", + "ExprScopes::body_expr_scopes_", + "StructSignature::of_", + "StructSignature::with_source_map_", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "value_ty_query", @@ -611,8 +611,8 @@ fn main() { "TraitImpls::for_crate_and_deps_", "TraitImpls::for_crate_", "impl_trait_with_diagnostics_query", - "impl_signature_shim", - "impl_signature_with_source_map_shim", + "ImplSignature::of_", + "ImplSignature::with_source_map_", "impl_self_ty_with_diagnostics_query", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", @@ -658,47 +658,47 @@ fn main() { }); for def in defs { - let _inference_result = InferenceResult::for_body(&db, def); + let _inference_result = InferenceResult::of(&db, def); } }, &[("trait_solve_shim", 0)], expect_test::expect![[r#" [ "parse_shim", - "ast_id_map_shim", + "ast_id_map", "file_item_tree_query", "real_span_map_shim", "crate_local_def_map", "TraitItems::query_with_diagnostics_", - "body_with_source_map_shim", + "Body::with_source_map_", "AttrFlags::query_", - "body_shim", + "Body::of_", "ImplItems::of_", "InferenceResult::for_body_", "AttrFlags::query_", - "trait_signature_with_source_map_shim", + "TraitSignature::with_source_map_", "AttrFlags::query_", - "function_signature_with_source_map_shim", - "function_signature_shim", - "body_with_source_map_shim", - "body_shim", + "FunctionSignature::with_source_map_", + "FunctionSignature::of_", + "Body::with_source_map_", + "Body::of_", "crate_lang_items", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", "InferenceResult::for_body_", - "function_signature_with_source_map_shim", + "FunctionSignature::with_source_map_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", - "expr_scopes_shim", - "struct_signature_with_source_map_shim", + "ExprScopes::body_expr_scopes_", + "StructSignature::with_source_map_", "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "InherentImpls::for_crate_", "callable_item_signature_query", "TraitImpls::for_crate_", - "impl_signature_with_source_map_shim", - "impl_signature_shim", + "ImplSignature::with_source_map_", + "ImplSignature::of_", "impl_trait_with_diagnostics_query", "impl_self_ty_with_diagnostics_query", "AttrFlags::query_", @@ -716,6 +716,7 @@ fn execute_assert_events( ) { crate::attach_db(db, || { let (executed, events) = db.log_executed(f); + expect.assert_debug_eq(&executed); for (event, count) in required { let n = executed.iter().filter(|it| it.contains(event)).count(); assert_eq!( @@ -731,6 +732,5 @@ fn execute_assert_events( .collect::<Vec<_>>(), ); } - expect.assert_debug_eq(&executed); }); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs index 8c7d29f..42dc074 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
@@ -421,6 +421,8 @@ fn index(&self, index: core::ops::RangeFull) -> &Self::Output { 254..256 '&v': &'? [u8; 3] 255..256 'v': [u8; 3] 257..259 '{}': () + 199..200 '3': usize + 62..63 'N': usize "#]], ); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index d88801a..e4fc7e5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -2754,6 +2754,7 @@ fn filter(&self, filter: &Filter<T>) -> Self::Output { 664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static 691..698 'loop {}': ! 696..698 '{}': () + 512..513 'N': usize "#]], ); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs index f47a26d..e6b3244 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -34,6 +34,7 @@ pub trait Space: IntoIterator { 223..227 'iter': IntoIter<u8> 230..231 'a': Vec<u8> 230..243 'a.into_iter()': IntoIter<u8> + 322..323 '1': usize "#]], ); } @@ -472,6 +473,8 @@ fn foo() { 249..257 'to_bytes': fn to_bytes() -> [u8; _] 249..259 'to_bytes()': [u8; _] 249..268 'to_byt..._vec()': Vec<<[u8; _] as Foo>::Item> + 205..206 '_': usize + 156..157 'N': usize "#]], ); } @@ -541,6 +544,11 @@ fn test_at_most() { 617..620 'num': Between<0, 1, char> 623..626 ''9'': char 623..641 ''9'.at...:<1>()': Between<0, 1, char> + 320..335 '{ Consts::MAX }': usize + 322..333 'Consts::MAX': usize + 421..422 '0': i32 + 144..159 '{ Consts::MAX }': usize + 146..157 'Consts::MAX': usize "#]], ); }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index dab8bdb..3ea21f8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -3868,6 +3868,8 @@ fn main() { 208..209 'c': u8 213..214 'a': A 213..221 'a.into()': [u8; 2] + 33..34 '2': usize + 111..112 '3': usize "#]], ); } @@ -4061,6 +4063,8 @@ fn foo() { 248..282 'LazyLo..._LOCK)': &'? [u32; _] 264..281 '&VALUE...Y_LOCK': &'? LazyLock<[u32; _]> 265..281 'VALUES...Y_LOCK': LazyLock<[u32; _]> + 197..202 '{ 0 }': usize + 199..200 '0': usize "#]], ); } @@ -4109,3 +4113,38 @@ fn foo() { "#, ); } + +#[test] +fn signature_inference() { + check_infer( + r#" +trait Trait<const A: u8> {} +struct S<T: Trait<2>, const C: f32 = 0.0> +where + (): Trait<2> +{ + field: [(); { C as usize }], + field2: *mut S<T, 5.0> +} + +struct S2<const C: u16>; + +type Alias = S2<0>; +impl S2<0> {} +enum E { + V(S2<0>) = 0, +} +union U { + field: S2<0> +} + "#, + expect![[r#" + 242..243 '0': isize + 46..47 '2': i32 + 65..68 '0.0': f32 + 90..91 '2': i32 + 200..201 '0': i32 + 212..213 '0': i32 + "#]], + ); +}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 74e9a8d..22359d8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -1271,6 +1271,7 @@ fn bar() { 241..245 'R::B': fn B<(), i32>(i32) -> R<(), i32> 241..248 'R::B(7)': R<(), i32> 246..247 '7': i32 + 46..47 '2': usize "#]], ); } @@ -3781,6 +3782,8 @@ fn main() { 371..373 'v4': usize 376..378 'v3': [u8; 4] 376..389 'v3.do_thing()': usize + 86..87 '4': usize + 192..193 '2': usize "#]], ) } @@ -3820,6 +3823,9 @@ fn main() { 240..242 'v2': [u8; 2] 245..246 'v': [u8; 2] 245..257 'v.do_thing()': [u8; 2] + 130..131 'L': usize + 102..103 'L': usize + 130..131 'L': usize "#]], ) }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index fb598fe..878696c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
@@ -7,7 +7,11 @@ AdtId, AssocItemId, HasModule, ImplId, Lookup, TraitId, lang_item::LangItems, nameres::DefMap, - signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags}, + signatures::{ + ConstFlags, ConstSignature, EnumFlags, EnumSignature, FnFlags, FunctionSignature, + StructFlags, StructSignature, TraitFlags, TraitSignature, TypeAliasFlags, + TypeAliasSignature, UnionSignature, + }, }; use hir_expand::name::Name; use intern::sym; @@ -279,21 +283,18 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id | TyKind::Float(_) => true, TyKind::Adt(adt_def, _) => match adt_def.def_id().0 { - hir_def::AdtId::StructId(id) => db - .struct_signature(id) + hir_def::AdtId::StructId(id) => StructSignature::of(db, id) .flags .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), - hir_def::AdtId::UnionId(id) => db - .union_signature(id) + hir_def::AdtId::UnionId(id) => UnionSignature::of(db, id) .flags .contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), - hir_def::AdtId::EnumId(it) => db - .enum_signature(it) + hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it) .flags .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), }, TyKind::Dynamic(it, _) => it.principal_def_id().is_some_and(|trait_id| { - db.trait_signature(trait_id.0) + TraitSignature::of(db, trait_id.0) .flags .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) }), @@ -304,14 +305,13 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id rustc_has_incoherent_inherent_impls && !items.items.is_empty() && items.items.iter().all(|&(_, assoc)| match assoc { - AssocItemId::FunctionId(it) => { - db.function_signature(it).flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL) - } - AssocItemId::ConstId(it) => { - db.const_signature(it).flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL) - } - AssocItemId::TypeAliasId(it) => db - .type_alias_signature(it) + AssocItemId::FunctionId(it) => FunctionSignature::of(db, it) + .flags + .contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL), + AssocItemId::ConstId(it) => ConstSignature::of(db, it) + .flags + .contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL), + AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it) .flags .contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL), }) @@ -350,7 +350,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool let AdtId::StructId(s) = adt_def.def_id().0 else { break ty; }; - let struct_signature = db.struct_signature(s); + let struct_signature = StructSignature::of(db, s); if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) { let next = subs.types().next(); match next {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs b/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs index ee864ab..489895f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs
@@ -44,10 +44,10 @@ pub fn upvars_mentioned( db: &dyn HirDatabase, owner: DefWithBodyId, ) -> Option<Box<FxHashMap<ExprId, Upvars>>> { - let body = db.body(owner); + let body = Body::of(db, owner); let mut resolver = owner.resolver(db); let mut result = FxHashMap::default(); - handle_expr_outside_closure(db, &mut resolver, owner, &body, body.body_expr, &mut result); + handle_expr_outside_closure(db, &mut resolver, owner, body, body.root_expr(), &mut result); return if result.is_empty() { None } else { @@ -198,7 +198,7 @@ fn resolve_maybe_upvar<'db>( #[cfg(test)] mod tests { use expect_test::{Expect, expect}; - use hir_def::{ModuleDefId, db::DefDatabase, nameres::crate_def_map}; + use hir_def::{ModuleDefId, expr_store::Body, nameres::crate_def_map}; use itertools::Itertools; use span::Edition; use test_fixture::WithFixture; @@ -219,7 +219,7 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) { }) .exactly_one() .unwrap_or_else(|_| panic!("expected one function")); - let (body, source_map) = db.body_with_source_map(func.into()); + let (body, source_map) = Body::with_source_map(&db, func.into()); let Some(upvars) = upvars_mentioned(&db, func.into()) else { expectation.assert_eq(""); return;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index be64f55..5091095 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -4,6 +4,7 @@ use base_db::target::{self, TargetData}; use hir_def::{ EnumId, EnumVariantId, FunctionId, Lookup, TraitId, attrs::AttrFlags, lang_item::LangItems, + signatures::FunctionSignature, }; use intern::sym; use rustc_abi::TargetDataLayout; @@ -79,7 +80,7 @@ pub fn is_fn_unsafe_to_call( call_edition: Edition, target_feature_is_safe: TargetFeatureIsSafeInTarget, ) -> Unsafety { - let data = db.function_signature(func); + let data = FunctionSignature::of(db, func); if data.is_unsafe() { return Unsafety::Unsafe; }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index 6f415a5..1945b04 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
@@ -13,7 +13,10 @@ //! by the next salsa version. If not, we will likely have to adapt and go with the rustc approach //! while installing firewall per item queries to prevent invalidation issues. -use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId, signatures::StructFlags}; +use hir_def::{ + AdtId, GenericDefId, GenericParamId, VariantId, + signatures::{StructFlags, StructSignature}, +}; use rustc_ast_ir::Mutability; use rustc_type_ir::{ Variance, @@ -45,7 +48,7 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance GenericDefId::FunctionId(_) => (), GenericDefId::AdtId(adt) => { if let AdtId::StructId(id) = adt { - let flags = &db.struct_signature(id).flags; + let flags = &StructSignature::of(db, id).flags; let types = || crate::next_solver::default_types(db); if flags.contains(StructFlags::IS_UNSAFE_CELL) { return types().one_invariant.store(); @@ -113,7 +116,7 @@ pub(crate) fn variances_of_cycle_initial( struct Context<'db> { db: &'db dyn HirDatabase, - generics: Generics, + generics: Generics<'db>, variances: Box<[Variance]>, }
diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index cfb95e0..27e7985 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
@@ -7,6 +7,7 @@ TraitId, TypeOrConstParamId, attrs::{AttrFlags, Docs, IsInnerDoc}, expr_store::path::Path, + hir::generics::GenericParams, item_scope::ItemInNs, per_ns::Namespace, resolver::{HasResolver, Resolver, TypeNs}, @@ -26,9 +27,9 @@ use stdx::never; use crate::{ - Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl, - Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro, Module, - ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, EnumVariant, + ExternCrateDecl, Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro, + Module, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, }; #[derive(Debug, Clone, Copy)] @@ -199,7 +200,7 @@ fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { } impl_has_attrs![ - (Variant, EnumVariantId), + (EnumVariant, EnumVariantId), (Static, StaticId), (Const, ConstId), (Trait, TraitId), @@ -377,7 +378,7 @@ fn resolve_assoc_or_field( let ty = match base_def { TypeNs::SelfType(id) => Impl::from(id).self_ty(db), TypeNs::GenericParam(param) => { - let generic_params = db.generic_params(param.parent()); + let generic_params = GenericParams::of(db, param.parent()); if generic_params[param.local_id()].is_trait_self() { // `Self::assoc` in traits should refer to the trait itself. let parent_trait = |container| match container { @@ -406,7 +407,7 @@ fn resolve_assoc_or_field( TypeNs::AdtId(id) | TypeNs::AdtSelfType(id) => Adt::from(id).ty(db), TypeNs::EnumVariantId(id) => { // Enum variants don't have path candidates. - let variant = Variant::from(id); + let variant = EnumVariant::from(id); return resolve_field(db, variant.into(), name, ns); } TypeNs::TypeAliasId(id) => { @@ -443,7 +444,7 @@ fn resolve_assoc_or_field( .id .enum_variants(db) .variant(&name) - .map(|variant| DocLinkDef::ModuleDef(ModuleDef::Variant(variant.into()))); + .map(|variant| DocLinkDef::ModuleDef(ModuleDef::EnumVariant(variant.into()))); } }; resolve_field(db, variant_def, name, ns) @@ -505,7 +506,7 @@ fn resolve_impl_trait_item<'db>( fn resolve_field( db: &dyn HirDatabase, - def: VariantDef, + def: Variant, name: Name, ns: Option<Namespace>, ) -> Option<DocLinkDef> {
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index 050777a..7f672a6 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -51,20 +51,6 @@ fn from(d: $diag $(<$lt>)?) -> $AnyDiagnostic<$db> { )* }; } -// FIXME Accept something like the following in the macro call instead -// diagnostics![ -// pub struct BreakOutsideOfLoop { -// pub expr: InFile<AstPtr<ast::Expr>>, -// pub is_break: bool, -// pub bad_value_break: bool, -// }, ... -// or more concisely -// BreakOutsideOfLoop { -// expr: InFile<AstPtr<ast::Expr>>, -// is_break: bool, -// bad_value_break: bool, -// }, ... -// ] diagnostics![AnyDiagnostic<'db> -> AwaitOutsideOfAsync,
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 91fdcb8..4bfdd23 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -4,10 +4,13 @@ use hir_def::{ AdtId, BuiltinDeriveImplId, FunctionId, GenericDefId, ImplId, ItemContainerId, builtin_derive::BuiltinDeriveImplMethod, - expr_store::ExpressionStore, + expr_store::{Body, ExpressionStore}, hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_tree::FieldsShape, - signatures::{StaticFlags, TraitFlags}, + signatures::{ + ConstSignature, FunctionSignature, ImplSignature, StaticFlags, StaticSignature, TraitFlags, + TraitSignature, TypeAliasSignature, + }, type_ref::{TypeBound, TypeRef, TypeRefId}, }; use hir_expand::name::Name; @@ -26,9 +29,9 @@ use crate::{ Adt, AnyFunctionId, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum, - ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam, - Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, Type, - TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant, + EnumVariant, ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, + LifetimeParam, Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, + TupleField, Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, }; fn write_builtin_derive_impl_method<'db>( @@ -38,7 +41,7 @@ fn write_builtin_derive_impl_method<'db>( ) -> Result { let db = f.db; let loc = impl_.loc(db); - let (adt_params, _adt_params_store) = db.generic_params_and_store(loc.adt.into()); + let adt_params = GenericParams::of(db, loc.adt.into()); if f.show_container_bounds() && !adt_params.is_empty() { f.write_str("impl")?; @@ -94,22 +97,22 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { // Write container (trait or impl) let container_params = match container { ItemContainerId::TraitId(trait_) => { - let (params, params_store) = f.db.generic_params_and_store(trait_.into()); + let (params, params_store) = GenericParams::with_store(f.db, trait_.into()); if f.show_container_bounds() && !params.is_empty() { write_trait_header(trait_.into(), f)?; f.write_char('\n')?; - has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) + has_disaplayable_predicates(f.db, params, params_store) .then_some((params, params_store)) } else { None } } ItemContainerId::ImplId(impl_) => { - let (params, params_store) = f.db.generic_params_and_store(impl_.into()); + let (params, params_store) = GenericParams::with_store(f.db, impl_.into()); if f.show_container_bounds() && !params.is_empty() { write_impl_header(impl_, f)?; f.write_char('\n')?; - has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) + has_disaplayable_predicates(f.db, params, params_store) .then_some((params, params_store)) } else { None @@ -131,7 +134,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { _ => unreachable!(), }; write!(f, "\n // Bounds from {container_name}:",)?; - write_where_predicates(&container_params, &container_params_store, f)?; + write_where_predicates(container_params, container_params_store, f)?; } Ok(()) } @@ -140,7 +143,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Result<bool> { let db = f.db; let func = Function::from(func_id); - let data = db.function_signature(func_id); + let data = FunctionSignature::of(db, func_id); let mut module = func.module(db); // Block-local impls are "hoisted" to the nearest (non-block) module. @@ -189,7 +192,7 @@ fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Re let comma = if too_long_param { ",\n " } else { ", " }; // FIXME: Use resolved `param.ty` once we no longer discard lifetimes - let body = db.body(func_id.into()); + let body = Body::of(db, func_id.into()); for (type_ref, param) in data.params.iter().zip(func.assoc_fn_params(db)).skip(skip_self) { if !first { f.write_str(comma)?; @@ -268,7 +271,7 @@ fn write_impl_header<'db>(impl_: ImplId, f: &mut HirFormatter<'_, 'db>) -> Resul let def_id = GenericDefId::ImplId(impl_); write_generic_params(def_id, f)?; - let impl_data = db.impl_signature(impl_); + let impl_data = ImplSignature::of(db, impl_); if let Some(target_trait) = &impl_data.target_trait { f.write_char(' ')?; hir_display_with_store(&impl_data.store[target_trait.path], &impl_data.store).hir_fmt(f)?; @@ -297,7 +300,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { } }, }; - let data = f.db.function_signature(func); + let data = FunctionSignature::of(f.db, func); let param = *data.params.first().unwrap(); match &data.store[param] { TypeRef::Path(p) if p.is_self_type() => f.write_str("self"), @@ -440,7 +443,7 @@ fn write_fields<'db>( } fn write_variants<'db>( - variants: &[Variant], + variants: &[EnumVariant], has_where_clause: bool, limit: usize, f: &mut HirFormatter<'_, 'db>, @@ -494,7 +497,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { } } -impl<'db> HirDisplay<'db> for Variant { +impl<'db> HirDisplay<'db> for EnumVariant { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?; let data = self.id.fields(f.db); @@ -569,7 +572,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { impl<'db> HirDisplay<'db> for TypeParam { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { - let params = f.db.generic_params(self.id.parent()); + let params = GenericParams::of(f.db, self.id.parent()); let param_data = ¶ms[self.id.local_id()]; let krate = self.id.parent().krate(f.db).id; let ty = self.ty(f.db).ty; @@ -657,7 +660,7 @@ fn write_generic_params_or_args<'db>( f: &mut HirFormatter<'_, 'db>, include_defaults: bool, ) -> Result { - let (params, store) = f.db.generic_params_and_store(def); + let (params, store) = GenericParams::with_store(f.db, def); if params.iter_lt().next().is_none() && params.iter_type_or_consts().all(|it| it.1.const_param().is_none()) && params @@ -693,17 +696,17 @@ fn write_generic_params_or_args<'db>( write!(f, "{}", name.display(f.db, f.edition()))?; if include_defaults && let Some(default) = &ty.default { f.write_str(" = ")?; - default.hir_fmt(f, &store)?; + default.hir_fmt(f, store)?; } } TypeOrConstParamData::ConstParamData(c) => { delim(f)?; write!(f, "const {}: ", name.display(f.db, f.edition()))?; - c.ty.hir_fmt(f, &store)?; + c.ty.hir_fmt(f, store)?; if include_defaults && let Some(default) = &c.default { f.write_str(" = ")?; - default.hir_fmt(f, &store)?; + default.hir_fmt(f, store)?; } } } @@ -715,13 +718,13 @@ fn write_generic_params_or_args<'db>( } fn write_where_clause<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result<bool> { - let (params, store) = f.db.generic_params_and_store(def); - if !has_disaplayable_predicates(f.db, ¶ms, &store) { + let (params, store) = GenericParams::with_store(f.db, def); + if !has_disaplayable_predicates(f.db, params, store) { return Ok(false); } f.write_str("\nwhere")?; - write_where_predicates(¶ms, &store, f)?; + write_where_predicates(params, store, f)?; Ok(true) } @@ -736,7 +739,7 @@ fn has_disaplayable_predicates( pred, WherePredicate::TypeBound { target, .. } if matches!(store[*target], - TypeRef::TypeParam(id) if db.generic_params(id.parent())[id.local_id()].name().is_none() + TypeRef::TypeParam(id) if GenericParams::of(db,id.parent())[id.local_id()].name().is_none() ) ) }) @@ -752,7 +755,7 @@ fn write_where_predicates<'db>( // unnamed type targets are displayed inline with the argument itself, e.g. `f: impl Y`. let is_unnamed_type_target = |target: TypeRefId| { matches!(store[target], - TypeRef::TypeParam(id) if f.db.generic_params(id.parent())[id.local_id()].name().is_none() + TypeRef::TypeParam(id) if GenericParams::of(f.db,id.parent())[id.local_id()].name().is_none() ) }; @@ -816,7 +819,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { module = module.nearest_non_block_module(db); } write_visibility(module.id, self.visibility(db), f)?; - let data = db.const_signature(self.id); + let data = ConstSignature::of(db, self.id); f.write_str("const ")?; match &data.name { Some(name) => write!(f, "{}: ", name.display(f.db, f.edition()))?, @@ -830,7 +833,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { impl<'db> HirDisplay<'db> for Static { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; - let data = f.db.static_signature(self.id); + let data = StaticSignature::of(f.db, self.id); f.write_str("static ")?; if data.flags.contains(StaticFlags::MUTABLE) { f.write_str("mut ")?; @@ -889,7 +892,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?; - let data = f.db.trait_signature(trait_.id); + let data = TraitSignature::of(f.db, trait_.id); if data.flags.contains(TraitFlags::UNSAFE) { f.write_str("unsafe ")?; } @@ -904,7 +907,7 @@ fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Resu impl<'db> HirDisplay<'db> for TypeAlias { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; - let data = f.db.type_alias_signature(self.id); + let data = TypeAliasSignature::of(f.db, self.id); write!(f, "type {}", data.name.display(f.db, f.edition()))?; let def_id = GenericDefId::TypeAliasId(self.id); write_generic_params(def_id, f)?;
diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs index fc20f4b..0a48be5 100644 --- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs +++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs
@@ -4,15 +4,15 @@ //! are splitting the hir. use hir_def::{ - AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, - GenericParamId, ModuleDefId, VariantId, + AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, + FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, ModuleDefId, VariantId, hir::{BindingId, LabelId}, }; use hir_ty::next_solver::AnyImplId; use crate::{ - Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, Field, GenericDef, GenericParam, - ItemInNs, Label, Local, ModuleDef, Variant, VariantDef, + Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, EnumVariant, ExpressionStoreOwner, + Field, Function, GenericDef, GenericParam, Impl, ItemInNs, Label, Local, ModuleDef, Variant, }; macro_rules! from_id { @@ -71,6 +71,15 @@ fn from(id: Adt) -> Self { } } +impl From<VariantId> for Variant { + fn from(v: VariantId) -> Self { + match v { + VariantId::EnumVariantId(it) => Variant::EnumVariant(it.into()), + VariantId::StructId(it) => Variant::Struct(it.into()), + VariantId::UnionId(it) => Variant::Union(it.into()), + } + } +} impl From<GenericParamId> for GenericParam { fn from(id: GenericParamId) -> Self { match id { @@ -91,14 +100,14 @@ fn from(id: GenericParam) -> Self { } } -impl From<EnumVariantId> for Variant { +impl From<EnumVariantId> for EnumVariant { fn from(id: EnumVariantId) -> Self { - Variant { id } + EnumVariant { id } } } -impl From<Variant> for EnumVariantId { - fn from(def: Variant) -> Self { +impl From<EnumVariant> for EnumVariantId { + fn from(def: EnumVariant) -> Self { def.id } } @@ -109,7 +118,7 @@ fn from(id: ModuleDefId) -> Self { ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), - ModuleDefId::EnumVariantId(it) => ModuleDef::Variant(it.into()), + ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()), ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), @@ -130,7 +139,7 @@ fn try_from(id: ModuleDef) -> Result<Self, Self::Error> { AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()), }, ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), - ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()), + ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()), ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), @@ -151,7 +160,7 @@ fn try_from(def: DefWithBody) -> Result<Self, ()> { }, DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id), DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id), - DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()), + DefWithBody::EnumVariant(it) => DefWithBodyId::VariantId(it.into()), }) } } @@ -162,7 +171,7 @@ fn from(def: DefWithBodyId) -> Self { DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()), DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()), DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()), - DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()), + DefWithBodyId::VariantId(it) => DefWithBody::EnumVariant(it.into()), } } } @@ -209,22 +218,12 @@ fn from(id: Adt) -> Self { } } -impl From<VariantId> for VariantDef { - fn from(def: VariantId) -> Self { +impl From<Variant> for VariantId { + fn from(def: Variant) -> Self { match def { - VariantId::StructId(it) => VariantDef::Struct(it.into()), - VariantId::EnumVariantId(it) => VariantDef::Variant(it.into()), - VariantId::UnionId(it) => VariantDef::Union(it.into()), - } - } -} - -impl From<VariantDef> for VariantId { - fn from(def: VariantDef) -> Self { - match def { - VariantDef::Struct(it) => VariantId::StructId(it.id), - VariantDef::Variant(it) => VariantId::EnumVariantId(it.into()), - VariantDef::Union(it) => VariantId::UnionId(it.id), + Variant::Struct(it) => VariantId::StructId(it.id), + Variant::EnumVariant(it) => VariantId::EnumVariantId(it.into()), + Variant::Union(it) => VariantId::UnionId(it.id), } } } @@ -255,14 +254,19 @@ fn try_from(item: AssocItem) -> Result<Self, Self::Error> { } } -impl From<(DefWithBodyId, BindingId)> for Local { - fn from((parent, binding_id): (DefWithBodyId, BindingId)) -> Self { +impl From<(ExpressionStoreOwnerId, BindingId)> for Local { + fn from((parent, binding_id): (ExpressionStoreOwnerId, BindingId)) -> Self { Local { parent, binding_id } } } +impl From<(DefWithBodyId, BindingId)> for Local { + fn from((parent, binding_id): (DefWithBodyId, BindingId)) -> Self { + Local { parent: parent.into(), binding_id } + } +} -impl From<(DefWithBodyId, LabelId)> for Label { - fn from((parent, label_id): (DefWithBodyId, LabelId)) -> Self { +impl From<(ExpressionStoreOwnerId, LabelId)> for Label { + fn from((parent, label_id): (ExpressionStoreOwnerId, LabelId)) -> Self { Label { parent, label_id } } } @@ -317,3 +321,43 @@ fn from(value: hir_def::FunctionId) -> Self { crate::Function { id: AnyFunctionId::FunctionId(value) } } } + +impl TryFrom<ExpressionStoreOwner> for ExpressionStoreOwnerId { + type Error = (); + + fn try_from(v: ExpressionStoreOwner) -> Result<Self, Self::Error> { + match v { + ExpressionStoreOwner::Signature(generic_def_id) => { + Ok(Self::Signature(generic_def_id.try_into()?)) + } + ExpressionStoreOwner::Body(def_with_body_id) => { + Ok(Self::Body(def_with_body_id.try_into()?)) + } + ExpressionStoreOwner::VariantFields(variant_id) => { + Ok(Self::VariantFields(variant_id.into())) + } + } + } +} + +impl TryFrom<Function> for FunctionId { + type Error = (); + + fn try_from(v: Function) -> Result<Self, Self::Error> { + match v.id { + AnyFunctionId::FunctionId(id) => Ok(id), + _ => Err(()), + } + } +} + +impl TryFrom<Impl> for ImplId { + type Error = (); + + fn try_from(v: Impl) -> Result<Self, Self::Error> { + match v.id { + AnyImplId::ImplId(id) => Ok(id), + _ => Err(()), + } + } +}
diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index e032a16..f9badc0 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs
@@ -3,6 +3,7 @@ use either::Either; use hir_def::{ CallableDefId, Lookup, MacroId, VariantId, + expr_store::ExpressionStore, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource as _}, }; @@ -12,9 +13,9 @@ use tt::TextRange; use crate::{ - Adt, AnyFunctionId, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, - InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, - Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, VariantDef, db::HirDatabase, + Adt, AnyFunctionId, Callee, Const, Enum, EnumVariant, ExternCrateDecl, Field, FieldSource, + Function, Impl, InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, + SelfParam, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, db::HirDatabase, }; pub trait HasSource: Sized { @@ -123,13 +124,13 @@ fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { } } } -impl HasSource for VariantDef { +impl HasSource for Variant { type Ast = ast::VariantDef; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { match self { - VariantDef::Struct(s) => Some(s.source(db)?.map(ast::VariantDef::Struct)), - VariantDef::Union(u) => Some(u.source(db)?.map(ast::VariantDef::Union)), - VariantDef::Variant(v) => Some(v.source(db)?.map(ast::VariantDef::Variant)), + Variant::Struct(s) => Some(s.source(db)?.map(ast::VariantDef::Struct)), + Variant::Union(u) => Some(u.source(db)?.map(ast::VariantDef::Union)), + Variant::EnumVariant(v) => Some(v.source(db)?.map(ast::VariantDef::Variant)), } } } @@ -151,7 +152,7 @@ fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { Some(self.id.lookup(db).source(db)) } } -impl HasSource for Variant { +impl HasSource for EnumVariant { type Ast = ast::Variant; fn source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Variant>> { Some(self.id.lookup(db).source(db)) @@ -293,7 +294,7 @@ fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { } Callee::Closure(closure, _) => { let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure); - let (_, source_map) = db.body_with_source_map(owner); + let (_, source_map) = ExpressionStore::with_source_map(db, owner); let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?; let root = db.parse_or_expand(file_id); match value.to_node(&root) { @@ -327,8 +328,7 @@ impl HasSource for Label { type Ast = ast::Label; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { - let (_body, source_map) = db.body_with_source_map(self.parent); - let src = source_map.label_syntax(self.label_id); + let src = ExpressionStore::with_source_map(db, self.parent).1.label_syntax(self.label_id); let root = src.file_syntax(db); src.map(|ast| ast.to_node(&root).left()).transpose() } @@ -345,7 +345,7 @@ fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { impl HasSource for InlineAsmOperand { type Ast = ast::AsmOperandNamed; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { - let source_map = db.body_with_source_map(self.owner).1; + let (_, source_map) = ExpressionStore::with_source_map(db, self.owner); if let Ok(src) = source_map.expr_syntax(self.expr) { let root = src.file_syntax(db); return src
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 0b3515f..bc5e164 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -49,16 +49,16 @@ use either::Either; use hir_def::{ AdtId, AssocItemId, AssocItemLoc, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, - DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, - HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, - MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UnionId, + DefWithBodyId, EnumId, EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, + FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, + Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UnionId, attrs::AttrFlags, builtin_derive::BuiltinDeriveImplMethod, - expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, + expr_store::{ExpressionStore, ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat, - generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, + generics::{GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, }, item_tree::ImportAlias, lang_item::LangItemTarget, @@ -69,7 +69,11 @@ }, per_ns::PerNs, resolver::{HasResolver, Resolver}, - signatures::{EnumSignature, ImplFlags, StaticFlags, StructFlags, TraitFlags, VariantFields}, + signatures::{ + ConstSignature, EnumSignature, FunctionSignature, ImplFlags, ImplSignature, StaticFlags, + StaticSignature, StructFlags, StructSignature, TraitFlags, TraitSignature, + TypeAliasSignature, UnionSignature, VariantFields, + }, src::HasSource as _, visibility::visibility_from_ast, }; @@ -141,6 +145,7 @@ Complete, FindPathConfig, attrs::{Docs, IsInnerDoc}, + expr_store::Body, find_path::PrefixKind, import_map, lang_item::{LangItemEnum as LangItem, crate_lang_items}, @@ -351,8 +356,7 @@ pub enum ModuleDef { Function(Function), Adt(Adt), // Can't be directly declared, but can be imported. - // FIXME: Rename to `EnumVariant` - Variant(Variant), + EnumVariant(EnumVariant), Const(Const), Static(Static), Trait(Trait), @@ -364,7 +368,7 @@ pub enum ModuleDef { Module, Function, Adt(Struct, Enum, Union), - Variant, + EnumVariant, Const, Static, Trait, @@ -374,12 +378,12 @@ pub enum ModuleDef { for ModuleDef ); -impl From<VariantDef> for ModuleDef { - fn from(var: VariantDef) -> Self { +impl From<Variant> for ModuleDef { + fn from(var: Variant) -> Self { match var { - VariantDef::Struct(t) => Adt::from(t).into(), - VariantDef::Union(t) => Adt::from(t).into(), - VariantDef::Variant(t) => t.into(), + Variant::Struct(t) => Adt::from(t).into(), + Variant::Union(t) => Adt::from(t).into(), + Variant::EnumVariant(t) => t.into(), } } } @@ -390,7 +394,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Option<Module> { ModuleDef::Module(it) => it.parent(db), ModuleDef::Function(it) => Some(it.module(db)), ModuleDef::Adt(it) => Some(it.module(db)), - ModuleDef::Variant(it) => Some(it.module(db)), + ModuleDef::EnumVariant(it) => Some(it.module(db)), ModuleDef::Const(it) => Some(it.module(db)), ModuleDef::Static(it) => Some(it.module(db)), ModuleDef::Trait(it) => Some(it.module(db)), @@ -423,7 +427,7 @@ pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { ModuleDef::Adt(it) => it.name(db), ModuleDef::Trait(it) => it.name(db), ModuleDef::Function(it) => it.name(db), - ModuleDef::Variant(it) => it.name(db), + ModuleDef::EnumVariant(it) => it.name(db), ModuleDef::TypeAlias(it) => it.name(db), ModuleDef::Static(it) => it.name(db), ModuleDef::Macro(it) => it.name(db), @@ -452,7 +456,7 @@ pub fn diagnostics<'db>( ModuleDef::Module(it) => it.id.into(), ModuleDef::Const(it) => it.id.into(), ModuleDef::Static(it) => it.id.into(), - ModuleDef::Variant(it) => it.id.into(), + ModuleDef::EnumVariant(it) => it.id.into(), ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(), }; @@ -481,7 +485,7 @@ pub fn as_def_with_body(self) -> Option<DefWithBody> { ModuleDef::Function(it) => Some(it.into()), ModuleDef::Const(it) => Some(it.into()), ModuleDef::Static(it) => Some(it.into()), - ModuleDef::Variant(it) => Some(it.into()), + ModuleDef::EnumVariant(it) => Some(it.into()), ModuleDef::Module(_) | ModuleDef::Adt(_) @@ -500,7 +504,7 @@ pub fn as_self_generic_def(self) -> Option<GenericDef> { ModuleDef::Trait(it) => Some(it.into()), ModuleDef::TypeAlias(it) => Some(it.into()), ModuleDef::Module(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::BuiltinType(_) @@ -508,12 +512,27 @@ pub fn as_self_generic_def(self) -> Option<GenericDef> { } } + pub fn as_generic_def(self) -> Option<GenericDef> { + match self { + ModuleDef::Function(it) => Some(it.into()), + ModuleDef::Adt(it) => Some(it.into()), + ModuleDef::Trait(it) => Some(it.into()), + ModuleDef::TypeAlias(it) => Some(it.into()), + ModuleDef::Static(it) => Some(it.into()), + ModuleDef::Const(it) => Some(it.into()), + ModuleDef::EnumVariant(_) + | ModuleDef::Module(_) + | ModuleDef::BuiltinType(_) + | ModuleDef::Macro(_) => None, + } + } + pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> { Some(match self { ModuleDef::Module(it) => it.attrs(db), ModuleDef::Function(it) => HasAttrs::attrs(*it, db), ModuleDef::Adt(it) => it.attrs(db), - ModuleDef::Variant(it) => it.attrs(db), + ModuleDef::EnumVariant(it) => it.attrs(db), ModuleDef::Const(it) => it.attrs(db), ModuleDef::Static(it) => it.attrs(db), ModuleDef::Trait(it) => it.attrs(db), @@ -543,7 +562,7 @@ fn visibility(&self, db: &dyn HirDatabase) -> Visibility { ModuleDef::Static(it) => it.visibility(db), ModuleDef::Trait(it) => it.visibility(db), ModuleDef::TypeAlias(it) => it.visibility(db), - ModuleDef::Variant(it) => it.visibility(db), + ModuleDef::EnumVariant(it) => it.visibility(db), ModuleDef::Macro(it) => it.visibility(db), ModuleDef::BuiltinType(_) => Visibility::Public, } @@ -714,8 +733,8 @@ pub fn diagnostics<'db>( ModuleDef::Adt(adt) => { match adt { Adt::Struct(s) => { - let source_map = db.struct_signature_with_source_map(s.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &StructSignature::with_source_map(db, s.id).1; + expr_store_diagnostics(db, acc, source_map); let source_map = &s.id.fields_with_source_map(db).1; expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( @@ -726,8 +745,8 @@ pub fn diagnostics<'db>( ); } Adt::Union(u) => { - let source_map = db.union_signature_with_source_map(u.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &UnionSignature::with_source_map(db, u.id).1; + expr_store_diagnostics(db, acc, source_map); let source_map = &u.id.fields_with_source_map(db).1; expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( @@ -738,8 +757,8 @@ pub fn diagnostics<'db>( ); } Adt::Enum(e) => { - let source_map = db.enum_signature_with_source_map(e.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &EnumSignature::with_source_map(db, e.id).1; + expr_store_diagnostics(db, acc, source_map); let (variants, diagnostics) = e.id.enum_variants_with_diagnostics(db); let file = e.id.lookup(db).id.file_id; let ast_id_map = db.ast_id_map(file); @@ -774,13 +793,13 @@ pub fn diagnostics<'db>( } ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m), ModuleDef::TypeAlias(type_alias) => { - let source_map = db.type_alias_signature_with_source_map(type_alias.id).1; - expr_store_diagnostics(db, acc, &source_map); + let source_map = &TypeAliasSignature::with_source_map(db, type_alias.id).1; + expr_store_diagnostics(db, acc, source_map); push_ty_diagnostics( db, acc, db.type_for_type_alias_with_diagnostics(type_alias.id).1, - &source_map, + source_map, ); acc.extend(def.diagnostics(db, style_lints)); } @@ -800,8 +819,8 @@ pub fn diagnostics<'db>( continue; }; let loc = impl_id.lookup(db); - let (impl_signature, source_map) = db.impl_signature_with_source_map(impl_id); - expr_store_diagnostics(db, acc, &source_map); + let (impl_signature, source_map) = ImplSignature::with_source_map(db, impl_id); + expr_store_diagnostics(db, acc, source_map); let file_id = loc.id.file_id; if file_id.macro_file().is_some_and(|it| it.kind(db) == MacroKind::DeriveBuiltIn) { @@ -873,9 +892,9 @@ pub fn diagnostics<'db>( if let (false, Some(trait_)) = (impl_is_negative, trait_) { let items = &trait_.id.trait_items(db).items; let required_items = items.iter().filter(|&(_, assoc)| match *assoc { - AssocItemId::FunctionId(it) => !db.function_signature(it).has_body(), - AssocItemId::ConstId(id) => !db.const_signature(id).has_body(), - AssocItemId::TypeAliasId(it) => db.type_alias_signature(it).ty.is_none(), + AssocItemId::FunctionId(it) => !FunctionSignature::of(db, it).has_body(), + AssocItemId::ConstId(id) => !ConstSignature::of(db, id).has_body(), + AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it).ty.is_none(), }); impl_assoc_items_scratch.extend(impl_id.impl_items(db).items.iter().cloned()); @@ -913,7 +932,7 @@ pub fn diagnostics<'db>( let self_ty = structurally_normalize_ty( &infcx, self_ty, - db.trait_environment(impl_id.into()), + db.trait_environment(GenericDefId::from(impl_id).into()), ); let self_ty_is_guaranteed_unsized = matches!( self_ty.kind(), @@ -968,7 +987,7 @@ pub fn diagnostics<'db>( continue; } - if db.function_signature(*fn_).is_default() { + if FunctionSignature::of(db, *fn_).is_default() { return false; } } @@ -992,12 +1011,12 @@ pub fn diagnostics<'db>( impl_assoc_items_scratch.clear(); } - push_ty_diagnostics(db, acc, db.impl_self_ty_with_diagnostics(impl_id).1, &source_map); + push_ty_diagnostics(db, acc, db.impl_self_ty_with_diagnostics(impl_id).1, source_map); push_ty_diagnostics( db, acc, db.impl_trait_with_diagnostics(impl_id).and_then(|it| it.1), - &source_map, + source_map, ); for &(_, item) in impl_id.impl_items(db).items.iter() { @@ -1280,7 +1299,7 @@ fn visibility(&self, db: &dyn HirDatabase) -> Visibility { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Field { - pub(crate) parent: VariantDef, + pub(crate) parent: Variant, pub(crate) id: LocalFieldId, } @@ -1304,7 +1323,7 @@ pub fn ty(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> { #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct TupleField { - pub owner: DefWithBodyId, + pub owner: ExpressionStoreOwnerId, pub tuple: TupleId, pub index: u32, } @@ -1316,7 +1335,7 @@ pub fn name(&self) -> Name { pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let interner = DbInterner::new_no_crate(db); - let ty = InferenceResult::for_body(db, self.owner) + let ty = InferenceResult::of(db, self.owner) .tuple_field_access_type(self.tuple) .as_slice() .get(self.index as usize) @@ -1386,9 +1405,9 @@ pub fn ty_with_args<'db>( ) -> Type<'db> { let var_id = self.parent.into(); let def_id: AdtId = match self.parent { - VariantDef::Struct(it) => it.id.into(), - VariantDef::Union(it) => it.id.into(), - VariantDef::Variant(it) => it.parent_enum(db).id.into(), + Variant::Struct(it) => it.id.into(), + Variant::Union(it) => it.id.into(), + Variant::EnumVariant(it) => it.parent_enum(db).id.into(), }; let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty)); @@ -1414,7 +1433,7 @@ pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap())) } - pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef { + pub fn parent_def(&self, _db: &dyn HirDatabase) -> Variant { self.parent } } @@ -1440,7 +1459,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.struct_signature(self.id).name.clone() + StructSignature::of(db, self.id).name.clone() } pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { @@ -1533,7 +1552,7 @@ pub struct Union { impl Union { pub fn name(self, db: &dyn HirDatabase) -> Name { - db.union_signature(self.id).name.clone() + UnionSignature::of(db, self.id).name.clone() } pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -1592,11 +1611,11 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.enum_signature(self.id).name.clone() + EnumSignature::of(db, self.id).name.clone() } - pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> { - self.id.enum_variants(db).variants.iter().map(|&(id, _, _)| Variant { id }).collect() + pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> { + self.id.enum_variants(db).variants.iter().map(|&(id, _, _)| EnumVariant { id }).collect() } pub fn num_variants(self, db: &dyn HirDatabase) -> usize { @@ -1688,19 +1707,18 @@ pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> { } } -impl From<&Variant> for DefWithBodyId { - fn from(&v: &Variant) -> Self { +impl From<&EnumVariant> for DefWithBodyId { + fn from(&v: &EnumVariant) -> Self { DefWithBodyId::VariantId(v.into()) } } -// FIXME: Rename to `EnumVariant` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Variant { +pub struct EnumVariant { pub(crate) id: EnumVariantId, } -impl Variant { +impl EnumVariant { pub fn module(self, db: &dyn HirDatabase) -> Module { Module { id: self.id.module(db) } } @@ -1737,7 +1755,7 @@ pub fn kind(self, db: &dyn HirDatabase) -> StructKind { } pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> { - self.source(db)?.value.expr() + self.source(db)?.value.const_arg()?.expr() } pub fn eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError> { @@ -1774,7 +1792,7 @@ pub fn instantiate_infer<'db>(self, infer_ctxt: &InferCtxt<'db>) -> Instantiated // FIXME: Rename to `EnumVariant` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct InstantiatedVariant<'db> { - pub(crate) inner: Variant, + pub(crate) inner: EnumVariant, pub(crate) args: GenericArgs<'db>, } @@ -1805,7 +1823,7 @@ pub enum StructKind { } /// Variants inherit visibility from the parent enum. -impl HasVisibility for Variant { +impl HasVisibility for EnumVariant { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { self.parent_enum(db).visibility(db) } @@ -1914,35 +1932,78 @@ fn visibility(&self, db: &dyn HirDatabase) -> Visibility { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum VariantDef { +pub enum Variant { Struct(Struct), Union(Union), - Variant(Variant), + EnumVariant(EnumVariant), } -impl_from!(Struct, Union, Variant for VariantDef); +impl_from!(Struct, Union, EnumVariant for Variant); -impl VariantDef { +impl Variant { pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { match self { - VariantDef::Struct(it) => it.fields(db), - VariantDef::Union(it) => it.fields(db), - VariantDef::Variant(it) => it.fields(db), + Variant::Struct(it) => it.fields(db), + Variant::Union(it) => it.fields(db), + Variant::EnumVariant(it) => it.fields(db), } } pub fn module(self, db: &dyn HirDatabase) -> Module { match self { - VariantDef::Struct(it) => it.module(db), - VariantDef::Union(it) => it.module(db), - VariantDef::Variant(it) => it.module(db), + Variant::Struct(it) => it.module(db), + Variant::Union(it) => it.module(db), + Variant::EnumVariant(it) => it.module(db), } } pub fn name(&self, db: &dyn HirDatabase) -> Name { match self { - VariantDef::Struct(s) => (*s).name(db), - VariantDef::Union(u) => (*u).name(db), - VariantDef::Variant(e) => (*e).name(db), + Variant::Struct(s) => (*s).name(db), + Variant::Union(u) => (*u).name(db), + Variant::EnumVariant(e) => (*e).name(db), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ExpressionStoreOwner { + Body(DefWithBody), + Signature(GenericDef), + VariantFields(Variant), +} + +impl From<GenericDef> for ExpressionStoreOwner { + fn from(v: GenericDef) -> Self { + Self::Signature(v) + } +} + +impl From<DefWithBody> for ExpressionStoreOwner { + fn from(v: DefWithBody) -> Self { + Self::Body(v) + } +} + +impl From<ExpressionStoreOwnerId> for ExpressionStoreOwner { + fn from(v: ExpressionStoreOwnerId) -> Self { + match v { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + Self::Signature(generic_def_id.into()) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => Self::Body(def_with_body_id.into()), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::VariantFields(variant_id.into()) + } + } + } +} + +impl ExpressionStoreOwner { + pub fn module(self, db: &dyn HirDatabase) -> Module { + match self { + Self::Body(body) => body.module(db), + Self::Signature(generic_def) => generic_def.module(db), + Self::VariantFields(variant) => variant.module(db), } } } @@ -1953,9 +2014,9 @@ pub enum DefWithBody { Function(Function), Static(Static), Const(Const), - Variant(Variant), + EnumVariant(EnumVariant), } -impl_from!(Function, Const, Static, Variant for DefWithBody); +impl_from!(Function, Const, Static, EnumVariant for DefWithBody); impl DefWithBody { pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -1963,7 +2024,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { DefWithBody::Const(c) => c.module(db), DefWithBody::Function(f) => f.module(db), DefWithBody::Static(s) => s.module(db), - DefWithBody::Variant(v) => v.module(db), + DefWithBody::EnumVariant(v) => v.module(db), } } @@ -1972,7 +2033,7 @@ pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { DefWithBody::Function(f) => Some(f.name(db)), DefWithBody::Static(s) => Some(s.name(db)), DefWithBody::Const(c) => c.name(db), - DefWithBody::Variant(v) => Some(v.name(db)), + DefWithBody::EnumVariant(v) => Some(v.name(db)), } } @@ -1982,7 +2043,7 @@ pub fn body_type(self, db: &dyn HirDatabase) -> Type<'_> { DefWithBody::Function(it) => it.ret_type(db), DefWithBody::Static(it) => it.ty(db), DefWithBody::Const(it) => it.ty(db), - DefWithBody::Variant(it) => it.parent_enum(db).variant_body_ty(db), + DefWithBody::EnumVariant(it) => it.parent_enum(db).variant_body_ty(db), } } @@ -1994,7 +2055,7 @@ fn id(&self) -> Option<DefWithBodyId> { }, DefWithBody::Static(it) => it.id.into(), DefWithBody::Const(it) => it.id.into(), - DefWithBody::Variant(it) => it.into(), + DefWithBody::EnumVariant(it) => it.into(), }) } @@ -2003,7 +2064,7 @@ pub fn debug_hir(self, db: &dyn HirDatabase) -> String { let Some(id) = self.id() else { return String::new(); }; - let body = db.body(id); + let body = Body::of(db, id); body.pretty_print(db, id, Edition::CURRENT) } @@ -2030,17 +2091,17 @@ pub fn diagnostics<'db>( }; let krate = self.module(db).id.krate(db); - let (body, source_map) = db.body_with_source_map(id); + let (body, source_map) = Body::with_source_map(db, id); let sig_source_map = match self { DefWithBody::Function(id) => match id.id { - AnyFunctionId::FunctionId(id) => db.function_signature_with_source_map(id).1, + AnyFunctionId::FunctionId(id) => &FunctionSignature::with_source_map(db, id).1, AnyFunctionId::BuiltinDeriveImplMethod { .. } => return, }, - DefWithBody::Static(id) => db.static_signature_with_source_map(id.into()).1, - DefWithBody::Const(id) => db.const_signature_with_source_map(id.into()).1, - DefWithBody::Variant(variant) => { + DefWithBody::Static(id) => &StaticSignature::with_source_map(db, id.into()).1, + DefWithBody::Const(id) => &ConstSignature::with_source_map(db, id.into()).1, + DefWithBody::EnumVariant(variant) => { let enum_id = variant.parent_enum(db).id; - db.enum_signature_with_source_map(enum_id).1 + &EnumSignature::with_source_map(db, enum_id).1 } }; @@ -2048,17 +2109,11 @@ pub fn diagnostics<'db>( Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints); } - expr_store_diagnostics(db, acc, &source_map); + expr_store_diagnostics(db, acc, source_map); - let infer = InferenceResult::for_body(db, id); + let infer = InferenceResult::of(db, id); for d in infer.diagnostics() { - acc.extend(AnyDiagnostic::inference_diagnostic( - db, - id, - d, - &source_map, - &sig_source_map, - )); + acc.extend(AnyDiagnostic::inference_diagnostic(db, id, d, source_map, sig_source_map)); } for (pat_or_expr, mismatch) in infer.type_mismatches() { @@ -2180,7 +2235,7 @@ pub fn diagnostics<'db>( { need_mut = &mir::MutabilityReason::Not; } - let local = Local { parent: id, binding_id }; + let local = Local { parent: id.into(), binding_id }; let is_mut = body[binding_id].mode == BindingAnnotation::Mutable; match (need_mut, is_mut) { @@ -2237,7 +2292,7 @@ pub fn diagnostics<'db>( } for diagnostic in BodyValidationDiagnostic::collect(db, id, style_lints) { - acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, &source_map)); + acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, source_map)); } for diag in hir_ty::diagnostics::incorrect_case(db, id.into()) { @@ -2251,7 +2306,7 @@ pub fn expression_types<'db>( db: &'db dyn HirDatabase, ) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.expression_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2261,7 +2316,7 @@ pub fn expression_types<'db>( /// Returns an iterator over the inferred types of all patterns in this body. pub fn pattern_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.pattern_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2271,7 +2326,7 @@ pub fn pattern_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item /// Returns an iterator over the inferred types of all bindings in this body. pub fn binding_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> { self.id().into_iter().flat_map(move |def_id| { - let infer = InferenceResult::for_body(db, def_id); + let infer = InferenceResult::of(db, def_id); let resolver = def_id.resolver(db); infer.binding_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) @@ -2339,7 +2394,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { pub fn name(self, db: &dyn HirDatabase) -> Name { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).name.clone(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).name.clone(), AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => { Name::new_symbol_root(method.name()) } @@ -2541,7 +2596,7 @@ pub fn async_ret_type<'db>(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).has_self_param(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_self_param(), AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method { BuiltinDeriveImplMethod::clone | BuiltinDeriveImplMethod::fmt @@ -2576,7 +2631,7 @@ pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param<'_>> { pub fn num_params(self, db: &dyn HirDatabase) -> usize { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).params.len(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).params.len(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => { self.fn_sig(db).1.skip_binder().inputs().len() } @@ -2620,21 +2675,21 @@ pub fn params_without_self_with_args<'db>( pub fn is_const(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_const(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_const(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } pub fn is_async(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_async(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_async(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } pub fn is_varargs(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).is_varargs(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_varargs(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } } @@ -2687,7 +2742,7 @@ pub fn is_main(self, db: &dyn HirDatabase) -> bool { AnyFunctionId::FunctionId(id) => { self.exported_main(db) || self.module(db).is_crate_root(db) - && db.function_signature(id).name == sym::main + && FunctionSignature::of(db, id).name == sym::main } AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, } @@ -2764,7 +2819,7 @@ pub fn is_unsafe_to_call( /// This is false in the case of required (not provided) trait methods. pub fn has_body(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyFunctionId::FunctionId(id) => db.function_signature(id).has_body(), + AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_body(), AnyFunctionId::BuiltinDeriveImplMethod { .. } => true, } } @@ -2792,7 +2847,7 @@ pub fn eval( id.into(), GenericArgs::empty(interner).store(), ParamEnvAndCrate { - param_env: db.trait_environment(id.into()), + param_env: db.trait_environment(GenericDefId::from(id).into()), krate: id.module(db).krate(db), } .store(), @@ -2878,24 +2933,26 @@ pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> { match self.func { Callee::Def(CallableDefId::FunctionId(it)) => { let parent = DefWithBodyId::FunctionId(it); - let body = db.body(parent); + let body = Body::of(db, parent); if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { - Some(Local { parent, binding_id: self_param }) + Some(Local { parent: parent.into(), binding_id: self_param }) } else if let Pat::Bind { id, .. } = &body[body.params[self.idx - body.self_param.is_some() as usize]] { - Some(Local { parent, binding_id: *id }) + Some(Local { parent: parent.into(), binding_id: *id }) } else { None } } Callee::Closure(closure, _) => { let c = db.lookup_intern_closure(closure); - let body = db.body(c.0); - if let Expr::Closure { args, .. } = &body[c.1] - && let Pat::Bind { id, .. } = &body[args[self.idx]] + let body_owner = c.0; + let store = ExpressionStore::of(db, c.0); + + if let Expr::Closure { args, .. } = &store[c.1] + && let Pat::Bind { id, .. } = &store[args[self.idx]] { - return Some(Local { parent: c.0, binding_id: *id }); + return Some(Local { parent: body_owner, binding_id: *id }); } None } @@ -2917,7 +2974,7 @@ impl SelfParam { pub fn access(self, db: &dyn HirDatabase) -> Access { match self.func.id { AnyFunctionId::FunctionId(id) => { - let func_data = db.function_signature(id); + let func_data = FunctionSignature::of(db, id); func_data .params .first() @@ -3046,7 +3103,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { } pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { - db.const_signature(self.id).name.clone() + ConstSignature::of(db, self.id).name.clone() } pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> { @@ -3119,11 +3176,11 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.static_signature(self.id).name.clone() + StaticSignature::of(db, self.id).name.clone() } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { - db.static_signature(self.id).flags.contains(StaticFlags::MUTABLE) + StaticSignature::of(db, self.id).flags.contains(StaticFlags::MUTABLE) } pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> { @@ -3179,7 +3236,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.trait_signature(self.id).name.clone() + TraitSignature::of(db, self.id).name.clone() } pub fn direct_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> { @@ -3209,11 +3266,11 @@ pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem> { } pub fn is_auto(self, db: &dyn HirDatabase) -> bool { - db.trait_signature(self.id).flags.contains(TraitFlags::AUTO) + TraitSignature::of(db, self.id).flags.contains(TraitFlags::AUTO) } pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool { - db.trait_signature(self.id).flags.contains(TraitFlags::UNSAFE) + TraitSignature::of(db, self.id).flags.contains(TraitFlags::UNSAFE) } pub fn type_or_const_param_count( @@ -3221,7 +3278,7 @@ pub fn type_or_const_param_count( db: &dyn HirDatabase, count_required_only: bool, ) -> usize { - db.generic_params(self.id.into()) + GenericParams::of(db,self.id.into()) .iter_type_or_consts() .filter(|(_, ty)| !matches!(ty, TypeOrConstParamData::TypeParamData(ty) if ty.provenance != TypeParamProvenance::TypeParamList)) .filter(|(_, ty)| !count_required_only || !ty.has_default()) @@ -3289,7 +3346,7 @@ pub fn ty_params(self, db: &dyn HirDatabase) -> Type<'_> { } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.type_alias_signature(self.id).name.clone() + TypeAliasSignature::of(db, self.id).name.clone() } } @@ -3731,7 +3788,18 @@ fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> { match self { DefWithBody::Function(it) => it.as_assoc_item(db), DefWithBody::Const(it) => it.as_assoc_item(db), - DefWithBody::Static(_) | DefWithBody::Variant(_) => None, + DefWithBody::Static(_) | DefWithBody::EnumVariant(_) => None, + } + } +} + +impl AsAssocItem for GenericDef { + fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> { + match self { + GenericDef::Function(it) => it.as_assoc_item(db), + GenericDef::Const(it) => it.as_assoc_item(db), + GenericDef::TypeAlias(it) => it.as_assoc_item(db), + _ => None, } } } @@ -3918,7 +3986,7 @@ pub fn diagnostics<'db>( db, acc, db.type_for_type_alias_with_diagnostics(type_alias.id).1, - &db.type_alias_signature_with_source_map(type_alias.id).1, + &TypeAliasSignature::with_source_map(db, type_alias.id).1, ); for diag in hir_ty::diagnostics::incorrect_case(db, type_alias.id.into()) { acc.push(diag.into()); @@ -3971,12 +4039,36 @@ pub enum GenericDef { ); impl GenericDef { + pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { + match self { + GenericDef::Function(it) => Some(it.name(db)), + GenericDef::Adt(it) => Some(it.name(db)), + GenericDef::Trait(it) => Some(it.name(db)), + GenericDef::TypeAlias(it) => Some(it.name(db)), + GenericDef::Impl(_) => None, + GenericDef::Const(it) => it.name(db), + GenericDef::Static(it) => Some(it.name(db)), + } + } + + pub fn module(self, db: &dyn HirDatabase) -> Module { + match self { + GenericDef::Function(it) => it.module(db), + GenericDef::Adt(it) => it.module(db), + GenericDef::Trait(it) => it.module(db), + GenericDef::TypeAlias(it) => it.module(db), + GenericDef::Impl(it) => it.module(db), + GenericDef::Const(it) => it.module(db), + GenericDef::Static(it) => it.module(db), + } + } + pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> { let Ok(id) = self.try_into() else { // Let's pretend builtin derive impls don't have generic parameters. return Vec::new(); }; - let generics = db.generic_params(id); + let generics = GenericParams::of(db, id); let ty_params = generics.iter_type_or_consts().map(|(local_id, _)| { let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: id, local_id } }; match toc.split(db) { @@ -3996,7 +4088,7 @@ pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam> { // Let's pretend builtin derive impls don't have generic parameters. return Vec::new(); }; - let generics = db.generic_params(id); + let generics = GenericParams::of(db, id); generics .iter_lt() .map(|(local_id, _)| LifetimeParam { id: LifetimeParamId { parent: id, local_id } }) @@ -4008,7 +4100,7 @@ pub fn type_or_const_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> // Let's pretend builtin derive impls don't have generic parameters. return Vec::new(); }; - let generics = db.generic_params(id); + let generics = GenericParams::of(db, id); generics .iter_type_or_consts() .map(|(local_id, _)| TypeOrConstParam { @@ -4038,31 +4130,31 @@ fn id(self) -> Option<GenericDefId> { pub fn diagnostics<'db>(self, db: &'db dyn HirDatabase, acc: &mut Vec<AnyDiagnostic<'db>>) { let Some(def) = self.id() else { return }; - let generics = db.generic_params(def); + let generics = GenericParams::of(db, def); if generics.is_empty() && generics.has_no_predicates() { return; } let source_map = match def { - GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature_with_source_map(it).1, - GenericDefId::AdtId(AdtId::StructId(it)) => db.struct_signature_with_source_map(it).1, - GenericDefId::AdtId(AdtId::UnionId(it)) => db.union_signature_with_source_map(it).1, + GenericDefId::AdtId(AdtId::EnumId(it)) => &EnumSignature::with_source_map(db, it).1, + GenericDefId::AdtId(AdtId::StructId(it)) => &StructSignature::with_source_map(db, it).1, + GenericDefId::AdtId(AdtId::UnionId(it)) => &UnionSignature::with_source_map(db, it).1, GenericDefId::ConstId(_) => return, - GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1, - GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1, + GenericDefId::FunctionId(it) => &FunctionSignature::with_source_map(db, it).1, + GenericDefId::ImplId(it) => &ImplSignature::with_source_map(db, it).1, GenericDefId::StaticId(_) => return, - GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1, - GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1, + GenericDefId::TraitId(it) => &TraitSignature::with_source_map(db, it).1, + GenericDefId::TypeAliasId(it) => &TypeAliasSignature::with_source_map(db, it).1, }; - expr_store_diagnostics(db, acc, &source_map); - push_ty_diagnostics(db, acc, db.generic_defaults_with_diagnostics(def).1, &source_map); + expr_store_diagnostics(db, acc, source_map); + push_ty_diagnostics(db, acc, db.generic_defaults_with_diagnostics(def).1, source_map); push_ty_diagnostics( db, acc, GenericPredicates::query_with_diagnostics(db, def).1.clone(), - &source_map, + source_map, ); for (param_id, param) in generics.iter_type_or_consts() { if let TypeOrConstParamData::ConstParamData(_) = param { @@ -4073,7 +4165,7 @@ pub fn diagnostics<'db>(self, db: &'db dyn HirDatabase, acc: &mut Vec<AnyDiagnos TypeOrConstParamId { parent: def, local_id: param_id }, )) .1, - &source_map, + source_map, ); } } @@ -4134,7 +4226,7 @@ pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> { _ => None, }) .map(|container| { - db.generic_params(container) + GenericParams::of(db, container) .iter_type_or_consts() .filter_map(|param| match param.1 { TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()), @@ -4142,7 +4234,7 @@ pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> { }) .collect::<Vec<_>>() }); - let generics = db.generic_params(self.def); + let generics = GenericParams::of(db, self.def); let type_params = generics.iter_type_or_consts().filter_map(|param| match param.1 { TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()), TypeOrConstParamData::ConstParamData(_) => None, @@ -4170,7 +4262,7 @@ pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> { /// A single local definition. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Local { - pub(crate) parent: DefWithBodyId, + pub(crate) parent: ExpressionStoreOwnerId, pub(crate) binding_id: BindingId, } @@ -4232,7 +4324,7 @@ pub fn is_param(self, db: &dyn HirDatabase) -> bool { pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { match self.parent { - DefWithBodyId::FunctionId(func) if self.is_self(db) => { + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) if self.is_self(db) => { Some(SelfParam { func: func.into() }) } _ => None, @@ -4240,8 +4332,7 @@ pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { } pub fn name(self, db: &dyn HirDatabase) -> Name { - let body = db.body(self.parent); - body[self.binding_id].name.clone() + ExpressionStore::of(db, self.parent)[self.binding_id].name.clone() } pub fn is_self(self, db: &dyn HirDatabase) -> bool { @@ -4249,16 +4340,17 @@ pub fn is_self(self, db: &dyn HirDatabase) -> bool { } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { - let body = db.body(self.parent); - body[self.binding_id].mode == BindingAnnotation::Mutable + ExpressionStore::of(db, self.parent)[self.binding_id].mode == BindingAnnotation::Mutable } pub fn is_ref(self, db: &dyn HirDatabase) -> bool { - let body = db.body(self.parent); - matches!(body[self.binding_id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) + matches!( + ExpressionStore::of(db, self.parent)[self.binding_id].mode, + BindingAnnotation::Ref | BindingAnnotation::RefMut + ) } - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.parent.into() } @@ -4272,67 +4364,91 @@ pub fn as_id(self) -> u32 { pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; - let infer = InferenceResult::for_body(db, def); + let infer = InferenceResult::of(db, def); let ty = infer.binding_ty(self.binding_id); Type::new(db, def, ty) } /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;` pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> { - let (body, source_map) = db.body_with_source_map(self.parent); - match body.self_param.zip(source_map.self_param_syntax()) { - Some((param, source)) if param == self.binding_id => { - let root = source.file_syntax(db); - vec![LocalSource { - local: self, - source: source.map(|ast| Either::Right(ast.to_node(&root))), - }] + let b; + let (_, source_map) = match self.parent { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::with_source_map(db, generic_def_id.into()) } - _ => source_map - .patterns_for_binding(self.binding_id) - .iter() - .map(|&definition| { - let src = source_map.pat_syntax(definition).unwrap(); // Hmm... - let root = src.file_syntax(db); - LocalSource { + ExpressionStoreOwnerId::Body(def_with_body_id) => { + b = Body::with_source_map(db, def_with_body_id); + if let Some((param, source)) = b.0.self_param.zip(b.1.self_param_syntax()) + && param == self.binding_id + { + let root = source.file_syntax(db); + return vec![LocalSource { local: self, - source: src.map(|ast| match ast.to_node(&root) { - Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), - _ => unreachable!("local with non ident-pattern"), - }), - } - }) - .collect(), - } + source: source.map(|ast| Either::Right(ast.to_node(&root))), + }]; + } + (&b.0.store, &b.1.store) + } + ExpressionStoreOwnerId::VariantFields(def) => { + ExpressionStore::with_source_map(db, def.into()) + } + }; + source_map + .patterns_for_binding(self.binding_id) + .iter() + .map(|&definition| { + let src = source_map.pat_syntax(definition).unwrap(); // Hmm... + let root = src.file_syntax(db); + LocalSource { + local: self, + source: src.map(|ast| match ast.to_node(&root) { + Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), + _ => unreachable!("local with non ident-pattern"), + }), + } + }) + .collect() } /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;` pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource { - let (body, source_map) = db.body_with_source_map(self.parent); - match body.self_param.zip(source_map.self_param_syntax()) { - Some((param, source)) if param == self.binding_id => { - let root = source.file_syntax(db); + let b; + let (_, source_map) = match self.parent { + ExpressionStoreOwnerId::Signature(generic_def_id) => { + ExpressionStore::with_source_map(db, generic_def_id.into()) + } + ExpressionStoreOwnerId::Body(def_with_body_id) => { + b = Body::with_source_map(db, def_with_body_id); + if let Some((param, source)) = b.0.self_param.zip(b.1.self_param_syntax()) + && param == self.binding_id + { + let root = source.file_syntax(db); + return LocalSource { + local: self, + source: source.map(|ast| Either::Right(ast.to_node(&root))), + }; + } + (&b.0.store, &b.1.store) + } + ExpressionStoreOwnerId::VariantFields(def) => { + ExpressionStore::with_source_map(db, def.into()) + } + }; + source_map + .patterns_for_binding(self.binding_id) + .first() + .map(|&definition| { + let src = source_map.pat_syntax(definition).unwrap(); // Hmm... + let root = src.file_syntax(db); LocalSource { local: self, - source: source.map(|ast| Either::Right(ast.to_node(&root))), + source: src.map(|ast| match ast.to_node(&root) { + Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), + _ => unreachable!("local with non ident-pattern"), + }), } - } - _ => source_map - .patterns_for_binding(self.binding_id) - .first() - .map(|&definition| { - let src = source_map.pat_syntax(definition).unwrap(); // Hmm... - let root = src.file_syntax(db); - LocalSource { - local: self, - source: src.map(|ast| match ast.to_node(&root) { - Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it), - _ => unreachable!("local with non ident-pattern"), - }), - } - }) - .unwrap(), - } + }) + .unwrap() } } @@ -4417,7 +4533,7 @@ pub fn krate(&self) -> Crate { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Label { - pub(crate) parent: DefWithBodyId, + pub(crate) parent: ExpressionStoreOwnerId, pub(crate) label_id: LabelId, } @@ -4426,13 +4542,12 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { self.parent(db).module(db) } - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.parent.into() } pub fn name(self, db: &dyn HirDatabase) -> Name { - let body = db.body(self.parent); - body[self.label_id].name.clone() + ExpressionStore::of(db, self.parent)[self.label_id].name.clone() } } @@ -4543,7 +4658,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module { /// Is this type parameter implicitly introduced (eg. `Self` in a trait or an `impl Trait` /// argument)? pub fn is_implicit(self, db: &dyn HirDatabase) -> bool { - let params = db.generic_params(self.id.parent()); + let params = GenericParams::of(db, self.id.parent()); let data = ¶ms[self.id.local_id()]; match data.type_param().unwrap().provenance { TypeParamProvenance::TypeParamList => false, @@ -4598,7 +4713,7 @@ pub struct LifetimeParam { impl LifetimeParam { pub fn name(self, db: &dyn HirDatabase) -> Name { - let params = db.generic_params(self.id.parent); + let params = GenericParams::of(db, self.id.parent); params[self.id.local_id].name.clone() } @@ -4622,7 +4737,7 @@ pub fn merge(self) -> TypeOrConstParam { } pub fn name(self, db: &dyn HirDatabase) -> Name { - let params = db.generic_params(self.id.parent()); + let params = GenericParams::of(db, self.id.parent()); match params[self.id.local_id()].name() { Some(it) => it.clone(), None => { @@ -4669,7 +4784,7 @@ pub struct TypeOrConstParam { impl TypeOrConstParam { pub fn name(self, db: &dyn HirDatabase) -> Name { - let params = db.generic_params(self.id.parent); + let params = GenericParams::of(db, self.id.parent); match params[self.id.local_id].name() { Some(n) => n.clone(), _ => Name::missing(), @@ -4685,7 +4800,7 @@ pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { } pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> { - let params = db.generic_params(self.id.parent); + let params = GenericParams::of(db, self.id.parent); match ¶ms[self.id.local_id] { TypeOrConstParamData::TypeParamData(_) => { Either::Right(TypeParam { id: TypeParamId::from_unchecked(self.id) }) @@ -4704,7 +4819,7 @@ pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { } pub fn as_type_param(self, db: &dyn HirDatabase) -> Option<TypeParam> { - let params = db.generic_params(self.id.parent); + let params = GenericParams::of(db, self.id.parent); match ¶ms[self.id.local_id] { TypeOrConstParamData::TypeParamData(_) => { Some(TypeParam { id: TypeParamId::from_unchecked(self.id) }) @@ -4714,7 +4829,7 @@ pub fn as_type_param(self, db: &dyn HirDatabase) -> Option<TypeParam> { } pub fn as_const_param(self, db: &dyn HirDatabase) -> Option<ConstParam> { - let params = db.generic_params(self.id.parent); + let params = GenericParams::of(db, self.id.parent); match ¶ms[self.id.local_id] { TypeOrConstParamData::TypeParamData(_) => None, TypeOrConstParamData::ConstParamData(_) => { @@ -4741,7 +4856,7 @@ fn extend_with_def_map(db: &dyn HirDatabase, def_map: &DefMap, result: &mut Vec< result.extend(module.scope.builtin_derive_impls().map(Impl::from)); for unnamed_const in module.scope.unnamed_consts() { - for (_, block_def_map) in db.body(unnamed_const.into()).blocks(db) { + for (_, block_def_map) in Body::of(db, unnamed_const.into()).blocks(db) { extend_with_def_map(db, block_def_map, result); } } @@ -4898,14 +5013,14 @@ pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> { pub fn is_negative(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::NEGATIVE), + AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::NEGATIVE), AnyImplId::BuiltinDeriveImplId(_) => false, } } pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { match self.id { - AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::UNSAFE), + AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::UNSAFE), AnyImplId::BuiltinDeriveImplId(_) => false, } } @@ -5012,7 +5127,7 @@ pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db return Vec::new(); }; let owner = db.lookup_intern_closure(id).0; - let infer = InferenceResult::for_body(db, owner); + let infer = InferenceResult::of(db, owner); let info = infer.closure_info(id); info.0 .iter() @@ -5032,9 +5147,12 @@ pub fn capture_types(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> { return Vec::new(); }; let owner = db.lookup_intern_closure(id).0; - let infer = InferenceResult::for_body(db, owner); + let Some(body_owner) = owner.as_def_with_body() else { + return Vec::new(); + }; + let infer = InferenceResult::of(db, body_owner); let (captures, _) = infer.closure_info(id); - let env = body_param_env_from_has_crate(db, owner); + let env = body_param_env_from_has_crate(db, body_owner); captures.iter().map(|capture| Type { env, ty: capture.ty(db, self.subst) }).collect() } @@ -5042,7 +5160,10 @@ pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait { match self.id { AnyClosureId::ClosureId(id) => { let owner = db.lookup_intern_closure(id).0; - let infer = InferenceResult::for_body(db, owner); + let Some(body_owner) = owner.as_def_with_body() else { + return FnTrait::FnOnce; + }; + let infer = InferenceResult::of(db, body_owner); let info = infer.closure_info(id); info.1.into() } @@ -5125,7 +5246,7 @@ pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<Trait> { #[derive(Clone, Debug, PartialEq, Eq)] pub struct ClosureCapture<'db> { - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, closure: InternedClosureId, capture: hir_ty::CapturedItem, _marker: PhantomCovariantLifetime<'db>, @@ -5184,17 +5305,16 @@ pub enum CaptureKind { #[derive(Debug, Clone)] pub struct CaptureUsages { - parent: DefWithBodyId, + parent: ExpressionStoreOwnerId, spans: SmallVec<[mir::MirSpan; 3]>, } impl CaptureUsages { pub fn sources(&self, db: &dyn HirDatabase) -> Vec<CaptureUsageSource> { - let (body, source_map) = db.body_with_source_map(self.parent); - + let (body, source_map) = ExpressionStore::with_source_map(db, self.parent); let mut result = Vec::with_capacity(self.spans.len()); for &span in self.spans.iter() { - let is_ref = span.is_ref_span(&body); + let is_ref = span.is_ref_span(body); match span { mir::MirSpan::ExprId(expr) => { if let Ok(expr) = source_map.expr_syntax(expr) { @@ -5362,7 +5482,7 @@ pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool { fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool { match adt_id { AdtId::StructId(s) => { - let flags = db.struct_signature(s).flags; + let flags = StructSignature::of(db, s).flags; flags.contains(StructFlags::IS_PHANTOM_DATA) } AdtId::UnionId(_) | AdtId::EnumId(_) => false, @@ -5956,8 +6076,8 @@ fn with_method_resolution<R>( // for a nicer IDE experience. However, method resolution is always done on real code (either // existing code or code to be inserted), and there using PostAnalysis is dangerous - we may // suggest invalid methods. So we're using the TypingMode of the body we're in. - let typing_mode = if let Some(body_owner) = resolver.body_owner() { - TypingMode::analysis_in_body(interner, body_owner.into()) + let typing_mode = if let Some(store_owner) = resolver.expression_store_owner() { + TypingMode::analysis_in_body(interner, store_owner.into()) } else { TypingMode::non_body_analysis() }; @@ -6362,18 +6482,19 @@ pub fn is_bool(&self) -> bool { #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct InlineAsmOperand { - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, expr: ExprId, index: usize, } impl InlineAsmOperand { - pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner { self.owner.into() } pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> { - match &db.body(self.owner)[self.expr] { + let body = ExpressionStore::of(db, self.owner); + match &body[self.expr] { hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(), _ => None, } @@ -6403,7 +6524,7 @@ enum Callee<'db> { pub enum CallableKind<'db> { Function(Function), TupleStruct(Struct), - TupleEnumVariant(Variant), + TupleEnumVariant(EnumVariant), Closure(Closure<'db>), FnPtr, FnImpl(FnTrait), @@ -6753,7 +6874,7 @@ fn krate(&self, db: &dyn HirDatabase) -> Crate { } } -impl HasCrate for Variant { +impl HasCrate for EnumVariant { fn krate(&self, db: &dyn HirDatabase) -> Crate { self.module(db).krate(db) } @@ -6922,9 +7043,9 @@ fn name(&self, db: &dyn HirDatabase) -> Option<Name> { Struct, Union, Enum, - Variant, + EnumVariant, Adt, - VariantDef, + Variant, DefWithBody, Function, ExternCrateDecl, @@ -7113,7 +7234,7 @@ fn generic_args_from_tys<'db>( } fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool { - let params = db.generic_params(generic_def); + let params = GenericParams::of(db, generic_def); let defaults = db.generic_defaults(generic_def); params .iter_type_or_consts() @@ -7134,7 +7255,7 @@ fn param_env_from_resolver<'db>( ParamEnvAndCrate { param_env: resolver .generic_def() - .map_or_else(ParamEnv::empty, |generic_def| db.trait_environment(generic_def)), + .map_or_else(ParamEnv::empty, |generic_def| db.trait_environment(generic_def.into())), krate: resolver.krate(), } } @@ -7143,14 +7264,14 @@ fn param_env_from_has_crate<'db>( db: &'db dyn HirDatabase, id: impl hir_def::HasModule + Into<GenericDefId> + Copy, ) -> ParamEnvAndCrate<'db> { - ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(id.into().into()), krate: id.krate(db) } } fn body_param_env_from_has_crate<'db>( db: &'db dyn HirDatabase, - id: impl hir_def::HasModule + Into<DefWithBodyId> + Copy, + id: impl hir_def::HasModule + Into<ExpressionStoreOwnerId> + Copy, ) -> ParamEnvAndCrate<'db> { - ParamEnvAndCrate { param_env: db.trait_environment_for_body(id.into()), krate: id.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) } } fn empty_param_env<'db>(krate: base_db::Crate) -> ParamEnvAndCrate<'db> {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index c816fe9..4e9e3c4 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -13,9 +13,10 @@ use base_db::FxIndexSet; use either::Either; use hir_def::{ - BuiltinDeriveImplId, DefWithBodyId, HasModule, MacroId, StructId, TraitId, VariantId, + BuiltinDeriveImplId, DefWithBodyId, ExpressionStoreOwnerId, HasModule, MacroId, StructId, + TraitId, VariantId, attrs::parse_extra_crate_attrs, - expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, + expr_store::{Body, ExprOrPatSource, ExpressionStore, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, nameres::{ModuleOrigin, crate_def_map}, resolver::{self, HasResolver, Resolver, TypeNs, ValueNs}, @@ -31,7 +32,7 @@ }; use hir_ty::{ InferenceResult, - diagnostics::{unsafe_operations, unsafe_operations_for_body}, + diagnostics::unsafe_operations, infer_query_with_inspect, next_solver::{ AnyImplId, DbInterner, Span, @@ -54,10 +55,10 @@ use crate::{ Adjust, Adjustment, Adt, AnyFunctionId, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, - ConstParam, Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, - HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, - Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, Trait, - TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + ConstParam, Crate, DeriveHelper, Enum, EnumVariant, ExpressionStoreOwner, Field, Function, + GenericSubstitution, HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, + Local, Macro, Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, + Trait, TupleField, Type, TypeAlias, TypeParam, Union, Variant, db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{SourceAnalyzer, resolve_hir_path}, @@ -90,7 +91,7 @@ pub(crate) fn in_type_ns(&self) -> Option<TypeNs> { } PathResolution::Def( ModuleDef::Const(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Macro(_) | ModuleDef::Function(_) | ModuleDef::Module(_) @@ -367,8 +368,8 @@ pub fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option<Function> { self.imp.resolve_try_expr(try_expr) } - pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> { - self.imp.resolve_variant(record_lit).map(VariantDef::from) + pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<Variant> { + self.imp.resolve_variant(record_lit).map(Variant::from) } pub fn file_to_module_def(&self, file: impl Into<FileId>) -> Option<Module> { @@ -409,7 +410,7 @@ pub fn to_enum_def(&self, e: &ast::Enum) -> Option<Enum> { self.imp.to_def(e) } - pub fn to_enum_variant_def(&self, v: &ast::Variant) -> Option<Variant> { + pub fn to_enum_variant_def(&self, v: &ast::Variant) -> Option<EnumVariant> { self.imp.to_def(v) } @@ -785,16 +786,21 @@ pub fn speculative_expand_derive_as_pseudo_attr_macro( /// Checks if renaming `renamed` to `new_name` may introduce conflicts with other locals, /// and returns the conflicting locals. pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &Name) -> Vec<Local> { - let body = self.db.body(to_be_renamed.parent); + // FIXME: signatures + let Some(def) = to_be_renamed.parent.as_def_with_body() else { + return Vec::new(); + }; + let body = Body::of(self.db, def); let resolver = to_be_renamed.parent.resolver(self.db); - let starting_expr = body.binding_owner(to_be_renamed.binding_id).unwrap_or(body.body_expr); + let starting_expr = + body.binding_owner(to_be_renamed.binding_id).unwrap_or(body.root_expr()); let mut visitor = RenameConflictsVisitor { - body: &body, + body, conflicts: FxHashSet::default(), db: self.db, new_name: new_name.symbol().clone(), old_name: to_be_renamed.name(self.db).symbol().clone(), - owner: to_be_renamed.parent, + owner: def, to_be_renamed: to_be_renamed.binding_id, resolver, }; @@ -1913,36 +1919,32 @@ pub fn resolve_macro_call_arm(&self, macro_call: &ast::MacroCall) -> Option<u32> self.db.parse_macro_expansion(file_id).value.1.matched_arm } - pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet<ExprOrPatSource> { - let Ok(def) = DefWithBodyId::try_from(def) else { - return FxHashSet::default(); - }; - let (body, source_map) = self.db.body_with_source_map(def); - let infer = InferenceResult::for_body(self.db, def); + pub fn get_unsafe_ops(&self, def: ExpressionStoreOwner) -> FxHashSet<ExprOrPatSource> { + let Ok(def) = ExpressionStoreOwnerId::try_from(def) else { return Default::default() }; + let (body, source_map) = ExpressionStore::with_source_map(self.db, def); + let infer = InferenceResult::of(self.db, def); let mut res = FxHashSet::default(); - unsafe_operations_for_body(self.db, infer, def, &body, &mut |node| { - if let Ok(node) = source_map.expr_or_pat_syntax(node) { - res.insert(node); - } - }); + for root in body.expr_roots() { + unsafe_operations(self.db, infer, def, body, root, &mut |node, _| { + if let Ok(node) = source_map.expr_or_pat_syntax(node) { + res.insert(node); + } + }); + } res } pub fn get_unsafe_ops_for_unsafe_block(&self, block: ast::BlockExpr) -> Vec<ExprOrPatSource> { always!(block.unsafe_token().is_some()); + let Some(sa) = self.analyze(block.syntax()) else { return vec![] }; + let Some((def, store, sm, Some(infer))) = sa.def() else { return vec![] }; let block = self.wrap_node_infile(ast::Expr::from(block)); - let Some(def) = self.body_for(block.syntax()) else { return Vec::new() }; - let Ok(def) = def.try_into() else { - return Vec::new(); - }; - let (body, source_map) = self.db.body_with_source_map(def); - let infer = InferenceResult::for_body(self.db, def); - let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else { + let Some(ExprOrPatId::ExprId(block)) = sm.node_expr(block.as_ref()) else { return Vec::new(); }; let mut res = Vec::default(); - unsafe_operations(self.db, infer, def, &body, block, &mut |node, _| { - if let Ok(node) = source_map.expr_or_pat_syntax(node) { + unsafe_operations(self.db, infer, def, store, block, &mut |node, _| { + if let Ok(node) = sm.expr_or_pat_syntax(node) { res.push(node); } }); @@ -1994,7 +1996,7 @@ pub fn resolve_use_type_arg(&self, name: &ast::NameRef) -> Option<TypeParam> { pub fn resolve_offset_of_field( &self, name_ref: &ast::NameRef, - ) -> Option<(Either<Variant, Field>, GenericSubstitution<'db>)> { + ) -> Option<(Either<EnumVariant, Field>, GenericSubstitution<'db>)> { self.analyze_no_infer(name_ref.syntax())?.resolve_offset_of_field(self.db, name_ref) } @@ -2114,13 +2116,9 @@ pub fn source_with_range<Def: HasSource>( Some(res) } - pub fn body_for(&self, node: InFile<&SyntaxNode>) -> Option<DefWithBody> { + pub fn store_owner_for(&self, node: InFile<&SyntaxNode>) -> Option<ExpressionStoreOwner> { let container = self.with_ctx(|ctx| ctx.find_container(node))?; - - match container { - ChildContainer::DefWithBodyId(def) => Some(def.into()), - _ => None, - } + container.as_expression_store_owner().map(|id| id.into()) } /// Returns none if the file of the node is not part of a crate. @@ -2149,7 +2147,7 @@ fn analyze_impl( node: InFile<&SyntaxNode>, offset: Option<TextSize>, // replace this, just make the inference result a `LazyCell` - infer_body: bool, + infer: bool, ) -> Option<SourceAnalyzer<'db>> { let _p = tracing::info_span!("SemanticsImpl::analyze_impl").entered(); @@ -2157,26 +2155,42 @@ fn analyze_impl( let resolver = match container { ChildContainer::DefWithBodyId(def) => { - return Some(if infer_body { + return Some(if infer { SourceAnalyzer::new_for_body(self.db, def, node, offset) } else { SourceAnalyzer::new_for_body_no_infer(self.db, def, node, offset) }); } ChildContainer::VariantId(def) => { - return Some(SourceAnalyzer::new_variant_body(self.db, def, node, offset)); + return Some(SourceAnalyzer::new_variant_body(self.db, def, node, offset, infer)); } ChildContainer::TraitId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); + return Some(if infer { + SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset) + } else { + SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset) + }); } ChildContainer::ImplId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); + return Some(if infer { + SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset) + } else { + SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset) + }); } ChildContainer::EnumId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); + return Some(if infer { + SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset) + } else { + SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset) + }); } ChildContainer::GenericDefId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset)); + return Some(if infer { + SourceAnalyzer::new_generic_def(self.db, it, node, offset) + } else { + SourceAnalyzer::new_generic_def_no_infer(self.db, it, node, offset) + }); } ChildContainer::ModuleId(it) => it.resolver(self.db), }; @@ -2259,7 +2273,7 @@ pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool { let Some(def) = def else { return false }; let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax()); - let (body, source_map) = self.db.body_with_source_map(def); + let (body, source_map) = Body::with_source_map(self.db, def); let file_id = self.find_file(expr.syntax()).file_id; @@ -2310,7 +2324,7 @@ pub fn locals_used( let sa = self.analyze(element.either(|e| e.syntax(), |s| s.syntax()))?; let store = sa.store()?; let mut resolver = sa.resolver.clone(); - let def = resolver.body_owner()?; + let def = resolver.expression_store_owner()?; let is_not_generated = |path: &Path| { !path.mod_path().and_then(|path| path.as_ident()).is_some_and(Name::is_generated) @@ -2501,7 +2515,7 @@ fn to_def(sema: &SemanticsImpl<'_>, src: InFile<&Self>) -> Option<Self::Def> { (crate::Function, ast::Fn, fn_to_def), (crate::Field, ast::RecordField, record_field_to_def), (crate::Field, ast::TupleField, tuple_field_to_def), - (crate::Variant, ast::Variant, enum_variant_to_def), + (crate::EnumVariant, ast::Variant, enum_variant_to_def), (crate::TypeParam, ast::TypeParam, type_param_to_def), (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), (crate::ConstParam, ast::ConstParam, const_param_to_def), @@ -2560,13 +2574,18 @@ pub fn krate(&self) -> Crate { Crate { id: self.resolver.krate() } } + // FIXME: This is a weird function, we shouldn't have this? pub fn containing_function(&self) -> Option<Function> { - self.resolver.body_owner().and_then(|owner| match owner { - DefWithBodyId::FunctionId(id) => Some(id.into()), + self.resolver.expression_store_owner().and_then(|owner| match owner { + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => Some(id.into()), _ => None, }) } + pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwner> { + self.resolver.expression_store_owner().map(Into::into) + } + pub(crate) fn resolver(&self) -> &Resolver<'db> { &self.resolver } @@ -2588,14 +2607,18 @@ pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) { resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()), - resolver::ScopeDef::Local(binding_id) => match self.resolver.body_owner() { - Some(parent) => ScopeDef::Local(Local { parent, binding_id }), - None => continue, - }, - resolver::ScopeDef::Label(label_id) => match self.resolver.body_owner() { - Some(parent) => ScopeDef::Label(Label { parent, label_id }), - None => continue, - }, + resolver::ScopeDef::Local(binding_id) => { + match self.resolver.expression_store_owner() { + Some(parent) => ScopeDef::Local(Local { parent, binding_id }), + None => continue, + } + } + resolver::ScopeDef::Label(label_id) => { + match self.resolver.expression_store_owner() { + Some(parent) => ScopeDef::Label(Label { parent, label_id }), + None => continue, + } + } }; f(name.clone(), def) }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index 143cc14..f6d1bec 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
@@ -18,8 +18,10 @@ DynMap, keys::{self, Key}, }, + expr_store::Body, hir::generics::GenericParams, item_scope::ItemScope, + signatures::{EnumSignature, ImplSignature, TraitSignature}, src::{HasChildSource, HasSource}, }; @@ -49,7 +51,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); - let (_, source_map) = db.trait_signature_with_source_map(*self); + let (_, source_map) = TraitSignature::with_source_map(db, *self); source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( |(ast, &exp_id)| { res[keys::MACRO_CALL].insert(ast.value, exp_id); @@ -74,7 +76,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); - let (_, source_map) = db.impl_signature_with_source_map(*self); + let (_, source_map) = ImplSignature::with_source_map(db, *self); source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( |(ast, &exp_id)| { res[keys::MACRO_CALL].insert(ast.value, exp_id); @@ -204,7 +206,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi self.enum_variants(db).variants.iter().for_each(|&(variant, _, _)| { res[keys::ENUM_VARIANT].insert(ast_id_map.get(variant.lookup(db).id.value), variant); }); - let (_, source_map) = db.enum_signature_with_source_map(*self); + let (_, source_map) = EnumSignature::with_source_map(db, *self); source_map .expansions() .filter(|(ast, _)| ast.file_id == file_id) @@ -214,7 +216,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi impl ChildBySource for DefWithBodyId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { - let (body, sm) = db.body_with_source_map(*self); + let (body, sm) = Body::with_source_map(db, *self); if let &DefWithBodyId::VariantId(v) = self { VariantId::EnumVariantId(v).child_by_source_to(db, res, file_id) } @@ -239,8 +241,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi return; } - let (generic_params, _, source_map) = - GenericParams::generic_params_and_store_and_source_map(db, *self); + let (generic_params, _, source_map) = GenericParams::with_source_map(db, *self); let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx); let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index d222c3d..a9a779a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -88,13 +88,14 @@ use either::Either; use hir_def::{ AdtId, BlockId, BuiltinDeriveImplId, ConstId, ConstParamId, DefWithBodyId, EnumId, - EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, - ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeParamId, UnionId, UseId, VariantId, + EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FieldId, FunctionId, + GenericDefId, GenericParamId, ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, + StructId, TraitId, TypeAliasId, TypeParamId, UnionId, UseId, VariantId, dyn_map::{ DynMap, keys::{self, Key}, }, + expr_store::{Body, ExpressionStore}, hir::{BindingId, Expr, LabelId}, nameres::{block_def_map, crate_def_map}, }; @@ -334,8 +335,8 @@ pub(super) fn asm_operand_to_def( _ => None, }) .position(|it| it == *src.value)?; - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let source_map = self.db.body_with_source_map(container).1; + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (_, source_map) = ExpressionStore::with_source_map(self.db, container); let expr = source_map.node_expr(src.with_value(&ast::Expr::AsmExpr(asm)))?.as_expr()?; Some(InlineAsmOperand { owner: container, expr, index }) } @@ -343,13 +344,13 @@ pub(super) fn asm_operand_to_def( pub(super) fn bind_pat_to_def( &mut self, src: InFile<&ast::IdentPat>, - ) -> Option<(DefWithBodyId, BindingId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (body, source_map) = self.db.body_with_source_map(container); + ) -> Option<(ExpressionStoreOwnerId, BindingId)> { + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (store, source_map) = ExpressionStore::with_source_map(self.db, container); let src = src.cloned().map(ast::Pat::from); let pat_id = source_map.node_pat(src.as_ref())?; // the pattern could resolve to a constant, verify that this is not the case - if let crate::Pat::Bind { id, .. } = body[pat_id.as_pat()?] { + if let crate::Pat::Bind { id, .. } = store[pat_id.as_pat()?] { Some((container, id)) } else { None @@ -359,17 +360,19 @@ pub(super) fn self_param_to_def( &mut self, src: InFile<&ast::SelfParam>, ) -> Option<(DefWithBodyId, BindingId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let body = self.db.body(container); + let container = self + .find_container(src.syntax_ref())? + .as_expression_store_owner()? + .as_def_with_body()?; + let body = Body::of(self.db, container); Some((container, body.self_param?)) } pub(super) fn label_to_def( &mut self, src: InFile<&ast::Label>, - ) -> Option<(DefWithBodyId, LabelId)> { - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let source_map = self.db.body_with_source_map(container).1; - + ) -> Option<(ExpressionStoreOwnerId, LabelId)> { + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (_, source_map) = ExpressionStore::with_source_map(self.db, container); let label_id = source_map.node_label(src)?; Some((container, label_id)) } @@ -377,13 +380,14 @@ pub(super) fn label_to_def( pub(super) fn label_ref_to_def( &mut self, src: InFile<&ast::Lifetime>, - ) -> Option<(DefWithBodyId, LabelId)> { + ) -> Option<(ExpressionStoreOwnerId, LabelId)> { let break_or_continue = ast::Expr::cast(src.value.syntax().parent()?)?; - let container = self.find_pat_or_label_container(src.syntax_ref())?; - let (body, source_map) = self.db.body_with_source_map(container); + let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?; + let (store, source_map) = ExpressionStore::with_source_map(self.db, container); let break_or_continue = source_map.node_expr(src.with_value(&break_or_continue))?.as_expr()?; - let (Expr::Break { label, .. } | Expr::Continue { label }) = body[break_or_continue] else { + let (Expr::Break { label, .. } | Expr::Continue { label }) = store[break_or_continue] + else { return None; }; Some((container, label?)) @@ -557,29 +561,6 @@ fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<G }) } - // FIXME: Remove this when we do inference in signatures - fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> { - self.parent_ancestors_with_macros(src, |this, InFile { file_id, value }, _| { - let item = match ast::Item::cast(value.clone()) { - Some(it) => it, - None => { - let variant = ast::Variant::cast(value)?; - return this - .enum_variant_to_def(InFile::new(file_id, &variant)) - .map(Into::into); - } - }; - match &item { - ast::Item::Fn(it) => this.fn_to_def(InFile::new(file_id, it)).map(Into::into), - ast::Item::Const(it) => this.const_to_def(InFile::new(file_id, it)).map(Into::into), - ast::Item::Static(it) => { - this.static_to_def(InFile::new(file_id, it)).map(Into::into) - } - _ => None, - } - }) - } - /// Skips the attributed item that caused the macro invocation we are climbing up fn parent_ancestors_with_macros<T>( &mut self, @@ -756,4 +737,22 @@ fn child_by_source(self, db: &dyn HirDatabase, file_id: HirFileId) -> DynMap { ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id), } } + + pub(crate) fn as_expression_store_owner(self) -> Option<ExpressionStoreOwnerId> { + match self { + ChildContainer::DefWithBodyId(it) => Some(it.into()), + ChildContainer::ModuleId(_) => None, + ChildContainer::TraitId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::TraitId(it))) + } + ChildContainer::EnumId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::AdtId(it.into()))) + } + ChildContainer::ImplId(it) => { + Some(ExpressionStoreOwnerId::Signature(GenericDefId::ImplId(it))) + } + ChildContainer::VariantId(_) => None, + ChildContainer::GenericDefId(it) => Some(it.into()), + } + } }
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index c6f2d15..1a34fa9 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -9,18 +9,18 @@ use either::Either; use hir_def::{ - AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, - LocalFieldId, ModuleDefId, StructId, TraitId, VariantId, + AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, + FunctionId, GenericDefId, LocalFieldId, ModuleDefId, StructId, TraitId, VariantId, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId, lower::ExprCollector, path::Path, scope::{ExprScopes, ScopeId}, }, - hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId}, + hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId, generics::GenericParams}, lang_item::LangItems, nameres::MacroSubNs, - resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope}, + resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope}, type_ref::{Mutability, TypeRef, TypeRefId}, }; use hir_expand::{ @@ -55,12 +55,11 @@ SyntaxKind, SyntaxNode, TextRange, TextSize, ast::{self, AstNode, RangeItem, RangeOp}, }; -use triomphe::Arc; use crate::{ Adt, AnyFunctionId, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, - DeriveHelper, Field, Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, - ToolModule, Trait, TupleField, Type, TypeAlias, Variant, + DeriveHelper, EnumVariant, Field, Function, GenericSubstitution, Local, Macro, ModuleDef, + Static, Struct, ToolModule, Trait, TupleField, Type, TypeAlias, db::HirDatabase, semantics::{PathResolution, PathResolutionPerNs}, }; @@ -78,21 +77,23 @@ pub(crate) struct SourceAnalyzer<'db> { pub(crate) enum BodyOrSig<'db> { Body { def: DefWithBodyId, - body: Arc<Body>, - source_map: Arc<BodySourceMap>, + body: &'db Body, + source_map: &'db BodySourceMap, infer: Option<&'db InferenceResult>, }, - // To be folded into body once it is considered one VariantFields { def: VariantId, - store: Arc<ExpressionStore>, - source_map: Arc<ExpressionStoreSourceMap>, + store: &'db ExpressionStore, + source_map: &'db ExpressionStoreSourceMap, + infer: Option<&'db InferenceResult>, }, Sig { def: GenericDefId, - store: Arc<ExpressionStore>, - source_map: Arc<ExpressionStoreSourceMap>, - // infer: Option<Arc<InferenceResult>>, + store: &'db ExpressionStore, + source_map: &'db ExpressionStoreSourceMap, + infer: Option<&'db InferenceResult>, + #[expect(dead_code)] + generics: &'db GenericParams, }, } @@ -103,7 +104,7 @@ pub(crate) fn new_for_body( node: InFile<&SyntaxNode>, offset: Option<TextSize>, ) -> SourceAnalyzer<'db> { - Self::new_for_body_(db, def, node, offset, Some(InferenceResult::for_body(db, def))) + Self::new_for_body_(db, def, node, offset, Some(InferenceResult::of(db, def))) } pub(crate) fn new_for_body_no_infer( @@ -122,10 +123,10 @@ pub(crate) fn new_for_body_( offset: Option<TextSize>, infer: Option<&'db InferenceResult>, ) -> SourceAnalyzer<'db> { - let (body, source_map) = db.body_with_source_map(def); - let scopes = db.expr_scopes(def); + let (body, source_map) = Body::with_source_map(db, def); + let scopes = ExprScopes::of(db, def); let scope = match offset { - None => scope_for(db, &scopes, &source_map, node), + None => scope_for(db, scopes, source_map, node), Some(offset) => { debug_assert!( node.text_range().contains_inclusive(offset), @@ -133,7 +134,7 @@ pub(crate) fn new_for_body_( offset, node.text_range() ); - scope_for_offset(db, &scopes, &source_map, node.file_id, offset) + scope_for_offset(db, scopes, source_map, node.file_id, offset) } }; let resolver = resolver_for_scope(db, def, scope); @@ -147,14 +148,47 @@ pub(crate) fn new_for_body_( pub(crate) fn new_generic_def( db: &'db dyn HirDatabase, def: GenericDefId, - InFile { file_id, .. }: InFile<&SyntaxNode>, - _offset: Option<TextSize>, + node: InFile<&SyntaxNode>, + offset: Option<TextSize>, ) -> SourceAnalyzer<'db> { - let (_params, store, source_map) = db.generic_params_and_store_and_source_map(def); - let resolver = def.resolver(db); + Self::new_generic_def_(db, def, node, offset, true) + } + + pub(crate) fn new_generic_def_no_infer( + db: &'db dyn HirDatabase, + def: GenericDefId, + node: InFile<&SyntaxNode>, + offset: Option<TextSize>, + ) -> SourceAnalyzer<'db> { + Self::new_generic_def_(db, def, node, offset, false) + } + + pub(crate) fn new_generic_def_( + db: &'db dyn HirDatabase, + def: GenericDefId, + node @ InFile { file_id, .. }: InFile<&SyntaxNode>, + offset: Option<TextSize>, + infer: bool, + ) -> SourceAnalyzer<'db> { + let (generics, store, source_map) = GenericParams::with_source_map(db, def); + let scopes = ExprScopes::of(db, def); + let scope = match offset { + None => scope_for(db, scopes, source_map, node), + Some(offset) => { + debug_assert!( + node.text_range().contains_inclusive(offset), + "{:?} not in {:?}", + offset, + node.text_range() + ); + scope_for_offset(db, scopes, source_map, node.file_id, offset) + } + }; + let resolver = resolver_for_scope(db, def, scope); + let infer = if infer { Some(InferenceResult::of(db, def)) } else { None }; SourceAnalyzer { resolver, - body_or_sig: Some(BodyOrSig::Sig { def, store, source_map }), + body_or_sig: Some(BodyOrSig::Sig { def, store, source_map, generics, infer }), file_id, } } @@ -162,17 +196,33 @@ pub(crate) fn new_generic_def( pub(crate) fn new_variant_body( db: &'db dyn HirDatabase, def: VariantId, - InFile { file_id, .. }: InFile<&SyntaxNode>, - _offset: Option<TextSize>, + node @ InFile { file_id, .. }: InFile<&SyntaxNode>, + offset: Option<TextSize>, + infer: bool, ) -> SourceAnalyzer<'db> { let (fields, source_map) = def.fields_with_source_map(db); - let resolver = def.resolver(db); + let scopes = ExprScopes::of(db, def); + let scope = match offset { + None => scope_for(db, scopes, source_map, node), + Some(offset) => { + debug_assert!( + node.text_range().contains_inclusive(offset), + "{:?} not in {:?}", + offset, + node.text_range() + ); + scope_for_offset(db, scopes, source_map, node.file_id, offset) + } + }; + let resolver = resolver_for_scope(db, def, scope); + let infer = if infer { Some(InferenceResult::of(db, def)) } else { None }; SourceAnalyzer { resolver, body_or_sig: Some(BodyOrSig::VariantFields { def, - store: fields.store.clone(), - source_map: source_map.clone(), + store: &fields.store, + source_map, + infer, }), file_id, } @@ -185,29 +235,40 @@ pub(crate) fn new_for_resolver( SourceAnalyzer { resolver, body_or_sig: None, file_id: node.file_id } } - // FIXME: Remove this - fn body_(&self) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult>)> { - self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::Body { def, body, source_map, infer } => { - Some((*def, &**body, &**source_map, infer.as_deref())) - } - _ => None, + fn owner(&self) -> Option<ExpressionStoreOwnerId> { + self.body_or_sig.as_ref().map(|it| match *it { + BodyOrSig::VariantFields { def, .. } => def.into(), + BodyOrSig::Sig { def, .. } => def.into(), + BodyOrSig::Body { def, .. } => def.into(), }) } fn infer(&self) -> Option<&InferenceResult> { self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::Sig { .. } => None, - BodyOrSig::VariantFields { .. } => None, - BodyOrSig::Body { infer, .. } => infer.as_deref(), + BodyOrSig::VariantFields { infer, .. } + | BodyOrSig::Sig { infer, .. } + | BodyOrSig::Body { infer, .. } => infer.as_deref(), }) } - fn body(&self) -> Option<&Body> { - self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::Sig { .. } => None, - BodyOrSig::VariantFields { .. } => None, - BodyOrSig::Body { body, .. } => Some(&**body), + pub(crate) fn def( + &self, + ) -> Option<( + ExpressionStoreOwnerId, + &ExpressionStore, + &ExpressionStoreSourceMap, + Option<&InferenceResult>, + )> { + self.body_or_sig.as_ref().map(|it| match *it { + BodyOrSig::VariantFields { def, store, source_map, infer, .. } => { + (def.into(), store, source_map, infer) + } + BodyOrSig::Sig { def, store, source_map, infer, .. } => { + (def.into(), store, source_map, infer) + } + BodyOrSig::Body { def, body, source_map, infer, .. } => { + (def.into(), &body.store, &source_map.store, infer) + } }) } @@ -232,11 +293,13 @@ fn param_and<'a>(&self, param_env: ParamEnv<'a>) -> ParamEnvAndCrate<'a> { } fn trait_environment(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> { - self.param_and( - self.body_() - .map(|(def, ..)| def) - .map_or_else(ParamEnv::empty, |def| db.trait_environment_for_body(def)), - ) + self.param_and(self.body_or_sig.as_ref().map_or_else(ParamEnv::empty, |body_or_sig| { + match *body_or_sig { + BodyOrSig::Body { def, .. } => db.trait_environment(def.into()), + BodyOrSig::VariantFields { def, .. } => db.trait_environment(def.into()), + BodyOrSig::Sig { def, .. } => db.trait_environment(def.into()), + } + })) } pub(crate) fn expr_id(&self, expr: ast::Expr) -> Option<ExprOrPatId> { @@ -371,7 +434,10 @@ pub(crate) fn type_of_self( db: &'db dyn HirDatabase, _param: &ast::SelfParam, ) -> Option<Type<'db>> { - let binding = self.body()?.self_param?; + let binding = match self.body_or_sig.as_ref()? { + BodyOrSig::Sig { .. } | BodyOrSig::VariantFields { .. } => return None, + BodyOrSig::Body { body, .. } => body.self_param?, + }; let ty = self.infer()?.binding_ty(binding); Some(Type::new_with_resolver(db, &self.resolver, ty)) } @@ -472,7 +538,7 @@ pub(crate) fn resolve_field( &self, field: &ast::FieldExpr, ) -> Option<Either<Field, TupleField>> { - let (def, ..) = self.body_()?; + let def = self.owner()?; let expr_id = self.expr_id(field.clone().into())?.as_expr()?; self.infer()?.field_resolution(expr_id).map(|it| { it.map_either(Into::into, |f| TupleField { owner: def, tuple: f.tuple, index: f.index }) @@ -499,7 +565,7 @@ pub(crate) fn resolve_field_fallback( field: &ast::FieldExpr, ) -> Option<(Either<Either<Field, TupleField>, Function>, Option<GenericSubstitution<'db>>)> { - let (def, ..) = self.body_()?; + let def = self.owner()?; let expr_id = self.expr_id(field.clone().into())?.as_expr()?; let inference_result = self.infer()?; match inference_result.field_resolution(expr_id) { @@ -771,7 +837,7 @@ pub(crate) fn resolve_record_field( name_hygiene(db, InFile::new(self.file_id, ast_name.syntax())), ) { Some(ValueNs::LocalBinding(binding_id)) => { - Some(Local { binding_id, parent: self.resolver.body_owner()? }) + Some(Local { binding_id, parent: self.resolver.expression_store_owner()? }) } _ => None, } @@ -831,8 +897,8 @@ pub(crate) fn resolve_bind_pat_to_const( }, }; - let body_owner = self.resolver.body_owner(); - let res = resolve_hir_value_path(db, &self.resolver, body_owner, path, HygieneId::ROOT)?; + let store_owner = self.resolver.expression_store_owner(); + let res = resolve_hir_value_path(db, &self.resolver, store_owner, path, HygieneId::ROOT)?; match res { PathResolution::Def(def) => Some(def), _ => None, @@ -843,7 +909,7 @@ pub(crate) fn resolve_use_type_arg(&self, name: &ast::NameRef) -> Option<crate:: let name = name.as_name(); self.resolver .all_generic_params() - .find_map(|(params, parent)| params.find_type_by_name(&name, *parent)) + .find_map(|(params, parent)| params.find_type_by_name(&name, parent)) .map(crate::TypeParam::from) } @@ -851,7 +917,7 @@ pub(crate) fn resolve_offset_of_field( &self, db: &'db dyn HirDatabase, name_ref: &ast::NameRef, - ) -> Option<(Either<crate::Variant, crate::Field>, GenericSubstitution<'db>)> { + ) -> Option<(Either<crate::EnumVariant, crate::Field>, GenericSubstitution<'db>)> { let offset_of_expr = ast::OffsetOfExpr::cast(name_ref.syntax().parent()?)?; let container = offset_of_expr.ty()?; let container = self.type_of_type(db, &container)?; @@ -902,7 +968,7 @@ pub(crate) fn resolve_offset_of_field( let variants = id.enum_variants(db); let variant = variants.variant(&field_name.as_name())?; container = Either::Left((variant, subst)); - (Either::Left(Variant { id: variant }), id.into(), subst) + (Either::Left(EnumVariant { id: variant }), id.into(), subst) } }, _ => return None, @@ -982,7 +1048,10 @@ pub(crate) fn resolve_path( if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } prefer_value_ns = true; } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) { @@ -1014,14 +1083,20 @@ pub(crate) fn resolve_path( if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_or_pat_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) { let expr_id = self.expr_id(rec_lit.into())?; if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } } else { let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from); @@ -1032,7 +1107,7 @@ pub(crate) fn resolve_path( let variant_res_for_pat = infer.variant_resolution_for_pat(pat_id.as_pat()?); if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat { return Some(( - PathResolution::Def(ModuleDef::Variant(variant.into())), + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), None, )); } @@ -1045,7 +1120,7 @@ pub(crate) fn resolve_path( } // FIXME: collectiong here shouldnt be necessary? - let mut collector = ExprCollector::new(db, self.resolver.module(), self.file_id); + let mut collector = ExprCollector::body(db, self.resolver.module(), self.file_id); let hir_path = collector.lower_path(path.clone(), &mut ExprCollector::impl_trait_error_allocator)?; let parent_hir_path = path @@ -1253,7 +1328,7 @@ pub(crate) fn resolve_hir_path_per_ns( db: &dyn HirDatabase, path: &ast::Path, ) -> Option<PathResolutionPerNs> { - let mut collector = ExprCollector::new(db, self.resolver.module(), self.file_id); + let mut collector = ExprCollector::body(db, self.resolver.module(), self.file_id); let hir_path = collector.lower_path(path.clone(), &mut ExprCollector::impl_trait_error_allocator)?; let (store, _) = collector.store.finish(); @@ -1366,7 +1441,7 @@ pub(crate) fn is_unsafe_macro_call_expr( db: &'db dyn HirDatabase, macro_expr: InFile<&ast::MacroExpr>, ) -> bool { - if let Some((def, body, sm, Some(infer))) = self.body_() + if let Some((def, body, sm, Some(infer))) = self.def() && let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr) { let mut is_unsafe = false; @@ -1400,7 +1475,7 @@ pub(crate) fn resolve_offset_in_format_args( resolve_hir_value_path( db, &self.resolver, - self.resolver.body_owner(), + self.resolver.expression_store_owner(), &Path::from_known_path_with_no_generic(ModPath::from_segments( PathKind::Plain, Some(name.clone()), @@ -1416,9 +1491,9 @@ pub(crate) fn resolve_offset_in_asm_template( asm: InFile<&ast::AsmExpr>, line: usize, offset: TextSize, - ) -> Option<(DefWithBodyId, (ExprId, TextRange, usize))> { - let (def, _, body_source_map, _) = self.body_()?; - let (expr, args) = body_source_map.asm_template_args(asm)?; + ) -> Option<(ExpressionStoreOwnerId, (ExprId, TextRange, usize))> { + let (def, _, sm, _) = self.def()?; + let (expr, args) = sm.asm_template_args(asm)?; Some(def).zip( args.get(line)? .iter() @@ -1439,7 +1514,7 @@ pub(crate) fn as_format_args_parts<'a>( resolve_hir_value_path( db, &self.resolver, - self.resolver.body_owner(), + self.resolver.expression_store_owner(), &Path::from_known_path_with_no_generic(ModPath::from_segments( PathKind::Plain, Some(name.clone()), @@ -1453,9 +1528,9 @@ pub(crate) fn as_format_args_parts<'a>( pub(crate) fn as_asm_parts( &self, asm: InFile<&ast::AsmExpr>, - ) -> Option<(DefWithBodyId, (ExprId, &[Vec<(TextRange, usize)>]))> { - let (def, _, body_source_map, _) = self.body_()?; - Some(def).zip(body_source_map.asm_template_args(asm)) + ) -> Option<(ExpressionStoreOwnerId, (ExprId, &[Vec<(TextRange, usize)>]))> { + let (def, _, sm, _) = self.def()?; + Some(def).zip(sm.asm_template_args(asm)) } fn resolve_impl_method_or_trait_def( @@ -1473,11 +1548,11 @@ fn resolve_impl_method_or_trait_def_with_subst( func: FunctionId, substs: GenericArgs<'db>, ) -> (Function, GenericArgs<'db>) { - let owner = match self.resolver.body_owner() { + let owner = match self.resolver.expression_store_owner() { Some(it) => it, None => return (func.into(), substs), }; - let env = self.param_and(db.trait_environment_for_body(owner)); + let env = self.param_and(db.trait_environment(owner)); let (func, args) = db.lookup_impl_method(env, func, substs); match func { Either::Left(func) => (func.into(), args), @@ -1493,11 +1568,11 @@ fn resolve_impl_const_or_trait_def_with_subst( const_id: ConstId, subs: GenericArgs<'db>, ) -> (ConstId, GenericArgs<'db>) { - let owner = match self.resolver.body_owner() { + let owner = match self.resolver.expression_store_owner() { Some(it) => it, None => return (const_id, subs), }; - let env = self.param_and(db.trait_environment_for_body(owner)); + let env = self.param_and(db.trait_environment(owner)); let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); method_resolution::lookup_impl_const(&infcx, env.param_env, const_id, subs) @@ -1526,7 +1601,7 @@ fn ty_of_expr(&self, expr: ast::Expr) -> Option<Ty<'db>> { fn scope_for( db: &dyn HirDatabase, scopes: &ExprScopes, - source_map: &BodySourceMap, + source_map: &ExpressionStoreSourceMap, node: InFile<&SyntaxNode>, ) -> Option<ScopeId> { node.ancestors_with_macros(db) @@ -1545,7 +1620,7 @@ fn scope_for( fn scope_for_offset( db: &dyn HirDatabase, scopes: &ExprScopes, - source_map: &BodySourceMap, + source_map: &ExpressionStoreSourceMap, from_file: HirFileId, offset: TextSize, ) -> Option<ScopeId> { @@ -1579,7 +1654,7 @@ fn scope_for_offset( fn adjust( db: &dyn HirDatabase, scopes: &ExprScopes, - source_map: &BodySourceMap, + source_map: &ExpressionStoreSourceMap, expr_range: TextRange, from_file: HirFileId, offset: TextSize, @@ -1684,7 +1759,7 @@ fn resolve_hir_path_( TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { PathResolution::Def(Adt::from(it).into()) } - TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), @@ -1708,7 +1783,7 @@ fn resolve_hir_path_( } }; - let body_owner = resolver.body_owner(); + let body_owner = resolver.expression_store_owner(); let values = || resolve_hir_value_path(db, resolver, body_owner, path, hygiene); let items = || { @@ -1754,21 +1829,21 @@ fn resolve_hir_path_( fn resolve_hir_value_path( db: &dyn HirDatabase, resolver: &Resolver<'_>, - body_owner: Option<DefWithBodyId>, + store_owner: Option<ExpressionStoreOwnerId>, path: &Path, hygiene: HygieneId, ) -> Option<PathResolution> { resolver.resolve_path_in_value_ns_fully(db, path, hygiene).and_then(|val| { let res = match val { ValueNs::LocalBinding(binding_id) => { - let var = Local { parent: body_owner?, binding_id }; + let var = Local { parent: store_owner?, binding_id }; PathResolution::Local(var) } ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), - ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), ValueNs::GenericParam(id) => PathResolution::ConstParam(id.into()), }; @@ -1833,7 +1908,7 @@ fn resolve_hir_path_qualifier( TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { PathResolution::Def(Adt::from(it).into()) } - TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index c088f3a..ff56544 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
@@ -8,9 +8,11 @@ AdtId, AssocItemId, AstIdLoc, Complete, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, db::DefDatabase, + expr_store::Body, item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob}, nameres::crate_def_map, per_ns::Item, + signatures::{EnumSignature, ImplSignature, TraitSignature}, src::{HasChildSource, HasSource}, visibility::{Visibility, VisibilityExplicitness}, }; @@ -185,7 +187,7 @@ fn collect_from_module(&mut self, module_id: ModuleId) { } ModuleDefId::AdtId(AdtId::EnumId(id)) => { this.push_decl(id, name, false, None); - let enum_name = Symbol::intern(this.db.enum_signature(id).name.as_str()); + let enum_name = Symbol::intern(EnumSignature::of(this.db, id).name.as_str()); this.with_container_name(Some(enum_name), |this| { let variants = id.enum_variants(this.db); for (variant_id, variant_name, _) in &variants.variants { @@ -386,7 +388,7 @@ fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>, name: Option< return; } let body_id = body_id.into(); - let body = self.db.body(body_id); + let body = Body::of(self.db, body_id); // Descend into the blocks and enqueue collection of all modules within. for (_, def_map) in body.blocks(self.db) { @@ -397,7 +399,7 @@ fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>, name: Option< } fn collect_from_impl(&mut self, impl_id: ImplId) { - let impl_data = self.db.impl_signature(impl_id); + let impl_data = ImplSignature::of(self.db, impl_id); let impl_name = Some( hir_display_with_store(impl_data.self_ty, &impl_data.store) .display( @@ -419,7 +421,7 @@ fn collect_from_impl(&mut self, impl_id: ImplId) { } fn collect_from_trait(&mut self, trait_id: TraitId, trait_do_not_complete: Complete) { - let trait_data = self.db.trait_signature(trait_id); + let trait_data = TraitSignature::of(self.db, trait_id); self.with_container_name(Some(Symbol::intern(trait_data.name.as_str())), |s| { for &(ref name, assoc_item_id) in &trait_id.trait_items(self.db).items { s.push_assoc_item(assoc_item_id, name, Some(trait_do_not_complete));
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index e56f9e9..e3d0121 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
@@ -10,8 +10,8 @@ use span::Edition; use crate::{ - Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Field, Function, Local, ModuleDef, - SemanticsScope, Static, Struct, StructKind, Trait, Type, Variant, + Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, EnumVariant, Field, Function, Local, + ModuleDef, SemanticsScope, Static, Struct, StructKind, Trait, Type, }; /// Helper function to get path to `ModuleDef` @@ -80,7 +80,7 @@ pub enum Expr<'db> { params: Vec<Expr<'db>>, }, /// Enum variant construction - Variant { variant: Variant, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, + Variant { variant: EnumVariant, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, /// Struct construction Struct { strukt: Struct, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, /// Tuple construction @@ -222,7 +222,7 @@ pub fn gen_source_code( StructKind::Unit => String::new(), }; - let prefix = mod_item_path_str(sema_scope, &ModuleDef::Variant(*variant))?; + let prefix = mod_item_path_str(sema_scope, &ModuleDef::EnumVariant(*variant))?; Ok(format!("{prefix}{inner}")) } Expr::Struct { strukt, params, .. } => {
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs index 8622aa1..c7ef4e5 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs
@@ -53,7 +53,7 @@ pub(super) fn trivial<'a, 'lt, 'db, DB: HirDatabase>( ScopeDef::GenericParam(GenericParam::ConstParam(it)) => Some(Expr::ConstParam(*it)), ScopeDef::Local(it) => { if ctx.config.enable_borrowcheck { - let borrowck = db.borrowck(it.parent).ok()?; + let borrowck = db.borrowck(it.parent.as_def_with_body()?).ok()?; let invalid = borrowck.iter().any(|b| { b.partially_moved.iter().any(|moved| {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs index 99ee50f..da1322d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_braces.rs
@@ -84,6 +84,7 @@ fn get_replacement_node(ctx: &AssistContext<'_>) -> Option<(ParentType, ast::Exp match parent { ast::LetStmt(it) => it.initializer()?, ast::LetExpr(it) => it.expr()?, + ast::BinExpr(it) => it.rhs()?, ast::Static(it) => it.body()?, ast::Const(it) => it.body()?, _ => return None, @@ -176,6 +177,70 @@ fn foo() { } "#, ); + + check_assist( + add_braces, + r#" +fn foo() { + let x; + x =$0 n + 100; +} +"#, + r#" +fn foo() { + let x; + x = { + n + 100 + }; +} +"#, + ); + + check_assist( + add_braces, + r#" +fn foo() { + if let x =$0 n + 100 {} +} +"#, + r#" +fn foo() { + if let x = { + n + 100 + } {} +} +"#, + ); + } + + #[test] + fn suggest_add_braces_for_const_initializer() { + check_assist( + add_braces, + r#" +const X: i32 =$0 1 + 2; +"#, + r#" +const X: i32 = { + 1 + 2 +}; +"#, + ); + } + + #[test] + fn suggest_add_braces_for_static_initializer() { + check_assist( + add_braces, + r#" +static X: i32 $0= 1 + 2; +"#, + r#" +static X: i32 = { + 1 + 2 +}; +"#, + ); } #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs index 7960373..75c5f84 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs
@@ -47,7 +47,7 @@ pub(crate) fn add_explicit_enum_discriminant( // Don't offer the assist if the enum has no variants or if all variants already have an // explicit discriminant. - if variant_list.variants().all(|variant_node| variant_node.expr().is_some()) { + if variant_list.variants().all(|variant_node| variant_node.const_arg().is_some()) { return None; } @@ -72,7 +72,9 @@ fn add_variant_discriminant( variant_node: &ast::Variant, radix: &mut Radix, ) { - if let Some(expr) = variant_node.expr() { + if let Some(expr) = variant_node.const_arg() + && let Some(expr) = expr.expr() + { *radix = expr_radix(&expr).unwrap_or(*radix); return; }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs index b84ad24..6a408e5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_label_to_loop.rs
@@ -3,11 +3,7 @@ }; use syntax::{ SyntaxToken, T, - ast::{ - self, AstNode, HasLoopBody, - make::{self, tokens}, - syntax_factory::SyntaxFactory, - }, + ast::{self, AstNode, HasLoopBody, syntax_factory::SyntaxFactory}, syntax_editor::{Position, SyntaxEditor}, }; @@ -35,9 +31,9 @@ // } // ``` pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let loop_kw = ctx.find_token_syntax_at_offset(T![loop])?; - let loop_expr = loop_kw.parent().and_then(ast::LoopExpr::cast)?; - if loop_expr.label().is_some() { + let loop_expr = ctx.find_node_at_offset::<ast::AnyHasLoopBody>()?; + let loop_kw = loop_token(&loop_expr)?; + if loop_expr.label().is_some() || !loop_kw.text_range().contains_inclusive(ctx.offset()) { return None; } @@ -52,8 +48,8 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O let label = make.lifetime("'l"); let elements = vec![ label.syntax().clone().into(), - make::token(T![:]).into(), - tokens::single_space().into(), + make.token(T![:]).into(), + make.whitespace(" ").into(), ]; editor.insert_all(Position::before(&loop_kw), elements); @@ -80,6 +76,14 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O ) } +fn loop_token(loop_expr: &ast::AnyHasLoopBody) -> Option<syntax::SyntaxToken> { + loop_expr + .syntax() + .children_with_tokens() + .filter_map(|it| it.into_token()) + .find(|it| matches!(it.kind(), T![for] | T![loop] | T![while])) +} + fn insert_label_after_token( editor: &mut SyntaxEditor, make: &SyntaxFactory, @@ -88,7 +92,7 @@ fn insert_label_after_token( builder: &mut SourceChangeBuilder, ) { let label = make.lifetime("'l"); - let elements = vec![tokens::single_space().into(), label.syntax().clone().into()]; + let elements = vec![make.whitespace(" ").into(), label.syntax().clone().into()]; editor.insert_all(Position::after(token), elements); if let Some(cap) = ctx.config.snippet_cap { @@ -124,6 +128,48 @@ fn main() { } #[test] + fn add_label_to_while_expr() { + check_assist( + add_label_to_loop, + r#" +fn main() { + while$0 true { + break; + continue; + } +}"#, + r#" +fn main() { + ${1:'l}: while true { + break ${2:'l}; + continue ${0:'l}; + } +}"#, + ); + } + + #[test] + fn add_label_to_for_expr() { + check_assist( + add_label_to_loop, + r#" +fn main() { + for$0 _ in 0..5 { + break; + continue; + } +}"#, + r#" +fn main() { + ${1:'l}: for _ in 0..5 { + break ${2:'l}; + continue ${0:'l}; + } +}"#, + ); + } + + #[test] fn add_label_to_outer_loop() { check_assist( add_label_to_loop, @@ -194,4 +240,29 @@ fn main() { }"#, ); } + + #[test] + fn do_not_add_label_if_outside_keyword() { + check_assist_not_applicable( + add_label_to_loop, + r#" +fn main() { + 'l: loop {$0 + break 'l; + continue 'l; + } +}"#, + ); + + check_assist_not_applicable( + add_label_to_loop, + r#" +fn main() { + 'l: while true {$0 + break 'l; + continue 'l; + } +}"#, + ); + } }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs index 27dbdcf..265ee3d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_lifetime_to_type.rs
@@ -1,4 +1,7 @@ -use syntax::ast::{self, AstNode, HasGenericParams, HasName}; +use syntax::{ + SyntaxKind, SyntaxNode, SyntaxToken, + ast::{self, AstNode, HasGenericParams, HasName}, +}; use crate::{AssistContext, AssistId, Assists}; @@ -21,7 +24,7 @@ // ``` pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let ref_type_focused = ctx.find_node_at_offset::<ast::RefType>()?; - if ref_type_focused.lifetime().is_some() { + if ref_type_focused.lifetime().is_some_and(|lifetime| lifetime.text() != "'_") { return None; } @@ -34,10 +37,10 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext<'_>) - return None; } - let ref_types = fetch_borrowed_types(&node)?; + let changes = fetch_borrowed_types(&node)?; let target = node.syntax().text_range(); - acc.add(AssistId::generate("add_lifetime_to_type"), "Add lifetime", target, |builder| { + acc.add(AssistId::quick_fix("add_lifetime_to_type"), "Add lifetime", target, |builder| { match node.generic_param_list() { Some(gen_param) => { if let Some(left_angle) = gen_param.l_angle_token() { @@ -51,16 +54,21 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext<'_>) - } } - for ref_type in ref_types { - if let Some(amp_token) = ref_type.amp_token() { - builder.insert(amp_token.text_range().end(), "'a "); + for change in changes { + match change { + Change::Replace(it) => { + builder.replace(it.text_range(), "'a"); + } + Change::Insert(it) => { + builder.insert(it.text_range().end(), "'a "); + } } } }) } -fn fetch_borrowed_types(node: &ast::Adt) -> Option<Vec<ast::RefType>> { - let ref_types: Vec<ast::RefType> = match node { +fn fetch_borrowed_types(node: &ast::Adt) -> Option<Vec<Change>> { + let ref_types: Vec<_> = match node { ast::Adt::Enum(enum_) => { let variant_list = enum_.variant_list()?; variant_list @@ -79,55 +87,50 @@ fn fetch_borrowed_types(node: &ast::Adt) -> Option<Vec<ast::RefType>> { } ast::Adt::Union(un) => { let record_field_list = un.record_field_list()?; - record_field_list - .fields() - .filter_map(|r_field| { - if let ast::Type::RefType(ref_type) = r_field.ty()? - && ref_type.lifetime().is_none() - { - return Some(ref_type); - } - - None - }) - .collect() + find_ref_types_from_field_list(&record_field_list.into())? } }; if ref_types.is_empty() { None } else { Some(ref_types) } } -fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option<Vec<ast::RefType>> { - let ref_types: Vec<ast::RefType> = match field_list { - ast::FieldList::RecordFieldList(record_list) => record_list - .fields() - .filter_map(|f| { - if let ast::Type::RefType(ref_type) = f.ty()? - && ref_type.lifetime().is_none() - { - return Some(ref_type); - } - - None - }) - .collect(), - ast::FieldList::TupleFieldList(tuple_field_list) => tuple_field_list - .fields() - .filter_map(|f| { - if let ast::Type::RefType(ref_type) = f.ty()? - && ref_type.lifetime().is_none() - { - return Some(ref_type); - } - - None - }) - .collect(), +fn find_ref_types_from_field_list(field_list: &ast::FieldList) -> Option<Vec<Change>> { + let ref_types: Vec<_> = match field_list { + ast::FieldList::RecordFieldList(record_list) => { + record_list.fields().flat_map(|f| infer_lifetimes(f.syntax())).collect() + } + ast::FieldList::TupleFieldList(tuple_field_list) => { + tuple_field_list.fields().flat_map(|f| infer_lifetimes(f.syntax())).collect() + } }; if ref_types.is_empty() { None } else { Some(ref_types) } } +enum Change { + Replace(SyntaxToken), + Insert(SyntaxToken), +} + +fn infer_lifetimes(node: &SyntaxNode) -> Vec<Change> { + node.children() + .filter(|it| !matches!(it.kind(), SyntaxKind::FN_PTR_TYPE | SyntaxKind::TYPE_BOUND_LIST)) + .flat_map(|it| { + infer_lifetimes(&it) + .into_iter() + .chain(ast::Lifetime::cast(it.clone()).and_then(|lt| { + lt.lifetime_ident_token().filter(|lt| lt.text() == "'_").map(Change::Replace) + })) + .chain( + ast::RefType::cast(it) + .filter(|ty| ty.lifetime().is_none()) + .and_then(|ty| ty.amp_token()) + .map(Change::Insert), + ) + }) + .collect() +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -165,6 +168,24 @@ fn add_lifetime_to_struct() { } #[test] + fn add_lifetime_to_nested_types() { + check_assist( + add_lifetime_to_type, + r#"struct Foo { a: &$0i32, b: &(&i32, fn(&str) -> &str) }"#, + r#"struct Foo<'a> { a: &'a i32, b: &'a (&'a i32, fn(&str) -> &str) }"#, + ); + } + + #[test] + fn add_lifetime_to_explicit_infer_lifetime() { + check_assist( + add_lifetime_to_type, + r#"struct Foo { a: &'_ $0i32, b: &'_ (&'_ i32, fn(&str) -> &str) }"#, + r#"struct Foo<'a> { a: &'a i32, b: &'a (&'a i32, fn(&str) -> &str) }"#, + ); + } + + #[test] fn add_lifetime_to_enum() { check_assist( add_lifetime_to_type,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index c0ce057..b063e5f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -3,14 +3,14 @@ use either::Either; use hir::{Adt, AsAssocItem, Crate, FindPathConfig, HasAttrs, ModuleDef, Semantics}; use ide_db::RootDatabase; -use ide_db::assists::ExprFillDefaultMode; use ide_db::syntax_helpers::suggest_name; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; -use syntax::ToSmolStr; -use syntax::ast::edit::{AstNodeEdit, IndentLevel}; +use syntax::ast::edit::IndentLevel; use syntax::ast::syntax_factory::SyntaxFactory; use syntax::ast::{self, AstNode, MatchArmList, MatchExpr, Pat, make}; +use syntax::syntax_editor::{Position, SyntaxEditor}; +use syntax::{SyntaxKind, SyntaxNode, ToSmolStr}; use crate::{AssistContext, AssistId, Assists, utils}; @@ -80,9 +80,16 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let module = scope.module(); let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(scope.krate())); let self_ty = if ctx.config.prefer_self_ty { - scope - .containing_function() - .and_then(|function| function.as_assoc_item(ctx.db())?.implementing_ty(ctx.db())) + scope.expression_store_owner().and_then(|def| { + match def { + hir::ExpressionStoreOwner::Body(def_with_body) => { + def_with_body.as_assoc_item(ctx.db()) + } + hir::ExpressionStoreOwner::Signature(def) => def.as_assoc_item(ctx.db()), + hir::ExpressionStoreOwner::VariantFields(_) => None, + }? + .implementing_ty(ctx.db()) + }) } else { None }; @@ -224,68 +231,26 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) // having any hidden variants means that we need a catch-all arm needs_catch_all_arm |= has_hidden_variants; - let missing_arms = missing_pats + let mut missing_arms = missing_pats .filter(|(_, hidden)| { // filter out hidden patterns because they're handled by the catch-all arm !hidden }) - .map(|(pat, _)| { - make.match_arm( - pat, - None, - match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }, - ) - }); - - let mut arms: Vec<_> = match_arm_list - .arms() - .filter(|arm| { - if matches!(arm.pat(), Some(ast::Pat::WildcardPat(_))) { - let is_empty_expr = arm.expr().is_none_or(|e| match e { - ast::Expr::BlockExpr(b) => { - b.statements().next().is_none() && b.tail_expr().is_none() - } - ast::Expr::TupleExpr(t) => t.fields().next().is_none(), - _ => false, - }); - if is_empty_expr { - false - } else { - cov_mark::hit!(add_missing_match_arms_empty_expr); - true - } - } else { - true - } - }) - .map(|arm| arm.reset_indent().indent(IndentLevel(1))) - .collect(); - - let first_new_arm_idx = arms.len(); - arms.extend(missing_arms); + .map(|(pat, _)| make.match_arm(pat, None, utils::expr_fill_default(ctx.config))) + .collect::<Vec<_>>(); if needs_catch_all_arm && !has_catch_all_arm { cov_mark::hit!(added_wildcard_pattern); let arm = make.match_arm( make.wildcard_pat().into(), None, - match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }, + utils::expr_fill_default(ctx.config), ); - arms.push(arm); + missing_arms.push(arm); } - let new_match_arm_list = make.match_arm_list(arms); - // FIXME: Hack for syntax trees not having great support for macros - // Just replace the element that the original range came from + // Just edit the element that the original range came from let old_place = { // Find the original element let file = ctx.sema.parse(arm_list_range.file_id); @@ -302,25 +267,27 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) }; let mut editor = builder.make_editor(&old_place); - let new_match_arm_list = new_match_arm_list.indent(IndentLevel::from_node(&old_place)); - editor.replace(old_place, new_match_arm_list.syntax()); + let mut arms_edit = ArmsEdit { match_arm_list, place: old_place, last_arm: None }; + + arms_edit.remove_wildcard_arms(ctx, &mut editor); + arms_edit.add_comma_after_last_arm(ctx, &make, &mut editor); + arms_edit.append_arms(&missing_arms, &make, &mut editor); if let Some(cap) = ctx.config.snippet_cap { - if let Some(it) = new_match_arm_list - .arms() - .nth(first_new_arm_idx) + if let Some(it) = missing_arms + .first() .and_then(|arm| arm.syntax().descendants().find_map(ast::WildcardPat::cast)) { editor.add_annotation(it.syntax(), builder.make_placeholder_snippet(cap)); } - for arm in new_match_arm_list.arms().skip(first_new_arm_idx) { + for arm in &missing_arms { if let Some(expr) = arm.expr() { editor.add_annotation(expr.syntax(), builder.make_placeholder_snippet(cap)); } } - if let Some(arm) = new_match_arm_list.arms().skip(first_new_arm_idx).last() { + if let Some(arm) = missing_arms.last() { editor.add_annotation(arm.syntax(), builder.make_tabstop_after(cap)); } } @@ -347,12 +314,24 @@ fn cursor_at_trivial_match_arm_list( // $0 // } if let Some(last_arm) = match_arm_list.arms().last() { - let last_arm_range = ctx.sema.original_range_opt(last_arm.syntax())?.range; + let last_node = match last_arm.expr() { + Some(expr) => expr.syntax().clone(), + None => last_arm.syntax().clone(), + }; + let last_node_range = ctx.sema.original_range_opt(&last_node)?.range; let match_expr_range = ctx.sema.original_range_opt(match_expr.syntax())?.range; - if last_arm_range.end() <= ctx.offset() && ctx.offset() < match_expr_range.end() { + if last_node_range.end() <= ctx.offset() && ctx.offset() < match_expr_range.end() { cov_mark::hit!(add_missing_match_arms_end_of_last_arm); return Some(()); } + + if ast::Expr::cast(last_node.clone()).is_some_and(is_empty_expr) + && last_node_range.contains(ctx.offset()) + && !last_node.text().contains_char('\n') + { + cov_mark::hit!(add_missing_match_arms_end_of_last_empty_arm); + return Some(()); + } } // match { _$0 => {...} } @@ -367,10 +346,113 @@ fn cursor_at_trivial_match_arm_list( None } +struct ArmsEdit { + match_arm_list: MatchArmList, + place: SyntaxNode, + last_arm: Option<ast::MatchArm>, +} + +impl ArmsEdit { + fn remove_wildcard_arms(&mut self, ctx: &AssistContext<'_>, editor: &mut SyntaxEditor) { + for arm in self.match_arm_list.arms() { + if !matches!(arm.pat(), Some(Pat::WildcardPat(_))) { + self.last_arm = Some(arm); + continue; + } + if !arm.expr().is_none_or(is_empty_expr) { + cov_mark::hit!(add_missing_match_arms_empty_expr); + self.last_arm = Some(arm); + continue; + } + let Some(range) = self.cover_edit_range(ctx, &arm) else { continue }; + + let prev = match range.start() { + syntax::NodeOrToken::Node(node) => { + node.first_token().and_then(|it| it.prev_token()) + } + syntax::NodeOrToken::Token(tok) => tok.prev_token(), + }; + if let Some(prev) = prev + && prev.kind() == SyntaxKind::WHITESPACE + { + editor.delete(prev); + } + + editor.delete_all(range); + } + } + + fn append_arms(&self, arms: &[ast::MatchArm], make: &SyntaxFactory, editor: &mut SyntaxEditor) { + let Some(mut before) = self.place.last_token() else { + stdx::never!("match arm list not contain any token"); + return; + }; + if let Some(prev) = before.prev_token() + && prev.kind() == SyntaxKind::WHITESPACE + { + before = prev; + } + let open_curly = + !self.place.text().contains_char('\n') || before.kind() == SyntaxKind::WHITESPACE; + let indent = IndentLevel::from_node(&self.place); + let arm_indent = indent + 1; + let indent = make.whitespace(&format!("\n{indent}")); + let arm_indent = make.whitespace(&format!("\n{arm_indent}")); + let elements = arms + .iter() + .flat_map(|arm| [arm_indent.clone().into(), arm.syntax().clone().into()]) + .chain(open_curly.then(|| indent.clone().into())) + .collect(); + + if before.kind() == SyntaxKind::WHITESPACE { + editor.replace_with_many(before, elements); + } else { + editor.insert_all(Position::before(before), elements); + } + } + + fn add_comma_after_last_arm( + &self, + ctx: &AssistContext<'_>, + make: &SyntaxFactory, + editor: &mut SyntaxEditor, + ) { + if let Some(last_arm) = &self.last_arm + && last_arm.comma_token().is_none() + && last_arm.expr().is_none_or(|it| !it.is_block_like()) + && let Some(range) = self.cover_edit_range(ctx, last_arm) + { + editor.insert(Position::after(range.end()), make.token(syntax::T![,])); + } + } + + fn cover_edit_range( + &self, + ctx: &AssistContext<'_>, + node: &impl AstNode, + ) -> Option<std::ops::RangeInclusive<syntax::SyntaxElement>> { + let range = ctx.sema.original_range_opt(node.syntax())?; + + if !self.place.text_range().contains_range(range.range) { + return None; + } + + Some(utils::cover_edit_range(&self.place, range.range)) + } +} + fn is_variant_missing(existing_pats: &[Pat], var: &Pat) -> bool { !existing_pats.iter().any(|pat| does_pat_match_variant(pat, var)) } +fn is_empty_expr(e: ast::Expr) -> bool { + match e { + ast::Expr::BlockExpr(b) => b.statements().next().is_none() && b.tail_expr().is_none(), + ast::Expr::TupleExpr(t) => t.fields().next().is_none(), + _ => false, + } +} + // Fixme: this is still somewhat limited, use hir_ty::diagnostics::match_check? fn does_pat_match_variant(pat: &Pat, var: &Pat) -> bool { match (pat, var) { @@ -396,7 +478,7 @@ enum ExtendedEnum { enum ExtendedVariant { True, False, - Variant { variant: hir::Variant, use_self: bool }, + Variant { variant: hir::EnumVariant, use_self: bool }, } impl ExtendedVariant { @@ -1066,7 +1148,7 @@ fn main() { #[test] fn add_missing_match_arms_end_of_last_arm() { - cov_mark::check!(add_missing_match_arms_end_of_last_arm); + cov_mark::check_count!(add_missing_match_arms_end_of_last_arm, 2); check_assist( add_missing_match_arms, r#" @@ -1097,6 +1179,103 @@ fn main() { } "#, ); + + check_assist( + add_missing_match_arms, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => 2$0, + } +} +"#, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => 2, + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::Two) => ${3:todo!()},$0 + } +} +"#, + ); + } + + #[test] + fn add_missing_match_arms_end_of_last_empty_arm() { + cov_mark::check_count!(add_missing_match_arms_end_of_last_empty_arm, 2); + check_assist( + add_missing_match_arms, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => {$0} + } +} +"#, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => {} + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::Two) => ${3:todo!()},$0 + } +} +"#, + ); + + check_assist( + add_missing_match_arms, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => ($0) + } +} +"#, + r#" +enum A { One, Two } +enum B { One, Two } + +fn main() { + let a = A::One; + let b = B::One; + match (a, b) { + (A::Two, B::One) => (), + (A::One, B::One) => ${1:todo!()}, + (A::One, B::Two) => ${2:todo!()}, + (A::Two, B::Two) => ${3:todo!()},$0 + } +} +"#, + ); } #[test] @@ -1639,7 +1818,7 @@ enum Test { fn foo(t: Test) { m!(match t { - Test::A=>(), + Test::A => (), Test::B => ${1:todo!()}, Test::C => ${2:todo!()},$0 }); @@ -2078,6 +2257,35 @@ fn foo(t: E) { } #[test] + fn keep_comments() { + check_assist( + add_missing_match_arms, + r#" +enum E { A, B, C } + +fn foo(t: E) -> i32 { + match $0t { + // variant a + E::A => 2 + // comment on end + } +}"#, + r#" +enum E { A, B, C } + +fn foo(t: E) -> i32 { + match t { + // variant a + E::A => 2, + // comment on end + E::B => ${1:todo!()}, + E::C => ${2:todo!()},$0 + } +}"#, + ); + } + + #[test] fn not_applicable_when_match_arm_list_cannot_be_upmapped() { check_assist_not_applicable( add_missing_match_arms,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 80d0a6d..4ee4970 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -197,7 +197,7 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> let (name, arg_expr) = validate_method_call_expr(ctx, &method_call)?; let ast::Expr::ClosureExpr(closure_expr) = arg_expr else { return None }; - let closure_body = closure_expr.body()?.clone_for_update(); + let closure_body = closure_expr.body()?; let op_range = method_call.syntax().text_range(); let label = format!("Apply De Morgan's law to `Iterator::{}`", name.text().as_str());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index da5c123..de5dfdf 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
@@ -268,7 +268,7 @@ pub(crate) fn relevance_score( hir::Adt::Union(it) => it.ty(ctx.db()), hir::Adt::Enum(it) => it.ty(ctx.db()), }), - hir::ModuleDef::Variant(variant) => Some(variant.constructor_ty(ctx.db())), + hir::ModuleDef::EnumVariant(variant) => Some(variant.constructor_ty(ctx.db())), hir::ModuleDef::Const(it) => Some(it.ty(ctx.db())), hir::ModuleDef::Static(it) => Some(it.ty(ctx.db())), hir::ModuleDef::TypeAlias(it) => Some(it.ty(ctx.db())),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 2364369..b3bfe5b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
@@ -237,7 +237,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> fn option_variants( sema: &Semantics<'_, RootDatabase>, expr: &SyntaxNode, -) -> Option<(hir::Variant, hir::Variant)> { +) -> Option<(hir::EnumVariant, hir::EnumVariant)> { let fam = FamousDefs(sema, sema.scope(expr)?.krate()); let option_variants = fam.core_option_Option()?.variants(sema.db); match &*option_variants { @@ -254,7 +254,7 @@ fn option_variants( /// If any of these conditions are met it is impossible to rewrite this as a `bool::then` call. fn is_invalid_body( sema: &Semantics<'_, RootDatabase>, - some_variant: hir::Variant, + some_variant: hir::EnumVariant, expr: &ast::Expr, ) -> bool { let mut invalid = false; @@ -277,7 +277,7 @@ fn is_invalid_body( && let Some(ast::Expr::PathExpr(p)) = call.expr() { let res = p.path().and_then(|p| sema.resolve_path(&p)); - if let Some(hir::PathResolution::Def(hir::ModuleDef::Variant(v))) = res { + if let Some(hir::PathResolution::Def(hir::ModuleDef::EnumVariant(v))) = res { return invalid |= v != some_variant; } } @@ -290,11 +290,11 @@ fn is_invalid_body( fn block_is_none_variant( sema: &Semantics<'_, RootDatabase>, block: &ast::BlockExpr, - none_variant: hir::Variant, + none_variant: hir::EnumVariant, ) -> bool { block_as_lone_tail(block).and_then(|e| match e { ast::Expr::PathExpr(pat) => match sema.resolve_path(&pat.path()?)? { - hir::PathResolution::Def(hir::ModuleDef::Variant(v)) => Some(v), + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(v)) => Some(v), _ => None, }, _ => None,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index 9347798..e88778a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs
@@ -533,7 +533,7 @@ fn make_bool_enum(make_pub: bool, make: &SyntaxFactory) -> ast::Enum { ], ), )); - make.enum_( + make.item_enum( [derive_eq], if make_pub { Some(make.visibility_pub()) } else { None }, make.name("Bool"),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs index 5a223e1..9f9ced9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
@@ -220,7 +220,7 @@ pub(crate) fn convert_closure_to_fn(acc: &mut Assists, ctx: &AssistContext<'_>) } let body = if wrap_body_in_block { - make::block_expr([], Some(body)) + make::block_expr([], Some(body.reset_indent().indent(1.into()))) } else { ast::BlockExpr::cast(body.syntax().clone()).unwrap() }; @@ -971,6 +971,32 @@ fn closure() { } "#, ); + check_assist( + convert_closure_to_fn, + r#" +//- minicore: copy +fn foo() { + { + let closure = |$0| match () { + () => {}, + }; + closure(); + } +} +"#, + r#" +fn foo() { + { + fn closure() { + match () { + () => {}, + } + } + closure(); + } +} +"#, + ); } #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index d64e9ce..15f324e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs
@@ -2,7 +2,7 @@ use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name}; use syntax::{ AstNode, - ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, + ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel, syntax_factory::SyntaxFactory}, syntax_editor::Position, }; @@ -24,8 +24,8 @@ // ``` // fn main() { // let x = vec![1, 2, 3]; -// let mut tmp = x.into_iter(); -// while let Some(v) = tmp.next() { +// let mut iter = x.into_iter(); +// while let Some(v) = iter.next() { // let y = v * 2; // }; // } @@ -57,13 +57,13 @@ pub(crate) fn convert_for_loop_to_while_let( { (expr, Some(make.name_ref(method.as_str()))) } else if let ast::Expr::RefExpr(_) = iterable { - (make::expr_paren(iterable).into(), Some(make.name_ref("into_iter"))) + (make.expr_paren(iterable).into(), Some(make.name_ref("into_iter"))) } else { (iterable, Some(make.name_ref("into_iter"))) }; let iterable = if let Some(method) = method { - make::expr_method_call(iterable, method, make::arg_list([])).into() + make.expr_method_call(iterable, method, make.arg_list([])).into() } else { iterable }; @@ -71,7 +71,7 @@ pub(crate) fn convert_for_loop_to_while_let( let mut new_name = suggest_name::NameGenerator::new_from_scope_locals( ctx.sema.scope(for_loop.syntax()), ); - let tmp_var = new_name.suggest_name("tmp"); + let tmp_var = new_name.suggest_name("iter"); let mut_expr = make.let_stmt( make.ident_pat(false, true, make.name(&tmp_var)).into(), @@ -89,17 +89,18 @@ pub(crate) fn convert_for_loop_to_while_let( for_loop.syntax(), &mut editor, for_loop.attrs().map(|it| it.clone_for_update()), + &make, ); editor.insert( Position::before(for_loop.syntax()), - make::tokens::whitespace(format!("\n{indent}").as_str()), + make.whitespace(format!("\n{indent}").as_str()), ); editor.insert(Position::before(for_loop.syntax()), mut_expr.syntax()); - let opt_pat = make.tuple_struct_pat(make::ext::ident_path("Some"), [pat]); + let opt_pat = make.tuple_struct_pat(make.ident_path("Some"), [pat]); let iter_next_expr = make.expr_method_call( - make.expr_path(make::ext::ident_path(&tmp_var)), + make.expr_path(make.ident_path(&tmp_var)), make.name_ref("next"), make.arg_list([]), ); @@ -187,8 +188,8 @@ fn main() { r" fn main() { let mut x = vec![1, 2, 3]; - let mut tmp = x.into_iter(); - while let Some(v) = tmp.next() { + let mut iter = x.into_iter(); + while let Some(v) = iter.next() { v *= 2; }; }", @@ -210,8 +211,8 @@ fn main() { r" fn main() { let mut x = vec![1, 2, 3]; - let mut tmp = x.into_iter(); - 'a: while let Some(v) = tmp.next() { + let mut iter = x.into_iter(); + 'a: while let Some(v) = iter.next() { v *= 2; break 'a; }; @@ -235,10 +236,10 @@ fn main() { r" fn main() { let mut x = vec![1, 2, 3]; - let mut tmp = x.into_iter(); + let mut iter = x.into_iter(); #[allow(unused)] #[deny(unsafe_code)] - while let Some(v) = tmp.next() { + while let Some(v) = iter.next() { v *= 2; }; }", @@ -274,8 +275,8 @@ fn next(&mut self) -> Option<Self::Item> { } fn main() { - let mut tmp = 0..92; - while let Some(x) = tmp.next() { + let mut iter = 0..92; + while let Some(x) = iter.next() { print!("{}", x); } }"#, @@ -329,8 +330,8 @@ fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) } fn main() { let x = S; - let mut tmp = x.iter(); - while let Some(v) = tmp.next() { + let mut iter = x.iter(); + while let Some(v) = iter.next() { let a = v * 2; } } @@ -355,8 +356,8 @@ fn main() { struct NoIterMethod; fn main() { let x = NoIterMethod; - let mut tmp = (&x).into_iter(); - while let Some(v) = tmp.next() { + let mut iter = (&x).into_iter(); + while let Some(v) = iter.next() { let a = v * 2; } } @@ -381,8 +382,8 @@ fn main() { struct NoIterMethod; fn main() { let x = NoIterMethod; - let mut tmp = (&mut x).into_iter(); - while let Some(v) = tmp.next() { + let mut iter = (&mut x).into_iter(); + while let Some(v) = iter.next() { let a = v * 2; } } @@ -422,8 +423,8 @@ fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) } fn main() { let x = S; - let mut tmp = x.iter_mut(); - while let Some(v) = tmp.next() { + let mut iter = x.iter_mut(); + while let Some(v) = iter.next() { let a = v * 2; } } @@ -447,8 +448,8 @@ fn main() { fn main() { let mut x = vec![1, 2, 3]; let y = &mut x; - let mut tmp = y.into_iter(); - while let Some(v) = tmp.next() { + let mut iter = y.into_iter(); + while let Some(v) = iter.next() { *v *= 2; } }", @@ -470,8 +471,8 @@ fn main() { "#, r#" fn main() { - let mut tmp = core::iter::repeat(92).take(1); - while let Some(a) = tmp.next() { + let mut iter = core::iter::repeat(92).take(1); + while let Some(a) = iter.next() { println!("{}", a); } }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index 6a74d21..66ccd2a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
@@ -1,6 +1,6 @@ use ide_db::{famous_defs::FamousDefs, traits::resolve_target_trait}; use syntax::ast::edit::IndentLevel; -use syntax::ast::{self, AstNode, HasGenericArgs, HasName, make}; +use syntax::ast::{self, AstNode, HasGenericArgs, HasName, syntax_factory::SyntaxFactory}; use syntax::syntax_editor::{Element, Position}; use crate::{AssistContext, AssistId, Assists}; @@ -74,36 +74,25 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> "Convert From to TryFrom", impl_.syntax().text_range(), |builder| { + let make = SyntaxFactory::with_mappings(); let mut editor = builder.make_editor(impl_.syntax()); - editor.replace( - trait_ty.syntax(), - make::ty(&format!("TryFrom<{from_type}>")).syntax().clone_for_update(), - ); + + editor.replace(trait_ty.syntax(), make.ty(&format!("TryFrom<{from_type}>")).syntax()); editor.replace( from_fn_return_type.syntax(), - make::ty("Result<Self, Self::Error>").syntax().clone_for_update(), + make.ty("Result<Self, Self::Error>").syntax(), ); - editor - .replace(from_fn_name.syntax(), make::name("try_from").syntax().clone_for_update()); - editor.replace( - tail_expr.syntax(), - wrap_ok(tail_expr.clone()).syntax().clone_for_update(), - ); + editor.replace(from_fn_name.syntax(), make.name("try_from").syntax()); + editor.replace(tail_expr.syntax(), wrap_ok(&make, tail_expr.clone()).syntax()); for r in return_exprs { - let t = r.expr().unwrap_or_else(make::ext::expr_unit); - editor.replace(t.syntax(), wrap_ok(t.clone()).syntax().clone_for_update()); + let t = r.expr().unwrap_or_else(|| make.expr_unit()); + editor.replace(t.syntax(), wrap_ok(&make, t.clone()).syntax()); } - let error_type = ast::AssocItem::TypeAlias(make::ty_alias( - None, - "Error", - None, - None, - None, - Some((make::ty_unit(), None)), - )) - .clone_for_update(); + let error_type_alias = + make.ty_alias(None, "Error", None, None, None, Some((make.ty("()"), None))); + let error_type = ast::AssocItem::TypeAlias(error_type_alias); if let Some(cap) = ctx.config.snippet_cap && let ast::AssocItem::TypeAlias(type_alias) = &error_type @@ -117,22 +106,19 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> editor.insert_all( Position::after(associated_l_curly), vec![ - make::tokens::whitespace(&format!("\n{indent}")).syntax_element(), + make.whitespace(&format!("\n{indent}")).syntax_element(), error_type.syntax().syntax_element(), - make::tokens::whitespace("\n").syntax_element(), + make.whitespace("\n").syntax_element(), ], ); + editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } -fn wrap_ok(expr: ast::Expr) -> ast::Expr { - make::expr_call( - make::expr_path(make::ext::ident_path("Ok")), - make::arg_list(std::iter::once(expr)), - ) - .into() +fn wrap_ok(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { + make.expr_call(make.expr_path(make.path_from_text("Ok")), make.arg_list([expr])).into() } #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index e518c39..aaf7270 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -1,14 +1,18 @@ use either::Either; use ide_db::{defs::Definition, search::FileReference}; -use itertools::Itertools; use syntax::{ - SyntaxKind, - ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility}, + NodeOrToken, SyntaxKind, SyntaxNode, T, + algo::next_non_trivia_token, + ast::{ + self, AstNode, HasAttrs, HasGenericParams, HasVisibility, syntax_factory::SyntaxFactory, + }, match_ast, - syntax_editor::{Position, SyntaxEditor}, + syntax_editor::{Element, Position, SyntaxEditor}, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; +use crate::{ + AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::cover_edit_range, +}; // Assist: convert_named_struct_to_tuple_struct // @@ -81,17 +85,17 @@ pub(crate) fn convert_named_struct_to_tuple_struct( AssistId::refactor_rewrite("convert_named_struct_to_tuple_struct"), "Convert to tuple struct", strukt_or_variant.syntax().text_range(), - |edit| { - edit_field_references(ctx, edit, record_fields.fields()); - edit_struct_references(ctx, edit, strukt_def); - edit_struct_def(ctx, edit, &strukt_or_variant, record_fields); + |builder| { + edit_field_references(ctx, builder, record_fields.fields()); + edit_struct_references(ctx, builder, strukt_def); + edit_struct_def(ctx, builder, &strukt_or_variant, record_fields); }, ) } fn edit_struct_def( ctx: &AssistContext<'_>, - edit: &mut SourceChangeBuilder, + builder: &mut SourceChangeBuilder, strukt: &Either<ast::Struct, ast::Variant>, record_fields: ast::RecordFieldList, ) { @@ -108,24 +112,23 @@ fn edit_struct_def( let field = ast::TupleField::cast(field_syntax)?; Some(field) }); - let tuple_fields = ast::make::tuple_field_list(tuple_fields); - let record_fields_text_range = record_fields.syntax().text_range(); - edit.edit_file(ctx.vfs_file_id()); - edit.replace(record_fields_text_range, tuple_fields.syntax().text()); + let make = SyntaxFactory::without_mappings(); + let mut edit = builder.make_editor(strukt.syntax()); + let tuple_fields = make.tuple_field_list(tuple_fields); + + let mut elements = vec![tuple_fields.syntax().clone().into()]; if let Either::Left(strukt) = strukt { if let Some(w) = strukt.where_clause() { - let mut where_clause = w.to_string(); - if where_clause.ends_with(',') { - where_clause.pop(); - } - where_clause.push(';'); + edit.delete(w.syntax()); - edit.delete(w.syntax().text_range()); - edit.insert(record_fields_text_range.end(), ast::make::tokens::single_newline().text()); - edit.insert(record_fields_text_range.end(), where_clause); - edit.insert(record_fields_text_range.end(), ast::make::tokens::single_newline().text()); + elements.extend([ + make.whitespace("\n").into(), + remove_trailing_comma(w).into(), + make.token(T![;]).into(), + make.whitespace("\n").into(), + ]); if let Some(tok) = strukt .generic_param_list() @@ -133,45 +136,51 @@ fn edit_struct_def( .and_then(|tok| tok.next_token()) .filter(|tok| tok.kind() == SyntaxKind::WHITESPACE) { - edit.delete(tok.text_range()); + edit.delete(tok); } } else { - edit.insert(record_fields_text_range.end(), ";"); + elements.push(make.token(T![;]).into()); } } + edit.replace_with_many(record_fields.syntax(), elements); if let Some(tok) = record_fields .l_curly_token() .and_then(|tok| tok.prev_token()) .filter(|tok| tok.kind() == SyntaxKind::WHITESPACE) { - edit.delete(tok.text_range()) + edit.delete(tok) } + + builder.add_file_edits(ctx.vfs_file_id(), edit); } fn edit_struct_references( ctx: &AssistContext<'_>, - edit: &mut SourceChangeBuilder, - strukt: Either<hir::Struct, hir::Variant>, + builder: &mut SourceChangeBuilder, + strukt: Either<hir::Struct, hir::EnumVariant>, ) { let strukt_def = match strukt { Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)), - Either::Right(v) => Definition::Variant(v), + Either::Right(v) => Definition::EnumVariant(v), }; let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); for (file_id, refs) in usages { - edit.edit_file(file_id.file_id(ctx.db())); + let source = ctx.sema.parse(file_id); + let mut edit = builder.make_editor(source.syntax()); for r in refs { - process_struct_name_reference(ctx, r, edit); + process_struct_name_reference(ctx, r, &mut edit, &source); } + builder.add_file_edits(file_id.file_id(ctx.db()), edit); } } fn process_struct_name_reference( ctx: &AssistContext<'_>, r: FileReference, - edit: &mut SourceChangeBuilder, + edit: &mut SyntaxEditor, + source: &ast::SourceFile, ) -> Option<()> { // First check if it's the last semgnet of a path that directly belongs to a record // expression/pattern. @@ -192,36 +201,26 @@ fn process_struct_name_reference( match_ast! { match parent { ast::RecordPat(record_struct_pat) => { - // When we failed to get the original range for the whole struct expression node, + // When we failed to get the original range for the whole struct pattern node, // we can't provide any reasonable edit. Leave it untouched. - let file_range = ctx.sema.original_range_opt(record_struct_pat.syntax())?; - edit.replace( - file_range.range, - ast::make::tuple_struct_pat( - record_struct_pat.path()?, - record_struct_pat - .record_pat_field_list()? - .fields() - .filter_map(|pat| pat.pat()) - .chain(record_struct_pat.record_pat_field_list()? - .rest_pat() - .map(Into::into)) - ) - .to_string() + record_to_tuple_struct_like( + ctx, + source, + edit, + record_struct_pat.record_pat_field_list()?, + |it| it.fields().filter_map(|it| it.name_ref()), ); }, ast::RecordExpr(record_expr) => { - // When we failed to get the original range for the whole struct pattern node, + // When we failed to get the original range for the whole struct expression node, // we can't provide any reasonable edit. Leave it untouched. - let file_range = ctx.sema.original_range_opt(record_expr.syntax())?; - let path = record_expr.path()?; - let args = record_expr - .record_expr_field_list()? - .fields() - .filter_map(|f| f.expr()) - .join(", "); - - edit.replace(file_range.range, format!("{path}({args})")); + record_to_tuple_struct_like( + ctx, + source, + edit, + record_expr.record_expr_field_list()?, + |it| it.fields().filter_map(|it| it.name_ref()), + ); }, _ => {} } @@ -230,11 +229,67 @@ fn process_struct_name_reference( Some(()) } +fn record_to_tuple_struct_like<T, I>( + ctx: &AssistContext<'_>, + source: &ast::SourceFile, + edit: &mut SyntaxEditor, + field_list: T, + fields: impl FnOnce(&T) -> I, +) -> Option<()> +where + T: AstNode, + I: IntoIterator<Item = ast::NameRef>, +{ + let make = SyntaxFactory::without_mappings(); + let orig = ctx.sema.original_range_opt(field_list.syntax())?; + let list_range = cover_edit_range(source.syntax(), orig.range); + + let l_curly = match list_range.start() { + NodeOrToken::Node(node) => node.first_token()?, + NodeOrToken::Token(t) => t.clone(), + }; + let r_curly = match list_range.end() { + NodeOrToken::Node(node) => node.last_token()?, + NodeOrToken::Token(t) => t.clone(), + }; + + if l_curly.kind() == T!['{'] { + delete_whitespace(edit, l_curly.prev_token()); + delete_whitespace(edit, l_curly.next_token()); + edit.replace(l_curly, make.token(T!['('])); + } + if r_curly.kind() == T!['}'] { + delete_whitespace(edit, r_curly.prev_token()); + edit.replace(r_curly, make.token(T![')'])); + } + + for name_ref in fields(&field_list) { + let Some(orig) = ctx.sema.original_range_opt(name_ref.syntax()) else { continue }; + let name_range = cover_edit_range(source.syntax(), orig.range); + + if let Some(colon) = next_non_trivia_token(name_range.end().clone()) + && colon.kind() == T![:] + { + edit.delete(&colon); + edit.delete_all(name_range); + + if let Some(next) = next_non_trivia_token(colon.clone()) + && next.kind() != T!['}'] + { + // Avoid overlapping delete whitespace on `{ field: }` + delete_whitespace(edit, colon.next_token()); + } + } + } + Some(()) +} + fn edit_field_references( ctx: &AssistContext<'_>, - edit: &mut SourceChangeBuilder, + builder: &mut SourceChangeBuilder, fields: impl Iterator<Item = ast::RecordField>, ) { + let make = SyntaxFactory::without_mappings(); for (index, field) in fields.enumerate() { let field = match ctx.sema.to_def(&field) { Some(it) => it, @@ -243,19 +298,46 @@ fn edit_field_references( let def = Definition::Field(field); let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { - edit.edit_file(file_id.file_id(ctx.db())); + let source = ctx.sema.parse(file_id); + let mut edit = builder.make_editor(source.syntax()); + for r in refs { if let Some(name_ref) = r.name.as_name_ref() { // Only edit the field reference if it's part of a `.field` access if name_ref.syntax().parent().and_then(ast::FieldExpr::cast).is_some() { - edit.replace(r.range, index.to_string()); + edit.replace_all( + cover_edit_range(source.syntax(), r.range), + vec![make.name_ref(&index.to_string()).syntax().clone().into()], + ); } } } + + builder.add_file_edits(file_id.file_id(ctx.db()), edit); } } } +fn delete_whitespace(edit: &mut SyntaxEditor, whitespace: Option<impl Element>) { + let Some(whitespace) = whitespace else { return }; + let NodeOrToken::Token(token) = whitespace.syntax_element() else { return }; + + if token.kind() == SyntaxKind::WHITESPACE && !token.text().contains('\n') { + edit.delete(token); + } +} + +fn remove_trailing_comma(w: ast::WhereClause) -> SyntaxNode { + let w = w.syntax().clone_subtree(); + let mut editor = SyntaxEditor::new(w.clone()); + if let Some(last) = w.last_child_or_token() + && last.kind() == T![,] + { + editor.delete(last); + } + editor.finish().new_root().clone() +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -678,6 +760,102 @@ struct Wrap<T>(T) } #[test] + fn convert_constructor_expr_uses_self() { + // regression test for #21595 + check_assist( + convert_named_struct_to_tuple_struct, + r#" +struct $0Foo { field1: u32 } +impl Foo { + fn clone(&self) -> Self { + Self { field1: self.field1 } + } +}"#, + r#" +struct Foo(u32); +impl Foo { + fn clone(&self) -> Self { + Self(self.0) + } +}"#, + ); + + check_assist( + convert_named_struct_to_tuple_struct, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +struct $0Foo { field1: u32 } +impl Foo { + fn clone(&self) -> Self { + id!(Self { field1: self.field1 }) + } +}"#, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +struct Foo(u32); +impl Foo { + fn clone(&self) -> Self { + id!(Self(self.0)) + } +}"#, + ); + } + + #[test] + fn convert_pat_uses_self() { + // regression test for #21595 + check_assist( + convert_named_struct_to_tuple_struct, + r#" +enum Foo { + $0Value { field: &'static Foo }, + Nil, +} +fn foo(foo: &Foo) { + if let Foo::Value { field: Foo::Value { field } } = foo {} +}"#, + r#" +enum Foo { + Value(&'static Foo), + Nil, +} +fn foo(foo: &Foo) { + if let Foo::Value(Foo::Value(field)) = foo {} +}"#, + ); + + check_assist( + convert_named_struct_to_tuple_struct, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +enum Foo { + $0Value { field: &'static Foo }, + Nil, +} +fn foo(foo: &Foo) { + if let id!(Foo::Value { field: Foo::Value { field } }) = foo {} +}"#, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +enum Foo { + Value(&'static Foo), + Nil, +} +fn foo(foo: &Foo) { + if let id!(Foo::Value(Foo::Value(field))) = foo {} +}"#, + ); + } + + #[test] fn not_applicable_other_than_record_variant() { check_assist_not_applicable( convert_named_struct_to_tuple_struct, @@ -1042,7 +1220,9 @@ macro_rules! id { fn test() { id! { - let s = Struct(42); + let s = Struct( + 42, + ); let Struct(value) = s; let Struct(inner) = s; }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index dc51bf4..db45916 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -10,14 +10,14 @@ ast::{ self, edit::{AstNodeEdit, IndentLevel}, - make, + syntax_factory::SyntaxFactory, }, }; use crate::{ AssistId, assist_context::{AssistContext, Assists}, - utils::{invert_boolean_expression_legacy, is_never_block}, + utils::{invert_boolean_expression, is_never_block}, }; // Assist: convert_to_guarded_return @@ -69,6 +69,7 @@ fn if_expr_to_guarded_return( acc: &mut Assists, ctx: &AssistContext<'_>, ) -> Option<()> { + let make = SyntaxFactory::without_mappings(); let else_block = match if_expr.else_branch() { Some(ast::ElseBranch::Block(block_expr)) if is_never_block(&ctx.sema, &block_expr) => { Some(block_expr) @@ -88,7 +89,7 @@ fn if_expr_to_guarded_return( return None; } - let let_chains = flat_let_chain(cond); + let let_chains = flat_let_chain(cond, &make); let then_branch = if_expr.then_branch()?; let then_block = then_branch.stmt_list()?; @@ -110,7 +111,8 @@ fn if_expr_to_guarded_return( let early_expression = else_block .or_else(|| { - early_expression(parent_container, &ctx.sema).map(ast::make::tail_only_block_expr) + early_expression(parent_container, &ctx.sema, &make) + .map(ast::make::tail_only_block_expr) })? .reset_indent(); @@ -133,6 +135,7 @@ fn if_expr_to_guarded_return( "Convert to guarded return", target, |edit| { + let make = SyntaxFactory::without_mappings(); let if_indent_level = IndentLevel::from_node(if_expr.syntax()); let replacement = let_chains.into_iter().map(|expr| { if let ast::Expr::LetExpr(let_expr) = &expr @@ -140,15 +143,15 @@ fn if_expr_to_guarded_return( { // If-let. let let_else_stmt = - make::let_else_stmt(pat, None, expr, early_expression.clone()); + make.let_else_stmt(pat, None, expr, early_expression.clone()); let let_else_stmt = let_else_stmt.indent(if_indent_level); let_else_stmt.syntax().clone() } else { // If. let new_expr = { - let then_branch = clean_stmt_block(&early_expression); - let cond = invert_boolean_expression_legacy(expr); - make::expr_if(cond, then_branch, None).indent(if_indent_level) + let then_branch = clean_stmt_block(&early_expression, &make); + let cond = invert_boolean_expression(&make, expr); + make.expr_if(cond, then_branch, None).indent(if_indent_level) }; new_expr.syntax().clone() } @@ -159,7 +162,7 @@ fn if_expr_to_guarded_return( .enumerate() .flat_map(|(i, node)| { (i != 0) - .then(|| make::tokens::whitespace(newline).into()) + .then(|| make.whitespace(newline).into()) .into_iter() .chain(node.children_with_tokens()) }) @@ -201,12 +204,13 @@ fn let_stmt_to_guarded_return( let happy_pattern = try_enum.happy_pattern(pat); let target = let_stmt.syntax().text_range(); + let make = SyntaxFactory::without_mappings(); let early_expression: ast::Expr = { let parent_block = let_stmt.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?; let parent_container = parent_block.syntax().parent()?; - early_expression(parent_container, &ctx.sema)? + early_expression(parent_container, &ctx.sema, &make)? }; acc.add( @@ -215,9 +219,10 @@ fn let_stmt_to_guarded_return( target, |edit| { let let_indent_level = IndentLevel::from_node(let_stmt.syntax()); + let make = SyntaxFactory::without_mappings(); let replacement = { - let let_else_stmt = make::let_else_stmt( + let let_else_stmt = make.let_else_stmt( happy_pattern, let_stmt.ty(), expr.reset_indent(), @@ -228,6 +233,7 @@ fn let_stmt_to_guarded_return( }; let mut editor = edit.make_editor(let_stmt.syntax()); editor.replace(let_stmt.syntax(), replacement); + editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -236,38 +242,39 @@ fn let_stmt_to_guarded_return( fn early_expression( parent_container: SyntaxNode, sema: &Semantics<'_, RootDatabase>, + make: &SyntaxFactory, ) -> Option<ast::Expr> { let return_none_expr = || { - let none_expr = make::expr_path(make::ext::ident_path("None")); - make::expr_return(Some(none_expr)) + let none_expr = make.expr_path(make.ident_path("None")); + make.expr_return(Some(none_expr)) }; if let Some(fn_) = ast::Fn::cast(parent_container.clone()) && let Some(fn_def) = sema.to_def(&fn_) && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &fn_def.ret_type(sema.db)) { - return Some(return_none_expr()); + return Some(return_none_expr().into()); } if let Some(body) = ast::ClosureExpr::cast(parent_container.clone()).and_then(|it| it.body()) && let Some(ret_ty) = sema.type_of_expr(&body).map(TypeInfo::original) && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &ret_ty) { - return Some(return_none_expr()); + return Some(return_none_expr().into()); } Some(match parent_container.kind() { - WHILE_EXPR | LOOP_EXPR | FOR_EXPR => make::expr_continue(None), - FN | CLOSURE_EXPR => make::expr_return(None), + WHILE_EXPR | LOOP_EXPR | FOR_EXPR => make.expr_continue(None).into(), + FN | CLOSURE_EXPR => make.expr_return(None).into(), _ => return None, }) } -fn flat_let_chain(mut expr: ast::Expr) -> Vec<ast::Expr> { +fn flat_let_chain(mut expr: ast::Expr, make: &SyntaxFactory) -> Vec<ast::Expr> { let mut chains = vec![]; let mut reduce_cond = |rhs| { if !matches!(rhs, ast::Expr::LetExpr(_)) && let Some(last) = chains.pop_if(|last| !matches!(last, ast::Expr::LetExpr(_))) { - chains.push(make::expr_bin_op(rhs, ast::BinaryOp::LogicOp(ast::LogicOp::And), last)); + chains.push(make.expr_bin_op(rhs, ast::BinaryOp::LogicOp(ast::LogicOp::And), last)); } else { chains.push(rhs); } @@ -286,12 +293,12 @@ fn flat_let_chain(mut expr: ast::Expr) -> Vec<ast::Expr> { chains } -fn clean_stmt_block(block: &ast::BlockExpr) -> ast::BlockExpr { +fn clean_stmt_block(block: &ast::BlockExpr, make: &SyntaxFactory) -> ast::BlockExpr { if block.statements().next().is_none() && let Some(tail_expr) = block.tail_expr() && block.modifier().is_none() { - make::block_expr(once(make::expr_stmt(tail_expr).into()), None) + make.block_expr(once(make.expr_stmt(tail_expr).into()), None) } else { block.clone() }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index f8b9bb6..ae41e6c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -1,17 +1,21 @@ use either::Either; -use hir::FileRangeWrapper; -use ide_db::defs::{Definition, NameRefClass}; -use std::ops::RangeInclusive; +use ide_db::{ + defs::{Definition, NameRefClass}, + search::FileReference, +}; use syntax::{ - SyntaxElement, SyntaxKind, SyntaxNode, T, TextSize, + SyntaxKind, T, ast::{ - self, AstNode, HasAttrs, HasGenericParams, HasVisibility, syntax_factory::SyntaxFactory, + self, AstNode, HasArgList, HasAttrs, HasGenericParams, HasVisibility, + syntax_factory::SyntaxFactory, }, match_ast, syntax_editor::{Element, Position, SyntaxEditor}, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; +use crate::{ + AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::cover_edit_range, +}; // Assist: convert_tuple_struct_to_named_struct // @@ -138,102 +142,130 @@ fn edit_struct_def( fn edit_struct_references( ctx: &AssistContext<'_>, edit: &mut SourceChangeBuilder, - strukt: Either<hir::Struct, hir::Variant>, + strukt: Either<hir::Struct, hir::EnumVariant>, names: &[ast::Name], ) { let strukt_def = match strukt { Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)), - Either::Right(v) => Definition::Variant(v), + Either::Right(v) => Definition::EnumVariant(v), }; let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); - let edit_node = |node: SyntaxNode| -> Option<SyntaxNode> { - let make = SyntaxFactory::without_mappings(); - match_ast! { - match node { - ast::TupleStructPat(tuple_struct_pat) => { - Some(make.record_pat_with_fields( - tuple_struct_pat.path()?, - generate_record_pat_list(&tuple_struct_pat, names), - ).syntax().clone()) - }, - // for tuple struct creations like Foo(42) - ast::CallExpr(call_expr) => { - let path = call_expr.syntax().descendants().find_map(ast::PathExpr::cast).and_then(|expr| expr.path())?; - - // this also includes method calls like Foo::new(42), we should skip them - if let Some(name_ref) = path.segment().and_then(|s| s.name_ref()) { - match NameRefClass::classify(&ctx.sema, &name_ref) { - Some(NameRefClass::Definition(Definition::SelfType(_), _)) => {}, - Some(NameRefClass::Definition(def, _)) if def == strukt_def => {}, - _ => return None, - }; - } - - let arg_list = call_expr.syntax().descendants().find_map(ast::ArgList::cast)?; - Some( - make.record_expr( - path, - ast::make::record_expr_field_list(arg_list.args().zip(names).map( - |(expr, name)| { - ast::make::record_expr_field( - ast::make::name_ref(&name.to_string()), - Some(expr), - ) - }, - )), - ).syntax().clone() - ) - }, - _ => None, - } - } - }; - for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let source = source.syntax(); + let mut editor = edit.make_editor(source.syntax()); - let mut editor = edit.make_editor(source); - for r in refs.iter().rev() { - if let Some((old_node, new_node)) = r - .name - .syntax() - .ancestors() - .find_map(|node| Some((node.clone(), edit_node(node.clone())?))) - { - if let Some(old_node) = ctx.sema.original_syntax_node_rooted(&old_node) { - editor.replace(old_node, new_node); - } else { - let FileRangeWrapper { file_id: _, range } = ctx.sema.original_range(&old_node); - let parent = source.covering_element(range); - match parent { - SyntaxElement::Token(token) => { - editor.replace(token, new_node.syntax_element()); - } - SyntaxElement::Node(parent_node) => { - // replace the part of macro - // ``` - // foo!(a, Test::A(0)); - // ^^^^^^^^^^^^^^^ // parent_node - // ^^^^^^^^^^ // replace_range - // ``` - let start = parent_node - .children_with_tokens() - .find(|t| t.text_range().contains(range.start())); - let end = parent_node - .children_with_tokens() - .find(|t| t.text_range().contains(range.end() - TextSize::new(1))); - if let (Some(start), Some(end)) = (start, end) { - let replace_range = RangeInclusive::new(start, end); - editor.replace_all(replace_range, vec![new_node.into()]); - } - } + for r in refs { + process_struct_name_reference(ctx, r, &mut editor, &source, &strukt_def, names); + } + + edit.add_file_edits(file_id.file_id(ctx.db()), editor); + } +} + +fn process_struct_name_reference( + ctx: &AssistContext<'_>, + r: FileReference, + editor: &mut SyntaxEditor, + source: &ast::SourceFile, + strukt_def: &Definition, + names: &[ast::Name], +) -> Option<()> { + let make = SyntaxFactory::without_mappings(); + let name_ref = r.name.as_name_ref()?; + let path_segment = name_ref.syntax().parent().and_then(ast::PathSegment::cast)?; + let full_path = path_segment.syntax().parent().and_then(ast::Path::cast)?.top_path(); + + if full_path.segment()?.name_ref()? != *name_ref { + // `name_ref` isn't the last segment of the path, so `full_path` doesn't point to the + // struct we want to edit. + return None; + } + + let parent = full_path.syntax().parent()?; + match_ast! { + match parent { + ast::TupleStructPat(tuple_struct_pat) => { + let range = ctx.sema.original_range_opt(tuple_struct_pat.syntax())?.range; + let new = make.record_pat_with_fields( + full_path, + generate_record_pat_list(&tuple_struct_pat, names), + ); + editor.replace_all(cover_edit_range(source.syntax(), range), vec![new.syntax().clone().into()]); + }, + ast::PathExpr(path_expr) => { + let call_expr = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; + + // this also includes method calls like Foo::new(42), we should skip them + match NameRefClass::classify(&ctx.sema, name_ref) { + Some(NameRefClass::Definition(Definition::SelfType(_), _)) => {}, + Some(NameRefClass::Definition(def, _)) if def == *strukt_def => {}, + _ => return None, + } + + let arg_list = call_expr.arg_list()?; + let mut first_insert = vec![]; + for (expr, name) in arg_list.args().zip(names) { + let range = ctx.sema.original_range_opt(expr.syntax())?.range; + let place = cover_edit_range(source.syntax(), range); + let elements = vec![ + make.name_ref(&name.text()).syntax().clone().into(), + make.token(T![:]).into(), + make.whitespace(" ").into(), + ]; + if first_insert.is_empty() { + // XXX: SyntaxEditor cannot insert after deleted element + first_insert = elements; + } else { + editor.insert_all(Position::before(place.start()), elements); } } - } + process_delimiter(ctx, source, editor, &arg_list, first_insert); + }, + _ => {} } - edit.add_file_edits(file_id.file_id(ctx.db()), editor); + } + Some(()) +} + +fn process_delimiter( + ctx: &AssistContext<'_>, + source: &ast::SourceFile, + editor: &mut SyntaxEditor, + list: &impl AstNode, + first_insert: Vec<syntax::SyntaxElement>, +) { + let Some(range) = ctx.sema.original_range_opt(list.syntax()) else { return }; + let place = cover_edit_range(source.syntax(), range.range); + + let l_paren = match place.start() { + syntax::NodeOrToken::Node(node) => node.first_token(), + syntax::NodeOrToken::Token(t) => Some(t.clone()), + }; + let r_paren = match place.end() { + syntax::NodeOrToken::Node(node) => node.last_token(), + syntax::NodeOrToken::Token(t) => Some(t.clone()), + }; + + let make = SyntaxFactory::without_mappings(); + if let Some(l_paren) = l_paren + && l_paren.kind() == T!['('] + { + let mut open_delim = vec![ + make.whitespace(" ").into(), + make.token(T!['{']).into(), + make.whitespace(" ").into(), + ]; + open_delim.extend(first_insert); + editor.replace_with_many(l_paren, open_delim); + } + if let Some(r_paren) = r_paren + && r_paren.kind() == T![')'] + { + editor.replace_with_many( + r_paren, + vec![make.whitespace(" ").into(), make.token(T!['}']).into()], + ); } } @@ -252,13 +284,15 @@ fn edit_field_references( let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { let source = ctx.sema.parse(file_id); - let source = source.syntax(); - let mut editor = edit.make_editor(source); + let mut editor = edit.make_editor(source.syntax()); for r in refs { if let Some(name_ref) = r.name.as_name_ref() - && let Some(original) = ctx.sema.original_ast_node(name_ref.clone()) + && let Some(original) = ctx.sema.original_range_opt(name_ref.syntax()) { - editor.replace(original.syntax(), name.syntax()); + editor.replace_all( + cover_edit_range(source.syntax(), original.range), + vec![name.syntax().clone().into()], + ); } } edit.add_file_edits(file_id.file_id(ctx.db()), editor); @@ -739,6 +773,64 @@ struct Wrap<T> "#, ); } + + #[test] + fn convert_expr_uses_self() { + check_assist( + convert_tuple_struct_to_named_struct, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +struct T$0(u8); +fn test(t: T) { + T(t.0); + id!(T(t.0)); +}"#, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +struct T { field1: u8 } +fn test(t: T) { + T { field1: t.field1 }; + id!(T { field1: t.field1 }); +}"#, + ); + } + + #[test] + #[ignore = "FIXME overlap edits in nested uses self"] + fn convert_pat_uses_self() { + check_assist( + convert_tuple_struct_to_named_struct, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +enum T { + $0Value(&'static T), + Nil, +} +fn test(t: T) { + if let T::Value(T::Value(t)) = t {} + if let id!(T::Value(T::Value(t))) = t {} +}"#, + r#" +macro_rules! id { + ($($t:tt)*) => { $($t)* } +} +enum T { + Value { field1: &'static T }, + Nil, +} +fn test(t: T) { + if let T::Value { field1: T::Value { field1: t } } = t {} + if let id!(T::Value { field1: T::Value { field1: t } }) = t {} +}"#, + ); + } + #[test] fn not_applicable_other_than_tuple_variant() { check_assist_not_applicable(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs index 9fd8b4b..f8215d6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs
@@ -6,7 +6,7 @@ ast::{ self, HasLoopBody, edit::{AstNodeEdit, IndentLevel}, - make, + syntax_factory::SyntaxFactory, }, syntax_editor::{Element, Position}, }; @@ -14,7 +14,7 @@ use crate::{ AssistId, assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression_legacy, + utils::invert_boolean_expression, }; // Assist: convert_while_to_loop @@ -52,44 +52,47 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) "Convert while to loop", target, |builder| { + let make = SyntaxFactory::without_mappings(); let mut edit = builder.make_editor(while_expr.syntax()); let while_indent_level = IndentLevel::from_node(while_expr.syntax()); - let break_block = make::block_expr( - iter::once(make::expr_stmt(make::expr_break(None, None)).into()), - None, - ) - .indent(IndentLevel(1)); + let break_block = make + .block_expr( + iter::once(make.expr_stmt(make.expr_break(None, None).into()).into()), + None, + ) + .indent(IndentLevel(1)); edit.replace_all( while_kw.syntax_element()..=while_cond.syntax().syntax_element(), - vec![make::token(T![loop]).syntax_element()], + vec![make.token(T![loop]).syntax_element()], ); if is_pattern_cond(while_cond.clone()) { let then_branch = while_body.reset_indent().indent(IndentLevel(1)); - let if_expr = make::expr_if(while_cond, then_branch, Some(break_block.into())); - let stmts = iter::once(make::expr_stmt(if_expr.into()).into()); - let block_expr = make::block_expr(stmts, None); + let if_expr = make.expr_if(while_cond, then_branch, Some(break_block.into())); + let stmts = iter::once(make.expr_stmt(if_expr.into()).into()); + let block_expr = make.block_expr(stmts, None); edit.replace(while_body.syntax(), block_expr.indent(while_indent_level).syntax()); } else { - let if_cond = invert_boolean_expression_legacy(while_cond); - let if_expr = make::expr_if(if_cond, break_block, None).indent(while_indent_level); + let if_cond = invert_boolean_expression(&make, while_cond); + let if_expr = make.expr_if(if_cond, break_block, None).indent(while_indent_level); if !while_body.syntax().text().contains_char('\n') { edit.insert( Position::after(&l_curly), - make::tokens::whitespace(&format!("\n{while_indent_level}")), + make.whitespace(&format!("\n{while_indent_level}")), ); } edit.insert_all( Position::after(&l_curly), vec![ - make::tokens::whitespace(&format!("\n{}", while_indent_level + 1)).into(), + make.whitespace(&format!("\n{}", while_indent_level + 1)).into(), if_expr.syntax().syntax_element(), ], ); }; + edit.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), edit); }, )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 4c4cee1..ec4a83b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
@@ -17,7 +17,7 @@ use crate::{ assist_context::{AssistContext, Assists, SourceChangeBuilder}, - utils::ref_field_expr::determine_ref_and_parens, + utils::{cover_edit_range, ref_field_expr::determine_ref_and_parens}, }; // Assist: destructure_struct_binding @@ -358,6 +358,7 @@ fn update_usages( data: &StructEditData, field_names: &FxHashMap<SmolStr, SmolStr>, ) { + let source = ctx.source_file().syntax(); let make = SyntaxFactory::with_mappings(); let edits = data .usages @@ -366,7 +367,9 @@ fn update_usages( .collect_vec(); editor.add_mappings(make.finish_with_mappings()); for (old, new) in edits { - editor.replace(old, new); + if let Some(range) = ctx.sema.original_range_opt(&old) { + editor.replace_all(cover_edit_range(source, range.range), vec![new.into()]); + } } } @@ -381,23 +384,20 @@ fn build_usage_edit( Some(field_expr) => Some({ let field_name: SmolStr = field_expr.name_ref()?.to_string().into(); let new_field_name = field_names.get(&field_name)?; - let new_expr = ast::make::expr_path(ast::make::ext::ident_path(new_field_name)); + let new_expr = make.expr_path(make.ident_path(new_field_name)); // If struct binding is a reference, we might need to deref field usages if data.is_ref { let (replace_expr, ref_data) = determine_ref_and_parens(ctx, &field_expr); - ( - replace_expr.syntax().clone_for_update(), - ref_data.wrap_expr(new_expr).syntax().clone_for_update(), - ) + (replace_expr.syntax().clone(), ref_data.wrap_expr(new_expr, make).syntax().clone()) } else { - (field_expr.syntax().clone(), new_expr.syntax().clone_for_update()) + (field_expr.syntax().clone(), new_expr.syntax().clone()) } }), None => Some(( usage.name.syntax().as_node().unwrap().clone(), make.expr_macro( - ast::make::ext::ident_path("todo"), + make.ident_path("todo"), make.token_tree(syntax::SyntaxKind::L_PAREN, []), ) .syntax() @@ -1009,4 +1009,33 @@ fn main($0foo: dep::Foo) {} "#, ) } + + #[test] + fn record_struct_usage_in_macro_call() { + // exact repro from #20716: struct field access inside write! must not panic + check_assist( + destructure_struct_binding, + r#" +//- minicore: write, fmt +use core::fmt::Write; +struct Foo { y: i8 } + +fn main() { + let mut s = String::new(); + let $0x = Foo { y: 8 }; + write!(s, "{}", x.y).unwrap(); +} +"#, + r#" +use core::fmt::Write; +struct Foo { y: i8 } + +fn main() { + let mut s = String::new(); + let Foo { y } = Foo { y: 8 }; + write!(s, "{}", y).unwrap(); +} +"#, + ) + } }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index d51a3a2..23c11b2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -14,7 +14,7 @@ use crate::{ assist_context::{AssistContext, Assists, SourceChangeBuilder}, - utils::ref_field_expr::determine_ref_and_parens, + utils::{cover_edit_range, ref_field_expr::determine_ref_and_parens}, }; // Assist: destructure_tuple_binding @@ -98,7 +98,9 @@ fn destructure_tuple_edit_impl( assignment_edit.apply(&mut syntax_editor, &syntax_factory); if let Some(usages_edit) = current_file_usages_edit { - usages_edit.into_iter().for_each(|usage_edit| usage_edit.apply(edit, &mut syntax_editor)) + usages_edit + .into_iter() + .for_each(|usage_edit| usage_edit.apply(ctx, edit, &mut syntax_editor)) } syntax_editor.add_mappings(syntax_factory.finish_with_mappings()); @@ -311,14 +313,25 @@ enum EditTupleUsage { } impl EditTupleUsage { - fn apply(self, edit: &mut SourceChangeBuilder, syntax_editor: &mut SyntaxEditor) { + fn apply( + self, + ctx: &AssistContext<'_>, + edit: &mut SourceChangeBuilder, + syntax_editor: &mut SyntaxEditor, + ) { match self { EditTupleUsage::NoIndex(range) => { edit.insert(range.start(), "/*"); edit.insert(range.end(), "*/"); } EditTupleUsage::ReplaceExpr(target_expr, replace_with) => { - syntax_editor.replace(target_expr.syntax(), replace_with.syntax()) + if let Some(range) = ctx.sema.original_range_opt(target_expr.syntax()) { + let source = ctx.source_file().syntax(); + syntax_editor.replace_all( + cover_edit_range(source, range.range), + vec![replace_with.syntax().clone().into()], + ); + } } } } @@ -349,24 +362,6 @@ fn detect_tuple_index(usage: &FileReference, data: &TupleData) -> Option<TupleIn if let Some(field_expr) = ast::FieldExpr::cast(node) { let idx = field_expr.name_ref()?.as_tuple_field()?; if idx < data.field_names.len() { - // special case: in macro call -> range of `field_expr` in applied macro, NOT range in actual file! - if field_expr.syntax().ancestors().any(|a| ast::MacroStmts::can_cast(a.kind())) { - cov_mark::hit!(destructure_tuple_macro_call); - - // issue: cannot differentiate between tuple index passed into macro or tuple index as result of macro: - // ```rust - // macro_rules! m { - // ($t1:expr, $t2:expr) => { $t1; $t2.0 } - // } - // let t = (1,2); - // m!(t.0, t) - // ``` - // -> 2 tuple index usages detected! - // - // -> only handle `t` - return None; - } - Some(TupleIndex { index: idx, field_expr }) } else { // tuple index out of range @@ -1437,7 +1432,6 @@ mod in_macro_call { #[test] fn detect_macro_call() { - cov_mark::check!(destructure_tuple_macro_call); check_in_place_assist( r#" macro_rules! m { @@ -1456,7 +1450,7 @@ macro_rules! m { fn main() { let ($0_0, _1) = (1,2); - m!(/*t*/.0); + m!(_0); } "#, ) @@ -1548,7 +1542,6 @@ fn main() { m!(t.0); } "#, - // FIXME: replace `t.0` with `_0` (cannot detect range of tuple index in macro call) r#" macro_rules! m { ($e:expr) => { "foo"; $e }; @@ -1556,10 +1549,9 @@ macro_rules! m { fn main() { let ($0_0, _1) = (1,2); - m!(/*t*/.0); + m!(_0); } "#, - // FIXME: replace `t.0` with `_0` r#" macro_rules! m { ($e:expr) => { "foo"; $e }; @@ -1567,7 +1559,7 @@ macro_rules! m { fn main() { let t @ ($0_0, _1) = (1,2); - m!(t.0); + m!(_0); } "#, ) @@ -1586,7 +1578,6 @@ fn main() { m!((t).0); } "#, - // FIXME: replace `(t).0` with `_0` r#" macro_rules! m { ($e:expr) => { "foo"; $e }; @@ -1594,10 +1585,9 @@ macro_rules! m { fn main() { let ($0_0, _1) = (1,2); - m!((/*t*/).0); + m!(_0); } "#, - // FIXME: replace `(t).0` with `_0` r#" macro_rules! m { ($e:expr) => { "foo"; $e }; @@ -1605,7 +1595,7 @@ macro_rules! m { fn main() { let t @ ($0_0, _1) = (1,2); - m!((t).0); + m!(_0); } "#, ) @@ -1653,7 +1643,6 @@ fn main() { m!(t, t.0); } "#, - // FIXME: replace `t.0` in macro call (not IN macro) with `_0` r#" macro_rules! m { ($t:expr, $i:expr) => { $t.0 + $i }; @@ -1661,10 +1650,9 @@ macro_rules! m { fn main() { let ($0_0, _1) = (1,2); - m!(/*t*/, /*t*/.0); + m!(t, _0); } "#, - // FIXME: replace `t.0` in macro call with `_0` r#" macro_rules! m { ($t:expr, $i:expr) => { $t.0 + $i }; @@ -1672,13 +1660,41 @@ macro_rules! m { fn main() { let t @ ($0_0, _1) = (1,2); - m!(t, t.0); + m!(t, _0); } "#, ) } } + mod in_macro_expr { + use super::assist::*; + + // exact repro from #20716: tuple index inside write! must not panic + #[test] + fn tuple_index_in_write_macro() { + check_in_place_assist( + r#" +//- minicore: write, fmt +use core::fmt::Write; +fn main() { + let mut s = String::new(); + let $0x = (2i32, 3i32); + write!(s, "{}", x.0).unwrap(); +} +"#, + r#" +use core::fmt::Write; +fn main() { + let mut s = String::new(); + let ($0_0, _1) = (2i32, 3i32); + write!(s, "{}", _0).unwrap(); +} +"#, + ) + } + } + mod refs { use super::assist::*;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs index 9976e34..865dc86 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs
@@ -1,15 +1,11 @@ use std::iter; -use ide_db::{ - assists::{AssistId, ExprFillDefaultMode}, - ty_filter::TryEnum, -}; +use ide_db::{assists::AssistId, ty_filter::TryEnum}; use syntax::{ AstNode, T, ast::{ self, edit::{AstNodeEdit, IndentLevel}, - make, syntax_factory::SyntaxFactory, }, }; @@ -68,41 +64,39 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op AssistId::refactor_rewrite("desugar_try_expr_match"), "Replace try expression with match", target, - |edit| { + |builder| { + let make = SyntaxFactory::with_mappings(); + let mut editor = builder.make_editor(try_expr.syntax()); + let sad_pat = match try_enum { - TryEnum::Option => make::path_pat(make::ext::ident_path("None")), - TryEnum::Result => make::tuple_struct_pat( - make::ext::ident_path("Err"), - iter::once(make::path_pat(make::ext::ident_path("err"))), - ) - .into(), - }; - let sad_expr = match try_enum { - TryEnum::Option => { - make::expr_return(Some(make::expr_path(make::ext::ident_path("None")))) - } - TryEnum::Result => make::expr_return(Some( - make::expr_call( - make::expr_path(make::ext::ident_path("Err")), - make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))), + TryEnum::Option => make.path_pat(make.ident_path("None")), + TryEnum::Result => make + .tuple_struct_pat( + make.ident_path("Err"), + iter::once(make.path_pat(make.ident_path("err"))), ) .into(), - )), }; + let sad_expr = make.expr_return(Some(sad_expr(try_enum, &make, || { + make.expr_path(make.ident_path("err")) + }))); - let happy_arm = make::match_arm( - try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()), + let happy_arm = make.match_arm( + try_enum.happy_pattern(make.ident_pat(false, false, make.name("it")).into()), None, - make::expr_path(make::ext::ident_path("it")), + make.expr_path(make.ident_path("it")), ); - let sad_arm = make::match_arm(sad_pat, None, sad_expr); + let sad_arm = make.match_arm(sad_pat, None, sad_expr.into()); - let match_arm_list = make::match_arm_list([happy_arm, sad_arm]); + let match_arm_list = make.match_arm_list([happy_arm, sad_arm]); - let expr_match = make::expr_match(expr.clone(), match_arm_list) + let expr_match = make + .expr_match(expr.clone(), match_arm_list) .indent(IndentLevel::from_node(try_expr.syntax())); - edit.replace_ast::<ast::Expr>(try_expr.clone().into(), expr_match.into()); + editor.replace(try_expr.syntax(), expr_match.syntax()); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); @@ -119,48 +113,18 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let mut editor = builder.make_editor(let_stmt.syntax()); let indent_level = IndentLevel::from_node(let_stmt.syntax()); + let fill_expr = || crate::utils::expr_fill_default(ctx.config); let new_let_stmt = make.let_else_stmt( try_enum.happy_pattern(pat), - let_stmt.ty(), + let_stmt.ty().map(|ty| match try_enum { + TryEnum::Option => make.ty_option(ty).into(), + TryEnum::Result => make.ty_result(ty, make.ty_infer().into()).into(), + }), expr, make.block_expr( iter::once( make.expr_stmt( - make.expr_return(Some(match try_enum { - TryEnum::Option => make.expr_path(make.ident_path("None")), - TryEnum::Result => make - .expr_call( - make.expr_path(make.ident_path("Err")), - make.arg_list(iter::once( - match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make - .expr_macro( - make.ident_path("todo"), - make.token_tree( - syntax::SyntaxKind::L_PAREN, - [], - ), - ) - .into(), - ExprFillDefaultMode::Underscore => { - make.expr_underscore().into() - } - ExprFillDefaultMode::Default => make - .expr_macro( - make.ident_path("todo"), - make.token_tree( - syntax::SyntaxKind::L_PAREN, - [], - ), - ) - .into(), - }, - )), - ) - .into(), - })) - .indent(indent_level + 1) - .into(), + make.expr_return(Some(sad_expr(try_enum, &make, fill_expr))).into(), ) .into(), ), @@ -177,6 +141,15 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op Some(()) } +fn sad_expr(try_enum: TryEnum, make: &SyntaxFactory, err: impl Fn() -> ast::Expr) -> ast::Expr { + match try_enum { + TryEnum::Option => make.expr_path(make.ident_path("None")), + TryEnum::Result => make + .expr_call(make.expr_path(make.ident_path("Err")), make.arg_list(iter::once(err()))) + .into(), + } +} + #[cfg(test)] mod tests { use super::*; @@ -278,4 +251,46 @@ fn test() { "Replace try expression with let else", ); } + + #[test] + fn test_desugar_try_expr_option_let_else_with_type() { + check_assist_by_label( + desugar_try_expr, + r#" +//- minicore: try, option +fn test() { + let pat: bool = Some(true)$0?; +} + "#, + r#" +fn test() { + let Some(pat): Option<bool> = Some(true) else { + return None; + }; +} + "#, + "Replace try expression with let else", + ); + } + + #[test] + fn test_desugar_try_expr_result_let_else_with_type() { + check_assist_by_label( + desugar_try_expr, + r#" +//- minicore: try, result +fn test() { + let pat: bool = Ok(true)$0?; +} + "#, + r#" +fn test() { + let Ok(pat): Result<bool, _> = Ok(true) else { + return Err(todo!()); + }; +} + "#, + "Replace try expression with let else", + ); + } }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs index 7eca4d3..6c5c21b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_glob_import.rs
@@ -317,7 +317,7 @@ fn find_refs_in_mod( .into_iter() .map(|v| Ref { visible_name: v.name(ctx.db()), - def: Definition::Variant(v), + def: Definition::EnumVariant(v), is_pub: true, }) .collect(), @@ -379,7 +379,7 @@ fn find_imported_defs(ctx: &AssistContext<'_>, use_item: Use) -> Vec<Definition> | Definition::Module(_) | Definition::Function(_) | Definition::Adt(_) - | Definition::Variant(_) + | Definition::EnumVariant(_) | Definition::Const(_) | Definition::Static(_) | Definition::Trait(_)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index 867ac48..a7e78df 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
@@ -102,7 +102,7 @@ fn expand_tuple_struct_rest_pattern( let fields = match ctx.sema.type_of_pat(&pat.clone().into())?.original.as_adt()? { hir::Adt::Struct(s) if s.kind(ctx.sema.db) == StructKind::Tuple => s.fields(ctx.sema.db), hir::Adt::Enum(_) => match ctx.sema.resolve_path(&path)? { - PathResolution::Def(hir::ModuleDef::Variant(v)) + PathResolution::Def(hir::ModuleDef::EnumVariant(v)) if v.kind(ctx.sema.db) == StructKind::Tuple => { v.fields(ctx.sema.db)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs index 61af2de..35e8baa 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
@@ -8,7 +8,7 @@ AstNode, AstToken, NodeOrToken, SyntaxKind::WHITESPACE, SyntaxToken, T, - ast::{self, TokenTree, make, syntax_factory::SyntaxFactory}, + ast::{self, TokenTree, syntax_factory::SyntaxFactory}, }; // Assist: extract_expressions_from_format_string @@ -57,6 +57,7 @@ pub(crate) fn extract_expressions_from_format_string( "Extract format expressions", tt.syntax().text_range(), |edit| { + let make = SyntaxFactory::without_mappings(); // Extract existing arguments in macro let mut raw_tokens = tt.token_trees_and_tokens().skip(1).collect_vec(); let format_string_index = format_str_index(&raw_tokens, &fmt_string); @@ -94,14 +95,14 @@ pub(crate) fn extract_expressions_from_format_string( let mut new_tt_bits = raw_tokens; let mut placeholder_indexes = vec![]; - new_tt_bits.push(NodeOrToken::Token(make::tokens::literal(&new_fmt))); + new_tt_bits.push(NodeOrToken::Token(make.expr_literal(&new_fmt).token().clone())); for arg in extracted_args { if matches!(arg, Arg::Expr(_) | Arg::Placeholder) { // insert ", " before each arg new_tt_bits.extend_from_slice(&[ - NodeOrToken::Token(make::token(T![,])), - NodeOrToken::Token(make::tokens::single_space()), + NodeOrToken::Token(make.token(T![,])), + NodeOrToken::Token(make.whitespace(" ")), ]); } @@ -109,7 +110,7 @@ pub(crate) fn extract_expressions_from_format_string( Arg::Expr(s) => { // insert arg let expr = ast::Expr::parse(&s, ctx.edition()).syntax_node(); - let mut expr_tt = utils::tt_from_syntax(expr); + let mut expr_tt = utils::tt_from_syntax(expr, &make); new_tt_bits.append(&mut expr_tt); } Arg::Placeholder => { @@ -120,7 +121,7 @@ pub(crate) fn extract_expressions_from_format_string( } None => { placeholder_indexes.push(new_tt_bits.len()); - new_tt_bits.push(NodeOrToken::Token(make::token(T![_]))); + new_tt_bits.push(NodeOrToken::Token(make.token(T![_]))); } } } @@ -129,7 +130,6 @@ pub(crate) fn extract_expressions_from_format_string( } // Insert new args - let make = SyntaxFactory::with_mappings(); let new_tt = make.token_tree(tt_delimiter, new_tt_bits); let mut editor = edit.make_editor(tt.syntax()); editor.replace(tt.syntax(), new_tt.syntax());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs index a17ae48..dcbeaef 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
@@ -728,7 +728,7 @@ macro_rules! check_item { } Definition::Function(x) => check_item!(x), Definition::Adt(x) => check_item!(x), - Definition::Variant(x) => check_item!(x), + Definition::EnumVariant(x) => check_item!(x), Definition::Const(x) => check_item!(x), Definition::Static(x) => check_item!(x), Definition::Trait(x) => check_item!(x),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 386652a..4c46a51 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -1,7 +1,7 @@ use std::iter; use either::Either; -use hir::{HasCrate, Module, ModuleDef, Name, Variant}; +use hir::{EnumVariant, HasCrate, Module, ModuleDef, Name}; use ide_db::{ FxHashSet, RootDatabase, defs::Definition, @@ -16,9 +16,7 @@ SyntaxKind::*, SyntaxNode, T, ast::{ - self, AstNode, HasAttrs, HasGenericParams, HasName, HasVisibility, - edit::{AstNodeEdit, IndentLevel}, - make, + self, AstNode, HasAttrs, HasGenericParams, HasName, HasVisibility, edit::AstNodeEdit, make, }, match_ast, ted, }; @@ -63,7 +61,7 @@ pub(crate) fn extract_struct_from_enum_variant( let edition = enum_hir.krate(ctx.db()).edition(ctx.db()); let variant_hir_name = variant_hir.name(ctx.db()); let enum_module_def = ModuleDef::from(enum_hir); - let usages = Definition::Variant(variant_hir).usages(&ctx.sema).all(); + let usages = Definition::EnumVariant(variant_hir).usages(&ctx.sema).all(); let mut visited_modules_set = FxHashSet::default(); let current_module = enum_hir.module(ctx.db()); @@ -163,7 +161,7 @@ fn extract_field_list_if_applicable( } } -fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Variant) -> bool { +fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool { variant .parent_enum(db) .module(db) @@ -175,7 +173,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va def, ModuleDef::Module(_) | ModuleDef::Adt(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) | ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) @@ -290,7 +288,6 @@ fn create_struct_def( field_list.clone().into() } }; - let field_list = field_list.indent(IndentLevel::single()); let strukt = make::struct_(enum_vis, name, generics, field_list).clone_for_update();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 7c60184..e5ce02c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -9,7 +9,6 @@ ast::{ self, AstNode, edit::{AstNodeEdit, IndentLevel}, - make, syntax_factory::SyntaxFactory, }, syntax_editor::Position, @@ -75,7 +74,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op .next() .and_then(ast::Expr::cast) { - expr.syntax().ancestors().find_map(valid_target_expr)?.syntax().clone() + expr.syntax().ancestors().find_map(valid_target_expr(ctx))?.syntax().clone() } else { return None; } @@ -96,7 +95,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let to_extract = node .descendants() .take_while(|it| range.contains_range(it.text_range())) - .find_map(valid_target_expr)?; + .find_map(valid_target_expr(ctx))?; let ty = ctx.sema.type_of_expr(&to_extract).map(TypeInfo::adjusted); if matches!(&ty, Some(ty_info) if ty_info.is_unit()) { @@ -176,7 +175,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let mut editor = edit.make_editor(&expr_replace); let pat_name = make.name(&var_name); - let name_expr = make.expr_path(make::ext::ident_path(&var_name)); + let name_expr = make.expr_path(make.ident_path(&var_name)); if let Some(cap) = ctx.config.snippet_cap { let tabstop = edit.make_tabstop_before(cap); @@ -233,7 +232,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op Position::before(place), vec![ new_stmt.syntax().clone().into(), - make::tokens::whitespace(&trailing_ws).into(), + make.whitespace(&trailing_ws).into(), ], ); @@ -283,14 +282,19 @@ fn peel_parens(mut expr: ast::Expr) -> ast::Expr { /// Check whether the node is a valid expression which can be extracted to a variable. /// In general that's true for any expression, but in some cases that would produce invalid code. -fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> { - match node.kind() { - SyntaxKind::PATH_EXPR | SyntaxKind::LOOP_EXPR | SyntaxKind::LET_EXPR => None, +fn valid_target_expr(ctx: &AssistContext<'_>) -> impl Fn(SyntaxNode) -> Option<ast::Expr> { + |node| match node.kind() { + SyntaxKind::LOOP_EXPR | SyntaxKind::LET_EXPR => None, SyntaxKind::BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), SyntaxKind::RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()), SyntaxKind::BLOCK_EXPR => { ast::BlockExpr::cast(node).filter(|it| it.is_standalone()).map(ast::Expr::from) } + SyntaxKind::PATH_EXPR => { + let path_expr = ast::PathExpr::cast(node)?; + let path_resolution = ctx.sema.resolve_path(&path_expr.path()?)?; + like_const_value(ctx, path_resolution).then_some(path_expr.into()) + } _ => ast::Expr::cast(node), } } @@ -455,6 +459,31 @@ fn from(to_extract: &ast::Expr, kind: &ExtractionKind) -> Option<Anchor> { } } +fn like_const_value(ctx: &AssistContext<'_>, path_resolution: hir::PathResolution) -> bool { + let db = ctx.db(); + let adt_like_const_value = |adt: Option<hir::Adt>| matches!(adt, Some(hir::Adt::Struct(s)) if s.kind(db) == hir::StructKind::Unit); + match path_resolution { + hir::PathResolution::Def(def) => match def { + hir::ModuleDef::Adt(adt) => adt_like_const_value(Some(adt)), + hir::ModuleDef::EnumVariant(variant) => variant.kind(db) == hir::StructKind::Unit, + hir::ModuleDef::TypeAlias(ty) => adt_like_const_value(ty.ty(db).as_adt()), + hir::ModuleDef::Const(_) | hir::ModuleDef::Static(_) => true, + hir::ModuleDef::Trait(_) + | hir::ModuleDef::BuiltinType(_) + | hir::ModuleDef::Macro(_) + | hir::ModuleDef::Module(_) => false, + hir::ModuleDef::Function(_) => false, // no extract named function + }, + hir::PathResolution::SelfType(ty) => adt_like_const_value(ty.self_ty(db).as_adt()), + hir::PathResolution::ConstParam(_) => true, + hir::PathResolution::Local(_) + | hir::PathResolution::TypeParam(_) + | hir::PathResolution::BuiltinAttr(_) + | hir::PathResolution::ToolModule(_) + | hir::PathResolution::DeriveHelper(_) => false, + } +} + #[cfg(test)] mod tests { // NOTE: We use check_assist_by_label, but not check_assist_not_applicable_by_label @@ -1748,6 +1777,27 @@ fn main() { } #[test] + fn extract_non_local_path_expr() { + check_assist_by_label( + extract_variable, + r#" +struct Foo; +fn foo() -> Foo { + $0Foo$0 +} +"#, + r#" +struct Foo; +fn foo() -> Foo { + let $0foo = Foo; + foo +} +"#, + "Extract into variable", + ); + } + + #[test] fn extract_var_for_return_not_applicable() { check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } "); }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 5134b98..440f2d5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -173,7 +173,7 @@ fn offset_target_and_file_id<S, Ast>( // FIXME hir::ModuleDef::Macro(_) => return None, // Enum variants can't be private, we can't modify builtin types - hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None, + hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, }; Some((offset, target, target_file, target_name))
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index b0fa9e6..e022a27 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs
@@ -5,15 +5,15 @@ use hir::{HasCrate, Semantics}; use ide_db::{ RootDatabase, - assists::{AssistId, AssistKind, ExprFillDefaultMode}, + assists::{AssistId, AssistKind}, famous_defs::FamousDefs, syntax_helpers::suggest_name, }; use syntax::{ AstNode, ast::{ - self, AssocItem, BlockExpr, GenericParam, HasAttrs, HasGenericParams, HasName, - HasTypeBounds, HasVisibility, edit::AstNodeEdit, make, + self, AssocItem, GenericParam, HasAttrs, HasGenericParams, HasName, HasTypeBounds, + HasVisibility, edit::AstNodeEdit, make, }, syntax_editor::Position, }; @@ -269,7 +269,7 @@ fn todo_fn(f: &ast::Fn, config: &AssistConfig) -> ast::Fn { f.generic_param_list(), f.where_clause(), params, - default_block(config), + make::block_expr(None, Some(crate::utils::expr_fill_default(config))), f.ret_type(), f.async_token().is_some(), f.const_token().is_some(), @@ -278,15 +278,6 @@ fn todo_fn(f: &ast::Fn, config: &AssistConfig) -> ast::Fn { ) } -fn default_block(config: &AssistConfig) -> BlockExpr { - let expr = match config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }; - make::block_expr(None, Some(expr)) -} - fn cfg_attrs(node: &impl HasAttrs) -> impl Iterator<Item = ast::Attr> { node.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")) }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs index 4851847..2d92bf5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs
@@ -1,8 +1,12 @@ use ide_db::famous_defs::FamousDefs; -use stdx::format_to; use syntax::{ AstNode, - ast::{self, HasGenericParams, HasName, HasTypeBounds, Impl, syntax_factory::SyntaxFactory}, + ast::{ + self, HasGenericParams, HasName, HasTypeBounds, Impl, + edit::{AstNodeEdit, IndentLevel}, + syntax_factory::SyntaxFactory, + }, + syntax_editor::Position, }; use crate::{ @@ -62,32 +66,32 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<' return None; } - let insert_location = impl_.syntax().text_range(); + let target = impl_.syntax().text_range(); acc.add( AssistId::generate("generate_default_from_new"), "Generate a Default impl from a new fn", - insert_location, + target, move |builder| { - let default_code = " fn default() -> Self { - Self::new() - }"; let make = SyntaxFactory::without_mappings(); - let code = - generate_trait_impl_text_from_impl(&impl_, self_ty, "Default", default_code, &make); - builder.insert(insert_location.end(), code); + let default_impl = generate_default_impl(&make, &impl_, self_ty); + let indent = IndentLevel::from_node(impl_.syntax()); + let default_impl = default_impl.indent(indent); + + let mut editor = builder.make_editor(impl_.syntax()); + editor.insert_all( + Position::after(impl_.syntax()), + vec![ + make.whitespace(&format!("\n\n{indent}")).into(), + default_impl.syntax().clone().into(), + ], + ); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } -// FIXME: based on from utils::generate_impl_text_inner -fn generate_trait_impl_text_from_impl( - impl_: &ast::Impl, - self_ty: ast::Type, - trait_text: &str, - code: &str, - make: &SyntaxFactory, -) -> String { +fn generate_default_impl(make: &SyntaxFactory, impl_: &ast::Impl, self_ty: ast::Type) -> ast::Impl { let generic_params = impl_.generic_param_list().map(|generic_params| { let lifetime_params = generic_params.lifetime_params().map(ast::GenericParam::LifetimeParam); @@ -109,26 +113,45 @@ fn generate_trait_impl_text_from_impl( make.generic_param_list(itertools::chain(lifetime_params, ty_or_const_params)) }); - let mut buf = String::with_capacity(code.len()); - buf.push_str("\n\n"); + let trait_ty: ast::Type = make.ty_path(make.ident_path("Default")).into(); - // `impl{generic_params} {trait_text} for {impl_.self_ty()}` - buf.push_str("impl"); - if let Some(generic_params) = &generic_params { - format_to!(buf, "{generic_params}") - } - format_to!(buf, " {trait_text} for {self_ty}"); + let self_new_path = make.path_concat(make.ident_path("Self"), make.ident_path("new")); + let self_new_call = + make.expr_call(make.expr_path(self_new_path), make.arg_list(std::iter::empty())); + let fn_body = make.block_expr(std::iter::empty(), Some(self_new_call.into())); + let self_ty_ret: ast::Type = make.ty_path(make.ident_path("Self")).into(); + let default_fn = make + .fn_( + [], + None, + make.name("default"), + None, + None, + make.param_list(None, std::iter::empty()), + fn_body, + Some(make.ret_type(self_ty_ret)), + false, + false, + false, + false, + ) + .indent(1.into()); + let body = make.assoc_item_list(Some(ast::AssocItem::from(default_fn))); - match impl_.where_clause() { - Some(where_clause) => { - format_to!(buf, "\n{where_clause}\n{{\n{code}\n}}"); - } - None => { - format_to!(buf, " {{\n{code}\n}}"); - } - } - - buf + make.impl_trait( + [], + false, + None, + None, + generic_params, + None, + false, + trait_ty, + self_ty, + None, + impl_.where_clause(), + Some(body), + ) } fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool { @@ -631,12 +654,12 @@ pub fn new() -> Self { } } -impl Default for Example { - fn default() -> Self { - Self::new() + impl Default for Example { + fn default() -> Self { + Self::new() + } } } -} "#, ); }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs index c1eb1a7..63033c7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -4,7 +4,7 @@ ast::{ self, AstNode, HasGenericParams, HasName, HasVisibility as _, edit::{AstNodeEdit, IndentLevel}, - make, + syntax_factory::SyntaxFactory, }, syntax_editor::Position, }; @@ -100,7 +100,6 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let Some(impl_def) = find_struct_impl(ctx, &adt, std::slice::from_ref(&name)) else { continue; }; - let field = make::ext::field_from_idents(["self", &field_name])?; acc.add_group( &GroupLabel("Generate delegate methods…".to_owned()), @@ -108,10 +107,14 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' format!("Generate delegate for `{field_name}.{name}()`",), target, |edit| { + let make = SyntaxFactory::without_mappings(); + let field = make + .field_from_idents(["self", &field_name]) + .expect("always be a valid expression"); // Create the function let method_source = match ctx.sema.source(method) { Some(source) => { - let v = source.value.clone_for_update(); + let v = source.value; let source_scope = ctx.sema.scope(v.syntax()); let target_scope = ctx.sema.scope(strukt.syntax()); if let (Some(s), Some(t)) = (source_scope, target_scope) { @@ -132,42 +135,42 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let is_unsafe = method_source.unsafe_token().is_some(); let is_gen = method_source.gen_token().is_some(); - let fn_name = make::name(&name); + let fn_name = make.name(&name); let type_params = method_source.generic_param_list(); let where_clause = method_source.where_clause(); let params = - method_source.param_list().unwrap_or_else(|| make::param_list(None, [])); + method_source.param_list().unwrap_or_else(|| make.param_list(None, [])); // compute the `body` let arg_list = method_source .param_list() - .map(convert_param_list_to_arg_list) - .unwrap_or_else(|| make::arg_list([])); + .map(|v| convert_param_list_to_arg_list(v, &make)) + .unwrap_or_else(|| make.arg_list([])); - let tail_expr = - make::expr_method_call(field, make::name_ref(&name), arg_list).into(); + let tail_expr = make.expr_method_call(field, make.name_ref(&name), arg_list).into(); let tail_expr_finished = - if is_async { make::expr_await(tail_expr) } else { tail_expr }; - let body = make::block_expr([], Some(tail_expr_finished)); + if is_async { make.expr_await(tail_expr).into() } else { tail_expr }; + let body = make.block_expr([], Some(tail_expr_finished)); let ret_type = method_source.ret_type(); - let f = make::fn_( - None, - vis, - fn_name, - type_params, - where_clause, - params, - body, - ret_type, - is_async, - is_const, - is_unsafe, - is_gen, - ) - .indent(IndentLevel(1)); + let f = make + .fn_( + None, + vis, + fn_name, + type_params, + where_clause, + params, + body, + ret_type, + is_async, + is_const, + is_unsafe, + is_gen, + ) + .indent(IndentLevel(1)); let item = ast::AssocItem::Fn(f.clone()); let mut editor = edit.make_editor(strukt.syntax()); @@ -179,7 +182,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' Some(item) } None => { - let assoc_item_list = make::assoc_item_list(Some(vec![item])); + let assoc_item_list = make.assoc_item_list(vec![item]); editor.insert( Position::last_child_of(impl_def.syntax()), assoc_item_list.syntax(), @@ -192,17 +195,16 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let ty_params = strukt.generic_param_list(); let ty_args = ty_params.as_ref().map(|it| it.to_generic_args()); let where_clause = strukt.where_clause(); - let assoc_item_list = make::assoc_item_list(Some(vec![item])); + let assoc_item_list = make.assoc_item_list(vec![item]); - let impl_def = make::impl_( + let impl_def = make.impl_( None, ty_params, ty_args, - make::ty_path(make::ext::ident_path(name)), + syntax::ast::Type::PathType(make.ty_path(make.ident_path(name))), where_clause, Some(assoc_item_list), - ) - .clone_for_update(); + ); // Fixup impl_def indentation let indent = strukt.indent_level(); @@ -213,7 +215,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' editor.insert_all( Position::after(strukt.syntax()), vec![ - make::tokens::whitespace(&format!("\n\n{indent}")).into(), + make.whitespace(&format!("\n\n{indent}")).into(), impl_def.syntax().clone().into(), ], ); @@ -227,6 +229,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let tabstop = edit.make_tabstop_before(cap); editor.add_annotation(fn_.syntax(), tabstop); } + editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, )?;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 921f04f..f703e4d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs
@@ -782,7 +782,7 @@ fn func_assoc_item( }; // Build argument list with self expression prepended - let other_args = convert_param_list_to_arg_list(l); + let other_args = convert_param_list_to_arg_list(l, &make); let all_args: Vec<ast::Expr> = std::iter::once(tail_expr_self).chain(other_args.args()).collect(); let args = make.arg_list(all_args); @@ -790,13 +790,13 @@ fn func_assoc_item( make.expr_call(make.expr_path(qualified_path), args).into() } None => make - .expr_call(make.expr_path(qualified_path), convert_param_list_to_arg_list(l)) + .expr_call(make.expr_path(qualified_path), convert_param_list_to_arg_list(l, &make)) .into(), }, None => make .expr_call( make.expr_path(qualified_path), - convert_param_list_to_arg_list(make.param_list(None, Vec::new())), + convert_param_list_to_arg_list(make.param_list(None, Vec::new()), &make), ) .into(), };
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index 494c87e..5534dc1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -1,16 +1,15 @@ -use std::fmt::Display; - use hir::{ModPath, ModuleDef}; -use ide_db::{RootDatabase, famous_defs::FamousDefs}; +use ide_db::{FileId, RootDatabase, famous_defs::FamousDefs}; use syntax::{ - AstNode, Edition, SyntaxNode, - ast::{self, HasName}, + Edition, + ast::{self, AstNode, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, + syntax_editor::Position, }; use crate::{ AssistId, assist_context::{AssistContext, Assists, SourceChangeBuilder}, - utils::generate_trait_impl_text_intransitive, + utils::generate_trait_impl_intransitive_with_item, }; // Assist: generate_deref @@ -64,6 +63,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let field_type = field.ty()?; let field_name = field.name()?; let target = field.syntax().text_range(); + let file_id = ctx.vfs_file_id(); acc.add( AssistId::generate("generate_deref"), format!("Generate `{deref_type_to_generate:?}` impl using `{field_name}`"), @@ -72,9 +72,10 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( generate_edit( ctx.db(), edit, + file_id, strukt, - field_type.syntax(), - field_name.syntax(), + field_type, + &field_name.to_string(), deref_type_to_generate, trait_path, module.krate(ctx.db()).edition(ctx.db()), @@ -105,6 +106,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() let field_type = field.ty()?; let target = field.syntax().text_range(); + let file_id = ctx.vfs_file_id(); acc.add( AssistId::generate("generate_deref"), format!("Generate `{deref_type_to_generate:?}` impl using `{field}`"), @@ -113,9 +115,10 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() generate_edit( ctx.db(), edit, + file_id, strukt, - field_type.syntax(), - field_list_index, + field_type, + &field_list_index.to_string(), deref_type_to_generate, trait_path, module.krate(ctx.db()).edition(ctx.db()), @@ -127,35 +130,81 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() fn generate_edit( db: &RootDatabase, edit: &mut SourceChangeBuilder, + file_id: FileId, strukt: ast::Struct, - field_type_syntax: &SyntaxNode, - field_name: impl Display, + field_type: ast::Type, + field_name: &str, deref_type: DerefType, trait_path: ModPath, edition: Edition, ) { - let start_offset = strukt.syntax().text_range().end(); - let impl_code = match deref_type { - DerefType::Deref => format!( - r#" type Target = {field_type_syntax}; + let make = SyntaxFactory::with_mappings(); + let strukt_adt = ast::Adt::Struct(strukt.clone()); + let trait_ty = make.ty(&trait_path.display(db, edition).to_string()); - fn deref(&self) -> &Self::Target {{ - &self.{field_name} - }}"#, - ), - DerefType::DerefMut => format!( - r#" fn deref_mut(&mut self) -> &mut Self::Target {{ - &mut self.{field_name} - }}"#, - ), + let assoc_items: Vec<ast::AssocItem> = match deref_type { + DerefType::Deref => { + let target_alias = + make.ty_alias([], "Target", None, None, None, Some((field_type, None))); + let ret_ty = + make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), false); + let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name); + let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), false))); + let fn_ = make + .fn_( + [], + None, + make.name("deref"), + None, + None, + make.param_list(Some(make.self_param()), []), + body, + Some(make.ret_type(ret_ty)), + false, + false, + false, + false, + ) + .indent(1.into()); + vec![ast::AssocItem::TypeAlias(target_alias), ast::AssocItem::Fn(fn_)] + } + DerefType::DerefMut => { + let ret_ty = + make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), true); + let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name); + let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), true))); + let fn_ = make + .fn_( + [], + None, + make.name("deref_mut"), + None, + None, + make.param_list(Some(make.mut_self_param()), []), + body, + Some(make.ret_type(ret_ty)), + false, + false, + false, + false, + ) + .indent(1.into()); + vec![ast::AssocItem::Fn(fn_)] + } }; - let strukt_adt = ast::Adt::Struct(strukt); - let deref_impl = generate_trait_impl_text_intransitive( - &strukt_adt, - &trait_path.display(db, edition).to_string(), - &impl_code, + + let body = make.assoc_item_list(assoc_items); + let indent = strukt.indent_level(); + let impl_ = generate_trait_impl_intransitive_with_item(&make, &strukt_adt, trait_ty, body) + .indent(indent); + + let mut editor = edit.make_editor(strukt.syntax()); + editor.insert_all( + Position::after(strukt.syntax()), + vec![make.whitespace(&format!("\n\n{indent}")).into(), impl_.syntax().clone().into()], ); - edit.insert(start_offset, deref_impl); + editor.add_mappings(make.finish_with_mappings()); + edit.add_file_edits(file_id, editor); } fn existing_deref_impl(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index 24f271d..1adb3f4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs
@@ -1,10 +1,11 @@ use hir::next_solver::{DbInterner, TypingMode}; use ide_db::{RootDatabase, famous_defs::FamousDefs}; -use syntax::ast::{self, AstNode, HasName}; +use syntax::ast::{self, AstNode, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory}; +use syntax::syntax_editor::Position; use crate::{ AssistContext, AssistId, Assists, - utils::{generate_trait_impl_text_intransitive, is_selected}, + utils::{generate_trait_impl_intransitive_with_item, is_selected}, }; // Assist: generate_from_impl_for_enum @@ -33,39 +34,72 @@ pub(crate) fn generate_from_impl_for_enum( let variants = selected_variants(ctx, &variant)?; let target = variant.syntax().text_range(); + let file_id = ctx.vfs_file_id(); acc.add( AssistId::generate("generate_from_impl_for_enum"), "Generate `From` impl for this enum variant(s)", target, |edit| { - let start_offset = variant.parent_enum().syntax().text_range().end(); - let from_impl = variants - .into_iter() - .map(|variant_info| { - let from_trait = format!("From<{}>", variant_info.ty); - let impl_code = generate_impl_code(variant_info); - generate_trait_impl_text_intransitive(&adt, &from_trait, &impl_code) - }) - .collect::<String>(); - edit.insert(start_offset, from_impl); + let make = SyntaxFactory::with_mappings(); + let indent = adt.indent_level(); + let mut elements = Vec::new(); + + for variant_info in variants { + let impl_ = build_from_impl(&make, &adt, variant_info).indent(indent); + elements.push(make.whitespace(&format!("\n\n{indent}")).into()); + elements.push(impl_.syntax().clone().into()); + } + + let mut editor = edit.make_editor(adt.syntax()); + editor.insert_all(Position::after(adt.syntax()), elements); + editor.add_mappings(make.finish_with_mappings()); + edit.add_file_edits(file_id, editor); }, ) } -fn generate_impl_code(VariantInfo { name, field_name, ty }: VariantInfo) -> String { - if let Some(field) = field_name { - format!( - r#" fn from({field}: {ty}) -> Self {{ - Self::{name} {{ {field} }} - }}"# - ) +fn build_from_impl(make: &SyntaxFactory, adt: &ast::Adt, variant_info: VariantInfo) -> ast::Impl { + let VariantInfo { name, field_name, ty } = variant_info; + let trait_ty = make.ty(&format!("From<{ty}>")); + let ret_ty = make.ret_type(make.ty_path(make.ident_path("Self")).into()); + + let (params, body_expr) = if let Some(field) = field_name { + let field_str = field.to_string(); + let param = make.param(make.ident_pat(false, false, make.name(&field_str)).into(), ty); + let field_item = make.record_expr_field(make.name_ref(&field_str), None); + let record = make.record_expr( + make.path_from_text(&format!("Self::{name}")), + make.record_expr_field_list([field_item]), + ); + (make.param_list(None, [param]), ast::Expr::from(record)) } else { - format!( - r#" fn from(v: {ty}) -> Self {{ - Self::{name}(v) - }}"# + let param = make.param(make.ident_pat(false, false, make.name("v")).into(), ty); + let call = make.expr_call( + make.expr_path(make.path_from_text(&format!("Self::{name}"))), + make.arg_list([make.expr_path(make.ident_path("v"))]), + ); + (make.param_list(None, [param]), ast::Expr::from(call)) + }; + + let from_fn = make + .fn_( + [], + None, + make.name("from"), + None, + None, + params, + make.block_expr([], Some(body_expr)), + Some(ret_ty), + false, + false, + false, + false, ) - } + .indent(1.into()); + + let body = make.assoc_item_list([ast::AssocItem::Fn(from_fn)]); + generate_trait_impl_intransitive_with_item(make, adt, trait_ty, body) } struct VariantInfo {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index f62ecca..fbf6241 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -4,7 +4,6 @@ }; use ide_db::{ FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, - assists::ExprFillDefaultMode, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::is_editable_crate, @@ -24,7 +23,7 @@ use crate::{ AssistContext, AssistId, Assists, - utils::{convert_reference_type, find_struct_impl}, + utils::{convert_reference_type, expr_fill_default, find_struct_impl}, }; // Assist: generate_function @@ -286,11 +285,7 @@ fn from_call( target_module, &mut necessary_generic_params, ); - let placeholder_expr = match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }; + let placeholder_expr = expr_fill_default(ctx.config); fn_body = make::block_expr(vec![], Some(placeholder_expr)); }; @@ -345,11 +340,7 @@ fn from_method_call( let (generic_param_list, where_clause) = fn_generic_params(ctx, necessary_generic_params, &target)?; - let placeholder_expr = match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }; + let placeholder_expr = expr_fill_default(ctx.config); let fn_body = make::block_expr(vec![], Some(placeholder_expr)); Some(Self { @@ -465,11 +456,7 @@ fn make_fn_body_as_new_function( let adt_info = adt_info.as_ref()?; let path_self = make::ext::ident_path("Self"); - let placeholder_expr = match ctx.config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }; + let placeholder_expr = expr_fill_default(ctx.config); let tail_expr = if let Some(strukt) = adt_info.adt.as_struct() { match strukt.kind(ctx.db()) { StructKind::Record => {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index 92a6547..62ffd3d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs
@@ -218,14 +218,14 @@ fn generate_getter_from_info( ctx: &AssistContext<'_>, info: &AssistInfo, record_field_info: &RecordFieldInfo, - syntax_factory: &SyntaxFactory, + make: &SyntaxFactory, ) -> ast::Fn { let (ty, body) = if matches!(info.assist_type, AssistType::MutGet) { - let self_expr = syntax_factory.expr_path(syntax_factory.ident_path("self")); + let self_expr = make.expr_path(make.ident_path("self")); ( - syntax_factory.ty_ref(record_field_info.field_ty.clone(), true), - syntax_factory.expr_ref( - syntax_factory.expr_field(self_expr, &record_field_info.field_name.text()).into(), + make.ty_ref(record_field_info.field_ty.clone(), true), + make.expr_ref( + make.expr_field(self_expr, &record_field_info.field_name.text()).into(), true, ), ) @@ -239,21 +239,20 @@ fn generate_getter_from_info( .map(|conversion| { cov_mark::hit!(convert_reference_type); ( - conversion.convert_type(ctx.db(), module), - conversion.getter(record_field_info.field_name.to_string()), + conversion.convert_type_with_factory(make, ctx.db(), module), + conversion.getter(make, record_field_info.field_name.to_string()), ) }) })() .unwrap_or_else(|| { ( - syntax_factory.ty_ref(record_field_info.field_ty.clone(), false), - syntax_factory.expr_ref( - syntax_factory - .expr_field( - syntax_factory.expr_path(syntax_factory.ident_path("self")), - &record_field_info.field_name.text(), - ) - .into(), + make.ty_ref(record_field_info.field_ty.clone(), false), + make.expr_ref( + make.expr_field( + make.expr_path(make.ident_path("self")), + &record_field_info.field_name.text(), + ) + .into(), false, ), ) @@ -261,18 +260,18 @@ fn generate_getter_from_info( }; let self_param = if matches!(info.assist_type, AssistType::MutGet) { - syntax_factory.mut_self_param() + make.mut_self_param() } else { - syntax_factory.self_param() + make.self_param() }; let strukt = &info.strukt; - let fn_name = syntax_factory.name(&record_field_info.fn_name); - let params = syntax_factory.param_list(Some(self_param), []); - let ret_type = Some(syntax_factory.ret_type(ty)); - let body = syntax_factory.block_expr([], Some(body)); + let fn_name = make.name(&record_field_info.fn_name); + let params = make.param_list(Some(self_param), []); + let ret_type = Some(make.ret_type(ty)); + let body = make.block_expr([], Some(body)); - syntax_factory.fn_( + make.fn_( None, strukt.visibility(), fn_name, @@ -291,32 +290,29 @@ fn generate_getter_from_info( fn generate_setter_from_info( info: &AssistInfo, record_field_info: &RecordFieldInfo, - syntax_factory: &SyntaxFactory, + make: &SyntaxFactory, ) -> ast::Fn { let strukt = &info.strukt; let field_name = &record_field_info.fn_name; - let fn_name = syntax_factory.name(&format!("set_{field_name}")); + let fn_name = make.name(&format!("set_{field_name}")); let field_ty = &record_field_info.field_ty; // Make the param list // `(&mut self, $field_name: $field_ty)` - let field_param = syntax_factory.param( - syntax_factory.ident_pat(false, false, syntax_factory.name(field_name)).into(), - field_ty.clone(), - ); - let params = syntax_factory.param_list(Some(syntax_factory.mut_self_param()), [field_param]); + let field_param = + make.param(make.ident_pat(false, false, make.name(field_name)).into(), field_ty.clone()); + let params = make.param_list(Some(make.mut_self_param()), [field_param]); // Make the assignment body // `self.$field_name = $field_name` - let self_expr = syntax_factory.expr_path(syntax_factory.ident_path("self")); - let lhs = syntax_factory.expr_field(self_expr, field_name); - let rhs = syntax_factory.expr_path(syntax_factory.ident_path(field_name)); - let assign_stmt = - syntax_factory.expr_stmt(syntax_factory.expr_assignment(lhs.into(), rhs).into()); - let body = syntax_factory.block_expr([assign_stmt.into()], None); + let self_expr = make.expr_path(make.ident_path("self")); + let lhs = make.expr_field(self_expr, field_name); + let rhs = make.expr_path(make.ident_path(field_name)); + let assign_stmt = make.expr_stmt(make.expr_assignment(lhs.into(), rhs).into()); + let body = make.block_expr([assign_stmt.into()], None); // Make the setter fn - syntax_factory.fn_( + make.fn_( None, strukt.visibility(), fn_name,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs index bbd4248..2d12357 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
@@ -1,15 +1,21 @@ use syntax::{ - ast::{self, AstNode, HasGenericParams, HasName, edit::AstNodeEdit, make}, + ast::{ + self, AstNode, HasGenericParams, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory, + }, syntax_editor::{Position, SyntaxEditor}, }; use crate::{ AssistContext, AssistId, Assists, - utils::{self, DefaultMethods, IgnoreAssocItems}, + utils::{ + self, DefaultMethods, IgnoreAssocItems, generate_impl_with_factory, + generate_trait_impl_intransitive, + }, }; fn insert_impl( editor: &mut SyntaxEditor, + make: &SyntaxFactory, impl_: &ast::Impl, nominal: &impl AstNodeEdit, ) -> ast::Impl { @@ -20,7 +26,7 @@ fn insert_impl( Position::after(nominal.syntax()), vec![ // Add a blank line after the ADT, and indentation for the impl to match the ADT - make::tokens::whitespace(&format!("\n\n{indent}")).into(), + make.whitespace(&format!("\n\n{indent}")).into(), impl_.syntax().clone().into(), ], ); @@ -59,12 +65,13 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio format!("Generate impl for `{name}`"), target, |edit| { + let make = SyntaxFactory::with_mappings(); // Generate the impl - let impl_ = utils::generate_impl(&nominal); + let impl_ = generate_impl_with_factory(&make, &nominal); let mut editor = edit.make_editor(nominal.syntax()); - let impl_ = insert_impl(&mut editor, &impl_, &nominal); + let impl_ = insert_impl(&mut editor, &make, &impl_, &nominal); // Add a tabstop after the left curly brace if let Some(cap) = ctx.config.snippet_cap && let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) @@ -73,6 +80,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio editor.add_annotation(l_curly, tabstop); } + editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -109,12 +117,13 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> format!("Generate trait impl for `{name}`"), target, |edit| { + let make = SyntaxFactory::with_mappings(); // Generate the impl - let impl_ = utils::generate_trait_impl_intransitive(&nominal, make::ty_placeholder()); + let impl_ = generate_trait_impl_intransitive(&make, &nominal, make.ty_placeholder()); let mut editor = edit.make_editor(nominal.syntax()); - let impl_ = insert_impl(&mut editor, &impl_, &nominal); + let impl_ = insert_impl(&mut editor, &make, &impl_, &nominal); // Make the trait type a placeholder snippet if let Some(cap) = ctx.config.snippet_cap { if let Some(trait_) = impl_.trait_() { @@ -128,6 +137,7 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> } } + editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) @@ -166,9 +176,10 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> format!("Generate `{name}` impl for type"), target, |edit| { + let make = SyntaxFactory::with_mappings(); let mut editor = edit.make_editor(trait_.syntax()); - let holder_arg = ast::GenericArg::TypeArg(make::type_arg(make::ty_placeholder())); + let holder_arg = ast::GenericArg::TypeArg(make.type_arg(make.ty_placeholder())); let missing_items = utils::filter_assoc_items( &ctx.sema, &hir_trait.items(ctx.db()), @@ -177,11 +188,11 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> ); let trait_gen_args = trait_.generic_param_list().map(|list| { - make::generic_arg_list(list.generic_params().map(|_| holder_arg.clone())) + make.generic_arg_list(list.generic_params().map(|_| holder_arg.clone()), false) }); let make_impl_ = |body| { - make::impl_trait( + make.impl_trait( None, trait_.unsafe_token().is_some(), None, @@ -189,13 +200,12 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> None, None, false, - make::ty(&name.text()), - make::ty_placeholder(), + make.ty(&name.text()), + make.ty_placeholder(), None, None, body, ) - .clone_for_update() }; let impl_ = if missing_items.is_empty() { @@ -210,11 +220,12 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> &impl_, &target_scope, ); - let assoc_item_list = make::assoc_item_list(Some(assoc_items)); + let assoc_item_list = make.assoc_item_list(assoc_items); make_impl_(Some(assoc_item_list)) }; - let impl_ = insert_impl(&mut editor, &impl_, &trait_); + let impl_ = insert_impl(&mut editor, &make, &impl_, &trait_); + editor.add_mappings(make.finish_with_mappings()); if let Some(cap) = ctx.config.snippet_cap { if let Some(generics) = impl_.trait_().and_then(|it| it.generic_arg_list()) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 793211a..301d13c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
@@ -3,7 +3,10 @@ use_trivial_constructor::use_trivial_constructor, }; use syntax::{ - ast::{self, AstNode, HasName, HasVisibility, StructKind, edit::AstNodeEdit, make}, + ast::{ + self, AstNode, HasName, HasVisibility, StructKind, edit::AstNodeEdit, + syntax_factory::SyntaxFactory, + }, syntax_editor::Position, }; @@ -36,6 +39,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let strukt = ctx.find_node_at_offset::<ast::Struct>()?; + let make = SyntaxFactory::without_mappings(); let field_list = match strukt.kind() { StructKind::Record(named) => { named.fields().filter_map(|f| Some((f.name()?, f.ty()?))).collect::<Vec<_>>() @@ -55,7 +59,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option Some(name) => name, None => name_generator.suggest_name(&format!("_{i}")), }; - Some((make::name(name.as_str()), f.ty()?)) + Some((make.name(name.as_str()), f.ty()?)) }) .collect::<Vec<_>>() } @@ -70,6 +74,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let target = strukt.syntax().text_range(); acc.add(AssistId::generate("generate_new"), "Generate `new`", target, |builder| { + let make = SyntaxFactory::with_mappings(); let trivial_constructors = field_list .iter() .map(|(name, ty)| { @@ -95,63 +100,63 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option edition, )?; - Some((make::name_ref(&name.text()), Some(expr))) + Some((make.name_ref(&name.text()), Some(expr))) }) .collect::<Vec<_>>(); let params = field_list.iter().enumerate().filter_map(|(i, (name, ty))| { if trivial_constructors[i].is_none() { - Some(make::param(make::ident_pat(false, false, name.clone()).into(), ty.clone())) + Some(make.param(make.ident_pat(false, false, name.clone()).into(), ty.clone())) } else { None } }); - let params = make::param_list(None, params); + let params = make.param_list(None, params); let fields = field_list.iter().enumerate().map(|(i, (name, _))| { if let Some(constructor) = trivial_constructors[i].clone() { constructor } else { - (make::name_ref(&name.text()), None) + (make.name_ref(&name.text()), None) } }); let tail_expr: ast::Expr = match strukt.kind() { StructKind::Record(_) => { - let fields = fields.map(|(name, expr)| make::record_expr_field(name, expr)); - let fields = make::record_expr_field_list(fields); - make::record_expr(make::ext::ident_path("Self"), fields).into() + let fields = fields.map(|(name, expr)| make.record_expr_field(name, expr)); + let fields = make.record_expr_field_list(fields); + make.record_expr(make.ident_path("Self"), fields).into() } StructKind::Tuple(_) => { let args = fields.map(|(arg, expr)| { - let arg = || make::expr_path(make::path_unqualified(make::path_segment(arg))); + let arg = || make.expr_path(make.path_unqualified(make.path_segment(arg))); expr.unwrap_or_else(arg) }); - let arg_list = make::arg_list(args); - make::expr_call(make::expr_path(make::ext::ident_path("Self")), arg_list).into() + let arg_list = make.arg_list(args); + make.expr_call(make.expr_path(make.ident_path("Self")), arg_list).into() } StructKind::Unit => unreachable!(), }; - let body = make::block_expr(None, tail_expr.into()); + let body = make.block_expr(None, tail_expr.into()); - let ret_type = make::ret_type(make::ty_path(make::ext::ident_path("Self"))); + let ret_type = make.ret_type(make.ty_path(make.ident_path("Self")).into()); - let fn_ = make::fn_( - None, - strukt.visibility(), - make::name("new"), - None, - None, - params, - body, - Some(ret_type), - false, - false, - false, - false, - ) - .clone_for_update() - .indent(1.into()); + let fn_ = make + .fn_( + [], + strukt.visibility(), + make.name("new"), + None, + None, + params, + body, + Some(ret_type), + false, + false, + false, + false, + ) + .indent(1.into()); let mut editor = builder.make_editor(strukt.syntax()); @@ -164,32 +169,30 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option editor.insert_all( Position::after(l_curly), vec![ - make::tokens::whitespace(&format!("\n{}", impl_def.indent_level() + 1)) - .into(), + make.whitespace(&format!("\n{}", impl_def.indent_level() + 1)).into(), fn_.syntax().clone().into(), - make::tokens::whitespace("\n").into(), + make.whitespace("\n").into(), ], ); fn_.syntax().clone() } else { - let items = vec![ast::AssocItem::Fn(fn_)]; - let list = make::assoc_item_list(Some(items)); + let list = make.assoc_item_list([ast::AssocItem::Fn(fn_)]); editor.insert(Position::after(impl_def.syntax()), list.syntax()); list.syntax().clone() } } else { // Generate a new impl to add the method to let indent_level = strukt.indent_level(); - let body = vec![ast::AssocItem::Fn(fn_)]; - let list = make::assoc_item_list(Some(body)); - let impl_def = generate_impl_with_item(&ast::Adt::Struct(strukt.clone()), Some(list)) - .indent(strukt.indent_level()); + let list = make.assoc_item_list([ast::AssocItem::Fn(fn_)]); + let impl_def = + generate_impl_with_item(&make, &ast::Adt::Struct(strukt.clone()), Some(list)) + .indent(strukt.indent_level()); // Insert it after the adt editor.insert_all( Position::after(strukt.syntax()), vec![ - make::tokens::whitespace(&format!("\n\n{indent_level}")).into(), + make.whitespace(&format!("\n\n{indent_level}")).into(), impl_def.syntax().clone().into(), ], ); @@ -233,6 +236,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option } } + editor.add_mappings(make.finish_with_mappings()); builder.add_file_edits(ctx.vfs_file_id(), editor); }) }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs index 8bc4d50..1286abe 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs
@@ -1,8 +1,10 @@ use crate::assist_context::{AssistContext, Assists}; use ide_db::assists::AssistId; use syntax::{ - AstNode, SyntaxKind, T, - ast::{self, HasGenericParams, HasName, HasVisibility, edit::AstNodeEdit, make}, + AstNode, AstToken, SyntaxKind, T, + ast::{ + self, HasDocComments, HasGenericParams, HasName, HasVisibility, edit::AstNodeEdit, make, + }, syntax_editor::{Position, SyntaxEditor}, }; @@ -45,7 +47,7 @@ // }; // } // -// trait ${0:NewTrait}<const N: usize> { +// trait ${0:Create}<const N: usize> { // // Used as an associated constant. // const CONST_ASSOC: usize = N * 4; // @@ -54,7 +56,7 @@ // const_maker! {i32, 7} // } // -// impl<const N: usize> ${0:NewTrait}<N> for Foo<N> { +// impl<const N: usize> ${0:Create}<N> for Foo<N> { // // Used as an associated constant. // const CONST_ASSOC: usize = N * 4; // @@ -107,7 +109,7 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ }; let trait_ast = make::trait_( false, - "NewTrait", + &trait_name(&impl_assoc_items).text(), impl_ast.generic_param_list(), impl_ast.where_clause(), trait_items, @@ -133,6 +135,7 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ let mut editor = builder.make_editor(impl_ast.syntax()); impl_assoc_items.assoc_items().for_each(|item| { remove_items_visibility(&mut editor, &item); + remove_doc_comments(&mut editor, &item); }); editor.insert_all(Position::before(impl_name.syntax()), elements); @@ -160,6 +163,18 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ Some(()) } +fn trait_name(items: &ast::AssocItemList) -> ast::Name { + let mut fn_names = items + .assoc_items() + .filter_map(|x| if let ast::AssocItem::Fn(f) = x { f.name() } else { None }); + fn_names + .next() + .and_then(|name| { + fn_names.next().is_none().then(|| make::name(&stdx::to_camel_case(&name.text()))) + }) + .unwrap_or_else(|| make::name("NewTrait")) +} + /// `E0449` Trait items always share the visibility of their trait fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) { if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) { @@ -175,6 +190,17 @@ fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) { } } +fn remove_doc_comments(editor: &mut SyntaxEditor, item: &ast::AssocItem) { + for doc in item.doc_comments() { + if let Some(next) = doc.syntax().next_token() + && next.kind() == SyntaxKind::WHITESPACE + { + editor.delete(next); + } + editor.delete(doc.syntax()); + } +} + fn strip_body(editor: &mut SyntaxEditor, item: &ast::AssocItem) { if let ast::AssocItem::Fn(f) = item && let Some(body) = f.body() @@ -226,11 +252,47 @@ fn add(&mut self, x: f64) { r#" struct Foo(f64); -trait NewTrait { +trait Add { fn add(&mut self, x: f64); } -impl NewTrait for Foo { +impl Add for Foo { + fn add(&mut self, x: f64) { + self.0 += x; + } +}"#, + ) + } + + #[test] + fn test_remove_doc_comments() { + check_assist_no_snippet_cap( + generate_trait_from_impl, + r#" +struct Foo(f64); + +impl F$0oo { + /// Add `x` + /// + /// # Examples + #[cfg(true)] + fn add(&mut self, x: f64) { + self.0 += x; + } +}"#, + r#" +struct Foo(f64); + +trait Add { + /// Add `x` + /// + /// # Examples + #[cfg(true)] + fn add(&mut self, x: f64); +} + +impl Add for Foo { + #[cfg(true)] fn add(&mut self, x: f64) { self.0 += x; } @@ -339,11 +401,11 @@ pub fn a_func() -> Option<()> { r#" struct Foo; -trait NewTrait { +trait AFunc { fn a_func() -> Option<()>; } -impl NewTrait for Foo { +impl AFunc for Foo { fn a_func() -> Option<()> { Some(()) } @@ -373,11 +435,11 @@ fn foo() {} }"#, r#" mod a { - trait NewTrait { + trait Foo { fn foo(); } - impl NewTrait for S { + impl Foo for S { fn foo() {} } }"#, @@ -385,6 +447,28 @@ fn foo() {} } #[test] + fn test_multi_fn_impl_not_suggest_trait_name() { + check_assist_no_snippet_cap( + generate_trait_from_impl, + r#" +impl S$0 { + fn foo() {} + fn bar() {} +}"#, + r#" +trait NewTrait { + fn foo(); + fn bar(); +} + +impl NewTrait for S { + fn foo() {} + fn bar() {} +}"#, + ) + } + + #[test] fn test_snippet_cap_is_some() { check_assist( generate_trait_from_impl,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index 5d4bdc6..f55ef42 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
@@ -1,3 +1,4 @@ +use either::{Either, for_both}; use hir::{PathResolution, Semantics}; use ide_db::{ EditionedFileId, RootDatabase, @@ -5,8 +6,9 @@ search::{FileReference, FileReferenceNode, UsageSearchResult}, }; use syntax::{ - SyntaxElement, TextRange, + Direction, TextRange, ast::{self, AstNode, AstToken, HasName, syntax_factory::SyntaxFactory}, + syntax_editor::{Element, SyntaxEditor}, }; use crate::{ @@ -36,12 +38,15 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) let InlineData { let_stmt, delete_let, references, target } = if let Some(path_expr) = ctx.find_node_at_offset::<ast::PathExpr>() { inline_usage(&ctx.sema, path_expr, range, file_id) - } else if let Some(let_stmt) = ctx.find_node_at_offset::<ast::LetStmt>() { + } else if let Some(let_stmt) = ctx.find_node_at_offset() { inline_let(&ctx.sema, let_stmt, range, file_id) } else { None }?; - let initializer_expr = let_stmt.initializer()?; + let initializer_expr = match &let_stmt { + either::Either::Left(it) => it.initializer()?, + either::Either::Right(it) => it.expr()?, + }; let wrap_in_parens = references .into_iter() @@ -81,13 +86,15 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) let mut editor = builder.make_editor(&target); if delete_let { editor.delete(let_stmt.syntax()); - if let Some(whitespace) = let_stmt - .syntax() - .next_sibling_or_token() - .and_then(SyntaxElement::into_token) - .and_then(ast::Whitespace::cast) + + if let Some(bin_expr) = let_stmt.syntax().parent().and_then(ast::BinExpr::cast) + && let Some(op_token) = bin_expr.op_token() { - editor.delete(whitespace.syntax()); + editor.delete(&op_token); + remove_whitespace(op_token, Direction::Prev, &mut editor); + remove_whitespace(let_stmt.syntax(), Direction::Prev, &mut editor); + } else { + remove_whitespace(let_stmt.syntax(), Direction::Next, &mut editor); } } @@ -116,7 +123,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) } struct InlineData { - let_stmt: ast::LetStmt, + let_stmt: Either<ast::LetStmt, ast::LetExpr>, delete_let: bool, target: ast::NameOrNameRef, references: Vec<FileReference>, @@ -124,11 +131,11 @@ struct InlineData { fn inline_let( sema: &Semantics<'_, RootDatabase>, - let_stmt: ast::LetStmt, + let_stmt: Either<ast::LetStmt, ast::LetExpr>, range: TextRange, file_id: EditionedFileId, ) -> Option<InlineData> { - let bind_pat = match let_stmt.pat()? { + let bind_pat = match for_both!(&let_stmt, it => it.pat())? { ast::Pat::IdentPat(pat) => pat, _ => return None, }; @@ -187,7 +194,7 @@ fn inline_usage( let bind_pat = source.as_ident_pat()?; - let let_stmt = ast::LetStmt::cast(bind_pat.syntax().parent()?)?; + let let_stmt = AstNode::cast(bind_pat.syntax().parent()?)?; let UsageSearchResult { mut references } = Definition::Local(local).usages(sema).all(); let mut references = references.remove(&file_id)?; @@ -197,6 +204,23 @@ fn inline_usage( Some(InlineData { let_stmt, delete_let, target: ast::NameOrNameRef::NameRef(name), references }) } +fn remove_whitespace(elem: impl Element, dir: Direction, editor: &mut SyntaxEditor) { + let token = match elem.syntax_element() { + syntax::NodeOrToken::Node(node) => match dir { + Direction::Next => node.last_token(), + Direction::Prev => node.first_token(), + }, + syntax::NodeOrToken::Token(t) => Some(t), + }; + let next_token = match dir { + Direction::Next => token.and_then(|it| it.next_token()), + Direction::Prev => token.and_then(|it| it.prev_token()), + }; + if let Some(whitespace) = next_token.and_then(ast::Whitespace::cast) { + editor.delete(whitespace.syntax()); + } +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -405,6 +429,38 @@ fn foo() { } #[test] + fn test_inline_let_expr() { + check_assist( + inline_local_variable, + r" +fn bar(a: usize) {} +fn foo() { + if let a$0 = 1 + && true + { + a + 1; + if a > 10 {} + while a > 10 {} + let b = a * 10; + bar(a); + } +}", + r" +fn bar(a: usize) {} +fn foo() { + if true + { + 1 + 1; + if 1 > 10 {} + while 1 > 10 {} + let b = 1 * 10; + bar(1); + } +}", + ); + } + + #[test] fn test_not_inline_mut_variable() { cov_mark::check!(test_not_inline_mut_variable); check_assist_not_applicable( @@ -817,6 +873,70 @@ fn f() { } #[test] + fn let_expr_works_on_local_usage() { + check_assist( + inline_local_variable, + r#" +fn f() { + if let xyz = 0 + && true + { + xyz$0; + } +} +"#, + r#" +fn f() { + if true + { + 0; + } +} +"#, + ); + + check_assist( + inline_local_variable, + r#" +fn f() { + if let xyz = true + && xyz$0 + { + } +} +"#, + r#" +fn f() { + if true + { + } +} +"#, + ); + + check_assist( + inline_local_variable, + r#" +fn f() { + if true + && let xyz = 0 + { + xyz$0; + } +} +"#, + r#" +fn f() { + if true + { + 0; + } +} +"#, + ); + } + + #[test] fn does_not_remove_let_when_multiple_usages() { check_assist( inline_local_variable,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index c7a48f3..f3ebe61 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -12,7 +12,7 @@ use syntax::ast::syntax_factory::SyntaxFactory; use syntax::syntax_editor::SyntaxEditor; use syntax::{ - AstNode, NodeOrToken, SyntaxNode, + AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T, ast::{self, HasGenericParams, HasName}, }; @@ -322,12 +322,42 @@ fn create_replacement( if let Some(old_lifetime) = ast::Lifetime::cast(syntax.clone()) { if let Some(new_lifetime) = lifetime_map.0.get(&old_lifetime.to_string()) { if new_lifetime.text() == "'_" { - removals.push(NodeOrToken::Node(syntax.clone())); + // Check if this lifetime is inside a LifetimeArg (in angle brackets) + if let Some(lifetime_arg) = + old_lifetime.syntax().parent().and_then(ast::LifetimeArg::cast) + { + // Remove LifetimeArg and associated comma/whitespace + let lifetime_arg_syntax = lifetime_arg.syntax(); + removals.push(NodeOrToken::Node(lifetime_arg_syntax.clone())); - if let Some(ws) = syntax.next_sibling_or_token() { - removals.push(ws.clone()); + // Remove comma and whitespace (look forward then backward) + let comma_and_ws: Vec<_> = lifetime_arg_syntax + .siblings_with_tokens(syntax::Direction::Next) + .skip(1) + .take_while(|it| it.as_token().is_some()) + .take_while_inclusive(|it| it.kind() == T![,]) + .collect(); + + if comma_and_ws.iter().any(|it| it.kind() == T![,]) { + removals.extend(comma_and_ws); + } else { + // No comma after, try before + let comma_and_ws: Vec<_> = lifetime_arg_syntax + .siblings_with_tokens(syntax::Direction::Prev) + .skip(1) + .take_while(|it| it.as_token().is_some()) + .take_while_inclusive(|it| it.kind() == T![,]) + .collect(); + removals.extend(comma_and_ws); + } + continue; } - + removals.push(NodeOrToken::Node(syntax.clone())); + if let Some(ws) = syntax.next_sibling_or_token() + && ws.kind() == SyntaxKind::WHITESPACE + { + removals.push(ws); + } continue; } @@ -349,6 +379,34 @@ fn create_replacement( } } + // Deduplicate removals to avoid intersecting changes + removals.sort_by_key(|n| n.text_range().start()); + removals.dedup(); + + // Remove GenericArgList entirely if all its args are being removed (avoids empty angle brackets) + let generic_arg_lists_to_check: Vec<_> = + updated_concrete_type.descendants().filter_map(ast::GenericArgList::cast).collect(); + + for generic_arg_list in generic_arg_lists_to_check { + let will_be_empty = generic_arg_list.generic_args().all(|arg| match arg { + ast::GenericArg::LifetimeArg(lt_arg) => removals.iter().any(|removal| { + if let NodeOrToken::Node(node) = removal { node == lt_arg.syntax() } else { false } + }), + _ => false, + }); + + if will_be_empty && generic_arg_list.generic_args().next().is_some() { + removals.retain(|removal| { + if let NodeOrToken::Node(node) = removal { + !node.ancestors().any(|anc| anc == *generic_arg_list.syntax()) + } else { + true + } + }); + removals.push(NodeOrToken::Node(generic_arg_list.syntax().clone())); + } + } + for (old, new) in replacements { editor.replace(old, new); } @@ -946,6 +1004,48 @@ trait Tr { ); } + #[test] + fn inline_types_with_lifetime() { + check_assist( + inline_type_alias_uses, + r#" +struct A<'a, 'b>(pub &'a mut &'b mut ()); + +type $0T<'a, 'b> = A<'a, 'b>; + +fn foo(_: T) {} +"#, + r#" +struct A<'a, 'b>(pub &'a mut &'b mut ()); + + + +fn foo(_: A) {} +"#, + ); + } + + #[test] + fn mixed_lifetime_and_type_args() { + check_assist( + inline_type_alias, + r#" +type Foo<'a, T> = Bar<'a, T>; +struct Bar<'a, T>(&'a T); +fn main() { + let a: $0Foo<u32>; +} +"#, + r#" +type Foo<'a, T> = Bar<'a, T>; +struct Bar<'a, T>(&'a T); +fn main() { + let a: Bar<u32>; +} +"#, + ); + } + mod inline_type_alias_uses { use crate::{handlers::inline_type_alias::inline_type_alias_uses, tests::check_assist};
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs index bf82d8d..c8cb7bb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs
@@ -1,13 +1,13 @@ use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ T, - ast::{self, AstNode}, + ast::{self, AstNode, syntax_factory::SyntaxFactory}, }; use crate::{ AssistId, assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression_legacy, + utils::invert_boolean_expression, }; // Assist: invert_if @@ -50,7 +50,8 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() }; acc.add(AssistId::refactor_rewrite("invert_if"), "Invert if", if_range, |edit| { - let flip_cond = invert_boolean_expression_legacy(cond.clone()); + let make = SyntaxFactory::without_mappings(); + let flip_cond = invert_boolean_expression(&make, cond.clone()); edit.replace_ast(cond, flip_cond); let else_node = else_block.syntax();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs index 9ba73d2..42bc058 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
@@ -49,8 +49,9 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio SyntaxElement::Node(n) => n, SyntaxElement::Token(t) => t.parent()?, }; - let mut selected_nodes = - parent_node.children().filter(|it| selection_range.contains_range(it.text_range())); + let mut selected_nodes = parent_node.children().filter(|it| { + selection_range.intersect(it.text_range()).is_some_and(|it| !it.is_empty()) + }); let first_selected = selected_nodes.next()?; let edits = match_ast! { @@ -678,6 +679,25 @@ fn merge_selection_uses() { } #[test] + fn merge_partial_selection_uses() { + cov_mark::check!(merge_with_selected_use_item_neighbors); + check_assist( + merge_imports, + r" +use std::fmt::Error; +$0use std::fmt::Display; +use std::fmt::Debug; +use std::fmt::Write; +use$0 std::fmt::Result; +", + r" +use std::fmt::Error; +use std::fmt::{Debug, Display, Result, Write}; +", + ); + } + + #[test] fn merge_selection_use_trees() { cov_mark::check!(merge_with_selected_use_tree_neighbors); check_assist(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs index 08170f8..6e84af5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
@@ -160,8 +160,11 @@ fn recurse<'db>( } } ast::Pat::IdentPat(ident_pat) => { - if let Some(name) = ident_pat.name() { + if let Some(name) = ident_pat.name() + && ctx.sema.to_def(ident_pat).is_some() + { let pat_type = ctx.sema.type_of_binding_in_pat(ident_pat); + map.insert(name.text().to_string(), pat_type); } } @@ -213,6 +216,40 @@ fn main() { } #[test] + fn merge_match_arms_ambiguous_ident_patterns() { + check_assist( + merge_match_arms, + r#" +#[derive(Debug)] +enum X { A, B, C } +use X::*; + +fn main() { + let x = A; + let y = match x { + A => { 1i32$0 } + B => { 1i32 } + C => { 2i32 } + } +} +"#, + r#" +#[derive(Debug)] +enum X { A, B, C } +use X::*; + +fn main() { + let x = A; + let y = match x { + A | B => { 1i32 }, + C => { 2i32 } + } +} +"#, + ); + } + + #[test] fn merge_match_arms_multiple_patterns() { check_assist( merge_match_arms,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index b4c347f..8058737 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
@@ -3,7 +3,7 @@ SyntaxKind::WHITESPACE, TextRange, ast::{ - AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make, + AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, prec::ExprPrecedence, syntax_factory::SyntaxFactory, }, syntax_editor::Element, @@ -53,14 +53,15 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) let space_after_arrow = match_arm.fat_arrow_token()?.next_sibling_or_token(); let arm_expr = match_arm.expr()?; + let make = SyntaxFactory::without_mappings(); let if_branch = chain([&match_arm], &rest_arms) .rfold(None, |else_branch, arm| { if let Some(guard) = arm.guard() { - let then_branch = crate::utils::wrap_block(&arm.expr()?); + let then_branch = crate::utils::wrap_block(&arm.expr()?, &make); let guard_condition = guard.condition()?.reset_indent(); - Some(make::expr_if(guard_condition, then_branch, else_branch).into()) + Some(make.expr_if(guard_condition, then_branch, else_branch).into()) } else { - arm.expr().map(|it| crate::utils::wrap_block(&it).into()) + arm.expr().map(|it| crate::utils::wrap_block(&it, &make).into()) } })? .indent(arm_expr.indent_level()); @@ -84,7 +85,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) if let Some(element) = space_after_arrow && element.kind() == WHITESPACE { - edit.replace(element, make::tokens::single_space()); + edit.replace(element, make.whitespace(" ")); } edit.delete(guard.syntax());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index 495a84d6..8b9e657 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
@@ -1,6 +1,6 @@ use hir::{AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef, db::HirDatabase}; use ide_db::assists::AssistId; -use syntax::{AstNode, ast}; +use syntax::{AstNode, ast, ast::syntax_factory::SyntaxFactory}; use crate::{ assist_context::{AssistContext, Assists}, @@ -52,19 +52,25 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> cfg, )?; - let qualify_candidate = QualifyCandidate::ImplMethod(ctx.sema.db, call, resolved_call); + let qualify_candidate = QualifyCandidate::ImplMethod(ctx.sema.db, call.clone(), resolved_call); acc.add( AssistId::refactor_rewrite("qualify_method_call"), format!("Qualify `{ident}` method call"), range, |builder| { + let make = SyntaxFactory::with_mappings(); + let mut editor = builder.make_editor(call.syntax()); qualify_candidate.qualify( - |replace_with: String| builder.replace(range, replace_with), + |_| {}, + &mut editor, + &make, &receiver_path, item_in_ns, current_edition, - ) + ); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); Some(())
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index b3cf296..c059f75 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
@@ -11,7 +11,8 @@ use syntax::ast::HasGenericArgs; use syntax::{ AstNode, ast, - ast::{HasArgList, make}, + ast::{HasArgList, syntax_factory::SyntaxFactory}, + syntax_editor::SyntaxEditor, }; use crate::{ @@ -54,25 +55,25 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let qualify_candidate = match candidate { ImportCandidate::Path(candidate) if !candidate.qualifier.is_empty() => { cov_mark::hit!(qualify_path_qualifier_start); - let path = ast::Path::cast(syntax_under_caret)?; + let path = ast::Path::cast(syntax_under_caret.clone())?; let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?); QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list()) } ImportCandidate::Path(_) => { cov_mark::hit!(qualify_path_unqualified_name); - let path = ast::Path::cast(syntax_under_caret)?; + let path = ast::Path::cast(syntax_under_caret.clone())?; let generics = path.segment()?.generic_arg_list(); QualifyCandidate::UnqualifiedName(generics) } ImportCandidate::TraitAssocItem(_) => { cov_mark::hit!(qualify_path_trait_assoc_item); - let path = ast::Path::cast(syntax_under_caret)?; + let path = ast::Path::cast(syntax_under_caret.clone())?; let (qualifier, segment) = (path.qualifier()?, path.segment()?); QualifyCandidate::TraitAssocItem(qualifier, segment) } ImportCandidate::TraitMethod(_) => { cov_mark::hit!(qualify_path_trait_method); - let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret)?; + let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret.clone())?; QualifyCandidate::TraitMethod(ctx.sema.db, mcall_expr) } }; @@ -101,12 +102,18 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option label(ctx.db(), candidate, &import, current_edition), range, |builder| { + let make = SyntaxFactory::with_mappings(); + let mut editor = builder.make_editor(&syntax_under_caret); qualify_candidate.qualify( |replace_with: String| builder.replace(range, replace_with), + &mut editor, + &make, &import.import_path, import.item_to_import, current_edition, - ) + ); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ); } @@ -124,6 +131,8 @@ impl QualifyCandidate<'_> { pub(crate) fn qualify( &self, mut replacer: impl FnMut(String), + editor: &mut SyntaxEditor, + make: &SyntaxFactory, import: &hir::ModPath, item: hir::ItemInNs, edition: Edition, @@ -142,10 +151,10 @@ pub(crate) fn qualify( replacer(format!("<{qualifier} as {import}>::{segment}")); } QualifyCandidate::TraitMethod(db, mcall_expr) => { - Self::qualify_trait_method(db, mcall_expr, replacer, import, item); + Self::qualify_trait_method(db, mcall_expr, editor, make, import, item); } QualifyCandidate::ImplMethod(db, mcall_expr, hir_fn) => { - Self::qualify_fn_call(db, mcall_expr, replacer, import, hir_fn); + Self::qualify_fn_call(db, mcall_expr, editor, make, import, hir_fn); } } } @@ -153,7 +162,8 @@ pub(crate) fn qualify( fn qualify_fn_call( db: &RootDatabase, mcall_expr: &ast::MethodCallExpr, - mut replacer: impl FnMut(String), + editor: &mut SyntaxEditor, + make: &SyntaxFactory, import: ast::Path, hir_fn: &hir::Function, ) -> Option<()> { @@ -165,15 +175,17 @@ fn qualify_fn_call( if let Some(self_access) = hir_fn.self_param(db).map(|sp| sp.access(db)) { let receiver = match self_access { - hir::Access::Shared => make::expr_ref(receiver, false), - hir::Access::Exclusive => make::expr_ref(receiver, true), + hir::Access::Shared => make.expr_ref(receiver, false), + hir::Access::Exclusive => make.expr_ref(receiver, true), hir::Access::Owned => receiver, }; let arg_list = match arg_list { - Some(args) => make::arg_list(iter::once(receiver).chain(args)), - None => make::arg_list(iter::once(receiver)), + Some(args) => make.arg_list(iter::once(receiver).chain(args)), + None => make.arg_list(iter::once(receiver)), }; - replacer(format!("{import}::{method_name}{generics}{arg_list}")); + let call_path = make.path_from_text(&format!("{import}::{method_name}{generics}")); + let call_expr = make.expr_call(make.expr_path(call_path), arg_list); + editor.replace(mcall_expr.syntax(), call_expr.syntax()); } Some(()) } @@ -181,14 +193,15 @@ fn qualify_fn_call( fn qualify_trait_method( db: &RootDatabase, mcall_expr: &ast::MethodCallExpr, - replacer: impl FnMut(String), + editor: &mut SyntaxEditor, + make: &SyntaxFactory, import: ast::Path, item: hir::ItemInNs, ) -> Option<()> { let trait_method_name = mcall_expr.name_ref()?; let trait_ = item_as_trait(db, item)?; let method = find_trait_method(db, trait_, &trait_method_name)?; - Self::qualify_fn_call(db, mcall_expr, replacer, import, &method) + Self::qualify_fn_call(db, mcall_expr, editor, make, import, &method) } }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 7c02426..f54f7a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -4,7 +4,7 @@ use syntax::{ SyntaxKind::WHITESPACE, T, - ast::{self, AstNode, HasName, make}, + ast::{self, AstNode, HasName, syntax_factory::SyntaxFactory}, syntax_editor::{Position, SyntaxEditor}, }; @@ -12,8 +12,8 @@ AssistConfig, AssistId, assist_context::{AssistContext, Assists}, utils::{ - DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items, - gen_trait_fn_body, generate_trait_impl, + DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl_with_factory, + filter_assoc_items, gen_trait_fn_body, generate_trait_impl, }, }; @@ -127,6 +127,7 @@ fn add_assist( let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`"); acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| { + let make = SyntaxFactory::without_mappings(); let insert_after = Position::after(adt.syntax()); let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false); let impl_def = impl_def_from_trait( @@ -142,7 +143,7 @@ fn add_assist( let mut editor = builder.make_editor(attr.syntax()); update_attribute(&mut editor, old_derives, old_tree, old_trait_path, attr); - let trait_path = make::ty_path(replace_trait_path.clone()); + let trait_path = make.ty_path(replace_trait_path.clone()).into(); let (impl_def, first_assoc_item) = if let Some(impl_def) = impl_def { ( @@ -150,7 +151,7 @@ fn add_assist( impl_def.assoc_item_list().and_then(|list| list.assoc_items().next()), ) } else { - (generate_trait_impl(impl_is_unsafe, adt, trait_path), None) + (generate_trait_impl(&make, impl_is_unsafe, adt, trait_path), None) }; if let Some(cap) = ctx.config.snippet_cap { @@ -174,7 +175,7 @@ fn add_assist( editor.insert_all( insert_after, - vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], + vec![make.whitespace("\n\n").into(), impl_def.syntax().clone().into()], ); builder.add_file_edits(ctx.vfs_file_id(), editor); }) @@ -205,10 +206,19 @@ fn impl_def_from_trait( if trait_items.is_empty() { return None; } - let impl_def = generate_trait_impl(impl_is_unsafe, adt, make::ty_path(trait_path.clone())); + let make = SyntaxFactory::without_mappings(); + let trait_ty = make.ty_path(trait_path.clone()).into(); + let impl_def = generate_trait_impl(&make, impl_is_unsafe, adt, trait_ty); - let assoc_items = - add_trait_assoc_items_to_impl(sema, config, &trait_items, trait_, &impl_def, &target_scope); + let assoc_items = add_trait_assoc_items_to_impl_with_factory( + &make, + sema, + config, + &trait_items, + trait_, + &impl_def, + &target_scope, + ); let assoc_item_list = if let Some((first, other)) = assoc_items.split_first().map(|(first, other)| (first.clone_subtree(), other)) { @@ -222,12 +232,12 @@ fn impl_def_from_trait( } else { Some(first.clone()) }; - let items = first_item.into_iter().chain(other.iter().cloned()).collect(); - make::assoc_item_list(Some(items)) + let items: Vec<ast::AssocItem> = + first_item.into_iter().chain(other.iter().cloned()).collect(); + make.assoc_item_list(items) } else { - make::assoc_item_list(None) - } - .clone_for_update(); + make.assoc_item_list_empty() + }; let impl_def = impl_def.clone_subtree(); let mut editor = SyntaxEditor::new(impl_def.syntax().clone()); @@ -243,6 +253,7 @@ fn update_attribute( old_trait_path: &ast::Path, attr: &ast::Attr, ) { + let make = SyntaxFactory::without_mappings(); let new_derives = old_derives .iter() .filter(|t| t.to_string() != old_trait_path.to_string()) @@ -257,13 +268,13 @@ fn update_attribute( .collect::<Vec<_>>() }); // ...which are interspersed with ", " - let tt = Itertools::intersperse(tt, vec![make::token(T![,]), make::tokens::single_space()]); + let tt = Itertools::intersperse(tt, vec![make.token(T![,]), make.whitespace(" ")]); // ...wrap them into the appropriate `NodeOrToken` variant let tt = tt.flatten().map(syntax::NodeOrToken::Token); // ...and make them into a flat list of tokens let tt = tt.collect::<Vec<_>>(); - let new_tree = make::token_tree(T!['('], tt).clone_for_update(); + let new_tree = make.token_tree(T!['('], tt); editor.replace(old_tree.syntax(), new_tree.syntax()); } else { // Remove the attr and any trailing whitespace
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs index d22e951..38d8c38 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs
@@ -1,8 +1,11 @@ use either::Either; use ide_db::syntax_helpers::suggest_name; -use syntax::ast::{self, AstNode, HasArgList, syntax_factory::SyntaxFactory}; +use syntax::ast::{self, AstNode, HasArgList, prec::ExprPrecedence, syntax_factory::SyntaxFactory}; -use crate::{AssistContext, AssistId, Assists, utils::cover_let_chain}; +use crate::{ + AssistContext, AssistId, Assists, + utils::{cover_let_chain, wrap_paren, wrap_paren_in_call}, +}; // Assist: replace_is_some_with_if_let_some // @@ -39,6 +42,7 @@ pub(crate) fn replace_is_method_with_if_let_method( match method_kind { "is_some" | "is_ok" => { let receiver = call_expr.receiver()?; + let make = SyntaxFactory::with_mappings(); let mut name_generator = suggest_name::NameGenerator::new_from_scope_locals( ctx.sema.scope(has_cond.syntax()), @@ -48,7 +52,7 @@ pub(crate) fn replace_is_method_with_if_let_method( } else { name_generator.for_variable(&receiver, &ctx.sema) }; - let (pat, predicate) = method_predicate(&call_expr).unzip(); + let (pat, predicate) = method_predicate(&call_expr, &var_name, &make); let (assist_id, message, text) = if method_kind == "is_some" { ("replace_is_some_with_if_let_some", "Replace `is_some` with `let Some`", "Some") @@ -61,13 +65,9 @@ pub(crate) fn replace_is_method_with_if_let_method( message, call_expr.syntax().text_range(), |edit| { - let make = SyntaxFactory::with_mappings(); let mut editor = edit.make_editor(call_expr.syntax()); - let var_pat = pat.unwrap_or_else(|| { - make.ident_pat(false, false, make.name(&var_name)).into() - }); - let pat = make.tuple_struct_pat(make.ident_path(text), [var_pat]).into(); + let pat = make.tuple_struct_pat(make.ident_path(text), [pat]).into(); let let_expr = make.expr_let(pat, receiver); if let Some(cap) = ctx.config.snippet_cap @@ -81,6 +81,7 @@ pub(crate) fn replace_is_method_with_if_let_method( let new_expr = if let Some(predicate) = predicate { let op = ast::BinaryOp::LogicOp(ast::LogicOp::And); + let predicate = wrap_paren(predicate, &make, ExprPrecedence::LAnd); make.expr_bin(let_expr.into(), op, predicate).into() } else { ast::Expr::from(let_expr) @@ -96,14 +97,23 @@ pub(crate) fn replace_is_method_with_if_let_method( } } -fn method_predicate(call_expr: &ast::MethodCallExpr) -> Option<(ast::Pat, ast::Expr)> { - let argument = call_expr.arg_list()?.args().next()?; - match argument { - ast::Expr::ClosureExpr(it) => { - let pat = it.param_list()?.params().next()?.pat()?; - Some((pat, it.body()?)) - } - _ => None, +fn method_predicate( + call_expr: &ast::MethodCallExpr, + name: &str, + make: &SyntaxFactory, +) -> (ast::Pat, Option<ast::Expr>) { + let argument = call_expr.arg_list().and_then(|it| it.args().next()); + if let Some(ast::Expr::ClosureExpr(it)) = argument.clone() + && let Some(pat) = it.param_list().and_then(|it| it.params().next()?.pat()) + { + (pat, it.body()) + } else { + let pat = make.ident_pat(false, false, make.name(name)); + let expr = argument.map(|expr| { + let arg_list = make.arg_list([make.expr_path(make.ident_path(name))]); + make.expr_call(wrap_paren_in_call(expr, make), arg_list).into() + }); + (pat.into(), expr) } } @@ -234,6 +244,54 @@ fn main() { } "#, ); + + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Some(1); + if x.is_som$0e_and(|it| it != 3 || it > 10) {} +} +"#, + r#" +fn main() { + let x = Some(1); + if let Some(it) = x && (it != 3 || it > 10) {} +} +"#, + ); + + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Some(1); + if x.is_som$0e_and(predicate) {} +} +"#, + r#" +fn main() { + let x = Some(1); + if let Some(x1) = x && predicate(x1) {} +} +"#, + ); + + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Some(1); + if x.is_som$0e_and(func.f) {} +} +"#, + r#" +fn main() { + let x = Some(1); + if let Some(x1) = x && (func.f)(x1) {} +} +"#, + ); } #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index 5587f1b..6ff5f0b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
@@ -86,8 +86,8 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> } fn let_expr_needs_paren(expr: &ast::Expr) -> bool { - let fake_expr_let = - ast::make::expr_let(ast::make::tuple_pat(None).into(), ast::make::ext::expr_unit()); + let make = SyntaxFactory::without_mappings(); + let fake_expr_let = make.expr_let(make.tuple_pat(None).into(), make.expr_unit()); let Some(fake_expr) = fake_expr_let.expr() else { stdx::never!(); return false;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 6ca3e26..6e4dd8c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs
@@ -2,10 +2,10 @@ use ide_db::{RootDatabase, assists::AssistId, defs::Definition}; use syntax::{ AstNode, - ast::{self, Expr, HasArgList, make}, + ast::{self, Expr, HasArgList, make, syntax_factory::SyntaxFactory}, }; -use crate::{AssistContext, Assists}; +use crate::{AssistContext, Assists, utils::wrap_paren_in_call}; // Assist: replace_with_lazy_method // @@ -177,11 +177,7 @@ fn into_call(param: &Expr, sema: &Semantics<'_, RootDatabase>) -> Expr { } })() .unwrap_or_else(|| { - let callable = if needs_parens_in_call(param) { - make::expr_paren(param.clone()).into() - } else { - param.clone() - }; + let callable = wrap_paren_in_call(param.clone(), &SyntaxFactory::without_mappings()); make::expr_call(callable, make::arg_list(Vec::new())).into() }) } @@ -200,12 +196,6 @@ fn ends_is(name: &str, end: &str) -> bool { name.strip_suffix(end).is_some_and(|s| s.is_empty() || s.ends_with('_')) } -fn needs_parens_in_call(param: &Expr) -> bool { - let call = make::expr_call(make::ext::expr_unit(), make::arg_list(Vec::new())); - let callable = call.expr().expect("invalid make call"); - param.needs_parens_in_place_of(call.syntax(), callable.syntax()) -} - #[cfg(test)] mod tests { use crate::tests::check_assist;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index 009fc07..cdf2058 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
@@ -102,7 +102,7 @@ fn target_path(ctx: &AssistContext<'_>, mut original_path: ast::Path) -> Option< } match ctx.sema.resolve_path(&original_path)? { - PathResolution::Def(ModuleDef::Variant(_)) if on_first => original_path.qualifier(), + PathResolution::Def(ModuleDef::EnumVariant(_)) if on_first => original_path.qualifier(), PathResolution::Def(def) if def.as_assoc_item(ctx.db()).is_some() => { on_first.then_some(original_path.qualifier()?) }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs index 7b0f2dc..c4c03d3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
@@ -38,11 +38,18 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O } let match_arm = ast::MatchArm::cast(or_pat.syntax().parent()?)?; let match_arm_body = match_arm.expr()?; + let pats_after = pipe_token + .siblings_with_tokens(Direction::Next) + .filter_map(|it| ast::Pat::cast(it.into_node()?)) + .collect::<Vec<_>>(); // We don't need to check for leading pipe because it is directly under `MatchArm` // without `OrPat`. let new_parent = match_arm.syntax().parent()?; + if pats_after.is_empty() { + return None; + } acc.add( AssistId::refactor_rewrite("unmerge_match_arm"), @@ -51,10 +58,6 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O |edit| { let make = SyntaxFactory::with_mappings(); let mut editor = edit.make_editor(&new_parent); - let pats_after = pipe_token - .siblings_with_tokens(Direction::Next) - .filter_map(|it| ast::Pat::cast(it.into_node()?)) - .collect::<Vec<_>>(); // It is guaranteed that `pats_after` has at least one element let new_pat = if pats_after.len() == 1 { pats_after[0].clone() @@ -191,6 +194,21 @@ fn main() { } #[test] + fn unmerge_match_arm_trailing_pipe() { + check_assist_not_applicable( + unmerge_match_arm, + r#" +fn main() { + let y = match 0 { + 0 |$0 => { 1i32 } + 1 => { 2i32 } + }; +} +"#, + ); + } + + #[test] fn unmerge_match_arm_multiple_pipes() { check_assist( unmerge_match_arm,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs index e4f5e35..e029d78 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs
@@ -45,6 +45,7 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option ast::LoopExpr(it) => it.syntax().clone(), ast::WhileExpr(it) => it.syntax().clone(), ast::MatchArm(it) => it.parent_match().syntax().clone(), + ast::LetElse(it) => it.syntax().parent()?, ast::LetStmt(it) => { replacement = wrap_let(&it, replacement); prefer_container = Some(it.syntax().clone()); @@ -557,6 +558,40 @@ fn main() { } #[test] + fn simple_let_else() { + check_assist( + unwrap_block, + r#" +fn main() { + let Some(2) = None else {$0 + return; + }; +} +"#, + r#" +fn main() { + return; +} +"#, + ); + check_assist( + unwrap_block, + r#" +fn main() { + let Some(2) = None else {$0 + return + }; +} +"#, + r#" +fn main() { + return +} +"#, + ); + } + + #[test] fn unwrap_match_arm() { check_assist( unwrap_block,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs index 46f3e85..e03274b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
@@ -1,3 +1,6 @@ +use std::iter; + +use either::Either; use syntax::{ AstNode, T, ast::{self, edit::AstNodeEdit}, @@ -24,11 +27,16 @@ // ``` pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let let_kw = ctx.find_token_syntax_at_offset(T![let])?; - let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?; - let indent_level = let_stmt.indent_level().0 as usize; - let pat = let_stmt.pat()?; - let ty = let_stmt.ty(); - let init = let_stmt.initializer()?; + let let_stmt = let_kw.parent().and_then(Either::<ast::LetStmt, ast::LetExpr>::cast)?; + let mut indent_level = let_stmt.indent_level(); + let pat = either::for_both!(&let_stmt, it => it.pat())?; + let (ty, init, prefix, suffix) = match &let_stmt { + Either::Left(let_stmt) => (let_stmt.ty(), let_stmt.initializer()?, "", ";"), + Either::Right(let_expr) => { + indent_level += 1; + (None, let_expr.expr()?, "&& ", "") + } + }; // This only applies for tuple patterns, types, and initializers. let tuple_pat = match pat { @@ -60,25 +68,19 @@ pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option "Unwrap tuple", let_kw.text_range(), |edit| { - let indents = " ".repeat(indent_level); + let mut decls = String::new(); // If there is an ascribed type, insert that type for each declaration, // otherwise, omit that type. - if let Some(tys) = tuple_ty { - let mut zipped_decls = String::new(); - for (pat, ty, expr) in - itertools::izip!(tuple_pat.fields(), tys.fields(), tuple_init.fields()) - { - zipped_decls.push_str(&format!("{indents}let {pat}: {ty} = {expr};\n")) - } - edit.replace(parent.text_range(), zipped_decls.trim()); - } else { - let mut zipped_decls = String::new(); - for (pat, expr) in itertools::izip!(tuple_pat.fields(), tuple_init.fields()) { - zipped_decls.push_str(&format!("{indents}let {pat} = {expr};\n")); - } - edit.replace(parent.text_range(), zipped_decls.trim()); + let tys = + tuple_ty.into_iter().flat_map(|it| it.fields().map(Some)).chain(iter::repeat(None)); + for (pat, ty, expr) in itertools::izip!(tuple_pat.fields(), tys, tuple_init.fields()) { + let ty = ty.map_or_else(String::new, |ty| format!(": {ty}")); + decls.push_str(&format!("{prefix}let {pat}{ty} = {expr}{suffix}\n{indent_level}")) } + + let s = decls.trim(); + edit.replace(parent.text_range(), s.strip_prefix(prefix).unwrap_or(s)); }, ) } @@ -124,6 +126,28 @@ fn main() { } #[test] + fn unwrap_tuples_in_let_expr() { + check_assist( + unwrap_tuple, + r#" +fn main() { + if $0let (foo, bar) = ("Foo", "Bar") { + code(); + } +} +"#, + r#" +fn main() { + if let foo = "Foo" + && let bar = "Bar" { + code(); + } +} +"#, + ); + } + + #[test] fn unwrap_tuple_with_types() { check_assist( unwrap_tuple,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 7d5740b..36df4af 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
@@ -2,7 +2,7 @@ use itertools::Itertools; use syntax::{ NodeOrToken, SyntaxToken, T, TextRange, algo, - ast::{self, AstNode, make, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, edit::AstNodeEdit, make, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, Assists}; @@ -27,7 +27,7 @@ enum WrapUnwrapOption { WrapDerive { derive: TextRange, attr: ast::Attr }, - WrapAttr(ast::Attr), + WrapAttr(Vec<ast::Attr>), } /// Attempts to get the derive attribute from a derive attribute list @@ -102,9 +102,9 @@ fn attempt_get_derive(attr: ast::Attr, ident: SyntaxToken) -> WrapUnwrapOption { if ident.parent().and_then(ast::TokenTree::cast).is_none() || !attr.simple_name().map(|v| v.eq("derive")).unwrap_or_default() { - WrapUnwrapOption::WrapAttr(attr) + WrapUnwrapOption::WrapAttr(vec![attr]) } else { - attempt_attr().unwrap_or(WrapUnwrapOption::WrapAttr(attr)) + attempt_attr().unwrap_or_else(|| WrapUnwrapOption::WrapAttr(vec![attr])) } } pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { @@ -118,13 +118,27 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - Some(attempt_get_derive(attr, ident)) } - (Some(attr), _) => Some(WrapUnwrapOption::WrapAttr(attr)), + (Some(attr), _) => Some(WrapUnwrapOption::WrapAttr(vec![attr])), _ => None, } } else { let covering_element = ctx.covering_element(); match covering_element { - NodeOrToken::Node(node) => ast::Attr::cast(node).map(WrapUnwrapOption::WrapAttr), + NodeOrToken::Node(node) => { + if let Some(attr) = ast::Attr::cast(node.clone()) { + Some(WrapUnwrapOption::WrapAttr(vec![attr])) + } else { + let attrs = node + .children() + .filter(|it| it.text_range().intersect(ctx.selection_trimmed()).is_some()) + .map(ast::Attr::cast) + .collect::<Option<Vec<_>>>()?; + if attrs.is_empty() { + return None; + } + Some(WrapUnwrapOption::WrapAttr(attrs)) + } + } NodeOrToken::Token(ident) if ident.kind() == syntax::T![ident] => { let attr = ident.parent_ancestors().find_map(ast::Attr::cast)?; Some(attempt_get_derive(attr, ident)) @@ -133,10 +147,12 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - } }?; match option { - WrapUnwrapOption::WrapAttr(attr) if attr.simple_name().as_deref() == Some("cfg_attr") => { - unwrap_cfg_attr(acc, attr) - } - WrapUnwrapOption::WrapAttr(attr) => wrap_cfg_attr(acc, ctx, attr), + WrapUnwrapOption::WrapAttr(attrs) => match &attrs[..] { + [attr] if attr.simple_name().as_deref() == Some("cfg_attr") => { + unwrap_cfg_attr(acc, attrs.into_iter().next().unwrap()) + } + _ => wrap_cfg_attrs(acc, ctx, attrs), + }, WrapUnwrapOption::WrapDerive { derive, attr } => wrap_derive(acc, ctx, attr, derive), } } @@ -220,40 +236,51 @@ fn wrap_derive( ); Some(()) } -fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) -> Option<()> { - let range = attr.syntax().text_range(); - let path = attr.path()?; +fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::Attr>) -> Option<()> { + let (first_attr, last_attr) = (attrs.first()?, attrs.last()?); + let range = first_attr.syntax().text_range().cover(last_attr.syntax().text_range()); + let path_attrs = + attrs.iter().map(|attr| Some((attr.path()?, attr.clone()))).collect::<Option<Vec<_>>>()?; let handle_source_change = |edit: &mut SourceChangeBuilder| { let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(attr.syntax()); - let mut raw_tokens = - vec![NodeOrToken::Token(make.token(T![,])), NodeOrToken::Token(make.whitespace(" "))]; - path.syntax().descendants_with_tokens().for_each(|it| { - if let NodeOrToken::Token(token) = it { - raw_tokens.push(NodeOrToken::Token(token)); - } - }); - if let Some(meta) = attr.meta() { - if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) { - raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); - raw_tokens.push(NodeOrToken::Token(eq)); - raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); + let mut editor = edit.make_editor(first_attr.syntax()); + let mut raw_tokens = vec![]; + for (path, attr) in path_attrs { + raw_tokens.extend([ + NodeOrToken::Token(make.token(T![,])), + NodeOrToken::Token(make.whitespace(" ")), + ]); + path.syntax().descendants_with_tokens().for_each(|it| { + if let NodeOrToken::Token(token) = it { + raw_tokens.push(NodeOrToken::Token(token)); + } + }); + if let Some(meta) = attr.meta() { + if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) { + raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); + raw_tokens.push(NodeOrToken::Token(eq)); + raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); - expr.syntax().descendants_with_tokens().for_each(|it| { - if let NodeOrToken::Token(token) = it { - raw_tokens.push(NodeOrToken::Token(token)); - } - }); - } else if let Some(tt) = meta.token_tree() { - raw_tokens.extend(tt.token_trees_and_tokens()); + expr.syntax().descendants_with_tokens().for_each(|it| { + if let NodeOrToken::Token(token) = it { + raw_tokens.push(NodeOrToken::Token(token)); + } + }); + } else if let Some(tt) = meta.token_tree() { + raw_tokens.extend(tt.token_trees_and_tokens()); + } } } let meta = make.meta_token_tree(make.ident_path("cfg_attr"), make.token_tree(T!['('], raw_tokens)); - let cfg_attr = - if attr.excl_token().is_some() { make.attr_inner(meta) } else { make.attr_outer(meta) }; + let cfg_attr = if first_attr.excl_token().is_some() { + make.attr_inner(meta) + } else { + make.attr_outer(meta) + }; - editor.replace(attr.syntax(), cfg_attr.syntax()); + let syntax_range = first_attr.syntax().clone().into()..=last_attr.syntax().clone().into(); + editor.replace_all(syntax_range, vec![cfg_attr.syntax().clone().into()]); if let Some(snippet_cap) = ctx.config.snippet_cap && let Some(first_meta) = @@ -332,7 +359,8 @@ fn unwrap_cfg_attr(acc: &mut Assists, attr: ast::Attr) -> Option<()> { return None; } let handle_source_change = |f: &mut SourceChangeBuilder| { - let inner_attrs = inner_attrs.iter().map(|it| it.to_string()).join("\n"); + let inner_attrs = + inner_attrs.iter().map(|it| it.to_string()).join(&format!("\n{}", attr.indent_level())); f.replace(range, inner_attrs); }; acc.add( @@ -414,6 +442,42 @@ pub struct Test { } "#, ); + check_assist( + wrap_unwrap_cfg_attr, + r#" + pub struct Test { + #[other_attr] + $0#[foo] + #[bar]$0 + #[other_attr] + test: u32, + } + "#, + r#" + pub struct Test { + #[other_attr] + #[cfg_attr($0, foo, bar)] + #[other_attr] + test: u32, + } + "#, + ); + check_assist( + wrap_unwrap_cfg_attr, + r#" + pub struct Test { + #[cfg_attr(debug_assertions$0, foo, bar)] + test: u32, + } + "#, + r#" + pub struct Test { + #[foo] + #[bar] + test: u32, + } + "#, + ); } #[test] fn to_from_eq_attr() {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 3040509..66d5cf8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -507,8 +507,8 @@ fn main() { r#####" fn main() { let x = vec![1, 2, 3]; - let mut tmp = x.into_iter(); - while let Some(v) = tmp.next() { + let mut iter = x.into_iter(); + while let Some(v) = iter.next() { let y = v * 2; }; } @@ -2282,7 +2282,7 @@ macro_rules! const_maker { }; } -trait ${0:NewTrait}<const N: usize> { +trait ${0:Create}<const N: usize> { // Used as an associated constant. const CONST_ASSOC: usize = N * 4; @@ -2291,7 +2291,7 @@ trait ${0:NewTrait}<const N: usize> { const_maker! {i32, 7} } -impl<const N: usize> ${0:NewTrait}<N> for Foo<N> { +impl<const N: usize> ${0:Create}<N> for Foo<N> { // Used as an associated constant. const CONST_ASSOC: usize = N * 4;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index b4055e7..10057f8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -25,6 +25,7 @@ edit::{AstNodeEdit, IndentLevel}, edit_in_place::AttrsOwnerEdit, make, + prec::ExprPrecedence, syntax_factory::SyntaxFactory, }, syntax_editor::{Element, Removable, SyntaxEditor}, @@ -86,17 +87,31 @@ pub fn extract_trivial_expression(block_expr: &ast::BlockExpr) -> Option<ast::Ex None } -pub(crate) fn wrap_block(expr: &ast::Expr) -> ast::BlockExpr { +pub(crate) fn wrap_block(expr: &ast::Expr, make: &SyntaxFactory) -> ast::BlockExpr { if let ast::Expr::BlockExpr(block) = expr && let Some(first) = block.syntax().first_token() && first.kind() == T!['{'] { block.reset_indent() } else { - make::block_expr(None, Some(expr.reset_indent().indent(1.into()))) + make.block_expr(None, Some(expr.reset_indent().indent(1.into()))) } } +pub(crate) fn wrap_paren(expr: ast::Expr, make: &SyntaxFactory, prec: ExprPrecedence) -> ast::Expr { + if expr.precedence().needs_parentheses_in(prec) { make.expr_paren(expr).into() } else { expr } +} + +pub(crate) fn wrap_paren_in_call(expr: ast::Expr, make: &SyntaxFactory) -> ast::Expr { + if needs_parens_in_call(make, &expr) { make.expr_paren(expr).into() } else { expr } +} + +fn needs_parens_in_call(make: &SyntaxFactory, param: &ast::Expr) -> bool { + let call = make.expr_call(make.expr_unit(), make.arg_list(Vec::new())); + let callable = call.expr().expect("invalid make call"); + param.needs_parens_in_place_of(call.syntax(), callable.syntax()) +} + /// This is a method with a heuristics to support test methods annotated with custom test annotations, such as /// `#[test_case(...)]`, `#[tokio::test]` and similar. /// Also a regular `#[test]` annotation is supported. @@ -188,6 +203,9 @@ fn has_def_name(item: &InFile<ast::AssocItem>) -> bool { /// [`filter_assoc_items()`]), clones each item for update and applies path transformation to it, /// then inserts into `impl_`. Returns the modified `impl_` and the first associated item that got /// inserted. +/// +/// Legacy: prefer [`add_trait_assoc_items_to_impl_with_factory`] when a [`SyntaxFactory`] is +/// available. #[must_use] pub fn add_trait_assoc_items_to_impl( sema: &Semantics<'_, RootDatabase>, @@ -233,15 +251,79 @@ pub fn add_trait_assoc_items_to_impl( .filter_map(|item| match item { ast::AssocItem::Fn(fn_) if fn_.body().is_none() => { let fn_ = fn_.clone_subtree(); - let new_body = &make::block_expr( - None, - Some(match config.expr_fill_default { - ExprFillDefaultMode::Todo => make::ext::expr_todo(), - ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), - ExprFillDefaultMode::Default => make::ext::expr_todo(), - }), - ); - let new_body = AstNodeEdit::indent(new_body, IndentLevel::single()); + let new_body = make::block_expr(None, Some(expr_fill_default(config))); + let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone()); + fn_.replace_or_insert_body(&mut fn_editor, new_body.clone_for_update()); + let new_fn_ = fn_editor.finish().new_root().clone(); + ast::AssocItem::cast(new_fn_) + } + ast::AssocItem::TypeAlias(type_alias) => { + let type_alias = type_alias.clone_subtree(); + if let Some(type_bound_list) = type_alias.type_bound_list() { + let mut type_alias_editor = SyntaxEditor::new(type_alias.syntax().clone()); + type_bound_list.remove(&mut type_alias_editor); + let type_alias = type_alias_editor.finish().new_root().clone(); + ast::AssocItem::cast(type_alias) + } else { + Some(ast::AssocItem::TypeAlias(type_alias)) + } + } + item => Some(item), + }) + .map(|item| AstNodeEdit::indent(&item, new_indent_level)) + .collect() +} + +/// [`SyntaxFactory`]-based variant of [`add_trait_assoc_items_to_impl`]. +#[must_use] +pub fn add_trait_assoc_items_to_impl_with_factory( + make: &SyntaxFactory, + sema: &Semantics<'_, RootDatabase>, + config: &AssistConfig, + original_items: &[InFile<ast::AssocItem>], + trait_: hir::Trait, + impl_: &ast::Impl, + target_scope: &hir::SemanticsScope<'_>, +) -> Vec<ast::AssocItem> { + let new_indent_level = IndentLevel::from_node(impl_.syntax()) + 1; + original_items + .iter() + .map(|InFile { file_id, value: original_item }| { + let mut cloned_item = { + if let Some(macro_file) = file_id.macro_file() { + let span_map = sema.db.expansion_span_map(macro_file); + let item_prettified = prettify_macro_expansion( + sema.db, + original_item.syntax().clone(), + &span_map, + target_scope.krate().into(), + ); + if let Some(formatted) = ast::AssocItem::cast(item_prettified) { + return formatted; + } else { + stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`"); + } + } + original_item + } + .reset_indent(); + + if let Some(source_scope) = sema.scope(original_item.syntax()) { + let transform = + PathTransform::trait_impl(target_scope, &source_scope, trait_, impl_.clone()); + cloned_item = ast::AssocItem::cast(transform.apply(cloned_item.syntax())).unwrap(); + } + cloned_item.remove_attrs_and_docs(); + cloned_item + }) + .filter_map(|item| match item { + ast::AssocItem::Fn(fn_) if fn_.body().is_none() => { + let fn_ = fn_.clone_subtree(); + let fill_expr: ast::Expr = match config.expr_fill_default { + ExprFillDefaultMode::Todo | ExprFillDefaultMode::Default => make.expr_todo(), + ExprFillDefaultMode::Underscore => make.expr_underscore().into(), + }; + let new_body = make.block_expr(None::<ast::Stmt>, Some(fill_expr)); let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone()); fn_.replace_or_insert_body(&mut fn_editor, new_body); let new_fn_ = fn_editor.finish().new_root().clone(); @@ -275,11 +357,6 @@ pub(crate) fn invert_boolean_expression(make: &SyntaxFactory, expr: ast::Expr) - invert_special_case(make, &expr).unwrap_or_else(|| make.expr_prefix(T![!], expr).into()) } -// FIXME: Migrate usages of this function to the above function and remove this. -pub(crate) fn invert_boolean_expression_legacy(expr: ast::Expr) -> ast::Expr { - invert_special_case_legacy(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into()) -} - fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option<ast::Expr> { match expr { ast::Expr::BinExpr(bin) => { @@ -343,62 +420,11 @@ fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option<ast::Ex } } -fn invert_special_case_legacy(expr: &ast::Expr) -> Option<ast::Expr> { - match expr { - ast::Expr::BinExpr(bin) => { - let bin = bin.clone_subtree(); - let op_token = bin.op_token()?; - let rev_token = match op_token.kind() { - T![==] => T![!=], - T![!=] => T![==], - T![<] => T![>=], - T![<=] => T![>], - T![>] => T![<=], - T![>=] => T![<], - // Parenthesize other expressions before prefixing `!` - _ => { - return Some( - make::expr_prefix(T![!], make::expr_paren(expr.clone()).into()).into(), - ); - } - }; - let mut bin_editor = SyntaxEditor::new(bin.syntax().clone()); - bin_editor.replace(op_token, make::token(rev_token)); - ast::Expr::cast(bin_editor.finish().new_root().clone()) - } - ast::Expr::MethodCallExpr(mce) => { - let receiver = mce.receiver()?; - let method = mce.name_ref()?; - let arg_list = mce.arg_list()?; - - let method = match method.text().as_str() { - "is_some" => "is_none", - "is_none" => "is_some", - "is_ok" => "is_err", - "is_err" => "is_ok", - _ => return None, - }; - Some(make::expr_method_call(receiver, make::name_ref(method), arg_list).into()) - } - ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? { - ast::Expr::ParenExpr(parexpr) => parexpr.expr(), - _ => pe.expr(), - }, - ast::Expr::Literal(lit) => match lit.kind() { - ast::LiteralKind::Bool(b) => match b { - true => Some(ast::Expr::Literal(make::expr_literal("false"))), - false => Some(ast::Expr::Literal(make::expr_literal("true"))), - }, - _ => None, - }, - _ => None, - } -} - pub(crate) fn insert_attributes( before: impl Element, edit: &mut SyntaxEditor, attrs: impl IntoIterator<Item = ast::Attr>, + make: &SyntaxFactory, ) { let mut attrs = attrs.into_iter().peekable(); if attrs.peek().is_none() { @@ -410,9 +436,7 @@ pub(crate) fn insert_attributes( edit.insert_all( syntax::syntax_editor::Position::before(elem), attrs - .flat_map(|attr| { - [attr.syntax().clone().into(), make::tokens::whitespace(&whitespace).into()] - }) + .flat_map(|attr| [attr.syntax().clone().into(), make.whitespace(&whitespace).into()]) .collect(), ); } @@ -508,6 +532,15 @@ fn check_pat_variant_nested_or_literal_with_depth( } } +pub(crate) fn expr_fill_default(config: &AssistConfig) -> ast::Expr { + let make = SyntaxFactory::without_mappings(); + match config.expr_fill_default { + ExprFillDefaultMode::Todo => make.expr_todo(), + ExprFillDefaultMode::Underscore => make.expr_underscore().into(), + ExprFillDefaultMode::Default => make.expr_todo(), + } +} + // Uses a syntax-driven approach to find any impl blocks for the struct that // exist within the module/file // @@ -596,29 +629,6 @@ pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String { generate_impl_text_inner(adt, None, true, code) } -/// Generates the surrounding `impl <trait> for Type { <code> }` including type -/// and lifetime parameters, with `<trait>` appended to `impl`'s generic parameters' bounds. -/// -/// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`. -// FIXME: migrate remaining uses to `generate_trait_impl` -#[allow(dead_code)] -pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String { - generate_impl_text_inner(adt, Some(trait_text), true, code) -} - -/// Generates the surrounding `impl <trait> for Type { <code> }` including type -/// and lifetime parameters, with `impl`'s generic parameters' bounds kept as-is. -/// -/// This is useful for traits like `From<T>`, since `impl<T> From<T> for U<T>` doesn't require `T: From<T>`. -// FIXME: migrate remaining uses to `generate_trait_impl_intransitive` -pub(crate) fn generate_trait_impl_text_intransitive( - adt: &ast::Adt, - trait_text: &str, - code: &str, -) -> String { - generate_impl_text_inner(adt, Some(trait_text), false, code) -} - fn generate_impl_text_inner( adt: &ast::Adt, trait_text: Option<&str>, @@ -699,10 +709,15 @@ fn generate_impl_text_inner( /// Generates the corresponding `impl Type {}` including type and lifetime /// parameters. pub(crate) fn generate_impl_with_item( + make: &SyntaxFactory, adt: &ast::Adt, body: Option<ast::AssocItemList>, ) -> ast::Impl { - generate_impl_inner(false, adt, None, true, body) + generate_impl_inner_with_factory(make, false, adt, None, true, body) +} + +pub(crate) fn generate_impl_with_factory(make: &SyntaxFactory, adt: &ast::Adt) -> ast::Impl { + generate_impl_inner_with_factory(make, false, adt, None, true, None) } pub(crate) fn generate_impl(adt: &ast::Adt) -> ast::Impl { @@ -713,16 +728,34 @@ pub(crate) fn generate_impl(adt: &ast::Adt) -> ast::Impl { /// and lifetime parameters, with `<trait>` appended to `impl`'s generic parameters' bounds. /// /// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`. -pub(crate) fn generate_trait_impl(is_unsafe: bool, adt: &ast::Adt, trait_: ast::Type) -> ast::Impl { - generate_impl_inner(is_unsafe, adt, Some(trait_), true, None) +pub(crate) fn generate_trait_impl( + make: &SyntaxFactory, + is_unsafe: bool, + adt: &ast::Adt, + trait_: ast::Type, +) -> ast::Impl { + generate_impl_inner_with_factory(make, is_unsafe, adt, Some(trait_), true, None) } /// Generates the corresponding `impl <trait> for Type {}` including type /// and lifetime parameters, with `impl`'s generic parameters' bounds kept as-is. /// /// This is useful for traits like `From<T>`, since `impl<T> From<T> for U<T>` doesn't require `T: From<T>`. -pub(crate) fn generate_trait_impl_intransitive(adt: &ast::Adt, trait_: ast::Type) -> ast::Impl { - generate_impl_inner(false, adt, Some(trait_), false, None) +pub(crate) fn generate_trait_impl_intransitive( + make: &SyntaxFactory, + adt: &ast::Adt, + trait_: ast::Type, +) -> ast::Impl { + generate_impl_inner_with_factory(make, false, adt, Some(trait_), false, None) +} + +pub(crate) fn generate_trait_impl_intransitive_with_item( + make: &SyntaxFactory, + adt: &ast::Adt, + trait_: ast::Type, + body: ast::AssocItemList, +) -> ast::Impl { + generate_impl_inner_with_factory(make, false, adt, Some(trait_), false, Some(body)) } fn generate_impl_inner( @@ -795,6 +828,76 @@ fn generate_impl_inner( .clone_for_update() } +fn generate_impl_inner_with_factory( + make: &SyntaxFactory, + is_unsafe: bool, + adt: &ast::Adt, + trait_: Option<ast::Type>, + trait_is_transitive: bool, + body: Option<ast::AssocItemList>, +) -> ast::Impl { + // Ensure lifetime params are before type & const params + let generic_params = adt.generic_param_list().map(|generic_params| { + let lifetime_params = + generic_params.lifetime_params().map(ast::GenericParam::LifetimeParam); + let ty_or_const_params = generic_params.type_or_const_params().filter_map(|param| { + let param = match param { + ast::TypeOrConstParam::Type(param) => { + // remove defaults since they can't be specified in impls + let mut bounds = + param.type_bound_list().map_or_else(Vec::new, |it| it.bounds().collect()); + if let Some(trait_) = &trait_ { + // Add the current trait to `bounds` if the trait is transitive, + // meaning `impl<T> Trait for U<T>` requires `T: Trait`. + if trait_is_transitive { + bounds.push(make.type_bound(trait_.clone())); + } + }; + // `{ty_param}: {bounds}` + let param = make.type_param(param.name()?, make.type_bound_list(bounds)); + ast::GenericParam::TypeParam(param) + } + ast::TypeOrConstParam::Const(param) => { + // remove defaults since they can't be specified in impls + let param = make.const_param(param.name()?, param.ty()?); + ast::GenericParam::ConstParam(param) + } + }; + Some(param) + }); + + make.generic_param_list(itertools::chain(lifetime_params, ty_or_const_params)) + }); + let generic_args = + generic_params.as_ref().map(|params| params.to_generic_args().clone_for_update()); + let adt_assoc_bounds = + trait_.as_ref().zip(generic_params.as_ref()).and_then(|(trait_, params)| { + generic_param_associated_bounds_with_factory(make, adt, trait_, params) + }); + + let ty: ast::Type = make.ty_path(make.ident_path(&adt.name().unwrap().text())).into(); + + let cfg_attrs = + adt.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")); + match trait_ { + Some(trait_) => make.impl_trait( + cfg_attrs, + is_unsafe, + None, + None, + generic_params, + generic_args, + false, + trait_, + ty, + adt_assoc_bounds, + adt.where_clause(), + body, + ), + None => make.impl_(cfg_attrs, generic_params, generic_args, ty, adt.where_clause(), body), + } +} + fn generic_param_associated_bounds( adt: &ast::Adt, trait_: &ast::Type, @@ -840,6 +943,52 @@ fn generic_param_associated_bounds( trait_where_clause.peek().is_some().then(|| make::where_clause(trait_where_clause)) } +fn generic_param_associated_bounds_with_factory( + make: &SyntaxFactory, + adt: &ast::Adt, + trait_: &ast::Type, + generic_params: &ast::GenericParamList, +) -> Option<ast::WhereClause> { + let in_type_params = |name: &ast::NameRef| { + generic_params + .generic_params() + .filter_map(|param| match param { + ast::GenericParam::TypeParam(type_param) => type_param.name(), + _ => None, + }) + .any(|param| param.text() == name.text()) + }; + let adt_body = match adt { + ast::Adt::Enum(e) => e.variant_list().map(|it| it.syntax().clone()), + ast::Adt::Struct(s) => s.field_list().map(|it| it.syntax().clone()), + ast::Adt::Union(u) => u.record_field_list().map(|it| it.syntax().clone()), + }; + let mut trait_where_clause = adt_body + .into_iter() + .flat_map(|it| it.descendants()) + .filter_map(ast::Path::cast) + .filter_map(|path| { + let qualifier = path.qualifier()?.as_single_segment()?; + let qualifier = qualifier + .name_ref() + .or_else(|| match qualifier.type_anchor()?.ty()? { + ast::Type::PathType(path_type) => path_type.path()?.as_single_name_ref(), + _ => None, + }) + .filter(in_type_params)?; + Some((qualifier, path.segment()?.name_ref()?)) + }) + .map(|(qualifier, assoc_name)| { + let segments = [qualifier, assoc_name].map(|nr| make.path_segment(nr)); + let path = make.path_from_segments(segments, false); + let bounds = [make.type_bound(trait_.clone())]; + make.where_pred(either::Either::Right(make.ty_path(path).into()), bounds) + }) + .unique_by(|it| it.syntax().to_string()) + .peekable(); + trait_where_clause.peek().is_some().then(|| make.where_clause(trait_where_clause)) +} + pub(crate) fn add_method_to_adt( builder: &mut SourceChangeBuilder, adt: &ast::Adt, @@ -886,8 +1035,8 @@ enum ReferenceConversionType { } impl<'db> ReferenceConversion<'db> { - pub(crate) fn convert_type(&self, db: &'db dyn HirDatabase, module: hir::Module) -> ast::Type { - let ty = match self.conversion { + fn type_to_string(&self, db: &'db dyn HirDatabase, module: hir::Module) -> String { + match self.conversion { ReferenceConversionType::Copy => self .ty .display_source_code(db, module.into(), true) @@ -937,25 +1086,38 @@ pub(crate) fn convert_type(&self, db: &'db dyn HirDatabase, module: hir::Module) .unwrap_or_else(|_| "_".to_owned()); format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>") } - }; + } + } + pub(crate) fn convert_type(&self, db: &'db dyn HirDatabase, module: hir::Module) -> ast::Type { + let ty = self.type_to_string(db, module); make::ty(&ty) } - pub(crate) fn getter(&self, field_name: String) -> ast::Expr { - let expr = make::expr_field(make::ext::expr_self(), &field_name); + pub(crate) fn convert_type_with_factory( + &self, + make: &SyntaxFactory, + db: &'db dyn HirDatabase, + module: hir::Module, + ) -> ast::Type { + let ty = self.type_to_string(db, module); + make.ty(&ty) + } + + pub(crate) fn getter(&self, make: &SyntaxFactory, field_name: String) -> ast::Expr { + let expr = make.expr_field(make.expr_self(), &field_name); match self.conversion { - ReferenceConversionType::Copy => expr, + ReferenceConversionType::Copy => expr.into(), ReferenceConversionType::AsRefStr | ReferenceConversionType::AsRefSlice | ReferenceConversionType::Dereferenced | ReferenceConversionType::Option | ReferenceConversionType::Result => { if self.impls_deref { - make::expr_ref(expr, false) + make.expr_ref(expr.into(), false) } else { - make::expr_method_call(expr, make::name_ref("as_ref"), make::arg_list([])) + make.expr_method_call(expr.into(), make.name_ref("as_ref"), make.arg_list([])) .into() } } @@ -1095,18 +1257,21 @@ pub(crate) fn trimmed_text_range(source_file: &SourceFile, initial_range: TextRa /// Convert a list of function params to a list of arguments that can be passed /// into a function call. -pub(crate) fn convert_param_list_to_arg_list(list: ast::ParamList) -> ast::ArgList { +pub(crate) fn convert_param_list_to_arg_list( + list: ast::ParamList, + make: &SyntaxFactory, +) -> ast::ArgList { let mut args = vec![]; for param in list.params() { if let Some(ast::Pat::IdentPat(pat)) = param.pat() && let Some(name) = pat.name() { let name = name.to_string(); - let expr = make::expr_path(make::ext::ident_path(&name)); + let expr = make.expr_path(make.ident_path(&name)); args.push(expr); } } - make::arg_list(args) + make.arg_list(args) } /// Calculate the number of hashes required for a raw string containing `s` @@ -1191,7 +1356,10 @@ pub(crate) fn replace_record_field_expr( /// Creates a token tree list from a syntax node, creating the needed delimited sub token trees. /// Assumes that the input syntax node is a valid syntax tree. -pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec<NodeOrToken<ast::TokenTree, SyntaxToken>> { +pub(crate) fn tt_from_syntax( + node: SyntaxNode, + make: &SyntaxFactory, +) -> Vec<NodeOrToken<ast::TokenTree, SyntaxToken>> { let mut tt_stack = vec![(None, vec![])]; for element in node.descendants_with_tokens() { @@ -1219,7 +1387,7 @@ pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec<NodeOrToken<ast::TokenTree "mismatched opening and closing delimiters" ); - let sub_tt = make::token_tree(delimiter.expect("unbalanced delimiters"), tt); + let sub_tt = make.token_tree(delimiter.expect("unbalanced delimiters"), tt); parent_tt.push(NodeOrToken::Node(sub_tt)); } _ => { @@ -1254,6 +1422,20 @@ pub(crate) fn cover_let_chain(mut expr: ast::Expr, range: TextRange) -> Option<a } } +pub(crate) fn cover_edit_range( + source: &SyntaxNode, + range: TextRange, +) -> std::ops::RangeInclusive<syntax::SyntaxElement> { + let node = match source.covering_element(range) { + NodeOrToken::Node(node) => node, + NodeOrToken::Token(t) => t.parent().unwrap(), + }; + let mut iter = node.children_with_tokens().filter(|it| range.contains_range(it.text_range())); + let first = iter.next().unwrap_or(node.into()); + let last = iter.last().unwrap_or_else(|| first.clone()); + first..=last +} + pub(crate) fn is_selected( it: &impl AstNode, selection: syntax::TextRange,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs index df8ad41..fc9bf21 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/ref_field_expr.rs
@@ -5,7 +5,7 @@ //! based on the parent of the existing expression. use syntax::{ AstNode, T, - ast::{self, FieldExpr, MethodCallExpr, make, syntax_factory::SyntaxFactory}, + ast::{self, FieldExpr, MethodCallExpr, syntax_factory::SyntaxFactory}, }; use crate::AssistContext; @@ -119,13 +119,13 @@ pub(crate) struct RefData { impl RefData { /// Derefs `expr` and wraps it in parens if necessary - pub(crate) fn wrap_expr(&self, mut expr: ast::Expr) -> ast::Expr { + pub(crate) fn wrap_expr(&self, mut expr: ast::Expr, make: &SyntaxFactory) -> ast::Expr { if self.needs_deref { - expr = make::expr_prefix(T![*], expr).into(); + expr = make.expr_prefix(T![*], expr).into(); } if self.needs_parentheses { - expr = make::expr_paren(expr).into(); + expr = make.expr_paren(expr).into(); } expr
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 355687b..1fb1fd4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -26,7 +26,7 @@ use std::iter; -use hir::{HasAttrs, Name, ScopeDef, Variant, sym}; +use hir::{EnumVariant, HasAttrs, Name, ScopeDef, sym}; use ide_db::{RootDatabase, SymbolKind, imports::import_assets::LocatedImport}; use syntax::{SmolStr, ToSmolStr, ast}; @@ -426,7 +426,7 @@ pub(crate) fn add_qualified_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx<'_>, - variant: hir::Variant, + variant: hir::EnumVariant, path: hir::ModPath, ) { if !ctx.check_stability_and_hidden(variant) { @@ -443,7 +443,7 @@ pub(crate) fn add_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx<'_>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<hir::Name>, ) { if !ctx.check_stability_and_hidden(variant) { @@ -569,7 +569,7 @@ pub(crate) fn add_variant_pat( ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx<'_>>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<hir::Name>, ) { if !ctx.check_stability_and_hidden(variant) { @@ -589,7 +589,7 @@ pub(crate) fn add_qualified_variant_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, - variant: hir::Variant, + variant: hir::EnumVariant, path: hir::ModPath, ) { if !ctx.check_stability_and_hidden(variant) { @@ -644,9 +644,9 @@ fn enum_variants_with_paths( ctx: &CompletionContext<'_>, enum_: hir::Enum, impl_: Option<&ast::Impl>, - cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), + cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::EnumVariant, hir::ModPath), ) { - let mut process_variant = |variant: Variant| { + let mut process_variant = |variant: EnumVariant| { let self_path = hir::ModPath::from_segments( hir::PathKind::Plain, iter::once(Name::new_symbol_root(sym::Self_)).chain(iter::once(variant.name(ctx.db))),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs index 96dac66..bd0b692 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs
@@ -30,14 +30,27 @@ pub(crate) fn complete_fn_param( _ => return None, }; + let qualifier = param_qualifier(param); let comma_wrapper = comma_wrapper(ctx); let mut add_new_item_to_acc = |label: &str| { - let mk_item = |label: &str, range: TextRange| { - CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition) + let label = label.strip_prefix(qualifier.as_str()).unwrap_or(label); + let insert = if label.starts_with('#') { + // FIXME: `#[attr] it: i32` -> `#[attr] mut it: i32` + label.to_smolstr() + } else { + format_smolstr!("{qualifier}{label}") + }; + let mk_item = |insert_text: &str, range: TextRange| { + let mut item = + CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition); + if insert_text != label { + item.insert_text(insert_text); + } + item }; let item = match &comma_wrapper { - Some((fmt, range)) => mk_item(&fmt(label), *range), - None => mk_item(label, ctx.source_range()), + Some((fmt, range)) => mk_item(&fmt(&insert), *range), + None => mk_item(&insert, ctx.source_range()), }; // Completion lookup is omitted intentionally here. // See the full discussion: https://github.com/rust-lang/rust-analyzer/issues/12073 @@ -75,9 +88,6 @@ fn fill_fn_params( let mut file_params = FxHashMap::default(); let mut extract_params = |f: ast::Fn| { - if !is_simple_param(current_param) { - return; - } f.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| { if let Some(pat) = param.pat() { let whole_param = param.to_smolstr(); @@ -88,6 +98,9 @@ fn fill_fn_params( }; for node in ctx.token.parent_ancestors() { + if !is_simple_param(current_param) { + break; + } match_ast! { match node { ast::SourceFile(it) => it.items().filter_map(|item| match item { @@ -214,3 +227,16 @@ fn is_simple_param(param: &ast::Param) -> bool { .pat() .is_none_or(|pat| matches!(pat, ast::Pat::IdentPat(ident_pat) if ident_pat.pat().is_none())) } + +fn param_qualifier(param: &ast::Param) -> SmolStr { + let mut b = syntax::SmolStrBuilder::new(); + if let Some(ast::Pat::IdentPat(pat)) = param.pat() { + if pat.ref_token().is_some() { + b.push_str("ref "); + } + if pat.mut_token().is_some() { + b.push_str("mut "); + } + } + b.finish() +}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs index 6e93281..e7597bf 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs
@@ -91,7 +91,7 @@ pub(crate) fn complete_pattern( acc.add_struct_pat(ctx, pattern_ctx, strukt, Some(name.clone())); true } - hir::ModuleDef::Variant(variant) + hir::ModuleDef::EnumVariant(variant) if refutable || single_variant_enum(variant.parent_enum(ctx.db)) => { acc.add_variant_pat(ctx, pattern_ctx, None, variant, Some(name.clone())); @@ -190,7 +190,7 @@ pub(crate) fn complete_pattern_path( let add_completion = match res { ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db), ScopeDef::ModuleDef(hir::ModuleDef::Adt(_)) => true, - ScopeDef::ModuleDef(hir::ModuleDef::Variant(_)) => true, + ScopeDef::ModuleDef(hir::ModuleDef::EnumVariant(_)) => true, ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true, ScopeDef::ImplSelfType(_) => true, _ => false,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index ea53aef..5b91e7c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -16,7 +16,7 @@ use stdx::never; use syntax::{ SmolStr, - SyntaxKind::{EXPR_STMT, STMT_LIST}, + SyntaxKind::{CLOSURE_EXPR, EXPR_STMT, MATCH_ARM, STMT_LIST}, T, TextRange, TextSize, ToSmolStr, ast::{self, AstNode, AstToken}, format_smolstr, match_ast, @@ -66,6 +66,12 @@ pub(crate) fn complete_postfix( Some(it) => it, None => return, }; + let semi = + if expr_ctx.in_block_expr && ctx.token.next_token().is_none_or(|it| it.kind() != T![;]) { + ";" + } else { + "" + }; let cfg = ctx.config.find_path_config(ctx.is_nightly); @@ -151,12 +157,12 @@ pub(crate) fn complete_postfix( .add_to(acc, ctx.db); } _ if matches!(parent.kind(), STMT_LIST | EXPR_STMT) => { - postfix_snippet("let", "let", &format!("let $0 = {receiver_text};")) + postfix_snippet("let", "let", &format!("let $0 = {receiver_text}{semi}")) .add_to(acc, ctx.db); - postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text};")) + postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text}{semi}")) .add_to(acc, ctx.db); } - _ if ast::MatchArm::can_cast(parent.kind()) => { + _ if matches!(parent.kind(), MATCH_ARM | CLOSURE_EXPR) => { postfix_snippet( "let", "let", @@ -307,26 +313,12 @@ pub(crate) fn complete_postfix( add_format_like_completions(acc, ctx, &dot_receiver_including_refs, cap, &literal_text); } - postfix_snippet( - "return", - "return expr", - &format!( - "return {receiver_text}{semi}", - semi = if expr_ctx.in_block_expr { ";" } else { "" } - ), - ) - .add_to(acc, ctx.db); + postfix_snippet("return", "return expr", &format!("return {receiver_text}{semi}")) + .add_to(acc, ctx.db); if let Some(BreakableKind::Block | BreakableKind::Loop) = expr_ctx.in_breakable { - postfix_snippet( - "break", - "break expr", - &format!( - "break {receiver_text}{semi}", - semi = if expr_ctx.in_block_expr { ";" } else { "" } - ), - ) - .add_to(acc, ctx.db); + postfix_snippet("break", "break expr", &format!("break {receiver_text}{semi}")) + .add_to(acc, ctx.db); } } @@ -371,12 +363,20 @@ fn get_receiver_text( range.range = TextRange::at(range.range.start(), range.range.len() - TextSize::of('.')) } let file_text = sema.db.file_text(range.file_id.file_id(sema.db)); - let mut text = file_text.text(sema.db)[range.range].to_owned(); + let text = file_text.text(sema.db); + let indent_spaces = indent_of_tail_line(&text[TextRange::up_to(range.range.start())]); + let mut text = stdx::dedent_by(indent_spaces, &text[range.range]); // The receiver texts should be interpreted as-is, as they are expected to be // normal Rust expressions. escape_snippet_bits(&mut text); - text + return text; + + fn indent_of_tail_line(text: &str) -> usize { + let tail_line = text.rsplit_once('\n').map_or(text, |(_, s)| s); + let trimmed = tail_line.trim_start_matches(' '); + tail_line.len() - trimmed.len() + } } /// Escapes `\` and `$` so that they don't get interpreted as snippet-specific constructs. @@ -402,6 +402,10 @@ fn receiver_accessor(receiver: &ast::Expr) -> ast::Expr { .unwrap_or_else(|| receiver.clone()) } +/// Given an `initial_element`, tries to expand it to include deref(s), and then references. +/// Returns the expanded expressions, and the added prefix as a string +/// +/// For example, if called with the `42` in `&&mut *42`, would return `(&&mut *42, "&&mut *")`. fn include_references(initial_element: &ast::Expr) -> (ast::Expr, String) { let mut resulting_element = initial_element.clone(); let mut prefix = String::new(); @@ -410,11 +414,8 @@ fn include_references(initial_element: &ast::Expr) -> (ast::Expr, String) { while let Some(parent_deref_element) = resulting_element.syntax().parent().and_then(ast::PrefixExpr::cast) + && parent_deref_element.op_kind() == Some(ast::UnaryOp::Deref) { - if parent_deref_element.op_kind() != Some(ast::UnaryOp::Deref) { - break; - } - found_ref_or_deref = true; resulting_element = ast::Expr::from(parent_deref_element); @@ -663,6 +664,22 @@ fn main() { #[test] fn let_middle_block() { + check_edit( + "let", + r#" +fn main() { + baz.l$0 + res +} +"#, + r#" +fn main() { + let $0 = baz; + res +} +"#, + ); + check( r#" fn main() { @@ -719,6 +736,20 @@ fn main() { #[test] fn let_tail_block() { + check_edit( + "let", + r#" +fn main() { + baz.l$0 +} +"#, + r#" +fn main() { + let $0 = baz; +} +"#, + ); + check( r#" fn main() { @@ -773,6 +804,23 @@ fn main() { } #[test] + fn let_before_semicolon() { + check_edit( + "let", + r#" +fn main() { + baz.l$0; +} +"#, + r#" +fn main() { + let $0 = baz; +} +"#, + ); + } + + #[test] fn option_iflet() { check_edit( "ifl", @@ -966,6 +1014,28 @@ fn main() { } #[test] + fn closure_let_block() { + check_edit( + "let", + r#" +fn main() { + let bar = 2; + let f = || bar.$0; +} +"#, + r#" +fn main() { + let bar = 2; + let f = || { + let $1 = bar; + $0 +}; +} +"#, + ); + } + + #[test] fn option_letelse() { check_edit( "lete", @@ -1040,6 +1110,7 @@ fn main() { #[test] fn postfix_completion_for_references() { check_edit("dbg", r#"fn main() { &&42.$0 }"#, r#"fn main() { dbg!(&&42) }"#); + check_edit("dbg", r#"fn main() { &&*"hello".$0 }"#, r#"fn main() { dbg!(&&*"hello") }"#); check_edit("refm", r#"fn main() { &&42.$0 }"#, r#"fn main() { &&&mut 42 }"#); check_edit( "ifl", @@ -1198,9 +1269,9 @@ fn main() { fn main() { ControlFlow::Break(match true { - true => "\${1:placeholder}", - false => "\\\$", - }) + true => "\${1:placeholder}", + false => "\\\$", +}) } "#, ); @@ -1440,4 +1511,31 @@ fn foo() { "#, ); } + + #[test] + fn snippet_dedent() { + check_edit( + "let", + r#" +//- minicore: option +fn foo(x: Option<i32>, y: Option<i32>) { + let _f = || { + x + .and(y) + .map(|it| it+2) + .$0 + }; +} +"#, + r#" +fn foo(x: Option<i32>, y: Option<i32>) { + let _f = || { + let $0 = x + .and(y) + .map(|it| it+2); + }; +} +"#, + ); + } }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs index abcf9fc..8ff9c32 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
@@ -23,7 +23,9 @@ pub(crate) fn complete_type_path( ScopeDef::GenericParam(LifetimeParam(_)) => location.complete_lifetimes(), ScopeDef::Label(_) => false, // no values in type places - ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false, + ScopeDef::ModuleDef(Function(_) | EnumVariant(_) | Static(_)) | ScopeDef::Local(_) => { + false + } // unless its a constant in a generic arg list position ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => { location.complete_consts()
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 97afd07..4fd0348 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -288,7 +288,7 @@ pub(crate) struct PatternContext { pub(crate) record_pat: Option<ast::RecordPat>, pub(crate) impl_or_trait: Option<Either<ast::Impl, ast::Trait>>, /// List of missing variants in a match expr - pub(crate) missing_variants: Vec<hir::Variant>, + pub(crate) missing_variants: Vec<hir::EnumVariant>, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -527,7 +527,7 @@ pub(crate) fn def_is_visible(&self, item: &ScopeDef) -> Visible { hir::ModuleDef::Module(it) => self.is_visible(it), hir::ModuleDef::Function(it) => self.is_visible(it), hir::ModuleDef::Adt(it) => self.is_visible(it), - hir::ModuleDef::Variant(it) => self.is_visible(it), + hir::ModuleDef::EnumVariant(it) => self.is_visible(it), hir::ModuleDef::Const(it) => self.is_visible(it), hir::ModuleDef::Static(it) => self.is_visible(it), hir::ModuleDef::Trait(it) => self.is_visible(it),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 4b0cc0c..a3494b9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{ExpandResult, InFile, Semantics, Type, TypeInfo, Variant}; +use hir::{EnumVariant, ExpandResult, InFile, Semantics, Type, TypeInfo}; use ide_db::{ RootDatabase, active_parameter::ActiveParameter, syntax_helpers::node_ext::find_loops, }; @@ -778,6 +778,16 @@ fn expected_type_and_name<'db>( let ty = sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::original); (ty, None) }, + ast::TupleStructPat(it) => { + let fields = it.path().and_then(|path| match sema.resolve_path(&path)? { + hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) => Some(adt.as_struct()?.fields(sema.db)), + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(variant)) => Some(variant.fields(sema.db)), + _ => None, + }); + let nr = it.fields().take_while(|it| it.syntax().text_range().end() <= token.text_range().start()).count(); + let ty = fields.and_then(|fields| Some(fields.get(nr)?.ty(sema.db).to_type(sema.db))); + (ty, None) + }, ast::Fn(it) => { cov_mark::hit!(expected_type_fn_ret_with_leading_char); cov_mark::hit!(expected_type_fn_ret_without_leading_char); @@ -944,10 +954,10 @@ fn classify_name_ref<'db>( let field_expr_handle = |receiver, node| { let receiver = find_opt_node_in_file(original_file, receiver); let receiver_is_ambiguous_float_literal = match &receiver { - Some(ast::Expr::Literal(l)) => matches! { - l.kind(), - ast::LiteralKind::FloatNumber { .. } if l.syntax().last_token().is_some_and(|it| it.text().ends_with('.')) - }, + Some(ast::Expr::Literal(l)) => { + matches!(l.kind(), ast::LiteralKind::FloatNumber { .. }) + && l.syntax().last_token().is_some_and(|it| it.text().ends_with('.')) + } _ => false, }; @@ -1139,7 +1149,7 @@ fn classify_name_ref<'db>( hir::ModuleDef::Adt(adt) => { sema.source(adt)?.value.generic_param_list() } - hir::ModuleDef::Variant(variant) => { + hir::ModuleDef::EnumVariant(variant) => { sema.source(variant.parent_enum(sema.db))?.value.generic_param_list() } hir::ModuleDef::Trait(trait_) => { @@ -1815,7 +1825,7 @@ fn pattern_context_for( }); (!variant_already_present).then_some(*variant) - }).collect::<Vec<Variant>>()) + }).collect::<Vec<EnumVariant>>()) }); if let Some(missing_variants_) = missing_variants_opt {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index e97d972..94d9049 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs
@@ -288,6 +288,50 @@ fn foo() -> Foo { } #[test] +fn expected_type_tuple_struct_pat() { + check_expected_type_and_name( + r#" +//- minicore: option +struct Foo(Option<i32>); +fn foo(x: Foo) -> Foo { + match x { Foo($0) => () } +} +"#, + expect![[r#"ty: Option<i32>, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo($0) => () } +} +"#, + expect![[r#"ty: i32, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo(num,$0) => () } +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo(num,$0,float) => () } +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); +} + +#[test] fn expected_type_if_let_without_leading_char() { cov_mark::check!(expected_type_if_let_without_leading_char); check_expected_type_and_name(
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 765304d..d77e793 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -408,7 +408,7 @@ fn render_resolution_path( let ctx = ctx.import_to_add(import_to_add); return render_fn(ctx, path_ctx, Some(local_name), func); } - ScopeDef::ModuleDef(Variant(var)) => { + ScopeDef::ModuleDef(EnumVariant(var)) => { let ctx = ctx.clone().import_to_add(import_to_add.clone()); if let Some(item) = render_variant_lit(ctx, path_ctx, Some(local_name.clone()), var, None) @@ -476,7 +476,7 @@ fn render_resolution_path( } // Filtered out above ScopeDef::ModuleDef( - ModuleDef::Function(_) | ModuleDef::Variant(_) | ModuleDef::Macro(_), + ModuleDef::Function(_) | ModuleDef::EnumVariant(_) | ModuleDef::Macro(_), ) => (), ScopeDef::ModuleDef(ModuleDef::Const(konst)) => set_item_relevance(konst.ty(db)), ScopeDef::ModuleDef(ModuleDef::Static(stat)) => set_item_relevance(stat.ty(db)), @@ -528,7 +528,7 @@ fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind { match resolution { ScopeDef::Unknown => CompletionItemKind::UnresolvedReference, ScopeDef::ModuleDef(Function(_)) => CompletionItemKind::SymbolKind(SymbolKind::Function), - ScopeDef::ModuleDef(Variant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant), + ScopeDef::ModuleDef(EnumVariant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant), ScopeDef::ModuleDef(Macro(_)) => CompletionItemKind::SymbolKind(SymbolKind::Macro), ScopeDef::ModuleDef(Module(..)) => CompletionItemKind::SymbolKind(SymbolKind::Module), ScopeDef::ModuleDef(Adt(adt)) => CompletionItemKind::SymbolKind(match adt { @@ -559,7 +559,7 @@ fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentati match resolution { ScopeDef::ModuleDef(Module(it)) => it.docs(db), ScopeDef::ModuleDef(Adt(it)) => it.docs(db), - ScopeDef::ModuleDef(Variant(it)) => it.docs(db), + ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(db), ScopeDef::ModuleDef(Const(it)) => it.docs(db), ScopeDef::ModuleDef(Static(it)) => it.docs(db), ScopeDef::ModuleDef(Trait(it)) => it.docs(db),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index 475e00d..dfa3084 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
@@ -678,7 +678,7 @@ fn main() { fn complete_fn_param() { // has mut kw check_edit( - "mut bar: u32", + "bar: u32", r#" fn f(foo: (), mut bar: u32) {} fn g(foo: (), mut ba$0) @@ -689,10 +689,35 @@ fn g(foo: (), mut bar: u32) "#, ); - // has type param + // has unmatched mut kw + check_edit( + "bar: u32", + r#" +fn f(foo: (), bar: u32) {} +fn g(foo: (), mut ba$0) +"#, + r#" +fn f(foo: (), bar: u32) {} +fn g(foo: (), mut bar: u32) +"#, + ); + check_edit( "mut bar: u32", r#" +fn f(foo: (), mut bar: u32) {} +fn g(foo: (), ba$0) +"#, + r#" +fn f(foo: (), mut bar: u32) {} +fn g(foo: (), mut bar: u32) +"#, + ); + + // has type param + check_edit( + "bar: u32", + r#" fn g(foo: (), mut ba$0: u32) fn f(foo: (), mut bar: u32) {} "#, @@ -707,7 +732,7 @@ fn f(foo: (), mut bar: u32) {} fn complete_fn_mut_param_add_comma() { // add leading and trailing comma check_edit( - ", mut bar: u32,", + "bar: u32", r#" fn f(foo: (), mut bar: u32) {} fn g(foo: ()mut ba$0 baz: ()) @@ -746,7 +771,7 @@ fn g(foo: (), #[baz = "qux"] mut bar: u32) ); check_edit( - r#", #[baz = "qux"] mut bar: u32"#, + r#"#[baz = "qux"] mut bar: u32"#, r#" fn f(foo: (), #[baz = "qux"] mut bar: u32) {} fn g(foo: ()#[baz = "qux"] mut ba$0)
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs index 8b14f05..6e49af9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
@@ -23,7 +23,7 @@ pub(crate) fn render_variant_lit( ctx: RenderContext<'_>, path_ctx: &PathCompletionCtx<'_>, local_name: Option<hir::Name>, - variant: hir::Variant, + variant: hir::EnumVariant, path: Option<hir::ModPath>, ) -> Option<Builder> { let _p = tracing::info_span!("render_variant_lit").entered(); @@ -150,7 +150,7 @@ fn render( #[derive(Clone, Copy)] enum Variant { Struct(hir::Struct), - EnumVariant(hir::Variant), + EnumVariant(hir::EnumVariant), } impl Variant {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs index 60474a3..fb35d7b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
@@ -47,7 +47,7 @@ pub(crate) fn render_variant_pat( ctx: RenderContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx<'_>>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<Name>, path: Option<&hir::ModPath>, ) -> Option<CompletionItem> {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs index d6d73da..aaa2256 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs
@@ -43,7 +43,7 @@ fn bar(file_id: usize) {} fn baz(file$0 id: u32) {} "#, expect![[r#" - bn file_id: usize, + bn file_id: usize kw mut kw ref "#]],
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs index f5a5b76..8bd4c6c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs
@@ -113,7 +113,7 @@ pub fn generic_def_for_node( sema: &Semantics<'_, RootDatabase>, generic_arg_list: &ast::GenericArgList, token: &SyntaxToken, -) -> Option<(hir::GenericDef, usize, bool, Option<hir::Variant>)> { +) -> Option<(hir::GenericDef, usize, bool, Option<hir::EnumVariant>)> { let parent = generic_arg_list.syntax().parent()?; let mut variant = None; let def = match_ast! { @@ -125,7 +125,7 @@ pub fn generic_def_for_node( hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(), hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(), hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(), - hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => { + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(it)) => { variant = Some(it); it.parent_enum(sema.db).into() },
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index 788f9b7..82cff37 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -14,11 +14,12 @@ use either::Either; use hir::{ Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType, - Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExternAssocItem, - ExternCrateDecl, Field, Function, GenericDef, GenericParam, GenericSubstitution, HasContainer, - HasVisibility, HirDisplay, Impl, InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, - ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, - TupleField, TypeAlias, Variant, VariantDef, Visibility, + Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, EnumVariant, + ExpressionStoreOwner, ExternAssocItem, ExternCrateDecl, Field, Function, GenericDef, + GenericParam, GenericSubstitution, HasContainer, HasVisibility, HirDisplay, Impl, + InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, ModuleDef, Name, PathResolution, + Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, TupleField, TypeAlias, Variant, + Visibility, }; use span::Edition; use stdx::{format_to, impl_from}; @@ -38,7 +39,7 @@ pub enum Definition { Crate(Crate), Function(Function), Adt(Adt), - Variant(Variant), + EnumVariant(EnumVariant), Const(Const), Static(Static), Trait(Trait), @@ -85,7 +86,7 @@ pub fn module(&self, db: &RootDatabase) -> Option<Module> { Definition::Static(it) => it.module(db), Definition::Trait(it) => it.module(db), Definition::TypeAlias(it) => it.module(db), - Definition::Variant(it) => it.module(db), + Definition::EnumVariant(it) => it.module(db), Definition::SelfType(it) => it.module(db), Definition::Local(it) => it.module(db), Definition::GenericParam(it) => it.module(db), @@ -123,7 +124,7 @@ fn container_to_definition(container: ItemContainer) -> Option<Definition> { Definition::Static(it) => container_to_definition(it.container(db)), Definition::Trait(it) => container_to_definition(it.container(db)), Definition::TypeAlias(it) => container_to_definition(it.container(db)), - Definition::Variant(it) => Some(Adt::Enum(it.parent_enum(db)).into()), + Definition::EnumVariant(it) => Some(Adt::Enum(it.parent_enum(db)).into()), Definition::SelfType(it) => Some(it.module(db).into()), Definition::Local(it) => it.parent(db).try_into().ok(), Definition::GenericParam(it) => Some(it.parent().into()), @@ -151,7 +152,7 @@ pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> { Definition::Static(it) => it.visibility(db), Definition::Trait(it) => it.visibility(db), Definition::TypeAlias(it) => it.visibility(db), - Definition::Variant(it) => it.visibility(db), + Definition::EnumVariant(it) => it.visibility(db), Definition::ExternCrateDecl(it) => it.visibility(db), Definition::Macro(it) => it.visibility(db), Definition::BuiltinType(_) | Definition::TupleField(_) => Visibility::Public, @@ -179,7 +180,7 @@ pub fn name(&self, db: &RootDatabase) -> Option<Name> { } Definition::Function(it) => it.name(db), Definition::Adt(it) => it.name(db), - Definition::Variant(it) => it.name(db), + Definition::EnumVariant(it) => it.name(db), Definition::Const(it) => it.name(db)?, Definition::Static(it) => it.name(db), Definition::Trait(it) => it.name(db), @@ -227,7 +228,7 @@ pub fn docs_with_rangemap<'db>( Definition::Crate(it) => it.docs_with_rangemap(db), Definition::Function(it) => it.docs_with_rangemap(db), Definition::Adt(it) => it.docs_with_rangemap(db), - Definition::Variant(it) => it.docs_with_rangemap(db), + Definition::EnumVariant(it) => it.docs_with_rangemap(db), Definition::Const(it) => it.docs_with_rangemap(db), Definition::Static(it) => it.docs_with_rangemap(db), Definition::Trait(it) => it.docs_with_rangemap(db), @@ -315,7 +316,7 @@ pub fn label(&self, db: &RootDatabase, display_target: DisplayTarget) -> String Definition::Crate(it) => it.display(db, display_target).to_string(), Definition::Function(it) => it.display(db, display_target).to_string(), Definition::Adt(it) => it.display(db, display_target).to_string(), - Definition::Variant(it) => it.display(db, display_target).to_string(), + Definition::EnumVariant(it) => it.display(db, display_target).to_string(), Definition::Const(it) => it.display(db, display_target).to_string(), Definition::Static(it) => it.display(db, display_target).to_string(), Definition::Trait(it) => it.display(db, display_target).to_string(), @@ -556,7 +557,7 @@ pub fn classify( ast::Rename(it) => classify_rename(sema, it)?, ast::SelfParam(it) => Definition::Local(sema.to_def(&it)?), ast::RecordField(it) => Definition::Field(sema.to_def(&it)?), - ast::Variant(it) => Definition::Variant(sema.to_def(&it)?), + ast::Variant(it) => Definition::EnumVariant(sema.to_def(&it)?), ast::TypeParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()), ast::ConstParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()), ast::AsmOperandNamed(it) => Definition::InlineAsmOperand(sema.to_def(&it)?), @@ -848,7 +849,7 @@ pub fn classify( ast::OffsetOfExpr(_) => { let (def, subst) = sema.resolve_offset_of_field(name_ref)?; let def = match def { - Either::Left(variant) => Definition::Variant(variant), + Either::Left(variant) => Definition::EnumVariant(variant), Either::Right(field) => Definition::Field(field), }; Some(NameRefClass::Definition(def, Some(subst))) @@ -891,7 +892,7 @@ pub fn classify_lifetime( } impl_from!( - Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local, + Field, Module, Function, Adt, EnumVariant, Const, Static, Trait, TypeAlias, BuiltinType, Local, GenericParam, Label, Macro, ExternCrateDecl for Definition ); @@ -967,7 +968,7 @@ fn from(def: ModuleDef) -> Self { ModuleDef::Module(it) => Definition::Module(it), ModuleDef::Function(it) => Definition::Function(it), ModuleDef::Adt(it) => Definition::Adt(it), - ModuleDef::Variant(it) => Definition::Variant(it), + ModuleDef::EnumVariant(it) => Definition::EnumVariant(it), ModuleDef::Const(it) => Definition::Const(it), ModuleDef::Static(it) => Definition::Static(it), ModuleDef::Trait(it) => Definition::Trait(it), @@ -988,8 +989,8 @@ fn from(def: DocLinkDef) -> Self { } } -impl From<VariantDef> for Definition { - fn from(def: VariantDef) -> Self { +impl From<Variant> for Definition { + fn from(def: Variant) -> Self { ModuleDef::from(def).into() } } @@ -1001,7 +1002,7 @@ fn try_from(def: DefWithBody) -> Result<Self, Self::Error> { DefWithBody::Function(it) => Ok(it.into()), DefWithBody::Static(it) => Ok(it.into()), DefWithBody::Const(it) => Ok(it.into()), - DefWithBody::Variant(it) => Ok(it.into()), + DefWithBody::EnumVariant(it) => Ok(it.into()), } } } @@ -1020,6 +1021,17 @@ fn from(def: GenericDef) -> Self { } } +impl TryFrom<ExpressionStoreOwner> for Definition { + type Error = (); + fn try_from(def: ExpressionStoreOwner) -> Result<Self, Self::Error> { + match def { + ExpressionStoreOwner::Body(def_with_body) => def_with_body.try_into(), + ExpressionStoreOwner::Signature(generic_def) => Ok(generic_def.into()), + ExpressionStoreOwner::VariantFields(it) => Ok(it.into()), + } + } +} + impl TryFrom<Definition> for GenericDef { type Error = (); fn try_from(def: Definition) -> Result<Self, Self::Error> {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs index 4c4691c..407049f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs
@@ -58,8 +58,22 @@ impl HasDocs for hir::$def {} } impl_has_docs![ - Variant, Field, Static, Const, Trait, TypeAlias, Macro, Function, Adt, Module, Impl, Crate, - AssocItem, Struct, Union, Enum, + EnumVariant, + Field, + Static, + Const, + Trait, + TypeAlias, + Macro, + Function, + Adt, + Module, + Impl, + Crate, + AssocItem, + Struct, + Union, + Enum, ]; impl HasDocs for hir::ExternCrateDecl {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index dedc12a..9e6d586 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
@@ -11576,9 +11576,9 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable. label: "try_blocks", description: r##"# `try_blocks` -The tracking issue for this feature is: [#31436] +The tracking issue for this feature is: [#154391] -[#31436]: https://github.com/rust-lang/rust/issues/31436 +[#154391]: https://github.com/rust-lang/rust/issues/154391 ------------------------ @@ -11590,14 +11590,14 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable. use std::num::ParseIntError; -let result: Result<i32, ParseIntError> = try { +let result = try { "1".parse::<i32>()? + "2".parse::<i32>()? + "3".parse::<i32>()? }; assert_eq!(result, Ok(6)); -let result: Result<i32, ParseIntError> = try { +let result = try { "1".parse::<i32>()? + "foo".parse::<i32>()? + "3".parse::<i32>()?
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 023b32b..cde0705 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -312,7 +312,7 @@ impl SymbolKind { pub fn from_module_def(db: &dyn HirDatabase, it: hir::ModuleDef) -> Self { match it { hir::ModuleDef::Const(..) => SymbolKind::Const, - hir::ModuleDef::Variant(..) => SymbolKind::Variant, + hir::ModuleDef::EnumVariant(..) => SymbolKind::Variant, hir::ModuleDef::Function(..) => SymbolKind::Function, hir::ModuleDef::Macro(mac) if mac.is_proc_macro() => SymbolKind::ProcMacro, hir::ModuleDef::Macro(..) => SymbolKind::Macro,
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 01a326a..508f841 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -580,7 +580,7 @@ fn transform_ident_pat( } } - if let hir::ModuleDef::Variant(v) = def + if let hir::ModuleDef::EnumVariant(v) = def && v.kind(self.source_scope.db) != hir::StructKind::Unit { return None;
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 015b06e..d264428 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
@@ -4,7 +4,7 @@ //! various caches, it's not really advanced at the moment. use std::panic::AssertUnwindSafe; -use hir::{Symbol, db::DefDatabase}; +use hir::{Symbol, import_map::ImportMap}; use rustc_hash::FxHashMap; use salsa::{Cancelled, Database}; @@ -123,7 +123,7 @@ enum ParallelPrimeCacheWorkerProgress { Ok::<_, crossbeam_channel::SendError<_>>(()) }; let handle_import_map = |crate_id| { - let cancelled = Cancelled::catch(|| _ = db.import_map(crate_id)); + let cancelled = Cancelled::catch(|| _ = ImportMap::of(&db, crate_id)); match cancelled { Ok(()) => {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index b03a5b6..b18ed69 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
@@ -170,7 +170,7 @@ pub fn range_for_rename(self, sema: &Semantics<'_, RootDatabase>) -> Option<File hir::Adt::Union(it) => name_range(it, sema).and_then(syn_ctx_is_root), hir::Adt::Enum(it) => name_range(it, sema).and_then(syn_ctx_is_root), }, - Definition::Variant(it) => name_range(it, sema).and_then(syn_ctx_is_root), + Definition::EnumVariant(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Const(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Static(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Trait(it) => name_range(it, sema).and_then(syn_ctx_is_root),
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 3822eaa..25acb47 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -10,9 +10,9 @@ use base_db::{RootQueryDb, SourceDatabase}; use either::Either; use hir::{ - Adt, AsAssocItem, DefWithBody, EditionedFileId, FileRange, FileRangeWrapper, HasAttrs, - HasContainer, HasSource, InFile, InFileWrapper, InRealFile, InlineAsmOperand, ItemContainer, - ModuleSource, PathResolution, Semantics, Visibility, + Adt, AsAssocItem, DefWithBody, EditionedFileId, ExpressionStoreOwner, FileRange, + FileRangeWrapper, HasAttrs, HasContainer, HasSource, InFile, InFileWrapper, InRealFile, + InlineAsmOperand, ItemContainer, ModuleSource, PathResolution, Semantics, Visibility, }; use memchr::memmem::Finder; use parser::SyntaxKind; @@ -310,10 +310,26 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope { if let Definition::Local(var) = self { let def = match var.parent(db) { - DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + ExpressionStoreOwner::Body(def) => match def { + DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), + DefWithBody::EnumVariant(v) => v.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::Signature(def) => match def { + hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Adt(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Trait(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::TypeAlias(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } + hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::VariantFields(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } }; return match def { Some(def) => SearchScope::file_range( @@ -325,10 +341,26 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope { if let Definition::InlineAsmOperand(op) = self { let def = match op.parent(db) { - DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + ExpressionStoreOwner::Body(def) => match def { + DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), + DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), + DefWithBody::EnumVariant(v) => v.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::Signature(def) => match def { + hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Adt(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Trait(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::TypeAlias(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } + hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), + hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), + }, + ExpressionStoreOwner::VariantFields(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } }; return match def { Some(def) => SearchScope::file_range(
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 46d938b..02a0230 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -8,8 +8,8 @@ [ FileSymbol { name: "A", - def: Variant( - Variant { + def: EnumVariant( + EnumVariant { id: EnumVariantId( 7c00, ), @@ -80,8 +80,8 @@ }, FileSymbol { name: "B", - def: Variant( - Variant { + def: EnumVariant( + EnumVariant { id: EnumVariantId( 7c01, ),
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index d5f25df..050d547 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
@@ -588,14 +588,14 @@ fn test_fn() { fn test_fill_struct_fields_default() { check_fix( r#" -//- minicore: default, option +//- minicore: default, option, slice struct TestWithDefault(usize); impl Default for TestWithDefault { pub fn default() -> Self { Self(0) } } -struct TestStruct { one: i32, two: TestWithDefault } +struct TestStruct { one: i32, two: TestWithDefault, r: &'static [i32] } fn test_fn() { let s = TestStruct{ $0 }; @@ -608,10 +608,10 @@ pub fn default() -> Self { Self(0) } } -struct TestStruct { one: i32, two: TestWithDefault } +struct TestStruct { one: i32, two: TestWithDefault, r: &'static [i32] } fn test_fn() { - let s = TestStruct{ one: 0, two: TestWithDefault::default() }; + let s = TestStruct{ one: 0, two: TestWithDefault::default(), r: <&'static [i32]>::default() }; } ", );
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs index 5cb710b..b10cdaa 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs
@@ -115,4 +115,20 @@ struct A<'a, T> { "#, ); } + + // FIXME: Ideally, should emit generic default forbidden as well + #[test] + fn regression_16280() { + check_diagnostics( + r#" +trait Traitor<'a, const M: Traitor = Traitor> { + fn crash<const Traitor: Traitor = Traitor, const M: Traitor = Traitor>(&self) -> Traitor { + // ^^^^^^^ error: missing lifetime specifier + // ^^^^^^^ error: missing lifetime specifier + Traitor + } +} +"#, + ); + } }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs index bcfe3a8..944622b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -64,20 +64,20 @@ fn missing_record_expr_field_fixes( let module; let def_file_id; let record_fields = match def_id { - hir::VariantDef::Struct(s) => { + hir::Variant::Struct(s) => { module = s.module(sema.db); let source = s.source(sema.db)?; def_file_id = source.file_id; let fields = source.value.field_list()?; record_field_list(fields)? } - hir::VariantDef::Union(u) => { + hir::Variant::Union(u) => { module = u.module(sema.db); let source = u.source(sema.db)?; def_file_id = source.file_id; source.value.record_field_list()? } - hir::VariantDef::Variant(e) => { + hir::Variant::EnumVariant(e) => { module = e.module(sema.db); let source = e.source(sema.db)?; def_file_id = source.file_id; @@ -97,25 +97,37 @@ fn missing_record_expr_field_fixes( make::ty(&new_field_type.display_source_code(sema.db, module.into(), true).ok()?), ); - let last_field = record_fields.fields().last()?; - let last_field_syntax = last_field.syntax(); - let indent = IndentLevel::from_node(last_field_syntax); + let (indent, offset, postfix, needs_comma) = + if let Some(last_field) = record_fields.fields().last() { + let indent = IndentLevel::from_node(last_field.syntax()); + let offset = last_field.syntax().text_range().end(); + let needs_comma = !last_field.to_string().ends_with(','); + (indent, offset, String::new(), needs_comma) + } else { + let indent = IndentLevel::from_node(record_fields.syntax()); + let offset = record_fields.l_curly_token()?.text_range().end(); + let postfix = if record_fields.syntax().text().contains_char('\n') { + ",".into() + } else { + format!(",\n{indent}") + }; + (indent + 1, offset, postfix, false) + }; let mut new_field = new_field.to_string(); // FIXME: check submodule instead of FileId - if usage_file_id != def_file_id && !matches!(def_id, hir::VariantDef::Variant(_)) { + if usage_file_id != def_file_id && !matches!(def_id, hir::Variant::EnumVariant(_)) { new_field = format!("pub(crate) {new_field}"); } - new_field = format!("\n{indent}{new_field}"); + new_field = format!("\n{indent}{new_field}{postfix}"); - let needs_comma = !last_field_syntax.to_string().ends_with(','); if needs_comma { new_field = format!(",{new_field}"); } let source_change = SourceChange::from_text_edit( def_file_id.file_id(sema.db), - TextEdit::insert(last_field_syntax.text_range().end(), new_field), + TextEdit::insert(offset, new_field), ); return Some(vec![fix( @@ -335,6 +347,44 @@ struct Foo { } #[test] + fn test_add_field_from_usage_with_empty_struct() { + check_fix( + r" +fn main() { + Foo { bar$0: false }; +} +struct Foo {} +", + r" +fn main() { + Foo { bar: false }; +} +struct Foo { + bar: bool, +} +", + ); + + check_fix( + r" +fn main() { + Foo { bar$0: false }; +} +struct Foo { +} +", + r" +fn main() { + Foo { bar: false }; +} +struct Foo { + bar: bool, +} +", + ); + } + + #[test] fn test_add_field_in_other_file_from_usage() { check_fix( r#"
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs index c86ecd2..bc10e82 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs
@@ -1,4 +1,11 @@ -use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; +use either::Either; +use hir::Semantics; +use ide_db::text_edit::TextEdit; +use ide_db::ty_filter::TryEnum; +use ide_db::{RootDatabase, source_change::SourceChange}; +use syntax::{AstNode, ast}; + +use crate::{Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // Diagnostic: non-exhaustive-let // @@ -15,11 +22,74 @@ pub(crate) fn non_exhaustive_let( d.pat.map(Into::into), ) .stable() + .with_fixes(fixes(&ctx.sema, d)) +} + +fn fixes(sema: &Semantics<'_, RootDatabase>, d: &hir::NonExhaustiveLet) -> Option<Vec<Assist>> { + let root = sema.parse_or_expand(d.pat.file_id); + let pat = d.pat.value.to_node(&root); + let let_stmt = ast::LetStmt::cast(pat.syntax().parent()?)?; + let early_node = + sema.ancestors_with_macros(let_stmt.syntax().clone()).find_map(AstNode::cast)?; + let early_text = early_text(sema, &early_node); + + if let_stmt.let_else().is_some() { + return None; + } + let hir::FileRangeWrapper { file_id, range } = sema.original_range_opt(let_stmt.syntax())?; + let insert_offset = if let Some(semicolon) = let_stmt.semicolon_token() + && let Some(token) = sema.parse(file_id).syntax().token_at_offset(range.end()).left_biased() + && token.kind() == semicolon.kind() + { + token.text_range().start() + } else { + range.end() + }; + let semicolon = if let_stmt.semicolon_token().is_none() { ";" } else { "" }; + let else_block = format!(" else {{ {early_text} }}{semicolon}"); + let file_id = file_id.file_id(sema.db); + + let source_change = + SourceChange::from_text_edit(file_id, TextEdit::insert(insert_offset, else_block)); + let target = sema.original_range(let_stmt.syntax()).range; + Some(vec![fix("add_let_else_block", "Add let-else block", source_change, target)]) +} + +fn early_text( + sema: &Semantics<'_, RootDatabase>, + early_node: &Either<ast::AnyHasLoopBody, Either<ast::Fn, ast::ClosureExpr>>, +) -> &'static str { + match early_node { + Either::Left(_any_loop) => "continue", + Either::Right(Either::Left(fn_)) => sema + .to_def(fn_) + .map(|fn_def| fn_def.ret_type(sema.db)) + .map(|ty| return_text(&ty, sema)) + .unwrap_or("return"), + Either::Right(Either::Right(closure)) => closure + .body() + .and_then(|expr| sema.type_of_expr(&expr)) + .map(|ty| return_text(&ty.adjusted(), sema)) + .unwrap_or("return"), + } +} + +fn return_text(ty: &hir::Type<'_>, sema: &Semantics<'_, RootDatabase>) -> &'static str { + if ty.is_unit() { + "return" + } else if let Some(try_enum) = TryEnum::from_ty(sema, ty) { + match try_enum { + TryEnum::Option => "return None", + TryEnum::Result => "return Err($0)", + } + } else { + "return $0" + } } #[cfg(test)] mod tests { - use crate::tests::check_diagnostics; + use crate::tests::{check_diagnostics, check_fix}; #[test] fn option_nonexhaustive() { @@ -28,7 +98,7 @@ fn option_nonexhaustive() { //- minicore: option fn main() { let None = Some(5); - //^^^^ error: non-exhaustive pattern: `Some(_)` not covered + //^^^^ 💡 error: non-exhaustive pattern: `Some(_)` not covered } "#, ); @@ -54,7 +124,7 @@ fn option_nonexhaustive_inside_blocks() { fn main() { '_a: { let None = Some(5); - //^^^^ error: non-exhaustive pattern: `Some(_)` not covered + //^^^^ 💡 error: non-exhaustive pattern: `Some(_)` not covered } } "#, @@ -66,7 +136,7 @@ fn main() { fn main() { let _ = async { let None = Some(5); - //^^^^ error: non-exhaustive pattern: `Some(_)` not covered + //^^^^ 💡 error: non-exhaustive pattern: `Some(_)` not covered }; } "#, @@ -78,7 +148,7 @@ fn main() { fn main() { unsafe { let None = Some(5); - //^^^^ error: non-exhaustive pattern: `Some(_)` not covered + //^^^^ 💡 error: non-exhaustive pattern: `Some(_)` not covered } } "#, @@ -101,7 +171,7 @@ fn test(x: Result<i32, !>) { //- minicore: result fn test(x: Result<i32, &'static !>) { let Ok(_y) = x; - //^^^^^^ error: non-exhaustive pattern: `Err(_)` not covered + //^^^^^^ 💡 error: non-exhaustive pattern: `Err(_)` not covered } "#, ); @@ -133,6 +203,136 @@ fn foo(v: Enum<()>) { } #[test] + fn fix_return_in_loop() { + check_fix( + r#" +//- minicore: option +fn foo() { + while cond { + let None$0 = Some(5); + } +} +"#, + r#" +fn foo() { + while cond { + let None = Some(5) else { continue }; + } +} +"#, + ); + } + + #[test] + fn fix_return_in_fn() { + check_fix( + r#" +//- minicore: option +fn foo() { + let None$0 = Some(5); +} +"#, + r#" +fn foo() { + let None = Some(5) else { return }; +} +"#, + ); + } + + #[test] + fn fix_return_in_macro_expanded() { + check_fix( + r#" +//- minicore: option +macro_rules! identity { ($($t:tt)*) => { $($t)* }; } +fn foo() { + identity! { + let None$0 = Some(5); + } +} +"#, + r#" +macro_rules! identity { ($($t:tt)*) => { $($t)* }; } +fn foo() { + identity! { + let None = Some(5) else { return }; + } +} +"#, + ); + } + + #[test] + fn fix_return_in_incomplete_let() { + check_fix( + r#" +//- minicore: option +fn foo() { + let None$0 = Some(5) +} +"#, + r#" +fn foo() { + let None = Some(5) else { return }; +} +"#, + ); + } + + #[test] + fn fix_return_in_closure() { + check_fix( + r#" +//- minicore: option +fn foo() -> Option<()> { + let _f = || { + let None$0 = Some(5); + }; +} +"#, + r#" +fn foo() -> Option<()> { + let _f = || { + let None = Some(5) else { return }; + }; +} +"#, + ); + } + + #[test] + fn fix_return_try_in_fn() { + check_fix( + r#" +//- minicore: option +fn foo() -> Option<()> { + let None$0 = Some(5); +} +"#, + r#" +fn foo() -> Option<()> { + let None = Some(5) else { return None }; +} +"#, + ); + + check_fix( + r#" +//- minicore: option, result +fn foo() -> Result<(), i32> { + let None$0 = Some(5); +} +"#, + r#" +fn foo() -> Result<(), i32> { + let None = Some(5) else { return Err($0) }; +} +"#, + ); + } + + #[test] fn regression_20259() { check_diagnostics( r#"
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs index 7dc5b5b..04f48ae 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs
@@ -48,7 +48,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &RemoveUnnecessaryElse) -> Option<Vec< let mut indent = IndentLevel::from_node(if_expr.syntax()); let has_parent_if_expr = if_expr.syntax().parent().and_then(ast::IfExpr::cast).is_some(); if has_parent_if_expr { - indent = indent + 1; + indent += 1; } let else_replacement = match if_expr.else_branch()? { ast::ElseBranch::Block(block) => block
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index cb3aac3..f405461 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs
@@ -6,6 +6,7 @@ source_change::SourceChangeBuilder, }; use syntax::ToSmolStr; +use syntax::ast::edit::AstNodeEdit; use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; @@ -23,6 +24,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( let default_range = d.impl_.syntax_node_ptr().text_range(); let trait_name = d.trait_.name(db).display_no_db(ctx.edition).to_smolstr(); + let indent_level = d.trait_.source(db).map_or(0, |it| it.value.indent_level().0) + 1; let (redundant_item_name, diagnostic_range, redundant_item_def) = match assoc_item { hir::AssocItem::Function(id) => { @@ -30,7 +32,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`fn {redundant_assoc_item_name}`"), function.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n {};", function.display(db, ctx.display_target)), + format!("\n{};", function.display(db, ctx.display_target)), ) } hir::AssocItem::Const(id) => { @@ -38,7 +40,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`const {redundant_assoc_item_name}`"), constant.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n {};", constant.display(db, ctx.display_target)), + format!("\n{};", constant.display(db, ctx.display_target)), ) } hir::AssocItem::TypeAlias(id) => { @@ -46,10 +48,8 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`type {redundant_assoc_item_name}`"), type_alias.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!( - "\n type {};", - type_alias.name(ctx.sema.db).display_no_db(ctx.edition).to_smolstr() - ), + // FIXME cannot generate generic parameter and bounds + format!("\ntype {};", type_alias.name(ctx.sema.db).display_no_db(ctx.edition)), ) } }; @@ -65,7 +65,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( .with_fixes(quickfix_for_redundant_assoc_item( ctx, d, - redundant_item_def, + stdx::indent_string(&redundant_item_def, indent_level), diagnostic_range, )) } @@ -192,6 +192,89 @@ impl Marker for Foo { } #[test] + fn quickfix_indentations() { + check_fix( + r#" +mod indent { + trait Marker { + fn boo(); + } + struct Foo; + impl Marker for Foo { + fn$0 bar<T: Copy>(_a: i32, _b: T) -> String {} + fn boo() {} + } +} + "#, + r#" +mod indent { + trait Marker { + fn bar<T>(_a: i32, _b: T) -> String + where + T: Copy,; + fn boo(); + } + struct Foo; + impl Marker for Foo { + fn bar<T: Copy>(_a: i32, _b: T) -> String {} + fn boo() {} + } +} + "#, + ); + + check_fix( + r#" +mod indent { + trait Marker { + fn foo () {} + } + struct Foo; + impl Marker for Foo { + const FLAG: bool$0 = false; + } +} + "#, + r#" +mod indent { + trait Marker { + const FLAG: bool; + fn foo () {} + } + struct Foo; + impl Marker for Foo { + const FLAG: bool = false; + } +} + "#, + ); + + check_fix( + r#" +mod indent { + trait Marker { + } + struct Foo; + impl Marker for Foo { + type T = i32;$0 + } +} + "#, + r#" +mod indent { + trait Marker { + type T; + } + struct Foo; + impl Marker for Foo { + type T = i32; + } +} + "#, + ); + } + + #[test] fn quickfix_dont_work() { check_no_fix( r#"
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 577c582..fd1674e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -442,4 +442,30 @@ fn rdtscp() -> u64 { }"#, ); } + + #[test] + fn asm_sym_with_macro_expr_fragment() { + // Regression test for issue #21582 + // When `$e:expr` captures a path and is used in `sym $e`, the path gets + // wrapped in parentheses during macro expansion due to invisible delimiters. + // This should not cause false positive typed-hole errors. + check_diagnostics( + r#" +//- minicore: asm +macro_rules! m { + ($e:expr) => { + core::arch::asm!("/*{f}*/", f = sym $e, out("ax") _) + }; +} + +fn generic<T>() {} + +fn main() { + unsafe { + m!(generic::<i32>); + } +} +"#, + ); + } }
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index d854c1c..33bed95 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -219,7 +219,7 @@ pub(crate) fn resolve_doc_path_for_def( Definition::Crate(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Function(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Adt(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), - Definition::Variant(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), + Definition::EnumVariant(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Const(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Static(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Trait(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), @@ -678,7 +678,7 @@ fn filename_and_frag_for_def( Definition::Function(f) => { format!("fn.{}.html", f.name(db).as_str()) } - Definition::Variant(ev) => { + Definition::EnumVariant(ev) => { let def = Definition::Adt(ev.parent_enum(db).into()); let (_, file, _) = filename_and_frag_for_def(db, def)?; return Some((def, file, Some(format!("variant.{}", ev.name(db).as_str())))); @@ -703,9 +703,9 @@ fn filename_and_frag_for_def( }, Definition::Field(field) => { let def = match field.parent_def(db) { - hir::VariantDef::Struct(it) => Definition::Adt(it.into()), - hir::VariantDef::Union(it) => Definition::Adt(it.into()), - hir::VariantDef::Variant(it) => Definition::Variant(it), + hir::Variant::Struct(it) => Definition::Adt(it.into()), + hir::Variant::Union(it) => Definition::Adt(it.into()), + hir::Variant::EnumVariant(it) => Definition::EnumVariant(it), }; let (_, file, _) = filename_and_frag_for_def(db, def)?; return Some((def, file, Some(format!("structfield.{}", field.name(db).as_str()))));
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index a61a6c6..509c55a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
@@ -113,7 +113,7 @@ fn node_to_def<'db>( ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Struct(def)))), ast::Union(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Union(def)))), ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Enum(def)))), - ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Variant(def))), + ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::EnumVariant(def))), ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Trait(def))), ast::Static(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Static(def))), ast::Const(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Const(def))),
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index cf5f137..af78e9a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -5,7 +5,7 @@ use hir::{ Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DisplayTarget, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, - MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, + MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, Variant, db::ExpandDatabase, }; use ide_db::{ @@ -366,14 +366,14 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) - let parent_name = parent.name(db); let parent_name = parent_name.display(db, edition).to_string(); return match parent { - VariantDef::Variant(variant) => { + Variant::EnumVariant(variant) => { let enum_name = variant.parent_enum(db).name(db); Some(format!("{}::{parent_name}", enum_name.display(db, edition))) } _ => Some(parent_name), }; } - Definition::Variant(e) => Some(e.parent_enum(db).name(db)), + Definition::EnumVariant(e) => Some(e.parent_enum(db).name(db)), Definition::GenericParam(generic_param) => match generic_param.parent() { hir::GenericDef::Adt(it) => Some(it.name(db)), hir::GenericDef::Trait(it) => Some(it.name(db)), @@ -470,7 +470,7 @@ pub(super) fn definition( Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => { adt.display_limited(db, config.max_fields_count, display_target).to_string() } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { variant.display_limited(db, config.max_fields_count, display_target).to_string() } Definition::Adt(adt @ Adt::Enum(_)) => { @@ -499,7 +499,7 @@ pub(super) fn definition( }; let docs = def.docs_with_rangemap(db, famous_defs, display_target); let value = || match def { - Definition::Variant(it) => { + Definition::EnumVariant(it) => { if !it.parent_enum(db).is_data_carrying(db) { match it.eval(db) { Ok(it) => { @@ -596,7 +596,7 @@ pub(super) fn definition( |_| { let var_def = it.parent_def(db); match var_def { - hir::VariantDef::Struct(s) => { + hir::Variant::Struct(s) => { Adt::from(s).layout(db).ok().and_then(|layout| layout.field_offset(it)) } _ => None, @@ -627,7 +627,7 @@ pub(super) fn definition( |_| None, |_| None, ), - Definition::Variant(it) => render_memory_layout( + Definition::EnumVariant(it) => render_memory_layout( config.memory_layout, || it.layout(db), |_| None, @@ -710,7 +710,7 @@ pub(super) fn definition( has_dtor: Some(enum_drop_glue > fields_drop_glue), } } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { let fields_drop_glue = variant .fields(db) .iter()
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs index 5b92671..e845fae 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
@@ -46,7 +46,7 @@ fn variant_hints( enum_: &ast::Enum, variant: &ast::Variant, ) -> Option<()> { - if variant.expr().is_some() { + if variant.const_arg().is_some() { return None; }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index e5e4c89..3af529e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -7,7 +7,7 @@ //! ``` use hir::{ DefWithBody, - db::{DefDatabase as _, HirDatabase as _}, + db::HirDatabase as _, mir::{MirSpan, TerminatorKind}, }; use ide_db::{FileRange, famous_defs::FamousDefs}; @@ -35,7 +35,7 @@ pub(super) fn hints( let def: DefWithBody = def.into(); let def = def.try_into().ok()?; - let (hir, source_map) = sema.db.body_with_source_map(def); + let (hir, source_map) = hir::Body::with_source_map(sema.db, def); let mir = sema.db.mir_body(def).ok()?;
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index f1e62a5..08588bb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
@@ -374,7 +374,7 @@ fn is_adt_constructor_similar_to_param_name( hir::PathResolution::Def(hir::ModuleDef::Adt(_)) => { Some(to_lower_snake_case(&path.segment()?.name_ref()?.text()) == param_name) } - hir::PathResolution::Def(hir::ModuleDef::Function(_) | hir::ModuleDef::Variant(_)) => { + hir::PathResolution::Def(hir::ModuleDef::Function(_) | hir::ModuleDef::EnumVariant(_)) => { if to_lower_snake_case(&path.segment()?.name_ref()?.text()) == param_name { return Some(true); }
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 1c1389c..335e1b5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -205,7 +205,7 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati Definition::Adt(Adt::Struct(..)) => Struct, Definition::Adt(Adt::Union(..)) => Union, Definition::Adt(Adt::Enum(..)) => Enum, - Definition::Variant(..) => EnumMember, + Definition::EnumVariant(..) => EnumMember, Definition::Const(..) => Constant, Definition::Static(..) => StaticVariable, Definition::Trait(..) => Trait,
diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 185df92..9202032 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
@@ -276,7 +276,7 @@ fn try_to_nav( Some(it.display(db, display_target).to_string()) } hir::ModuleDef::Adt(it) => Some(it.display(db, display_target).to_string()), - hir::ModuleDef::Variant(it) => { + hir::ModuleDef::EnumVariant(it) => { Some(it.display(db, display_target).to_string()) } hir::ModuleDef::Const(it) => { @@ -319,7 +319,7 @@ fn try_to_nav( Definition::GenericParam(it) => it.try_to_nav(sema), Definition::Function(it) => it.try_to_nav(sema), Definition::Adt(it) => it.try_to_nav(sema), - Definition::Variant(it) => it.try_to_nav(sema), + Definition::EnumVariant(it) => it.try_to_nav(sema), Definition::Const(it) => it.try_to_nav(sema), Definition::Static(it) => it.try_to_nav(sema), Definition::Trait(it) => it.try_to_nav(sema), @@ -347,7 +347,7 @@ fn try_to_nav( hir::ModuleDef::Module(it) => Some(it.to_nav(sema.db)), hir::ModuleDef::Function(it) => it.try_to_nav(sema), hir::ModuleDef::Adt(it) => it.try_to_nav(sema), - hir::ModuleDef::Variant(it) => it.try_to_nav(sema), + hir::ModuleDef::EnumVariant(it) => it.try_to_nav(sema), hir::ModuleDef::Const(it) => it.try_to_nav(sema), hir::ModuleDef::Static(it) => it.try_to_nav(sema), hir::ModuleDef::Trait(it) => it.try_to_nav(sema), @@ -406,7 +406,7 @@ fn container_name(self, db: &RootDatabase) -> Option<Symbol> { container_name(db, self) } } -impl ToNavFromAst for hir::Variant { +impl ToNavFromAst for hir::EnumVariant { const KIND: SymbolKind = SymbolKind::Variant; } impl ToNavFromAst for hir::Union {
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index 6464c47..9392651 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -299,7 +299,7 @@ fn retain_adt_literal_usages( }); usages.references.retain(|_, it| !it.is_empty()); } - Definition::Adt(_) | Definition::Variant(_) => { + Definition::Adt(_) | Definition::EnumVariant(_) => { refs.for_each(|it| { it.retain(|reference| reference.name.as_name_ref().is_some_and(is_lit_name_ref)) }); @@ -377,7 +377,7 @@ fn is_enum_lit_name_ref( let path_is_variant_of_enum = |path: ast::Path| { matches!( sema.resolve_path(&path), - Some(PathResolution::Def(hir::ModuleDef::Variant(variant))) + Some(PathResolution::Def(hir::ModuleDef::EnumVariant(variant))) if variant.parent_enum(sema.db) == enum_ ) };
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index ae19e77..900a885 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -480,7 +480,7 @@ fn rename_to_self( } let fn_def = match local.parent(sema.db) { - hir::DefWithBody::Function(func) => func, + hir::ExpressionStoreOwner::Body(hir::DefWithBody::Function(func)) => func, _ => bail!("Cannot rename local to self outside of function"), }; @@ -743,7 +743,7 @@ fn rename_self_to_param( } let fn_def = match local.parent(sema.db) { - hir::DefWithBody::Function(func) => func, + hir::ExpressionStoreOwner::Body(hir::DefWithBody::Function(func)) => func, _ => bail!("Cannot rename local to self outside of function"), };
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 42efa71..a0a6a24 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -494,7 +494,7 @@ fn module_def_doctest(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Op Definition::Module(it) => it.attrs(db), Definition::Function(it) => it.attrs(db), Definition::Adt(it) => it.attrs(db), - Definition::Variant(it) => it.attrs(db), + Definition::EnumVariant(it) => it.attrs(db), Definition::Const(it) => it.attrs(db), Definition::Static(it) => it.attrs(db), Definition::Trait(it) => it.attrs(db),
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index f86974b..9eb01b1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -497,7 +497,7 @@ fn signature_help_for_tuple_struct_pat( }; let db = sema.db; - let fields: Vec<_> = if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res { + let fields: Vec<_> = if let PathResolution::Def(ModuleDef::EnumVariant(variant)) = path_res { let en = variant.parent_enum(db); res.doc = en.docs(db).map(Documentation::into_owned); @@ -623,7 +623,7 @@ fn signature_help_for_record_<'db>( let db = sema.db; let path_res = sema.resolve_path(path)?; - if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res { + if let PathResolution::Def(ModuleDef::EnumVariant(variant)) = path_res { fields = variant.fields(db); let en = variant.parent_enum(db);
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index ce1df6a..217b13b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -14,7 +14,9 @@ use std::ops::ControlFlow; use either::Either; -use hir::{DefWithBody, EditionedFileId, InFile, InRealFile, MacroKind, Semantics}; +use hir::{ + DefWithBody, EditionedFileId, ExpressionStoreOwner, InFile, InRealFile, MacroKind, Semantics, +}; use ide_db::{FxHashMap, FxHashSet, MiniCore, Ranker, RootDatabase, SymbolKind}; use syntax::{ AstNode, AstToken, NodeOrToken, @@ -256,8 +258,8 @@ fn item(&self) -> &ast::Item { let mut inside_attribute = false; // FIXME: accommodate range highlighting - let mut body_stack: Vec<Option<DefWithBody>> = vec![]; - let mut per_body_cache: FxHashMap<DefWithBody, FxHashSet<_>> = FxHashMap::default(); + let mut body_stack: Vec<Option<ExpressionStoreOwner>> = vec![]; + let mut per_body_cache: FxHashMap<ExpressionStoreOwner, FxHashSet<_>> = FxHashMap::default(); // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. @@ -288,19 +290,18 @@ fn item(&self) -> &ast::Item { inside_attribute = false } Enter(NodeOrToken::Node(node)) => { + // FIXME: ExpressionStore signatures and variant fields + // Maybe we can re-use child container stuff here if let Some(item) = <Either<ast::Item, ast::Variant>>::cast(node.clone()) { match item { Either::Left(item) => { match &item { - ast::Item::Fn(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } - ast::Item::Const(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } - ast::Item::Static(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } + ast::Item::Fn(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), + ast::Item::Const(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), + ast::Item::Static(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), _ => (), } @@ -329,7 +330,9 @@ fn item(&self) -> &ast::Item { } } } - Either::Right(it) => body_stack.push(sema.to_def(&it).map(Into::into)), + Either::Right(it) => { + body_stack.push(sema.to_def(&it).map(DefWithBody::from).map(Into::into)) + } } } } @@ -392,11 +395,11 @@ fn item(&self) -> &ast::Item { let descended = descend_token(sema, InRealFile::new(file_id, token)); let body = match &descended.value { NodeOrToken::Node(n) => { - sema.body_for(InFile::new(descended.file_id, n.syntax())) + sema.store_owner_for(InFile::new(descended.file_id, n.syntax())) } - NodeOrToken::Token(t) => { - t.parent().and_then(|it| sema.body_for(InFile::new(descended.file_id, &it))) - } + NodeOrToken::Token(t) => t + .parent() + .and_then(|it| sema.store_owner_for(InFile::new(descended.file_id, &it))), }; (descended, body) }
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index a94bbc9..0e101ab 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -538,7 +538,7 @@ pub(super) fn highlight_def( (Highlight::new(h), Some(adt.attrs(sema.db))) } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { (Highlight::new(HlTag::Symbol(SymbolKind::Variant)), Some(variant.attrs(sema.db))) } Definition::Const(konst) => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs index 291333f..74a8d93 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
@@ -209,7 +209,7 @@ fn module_def_to_hl_tag(db: &dyn HirDatabase, def: Definition) -> HlTag { Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, Definition::Adt(hir::Adt::Union(_)) => SymbolKind::Union, - Definition::Variant(_) => SymbolKind::Variant, + Definition::EnumVariant(_) => SymbolKind::Variant, Definition::Const(_) => SymbolKind::Const, Definition::Static(_) => SymbolKind::Static, Definition::Trait(_) => SymbolKind::Trait,
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index c6dbc43..1184739 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -105,7 +105,7 @@ <span class="keyword control">loop</span> <span class="brace">{</span><span class="brace">}</span> <span class="brace">}</span> -<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle"><</span><span class="keyword const">const</span> <span class="const_param const declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="brace">{</span> +<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle"><</span><span class="keyword const">const</span> <span class="const_param const declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="keyword">where</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="const_param const">FOO</span><span class="bracket">]</span><span class="colon">:</span> <span class="trait default_library library">Sized</span> <span class="brace">{</span> <span class="function">const_param</span><span class="operator">::</span><span class="angle"><</span><span class="brace">{</span> <span class="const_param const">FOO</span> <span class="brace">}</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="const_param const">FOO</span> <span class="brace">}</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index c6aebd0..aecd1d3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -210,7 +210,7 @@ fn never() -> ! { loop {} } -fn const_param<const FOO: usize>() -> usize { +fn const_param<const FOO: usize>() -> usize where [(); FOO]: Sized { const_param::<{ FOO }>(); FOO }
diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index ad73c19..39320eb 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml
@@ -22,3 +22,6 @@ [lints] workspace = true + +[features] +prevent-gc = []
diff --git a/src/tools/rust-analyzer/crates/intern/src/gc.rs b/src/tools/rust-analyzer/crates/intern/src/gc.rs index 937de26..f4e8f75 100644 --- a/src/tools/rust-analyzer/crates/intern/src/gc.rs +++ b/src/tools/rust-analyzer/crates/intern/src/gc.rs
@@ -110,6 +110,10 @@ pub fn add_slice_storage<T: SliceInternable + GcInternedSliceVisit>(&mut self) { /// the added storages must form a DAG. /// - [`GcInternedVisit`] and [`GcInternedSliceVisit`] must mark all values reachable from the node. pub unsafe fn collect(mut self) { + if cfg!(feature = "prevent-gc") { + return; + } + let total_nodes = self.storages.iter().map(|storage| storage.len()).sum(); self.alive.clear(); self.alive.reserve(total_nodes);
diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 95fcfce..8753eab 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
@@ -42,6 +42,7 @@ pub struct LoadCargoConfig { pub load_out_dirs_from_check: bool, pub with_proc_macro_server: ProcMacroServerChoice, pub prefill_caches: bool, + pub num_worker_threads: usize, pub proc_macro_processes: usize, } @@ -197,7 +198,7 @@ pub fn load_workspace_into_db( ); if load_config.prefill_caches { - prime_caches::parallel_prime_caches(db, 1, &|_| ()); + prime_caches::parallel_prime_caches(db, load_config.num_worker_threads, &|_| ()); } Ok((vfs, proc_macro_server.and_then(Result::ok))) @@ -744,16 +745,26 @@ mod tests { #[test] fn test_loading_rust_analyzer() { - let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); + let cargo_toml_path = Path::new(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .parent() + .unwrap() + .join("Cargo.toml"); + let cargo_toml_path = AbsPathBuf::assert_utf8(cargo_toml_path); + let manifest = ProjectManifest::from_manifest_file(cargo_toml_path).unwrap(); + let cargo_config = CargoConfig { set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::None, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; + let workspace = ProjectWorkspace::load(manifest, &cargo_config, &|_| {}).unwrap(); let (db, _vfs, _proc_macro) = - load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap(); + load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config).unwrap(); let n_crates = db.all_crates().len(); // RA has quite a few crates, but the exact count doesn't matter
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index b75474e..3214fd9 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -407,8 +407,18 @@ pub(crate) fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedM op.complete(p, ASM_CONST); op_n.complete(p, ASM_OPERAND_NAMED); } else if p.eat_contextual_kw(T![sym]) { + // test asm_sym_paren + // fn foo() { + // builtin#asm("", f = sym (foo::bar)); + // } dir_spec.abandon(p); - paths::type_path(p); + if p.at(T!['(']) { + p.bump(T!['(']); + paths::type_path(p); + p.expect(T![')']); + } else { + paths::type_path(p); + } op.complete(p, ASM_SYM); op_n.complete(p, ASM_OPERAND_NAMED); } else if allow_templates {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs index a375696..cfba4c3 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items/adt.rs
@@ -96,7 +96,9 @@ fn variant(p: &mut Parser<'_>) { // test variant_discriminant // enum E { X(i32) = 10 } if p.eat(T![=]) { + let m = p.start(); expressions::expr(p); + m.complete(p, CONST_ARG); } m.complete(p, VARIANT); } else { @@ -139,7 +141,9 @@ fn record_field(p: &mut Parser<'_>) { // test record_field_default_values // struct S { f: f32 = 0.0 } if p.eat(T![=]) { + let m = p.start(); expressions::expr(p); + m.complete(p, CONST_ARG); } m.complete(p, RECORD_FIELD); } else {
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 9f919f6..4c00110 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -25,6 +25,8 @@ fn arb_self_types() { #[test] fn asm_label() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_label.rs"); } #[test] + fn asm_sym_paren() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_sym_paren.rs"); } + #[test] fn assoc_const_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_const_eq.rs"); }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast new file mode 100644 index 0000000..d189f63 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast
@@ -0,0 +1,49 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + EXPR_STMT + ASM_EXPR + BUILTIN_KW "builtin" + POUND "#" + ASM_KW "asm" + L_PAREN "(" + LITERAL + STRING "\"\"" + COMMA "," + WHITESPACE " " + ASM_OPERAND_NAMED + NAME + IDENT "f" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ASM_SYM + SYM_KW "sym" + WHITESPACE " " + L_PAREN "(" + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COLON2 "::" + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs new file mode 100644 index 0000000..7b2f807 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs
@@ -0,0 +1,3 @@ +fn foo() { + builtin#asm("", f = sym (foo::bar)); +}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast index 33088f2..e53b886 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_default_values.rast
@@ -21,8 +21,9 @@ WHITESPACE " " EQ "=" WHITESPACE " " - LITERAL - FLOAT_NUMBER "0.0" + CONST_ARG + LITERAL + FLOAT_NUMBER "0.0" WHITESPACE " " R_CURLY "}" WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast index 9f0c5a7..3494085 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast
@@ -23,8 +23,9 @@ WHITESPACE " " EQ "=" WHITESPACE " " - LITERAL - INT_NUMBER "10" + CONST_ARG + LITERAL + INT_NUMBER "10" WHITESPACE " " R_CURLY "}" WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0019_enums.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0019_enums.rast index dd47e3a..51837e5 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0019_enums.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0019_enums.rast
@@ -78,8 +78,9 @@ WHITESPACE " " EQ "=" WHITESPACE " " - LITERAL - INT_NUMBER "92" + CONST_ARG + LITERAL + INT_NUMBER "92" COMMA "," WHITESPACE "\n " VARIANT
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 9b91110..4ea136a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -365,9 +365,27 @@ pub enum RunnableKind { /// May include {test_id} which will get the test clicked on by the user. TestOne, + /// Run tests matching a pattern (in RA, usually a path::to::module::of::tests) + /// May include {label} which will get the label from the `build` section of a crate. + /// May include {test_pattern} which will get the test module clicked on by the user. + TestMod, + + /// Run a single doctest + /// May include {label} which will get the label from the `build` section of a crate. + /// May include {test_id} which will get the doctest clicked on by the user. + DocTestOne, + + /// Run a single benchmark + /// May include {label} which will get the label from the `build` section of a crate. + /// May include {bench_id} which will get the benchmark clicked on by the user. + BenchOne, + /// Template for checking a target, emitting rustc JSON diagnostics. /// May include {label} which will get the label from the `build` section of a crate. Flycheck, + + /// For forwards-compatibility, i.e. old rust-analyzer binary with newer workspace discovery tools + Unknown, } #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] @@ -380,6 +398,8 @@ pub struct ProjectJsonData { crates: Vec<CrateData>, #[serde(default)] runnables: Vec<RunnableData>, + // + // New fields should be Option or #[serde(default)]. This applies to most of this datastructure. } #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)] @@ -453,32 +473,40 @@ enum EditionData { } #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] -pub struct BuildData { +struct BuildData { label: String, build_file: Utf8PathBuf, target_kind: TargetKindData, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct RunnableData { - pub program: String, - pub args: Vec<String>, - pub cwd: Utf8PathBuf, - pub kind: RunnableKindData, +struct RunnableData { + program: String, + args: Vec<String>, + cwd: Utf8PathBuf, + kind: RunnableKindData, } #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub enum RunnableKindData { +enum RunnableKindData { Flycheck, Check, Run, TestOne, + TestMod, + DocTestOne, + BenchOne, + + /// For forwards-compatibility, i.e. old rust-analyzer binary with newer workspace discovery tools + #[allow(unused)] + #[serde(other)] + Unknown, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub enum TargetKindData { +enum TargetKindData { Bin, /// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...). Lib, @@ -541,7 +569,11 @@ fn from(data: RunnableKindData) -> Self { RunnableKindData::Check => RunnableKind::Check, RunnableKindData::Run => RunnableKind::Run, RunnableKindData::TestOne => RunnableKind::TestOne, + RunnableKindData::TestMod => RunnableKind::TestMod, + RunnableKindData::DocTestOne => RunnableKind::DocTestOne, + RunnableKindData::BenchOne => RunnableKind::BenchOne, RunnableKindData::Flycheck => RunnableKind::Flycheck, + RunnableKindData::Unknown => RunnableKind::Unknown, } } }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index a03ed56..395cea6 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -193,6 +193,12 @@ fn rust_project_hello_world_project_model() { } #[test] +fn rust_project_labeled_project_model() { + // This just needs to parse. + _ = load_rust_project("labeled-project.json"); +} + +#[test] fn rust_project_cfg_groups() { let (crate_graph, _proc_macros) = load_rust_project("cfg-groups.json"); check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]);
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/labeled-project.json b/src/tools/rust-analyzer/crates/project-model/test_data/labeled-project.json new file mode 100644 index 0000000..5c0e1f3 --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/test_data/labeled-project.json
@@ -0,0 +1,37 @@ +{ + "sysroot_src": null, + "crates": [ + { + "display_name": "hello_world", + "root_module": "$ROOT$src/lib.rs", + "edition": "2018", + "deps": [], + "is_workspace_member": true, + "build": { + "label": "//:hello_world", + "build_file": "$ROOT$BUILD", + "target_kind": "bin" + } + } + ], + "runnables": [ + { + "kind": "run", + "program": "bazel", + "args": ["run", "{label}"], + "cwd": "$ROOT$" + }, + { + "kind": "flycheck", + "program": "$ROOT$custom-flychecker.sh", + "args": ["{label}"], + "cwd": "$ROOT$" + }, + { + "kind": "we-ignore-unknown-runnable-kinds-for-forwards-compatibility", + "program": "abc", + "args": ["{label}"], + "cwd": "$ROOT$" + } + ] +}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index d1283ca..beb83a8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -94,6 +94,8 @@ test-fixture.workspace = true syntax-bridge.workspace = true +intern = { path = "../intern", features = ["prevent-gc"] } + [features] jemalloc = ["jemallocator", "profile/jemalloc"] force-always-assert = ["stdx/force-always-assert"]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 82f04aa..74828cb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -10,15 +10,15 @@ use cfg::{CfgAtom, CfgDiff}; use hir::{ - Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasCrate, HasSource, HirDisplay, ModuleDef, - Name, crate_lang_items, + Adt, AssocItem, Crate, DefWithBody, FindPathConfig, GenericDef, HasCrate, HasSource, + HirDisplay, ModuleDef, Name, Variant, VariantId, crate_lang_items, db::{DefDatabase, ExpandDatabase, HirDatabase}, next_solver::{DbInterner, GenericArgs}, }; use hir_def::{ - SyntheticSyntax, - expr_store::BodySourceMap, - hir::{ExprId, PatId}, + DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, + expr_store::{Body, BodySourceMap, ExpressionStore}, + hir::{ExprId, PatId, generics::GenericParams}, }; use hir_ty::InferenceResult; use ide::{ @@ -91,6 +91,7 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { } }, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; @@ -228,6 +229,8 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { eprint!(" crates: {num_crates}"); let mut num_decls = 0; let mut bodies = Vec::new(); + let mut signatures = Vec::new(); + let mut variants = Vec::new(); let mut adts = Vec::new(); let mut file_ids = Vec::new(); @@ -245,10 +248,15 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { match decl { ModuleDef::Function(f) => bodies.push(DefWithBody::from(f)), ModuleDef::Adt(a) => { - if let Adt::Enum(e) = a { - for v in e.variants(db) { - bodies.push(DefWithBody::from(v)); + match a { + Adt::Enum(e) => { + for v in e.variants(db) { + bodies.push(DefWithBody::from(v)); + variants.push(Variant::EnumVariant(v)); + } } + Adt::Struct(it) => variants.push(Variant::Struct(it)), + Adt::Union(it) => variants.push(Variant::Union(it)), } adts.push(a) } @@ -266,24 +274,32 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { }, _ => (), }; + if let Some(g) = decl.as_generic_def() { + signatures.push(g); + } } for impl_def in module.impl_defs(db) { + signatures.push(impl_def.into()); for item in impl_def.items(db) { num_decls += 1; match item { - AssocItem::Function(f) => bodies.push(DefWithBody::from(f)), + AssocItem::Function(f) => { + bodies.push(DefWithBody::from(f)); + signatures.push(f.into()) + } AssocItem::Const(c) => { bodies.push(DefWithBody::from(c)); + signatures.push(c.into()); } - _ => (), + AssocItem::TypeAlias(t) => signatures.push(t.into()), } } } } } eprintln!( - ", mods: {}, decls: {num_decls}, bodies: {}, adts: {}, consts: {}", + ", mods: {}, decls: {num_decls}, bodies: {}, adts: {}, consts: {}, signatures: {}, variants: {}", visited_modules.len(), bodies.len(), adts.len(), @@ -291,6 +307,8 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { .iter() .filter(|it| matches!(it, DefWithBody::Const(_) | DefWithBody::Static(_))) .count(), + signatures.len(), + variants.len() ); eprintln!(" Workspace:"); @@ -326,15 +344,15 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { } if !self.skip_lowering { - self.run_body_lowering(db, &vfs, &bodies, verbosity); + self.run_body_lowering(db, &vfs, &bodies, &signatures, &variants, verbosity); } if !self.skip_inference { - self.run_inference(db, &vfs, &bodies, verbosity); + self.run_inference(db, &vfs, &bodies, &signatures, &variants, verbosity); } if !self.skip_mir_stats { - self.run_mir_lowering(db, &bodies, verbosity); + self.run_mir_lowering(db, &bodies, &signatures, &variants, verbosity); } if !self.skip_data_layout { @@ -342,7 +360,7 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { } if !self.skip_const_eval { - self.run_const_eval(db, &bodies, verbosity); + self.run_const_eval(db, &bodies, &signatures, &variants, verbosity); } }); @@ -383,7 +401,7 @@ fn run_data_layout(&self, db: &RootDatabase, adts: &[hir::Adt], verbosity: Verbo let mut fail = 0; for &a in adts { let interner = DbInterner::new_no_crate(db); - let generic_params = db.generic_params(a.into()); + let generic_params = GenericParams::of(db, a.into()); if generic_params.iter_type_or_consts().next().is_some() || generic_params.iter_lt().next().is_some() { @@ -395,7 +413,7 @@ fn run_data_layout(&self, db: &RootDatabase, adts: &[hir::Adt], verbosity: Verbo hir_def::AdtId::from(a), GenericArgs::empty(interner).store(), hir_ty::ParamEnvAndCrate { - param_env: db.trait_environment(a.into()), + param_env: db.trait_environment(GenericDefId::from(a).into()), krate: a.krate(db).into(), } .store(), @@ -415,7 +433,14 @@ fn run_data_layout(&self, db: &RootDatabase, adts: &[hir::Adt], verbosity: Verbo report_metric("data layout time", data_layout_time.time.as_millis() as u64, "ms"); } - fn run_const_eval(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) { + fn run_const_eval( + &self, + db: &RootDatabase, + bodies: &[DefWithBody], + _signatures: &[GenericDef], + _variants: &[Variant], + verbosity: Verbosity, + ) { let len = bodies .iter() .filter(|body| matches!(body, DefWithBody::Const(_) | DefWithBody::Static(_))) @@ -430,7 +455,9 @@ fn run_const_eval(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: V let mut all = 0; let mut fail = 0; for &b in bodies { - bar.set_message(move || format!("const eval: {}", full_name(db, b, b.module(db)))); + bar.set_message(move || { + format!("const eval: {}", full_name(db, || b.name(db), b.module(db))) + }); let res = match b { DefWithBody::Const(c) => c.eval(db), DefWithBody::Static(s) => s.eval(db), @@ -686,7 +713,14 @@ fn trim(s: &str) -> String { bar.finish_and_clear(); } - fn run_mir_lowering(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) { + fn run_mir_lowering( + &self, + db: &RootDatabase, + bodies: &[DefWithBody], + _signatures: &[GenericDef], + _variants: &[Variant], + verbosity: Verbosity, + ) { let mut bar = match verbosity { Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), _ if self.parallel || self.output.is_some() => ProgressReport::hidden(), @@ -697,14 +731,14 @@ fn run_mir_lowering(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: let mut fail = 0; for &body in bodies { bar.set_message(move || { - format!("mir lowering: {}", full_name(db, body, body.module(db))) + format!("mir lowering: {}", full_name(db, || body.name(db), body.module(db))) }); bar.inc(1); - if matches!(body, DefWithBody::Variant(_)) { + if matches!(body, DefWithBody::EnumVariant(_)) { continue; } let module = body.module(db); - if !self.should_process(db, body, module) { + if !self.should_process(db, || body.name(db), module) { continue; } @@ -742,6 +776,8 @@ fn run_inference( db: &RootDatabase, vfs: &Vfs, bodies: &[DefWithBody], + signatures: &[GenericDef], + variants: &[Variant], verbosity: Verbosity, ) { let mut bar = match verbosity { @@ -752,12 +788,31 @@ fn run_inference( if self.parallel { let mut inference_sw = self.stop_watch(); - let bodies = bodies.iter().filter_map(|&body| body.try_into().ok()).collect::<Vec<_>>(); + let bodies = bodies + .iter() + .filter_map(|&body| body.try_into().ok()) + .collect::<Vec<DefWithBodyId>>(); bodies .par_iter() .map_with(db.clone(), |snap, &body| { - snap.body(body); - InferenceResult::for_body(snap, body); + InferenceResult::of(snap, body); + }) + .count(); + let signatures = signatures + .iter() + .filter_map(|&signatures| signatures.try_into().ok()) + .collect::<Vec<GenericDefId>>(); + signatures + .par_iter() + .map_with(db.clone(), |snap, &signatures| { + InferenceResult::of(snap, signatures); + }) + .count(); + let variants = variants.iter().copied().map(Into::into).collect::<Vec<VariantId>>(); + variants + .par_iter() + .map_with(db.clone(), |snap, &variants| { + InferenceResult::of(snap, variants); }) .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); @@ -781,7 +836,7 @@ fn run_inference( let display_target = module.krate(db).to_display_target(db); if let Some(only_name) = self.only.as_deref() && name.display(db, Edition::LATEST).to_string() != only_name - && full_name(db, body_id, module) != only_name + && full_name(db, || body_id.name(db), module) != only_name { continue; } @@ -791,7 +846,9 @@ fn run_inference( DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()), - DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()), + DefWithBody::EnumVariant(it) => { + it.source(db).map(|it| it.syntax().cloned()) + } }; if let Some(src) = source { let original_file = src.file_id.original_file(db); @@ -799,33 +856,44 @@ fn run_inference( let syntax_range = src.text_range(); format!( "processing: {} ({} {:?})", - full_name(db, body_id, module), + full_name(db, || body_id.name(db), module), path, syntax_range ) } else { - format!("processing: {}", full_name(db, body_id, module)) + format!("processing: {}", full_name(db, || body_id.name(db), module)) } } else { - format!("processing: {}", full_name(db, body_id, module)) + format!("processing: {}", full_name(db, || body_id.name(db), module)) } }; if verbosity.is_spammy() { bar.println(msg()); } bar.set_message(msg); - let body = db.body(body_def_id); + let body = Body::of(db, body_def_id); let inference_result = - catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_def_id))); + catch_unwind(AssertUnwindSafe(|| InferenceResult::of(db, body_def_id))); let inference_result = match inference_result { Ok(inference_result) => inference_result, Err(p) => { if let Some(s) = p.downcast_ref::<&str>() { - eprintln!("infer panicked for {}: {}", full_name(db, body_id, module), s); + eprintln!( + "infer panicked for {}: {}", + full_name(db, || body_id.name(db), module), + s + ); } else if let Some(s) = p.downcast_ref::<String>() { - eprintln!("infer panicked for {}: {}", full_name(db, body_id, module), s); + eprintln!( + "infer panicked for {}: {}", + full_name(db, || body_id.name(db), module), + s + ); } else { - eprintln!("infer panicked for {}", full_name(db, body_id, module)); + eprintln!( + "infer panicked for {}", + full_name(db, || body_id.name(db), module) + ); } panics += 1; bar.inc(1); @@ -833,7 +901,7 @@ fn run_inference( } }; // This query is LRU'd, so actually calling it will skew the timing results. - let sm = || db.body_with_source_map(body_def_id).1; + let sm = || &Body::with_source_map(db, body_def_id).1; // region:expressions let (previous_exprs, previous_unknown, previous_partially_unknown) = @@ -844,7 +912,7 @@ fn run_inference( let unknown_or_partial = if ty.is_ty_error() { num_exprs_unknown += 1; if verbosity.is_spammy() { - if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) + if let Some((path, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{} {}:{}-{}:{}: Unknown type", @@ -871,7 +939,7 @@ fn run_inference( }; if self.only.is_some() && verbosity.is_spammy() { // in super-verbose mode for just one function, we print every single expression - if let Some((_, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) { + if let Some((_, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{}:{}-{}:{}: {}", start.line + 1, @@ -890,14 +958,14 @@ fn run_inference( if unknown_or_partial && self.output == Some(OutputFormat::Csv) { println!( r#"{},type,"{}""#, - location_csv_expr(db, vfs, &sm(), expr_id), + location_csv_expr(db, vfs, sm(), expr_id), ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { num_expr_type_mismatches += 1; if verbosity.is_verbose() { - if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) + if let Some((path, start, end)) = expr_syntax_range(db, vfs, sm(), expr_id) { bar.println(format!( "{} {}:{}-{}:{}: Expected {}, got {}", @@ -921,7 +989,7 @@ fn run_inference( if self.output == Some(OutputFormat::Csv) { println!( r#"{},mismatch,"{}","{}""#, - location_csv_expr(db, vfs, &sm(), expr_id), + location_csv_expr(db, vfs, sm(), expr_id), mismatch.expected.as_ref().display(db, display_target), mismatch.actual.as_ref().display(db, display_target) ); @@ -931,7 +999,7 @@ fn run_inference( if verbosity.is_spammy() { bar.println(format!( "In {}: {} exprs, {} unknown, {} partial", - full_name(db, body_id, module), + full_name(db, || body_id.name(db), module), num_exprs - previous_exprs, num_exprs_unknown - previous_unknown, num_exprs_partially_unknown - previous_partially_unknown @@ -948,7 +1016,7 @@ fn run_inference( let unknown_or_partial = if ty.is_ty_error() { num_pats_unknown += 1; if verbosity.is_spammy() { - if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((path, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{} {}:{}-{}:{}: Unknown type", path, @@ -974,7 +1042,7 @@ fn run_inference( }; if self.only.is_some() && verbosity.is_spammy() { // in super-verbose mode for just one function, we print every single pattern - if let Some((_, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((_, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{}:{}-{}:{}: {}", start.line + 1, @@ -993,14 +1061,14 @@ fn run_inference( if unknown_or_partial && self.output == Some(OutputFormat::Csv) { println!( r#"{},type,"{}""#, - location_csv_pat(db, vfs, &sm(), pat_id), + location_csv_pat(db, vfs, sm(), pat_id), ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat_id) { num_pat_type_mismatches += 1; if verbosity.is_verbose() { - if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { + if let Some((path, start, end)) = pat_syntax_range(db, vfs, sm(), pat_id) { bar.println(format!( "{} {}:{}-{}:{}: Expected {}, got {}", path, @@ -1023,7 +1091,7 @@ fn run_inference( if self.output == Some(OutputFormat::Csv) { println!( r#"{},mismatch,"{}","{}""#, - location_csv_pat(db, vfs, &sm(), pat_id), + location_csv_pat(db, vfs, sm(), pat_id), mismatch.expected.as_ref().display(db, display_target), mismatch.actual.as_ref().display(db, display_target) ); @@ -1033,7 +1101,7 @@ fn run_inference( if verbosity.is_spammy() { bar.println(format!( "In {}: {} pats, {} unknown, {} partial", - full_name(db, body_id, module), + full_name(db, || body_id.name(db), module), num_pats - previous_pats, num_pats_unknown - previous_unknown, num_pats_partially_unknown - previous_partially_unknown @@ -1077,20 +1145,104 @@ fn run_body_lowering( db: &RootDatabase, vfs: &Vfs, bodies: &[DefWithBody], + signatures: &[GenericDef], + variants: &[Variant], verbosity: Verbosity, ) { let mut bar = match verbosity { Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), _ if self.output.is_some() => ProgressReport::hidden(), - _ => ProgressReport::new(bodies.len()), + _ => ProgressReport::new(bodies.len() + signatures.len() + variants.len()), }; let mut sw = self.stop_watch(); bar.tick(); + for &signature in signatures { + let Ok(signature_id) = signature.try_into() else { continue }; + let module = signature.module(db); + if !self.should_process(db, || signature.name(db), module) { + continue; + } + let msg = move || { + if verbosity.is_verbose() { + let source = match signature { + GenericDef::Function(it) => it.source(db).map(|it| it.syntax().cloned()), + GenericDef::Static(it) => it.source(db).map(|it| it.syntax().cloned()), + GenericDef::Const(it) => it.source(db).map(|it| it.syntax().cloned()), + GenericDef::Adt(adt) => adt.source(db).map(|it| it.syntax().cloned()), + GenericDef::Trait(it) => it.source(db).map(|it| it.syntax().cloned()), + GenericDef::TypeAlias(type_alias) => { + type_alias.source(db).map(|it| it.syntax().cloned()) + } + GenericDef::Impl(it) => it.source(db).map(|it| it.syntax().cloned()), + }; + if let Some(src) = source { + let original_file = src.file_id.original_file(db); + let path = vfs.file_path(original_file.file_id(db)); + let syntax_range = src.text_range(); + format!( + "processing: {} ({} {:?})", + full_name(db, || signature.name(db), module), + path, + syntax_range + ) + } else { + format!("processing: {}", full_name(db, || signature.name(db), module)) + } + } else { + format!("processing: {}", full_name(db, || signature.name(db), module)) + } + }; + if verbosity.is_spammy() { + bar.println(msg()); + } + bar.set_message(msg); + ExpressionStore::of(db, ExpressionStoreOwnerId::Signature(signature_id)); + bar.inc(1); + } + + for &variant in variants { + let variant_id = variant.into(); + let module = variant.module(db); + if !self.should_process(db, || Some(variant.name(db)), module) { + continue; + } + let msg = move || { + if verbosity.is_verbose() { + let source = match variant { + Variant::EnumVariant(it) => it.source(db).map(|it| it.syntax().cloned()), + Variant::Struct(it) => it.source(db).map(|it| it.syntax().cloned()), + Variant::Union(it) => it.source(db).map(|it| it.syntax().cloned()), + }; + if let Some(src) = source { + let original_file = src.file_id.original_file(db); + let path = vfs.file_path(original_file.file_id(db)); + let syntax_range = src.text_range(); + format!( + "processing: {} ({} {:?})", + full_name(db, || Some(variant.name(db)), module), + path, + syntax_range + ) + } else { + format!("processing: {}", full_name(db, || Some(variant.name(db)), module)) + } + } else { + format!("processing: {}", full_name(db, || Some(variant.name(db)), module)) + } + }; + if verbosity.is_spammy() { + bar.println(msg()); + } + bar.set_message(msg); + ExpressionStore::of(db, ExpressionStoreOwnerId::VariantFields(variant_id)); + bar.inc(1); + } + for &body_id in bodies { let Ok(body_def_id) = body_id.try_into() else { continue }; let module = body_id.module(db); - if !self.should_process(db, body_id, module) { + if !self.should_process(db, || body_id.name(db), module) { continue; } let msg = move || { @@ -1099,7 +1251,9 @@ fn run_body_lowering( DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()), - DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()), + DefWithBody::EnumVariant(it) => { + it.source(db).map(|it| it.syntax().cloned()) + } }; if let Some(src) = source { let original_file = src.file_id.original_file(db); @@ -1107,28 +1261,28 @@ fn run_body_lowering( let syntax_range = src.text_range(); format!( "processing: {} ({} {:?})", - full_name(db, body_id, module), + full_name(db, || body_id.name(db), module), path, syntax_range ) } else { - format!("processing: {}", full_name(db, body_id, module)) + format!("processing: {}", full_name(db, || body_id.name(db), module)) } } else { - format!("processing: {}", full_name(db, body_id, module)) + format!("processing: {}", full_name(db, || body_id.name(db), module)) } }; if verbosity.is_spammy() { bar.println(msg()); } bar.set_message(msg); - db.body(body_def_id); + Body::of(db, body_def_id); bar.inc(1); } bar.finish_and_clear(); let body_lowering_time = sw.elapsed(); - eprintln!("{:<20} {}", "Body lowering:", body_lowering_time); + eprintln!("{:<20} {}", "Expression Store Lowering:", body_lowering_time); report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms"); } @@ -1282,12 +1436,17 @@ fn run_ide_things( eprintln!("{:<20} {} ({} files)", "IDE:", ide_time, file_ids.len()); } - fn should_process(&self, db: &RootDatabase, body_id: DefWithBody, module: hir::Module) -> bool { + fn should_process( + &self, + db: &RootDatabase, + name_fn: impl Fn() -> Option<Name>, + module: hir::Module, + ) -> bool { if let Some(only_name) = self.only.as_deref() { - let name = body_id.name(db).unwrap_or_else(Name::missing); + let name = name_fn().unwrap_or_else(Name::missing); if name.display(db, Edition::LATEST).to_string() != only_name - && full_name(db, body_id, module) != only_name + && full_name(db, name_fn, module) != only_name { return false; } @@ -1300,7 +1459,7 @@ fn stop_watch(&self) -> StopWatch { } } -fn full_name(db: &RootDatabase, body_id: DefWithBody, module: hir::Module) -> String { +fn full_name(db: &RootDatabase, name: impl Fn() -> Option<Name>, module: hir::Module) -> String { module .krate(db) .display_name(db) @@ -1312,7 +1471,7 @@ fn full_name(db: &RootDatabase, body_id: DefWithBody, module: hir::Module) -> St .into_iter() .filter_map(|it| it.name(db)) .rev() - .chain(Some(body_id.name(db).unwrap_or_else(Name::missing))) + .chain(Some(name().unwrap_or_else(Name::missing))) .map(|it| it.display(db, Edition::LATEST).to_string()), ) .join("::")
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 575c77f..efbaad3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -41,6 +41,7 @@ fn run_(self) -> anyhow::Result<()> { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) =
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs index d68f7ab..0384993 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -191,6 +191,9 @@ /// Exclude code from vendored libraries from the resulting index. optional --exclude-vendored-libraries + + /// The number of worker threads for cache priming. Defaults to the number of physical cores. + optional --num-threads num_threads: usize } } } @@ -338,6 +341,7 @@ pub struct Scip { pub output: Option<PathBuf>, pub config_path: Option<PathBuf>, pub exclude_vendored_libraries: bool, + pub num_threads: Option<usize>, } impl RustAnalyzer {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs index e5e238d..3950a58 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
@@ -293,6 +293,7 @@ pub fn run( load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let path = AbsPathBuf::assert_utf8(env::current_dir()?.join(self.path));
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs index d5da679..beedcfa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs
@@ -38,6 +38,7 @@ pub fn run(self) -> anyhow::Result<()> { // we want to ensure that this command, not `load_workspace_at`, // is responsible for that work. prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: config.proc_macro_num_processes(), };
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs index d4a56d7..e8c88ca 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs
@@ -23,6 +23,7 @@ pub fn run(self) -> Result<()> { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) =
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index e8c6c5f..49f2835 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
@@ -103,6 +103,7 @@ fn new() -> Result<Self> { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) =
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs index ed04766..ef6d439 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -52,6 +52,7 @@ pub fn run(self) -> anyhow::Result<()> { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + num_worker_threads: self.num_threads.unwrap_or_else(num_cpus::get_physical), proc_macro_processes: config.proc_macro_num_processes(), }; let cargo_config = config.cargo(None);
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs index 6bc0792..7b00aeb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs
@@ -20,6 +20,7 @@ pub fn run(self) -> anyhow::Result<()> { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let (ref db, vfs, _proc_macro) = load_workspace_at( @@ -57,6 +58,7 @@ pub fn run(self) -> anyhow::Result<()> { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) = load_workspace_at(
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index 49c6fcb..2d9b870 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
@@ -44,6 +44,7 @@ fn run_(self) -> anyhow::Result<()> { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: config.proc_macro_num_processes(), }; let (db, vfs, _proc_macro) =
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 0dda7f3..2ccd85f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -948,18 +948,18 @@ pub enum MaxSubstitutionLength { /// Override the command used for bench runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically /// replace the package name, target option (such as `--bin` or `--example`), the target name and - /// the test name (name of test function or test mod path). + /// the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). runnables_bench_overrideCommand: Option<Vec<String>> = None, /// Command to be executed instead of 'cargo' for runnables. runnables_command: Option<String> = None, /// Override the command used for bench runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically /// replace the package name, target option (such as `--bin` or `--example`), the target name and - /// the test name (name of test function or test mod path). + /// the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). runnables_doctest_overrideCommand: Option<Vec<String>> = None, /// Additional arguments to be passed to cargo for runnables such as /// tests or binaries. For example, it may be `--release`. @@ -977,9 +977,9 @@ pub enum MaxSubstitutionLength { /// Override the command used for test runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically /// replace the package name, target option (such as `--bin` or `--example`), the target name and - /// the test name (name of test function or test mod path). + /// the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). runnables_test_overrideCommand: Option<Vec<String>> = None, /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index cdaf944..c41696b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
@@ -1021,7 +1021,7 @@ fn from_eof(&self) -> Option<CheckMessage> { } } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] #[serde(untagged)] enum JsonMessage { Cargo(cargo_metadata::Message),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 138310b..09b6794 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -295,8 +295,9 @@ pub(crate) fn handle_did_change_watched_files( for change in params.changes.iter().unique_by(|&it| &it.uri) { if let Ok(path) = from_proto::abs_path(&change.uri) { if !trigger_flycheck { + // Trigger if no workspaces contain this file. trigger_flycheck = - state.config.workspace_roots().iter().any(|root| !path.starts_with(root)); + state.config.workspace_roots().iter().all(|root| !path.starts_with(root)); } state.loader.handle.invalidate(path); }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index d16ca2f..6a74b8a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -53,6 +53,7 @@ fn integrated_highlighting_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + num_worker_threads: 1, proc_macro_processes: 1, }; @@ -122,6 +123,7 @@ fn integrated_completion_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + num_worker_threads: 1, proc_macro_processes: 1, }; @@ -324,6 +326,7 @@ fn integrated_diagnostics_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + num_worker_threads: 1, proc_macro_processes: 1, };
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 64decc9..7c494de 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -92,7 +92,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Event::DeferredTask(_) => write!(f, "Event::DeferredTask"), Event::TestResult(_) => write!(f, "Event::TestResult"), Event::DiscoverProject(_) => write!(f, "Event::DiscoverProject"), - Event::FetchWorkspaces(_) => write!(f, "Event::SwitchWorkspaces"), + Event::FetchWorkspaces(_) => write!(f, "Event::FetchWorkspaces"), } } } @@ -1178,6 +1178,8 @@ fn handle_flycheck_msg(&mut self, message: FlycheckMessage, cargo_finished: &mut } => self.diagnostics.clear_check_older_than_for_package(id, package_id, generation), FlycheckMessage::Progress { id, progress } => { let format_with_id = |user_facing_command: String| { + // When we're running multiple flychecks, we have to include a disambiguator in + // the title, or the editor complains. Note that this is a user-facing string. if self.flycheck.len() == 1 { user_facing_command } else {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index b8d9acc..8be061c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs
@@ -6,7 +6,7 @@ use cfg::{CfgAtom, CfgExpr}; use hir::sym; use ide::{Cancellable, Crate, FileId, RunnableKind, TestId}; -use project_model::project_json::Runnable; +use project_model::project_json::{self, Runnable}; use project_model::{CargoFeatures, ManifestPath, TargetKind}; use rustc_hash::FxHashSet; use triomphe::Arc; @@ -72,48 +72,51 @@ pub(crate) struct ProjectJsonTargetSpec { } impl ProjectJsonTargetSpec { + fn find_replace_runnable( + &self, + kind: project_json::RunnableKind, + replacer: &dyn Fn(&Self, &str) -> String, + ) -> Option<Runnable> { + for runnable in &self.shell_runnables { + if runnable.kind == kind { + let mut runnable = runnable.clone(); + + let replaced_args: Vec<_> = + runnable.args.iter().map(|arg| replacer(self, arg)).collect(); + runnable.args = replaced_args; + + return Some(runnable); + } + } + + None + } + pub(crate) fn runnable_args(&self, kind: &RunnableKind) -> Option<Runnable> { match kind { - RunnableKind::Bin => { - for runnable in &self.shell_runnables { - if matches!(runnable.kind, project_model::project_json::RunnableKind::Run) { - let mut runnable = runnable.clone(); - - let replaced_args: Vec<_> = runnable - .args - .iter() - .map(|arg| arg.replace("{label}", &self.label)) - .collect(); - runnable.args = replaced_args; - - return Some(runnable); - } - } - - None - } + RunnableKind::Bin => self + .find_replace_runnable(project_json::RunnableKind::Run, &|this, arg| { + arg.replace("{label}", &this.label) + }), RunnableKind::Test { test_id, .. } => { - for runnable in &self.shell_runnables { - if matches!(runnable.kind, project_model::project_json::RunnableKind::TestOne) { - let mut runnable = runnable.clone(); - - let replaced_args: Vec<_> = runnable - .args - .iter() - .map(|arg| arg.replace("{test_id}", &test_id.to_string())) - .map(|arg| arg.replace("{label}", &self.label)) - .collect(); - runnable.args = replaced_args; - - return Some(runnable); - } - } - - None + self.find_replace_runnable(project_json::RunnableKind::Run, &|this, arg| { + arg.replace("{label}", &this.label).replace("{test_id}", &test_id.to_string()) + }) } - RunnableKind::TestMod { .. } => None, - RunnableKind::Bench { .. } => None, - RunnableKind::DocTest { .. } => None, + RunnableKind::TestMod { path } => self + .find_replace_runnable(project_json::RunnableKind::TestMod, &|this, arg| { + arg.replace("{label}", &this.label).replace("{test_pattern}", path) + }), + RunnableKind::Bench { test_id } => { + self.find_replace_runnable(project_json::RunnableKind::BenchOne, &|this, arg| { + arg.replace("{label}", &this.label).replace("{bench_id}", &test_id.to_string()) + }) + } + RunnableKind::DocTest { test_id } => { + self.find_replace_runnable(project_json::RunnableKind::DocTestOne, &|this, arg| { + arg.replace("{label}", &this.label).replace("{test_id}", &test_id.to_string()) + }) + } } } } @@ -129,38 +132,21 @@ pub(crate) fn runnable_args( let extra_test_binary_args = config.extra_test_binary_args; let mut cargo_args = Vec::new(); - let mut executable_args = Vec::new(); + let executable_args = Self::executable_args_for(kind, extra_test_binary_args); match kind { - RunnableKind::Test { test_id, attr } => { + RunnableKind::Test { .. } => { cargo_args.push(config.test_command); - executable_args.push(test_id.to_string()); - if let TestId::Path(_) = test_id { - executable_args.push("--exact".to_owned()); - } - executable_args.extend(extra_test_binary_args); - if attr.ignore { - executable_args.push("--ignored".to_owned()); - } } - RunnableKind::TestMod { path } => { + RunnableKind::TestMod { .. } => { cargo_args.push(config.test_command); - executable_args.push(path.clone()); - executable_args.extend(extra_test_binary_args); } - RunnableKind::Bench { test_id } => { + RunnableKind::Bench { .. } => { cargo_args.push(config.bench_command); - executable_args.push(test_id.to_string()); - if let TestId::Path(_) = test_id { - executable_args.push("--exact".to_owned()); - } - executable_args.extend(extra_test_binary_args); } - RunnableKind::DocTest { test_id } => { + RunnableKind::DocTest { .. } => { cargo_args.push("test".to_owned()); cargo_args.push("--doc".to_owned()); - executable_args.push(test_id.to_string()); - executable_args.extend(extra_test_binary_args); } RunnableKind::Bin => { let subcommand = match spec { @@ -253,16 +239,70 @@ pub(crate) fn override_command( TargetKind::BuildScript | TargetKind::Other => "", }; + let target = |kind, target| match kind { + TargetKind::Bin | TargetKind::Test | TargetKind::Bench | TargetKind::Example => target, + _ => "", + }; + let replace_placeholders = |arg: String| match &spec { Some(spec) => arg .replace("${package}", &spec.package) .replace("${target_arg}", target_arg(spec.target_kind)) - .replace("${target}", &spec.target) + .replace("${target}", target(spec.target_kind, &spec.target)) .replace("${test_name}", &test_name), _ => arg, }; - args.map(|args| args.into_iter().map(replace_placeholders).collect()) + let extra_test_binary_args = config.extra_test_binary_args; + let executable_args = Self::executable_args_for(kind, extra_test_binary_args); + + args.map(|mut args| { + let exec_args_idx = args.iter().position(|a| a == "${executable_args}"); + + if let Some(idx) = exec_args_idx { + args.splice(idx..idx + 1, executable_args); + } + + args.into_iter().map(replace_placeholders).filter(|a| !a.trim().is_empty()).collect() + }) + } + + fn executable_args_for( + kind: &RunnableKind, + extra_test_binary_args: impl IntoIterator<Item = String>, + ) -> Vec<String> { + let mut executable_args = Vec::new(); + + match kind { + RunnableKind::Test { test_id, attr } => { + executable_args.push(test_id.to_string()); + if let TestId::Path(_) = test_id { + executable_args.push("--exact".to_owned()); + } + executable_args.extend(extra_test_binary_args); + if attr.ignore { + executable_args.push("--ignored".to_owned()); + } + } + RunnableKind::TestMod { path } => { + executable_args.push(path.clone()); + executable_args.extend(extra_test_binary_args); + } + RunnableKind::Bench { test_id } => { + executable_args.push(test_id.to_string()); + if let TestId::Path(_) = test_id { + executable_args.push("--exact".to_owned()); + } + executable_args.extend(extra_test_binary_args); + } + RunnableKind::DocTest { test_id } => { + executable_args.push(test_id.to_string()); + executable_args.extend(extra_test_binary_args); + } + RunnableKind::Bin => {} + } + + executable_args } pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index f52604e..f6500a9 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs
@@ -206,6 +206,11 @@ fn kind(self) -> u32 { self.0 >> (HASH_BITS + INDEX_BITS) } + #[inline] + pub fn is_root(self) -> bool { + self.kind() == ErasedFileAstIdKind::Root as u32 + } + fn ast_id_for( node: &SyntaxNode, index_map: &mut ErasedAstIdNextIndexMap, @@ -220,14 +225,16 @@ fn ast_id_for( .or_else(|| asm_expr_ast_id(node, index_map)) } - fn should_alloc(node: &SyntaxNode) -> bool { + fn should_alloc(node: &SyntaxNode) -> Option<ErasedFileAstIdKind> { let kind = node.kind(); should_alloc_has_name(kind) - || should_alloc_assoc_item(kind) - || ast::ExternBlock::can_cast(kind) - || ast::Use::can_cast(kind) - || ast::Impl::can_cast(kind) - || ast::AsmExpr::can_cast(kind) + .or_else(|| should_alloc_assoc_item(kind)) + .or_else(|| { + ast::ExternBlock::can_cast(kind).then_some(ErasedFileAstIdKind::ExternBlock) + }) + .or_else(|| ast::Use::can_cast(kind).then_some(ErasedFileAstIdKind::Use)) + .or_else(|| ast::Impl::can_cast(kind).then_some(ErasedFileAstIdKind::Impl)) + .or_else(|| ast::AsmExpr::can_cast(kind).then_some(ErasedFileAstIdKind::AsmExpr)) } #[inline] @@ -478,8 +485,8 @@ fn has_name_ast_id(node: &SyntaxNode, index_map: &mut ErasedAstIdNextIndexMap) - } } - fn should_alloc_has_name(kind: SyntaxKind) -> bool { - false $( || ast::$ident::can_cast(kind) )* + fn should_alloc_has_name(kind: SyntaxKind) -> Option<ErasedFileAstIdKind> { + $( if ast::$ident::can_cast(kind) { Some(ErasedFileAstIdKind::$ident) } else )* { None } } }; } @@ -528,8 +535,8 @@ fn assoc_item_ast_id( } } - fn should_alloc_assoc_item(kind: SyntaxKind) -> bool { - false $( || ast::$ident::can_cast(kind) )* + fn should_alloc_assoc_item(kind: SyntaxKind) -> Option<ErasedFileAstIdKind> { + $( if ast::$ident::can_cast(kind) { Some(ErasedFileAstIdKind::$ident) } else )* { None } } }; } @@ -612,22 +619,49 @@ pub fn from_source(node: &SyntaxNode) -> AstIdMap { syntax::WalkEvent::Enter(node) => { if ast::BlockExpr::can_cast(node.kind()) { blocks.push((node, ContainsItems::No)); - } else if ErasedFileAstId::should_alloc(&node) { + } else if let Some(kind) = ErasedFileAstId::should_alloc(&node) { // Allocate blocks on-demand, only if they have items. // We don't associate items with blocks, only with items, since block IDs can be quite unstable. // FIXME: Is this the correct thing to do? Macro calls might actually be more incremental if // associated with blocks (not sure). Either way it's not a big deal. + let is_item = matches!( + kind, + ErasedFileAstIdKind::Enum + | ErasedFileAstIdKind::Struct + | ErasedFileAstIdKind::Union + | ErasedFileAstIdKind::ExternCrate + | ErasedFileAstIdKind::MacroDef + | ErasedFileAstIdKind::MacroRules + | ErasedFileAstIdKind::Module + | ErasedFileAstIdKind::Static + | ErasedFileAstIdKind::Trait + | ErasedFileAstIdKind::Const + | ErasedFileAstIdKind::Fn + | ErasedFileAstIdKind::TypeAlias + | ErasedFileAstIdKind::ExternBlock + | ErasedFileAstIdKind::Use + | ErasedFileAstIdKind::Impl + ); if let Some(( last_block_node, already_allocated @ ContainsItems::No, )) = blocks.last_mut() + && (is_item + || (kind == ErasedFileAstIdKind::MacroCall && { + let mut anc = node.ancestors(); + _ = anc.next(); + anc.next().is_some_and(|it| { + it.kind() == SyntaxKind::MACRO_EXPR + }) && anc.next().is_some_and(|it| { + it.kind() == SyntaxKind::EXPR_STMT + || it.kind() == SyntaxKind::STMT_LIST + }) + })) { - let block_ast_id = block_expr_ast_id( - last_block_node, - &mut index_map, - parent_of(parent_idx, &res), - ) - .expect("not a BlockExpr"); + let parent = parent_of(parent_idx, &res); + let block_ast_id = + block_expr_ast_id(last_block_node, &mut index_map, parent) + .expect("not a BlockExpr"); res.arena .alloc((SyntaxNodePtr::new(last_block_node), block_ast_id)); *already_allocated = ContainsItems::Yes; @@ -645,8 +679,9 @@ pub fn from_source(node: &SyntaxNode) -> AstIdMap { } syntax::WalkEvent::Leave(node) => { if ast::BlockExpr::can_cast(node.kind()) { - assert_eq!( - blocks.pop().map(|it| it.0), + let block = blocks.pop(); + debug_assert_eq!( + block.map(|it| it.0), Some(node), "left a BlockExpr we never entered" );
diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 7ab26b1..275e0e5 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
@@ -1,5 +1,6 @@ //! Missing batteries for standard libraries. +use std::borrow::Cow; use std::io as sio; use std::process::Command; use std::{cmp::Ordering, ops, time::Instant}; @@ -221,12 +222,7 @@ pub fn trim_indent(mut text: &str) -> String { if text.starts_with('\n') { text = &text[1..]; } - let indent = text - .lines() - .filter(|it| !it.trim().is_empty()) - .map(|it| it.len() - it.trim_start().len()) - .min() - .unwrap_or(0); + let indent = indent_of(text); text.split_inclusive('\n') .map( |line| { @@ -236,6 +232,43 @@ pub fn trim_indent(mut text: &str) -> String { .collect() } +#[must_use] +fn indent_of(text: &str) -> usize { + text.lines() + .filter(|it| !it.trim().is_empty()) + .map(|it| it.len() - it.trim_start().len()) + .min() + .unwrap_or(0) +} + +#[must_use] +pub fn dedent_by(spaces: usize, text: &str) -> String { + text.split_inclusive('\n') + .map(|line| { + let trimmed = line.trim_start_matches(' '); + if line.len() - trimmed.len() <= spaces { trimmed } else { &line[spaces..] } + }) + .collect() +} + +/// Indent non empty lines, including the first line +#[must_use] +pub fn indent_string(s: &str, indent_level: u8) -> String { + if indent_level == 0 || s.is_empty() { + return s.to_owned(); + } + let indent_str = " ".repeat(indent_level as usize); + s.split_inclusive("\n") + .map(|line| { + if line.trim_end().is_empty() { + Cow::Borrowed(line) + } else { + format!("{indent_str}{line}").into() + } + }) + .collect() +} + pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize> where F: FnMut(&T) -> Ordering, @@ -367,6 +400,37 @@ fn main() { } #[test] + fn test_dedent() { + assert_eq!(dedent_by(0, ""), ""); + assert_eq!(dedent_by(1, ""), ""); + assert_eq!(dedent_by(2, ""), ""); + assert_eq!(dedent_by(0, "foo"), "foo"); + assert_eq!(dedent_by(2, "foo"), "foo"); + assert_eq!(dedent_by(2, " foo"), "foo"); + assert_eq!(dedent_by(2, " foo"), " foo"); + assert_eq!(dedent_by(2, " foo\nbar"), " foo\nbar"); + assert_eq!(dedent_by(2, "foo\n bar"), "foo\n bar"); + assert_eq!(dedent_by(2, "foo\n\n bar"), "foo\n\n bar"); + assert_eq!(dedent_by(2, "foo\n.\n bar"), "foo\n.\n bar"); + assert_eq!(dedent_by(2, "foo\n .\n bar"), "foo\n.\n bar"); + assert_eq!(dedent_by(2, "foo\n .\n bar"), "foo\n .\n bar"); + } + + #[test] + fn test_indent_of() { + assert_eq!(indent_of(""), 0); + assert_eq!(indent_of(" "), 0); + assert_eq!(indent_of(" x"), 1); + assert_eq!(indent_of(" x\n"), 1); + assert_eq!(indent_of(" x\ny"), 0); + assert_eq!(indent_of(" x\n y"), 1); + assert_eq!(indent_of(" x\n y"), 1); + assert_eq!(indent_of(" x\n y"), 2); + assert_eq!(indent_of(" x\n y\n"), 2); + assert_eq!(indent_of(" x\n\n y\n"), 2); + } + + #[test] fn test_replace() { #[track_caller] fn test_replace(src: &str, from: char, to: &str, expected: &str) {
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 5440534..3113fc7 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -245,7 +245,7 @@ RecordField = Attr* Visibility? 'unsafe'? - Name ':' Type ('=' Expr)? + Name ':' Type ('=' default_val:ConstArg)? TupleFieldList = '(' fields:(TupleField (',' TupleField)* ','?)? ')' @@ -268,7 +268,7 @@ Variant = Attr* Visibility? - Name FieldList? ('=' Expr)? + Name FieldList? ('=' ConstArg)? Union = Attr* Visibility?
diff --git a/src/tools/rust-analyzer/crates/syntax/src/algo.rs b/src/tools/rust-analyzer/crates/syntax/src/algo.rs index 3ab9c90..c679921 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/algo.rs
@@ -132,3 +132,19 @@ pub fn previous_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxTo } None } + +pub fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> { + let mut token = match e.into() { + SyntaxElement::Node(n) => n.last_token()?, + SyntaxElement::Token(t) => t, + } + .next_token(); + while let Some(inner) = token { + if !inner.kind().is_trivia() { + return Some(inner); + } else { + token = inner.next_token(); + } + } + None +}
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs index 9b30642..b706d7f 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
@@ -43,8 +43,14 @@ fn add(self, rhs: u8) -> IndentLevel { } } +impl ops::AddAssign<u8> for IndentLevel { + fn add_assign(&mut self, rhs: u8) { + self.0 += rhs; + } +} + impl IndentLevel { - pub fn single() -> IndentLevel { + pub fn zero() -> IndentLevel { IndentLevel(0) } pub fn is_zero(&self) -> bool {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs index 2b7dc5c..7f59ae4 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
@@ -591,7 +591,7 @@ pub fn add_item(&self, item: ast::AssocItem) { normalize_ws_between_braces(self.syntax()); (IndentLevel::from_token(&l_curly) + 1, ted::Position::after(&l_curly), "\n") } - None => (IndentLevel::single(), ted::Position::last_child_of(self.syntax()), "\n"), + None => (IndentLevel::zero(), ted::Position::last_child_of(self.syntax()), "\n"), }, }; let elements: Vec<SyntaxElement> = vec![
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index c4e72ea..7334de0 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -1337,7 +1337,7 @@ impl ast::HasName for RecordField {} impl ast::HasVisibility for RecordField {} impl RecordField { #[inline] - pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } + pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) } #[inline] pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } #[inline] @@ -1896,7 +1896,7 @@ impl ast::HasName for Variant {} impl ast::HasVisibility for Variant {} impl Variant { #[inline] - pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } + pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) } #[inline] pub fn field_list(&self) -> Option<FieldList> { support::child(&self.syntax) } #[inline]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index f5d1d00..0097156 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -74,10 +74,18 @@ pub fn expr_underscore() -> ast::Expr { expr_from_text("_") } pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr { - expr_from_text(&format!("{ty}::default()")) + if !ty.needs_angles_in_path() { + expr_from_text(&format!("{ty}::default()")) + } else { + expr_from_text(&format!("<{ty}>::default()")) + } } pub fn expr_ty_new(ty: &ast::Type) -> ast::Expr { - expr_from_text(&format!("{ty}::new()")) + if !ty.needs_angles_in_path() { + expr_from_text(&format!("{ty}::new()")) + } else { + expr_from_text(&format!("<{ty}>::new()")) + } } pub fn expr_self() -> ast::Expr { expr_from_text("self")
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 76cfea9..63e4608 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
@@ -717,6 +717,10 @@ pub fn generic_arg_list(&self) -> Option<ast::GenericArgList> { None } } + + pub fn needs_angles_in_path(&self) -> bool { + !matches!(self, ast::Type::PathType(_)) || self.generic_arg_list().is_some() + } } #[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 50fe565..44114a7 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -5,7 +5,7 @@ AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, ast::{ self, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, - HasTypeBounds, HasVisibility, Param, RangeItem, make, + HasTypeBounds, HasVisibility, Lifetime, Param, RangeItem, make, }, syntax_editor::SyntaxMappingBuilder, }; @@ -21,6 +21,18 @@ pub fn name_ref(&self, name: &str) -> ast::NameRef { make::name_ref(name).clone_for_update() } + pub fn name_ref_self_ty(&self) -> ast::NameRef { + make::name_ref_self_ty().clone_for_update() + } + + pub fn expr_todo(&self) -> ast::Expr { + make::ext::expr_todo().clone_for_update() + } + + pub fn expr_self(&self) -> ast::Expr { + make::ext::expr_self().clone_for_update() + } + pub fn lifetime(&self, text: &str) -> ast::Lifetime { make::lifetime(text).clone_for_update() } @@ -51,6 +63,26 @@ pub fn ty_path(&self, path: ast::Path) -> ast::PathType { ast } + pub fn type_bound(&self, bound: ast::Type) -> ast::TypeBound { + make::type_bound(bound).clone_for_update() + } + + pub fn type_bound_list( + &self, + bounds: impl IntoIterator<Item = ast::TypeBound>, + ) -> Option<ast::TypeBoundList> { + let (bounds, input) = iterator_input(bounds); + let ast = make::type_bound_list(bounds)?.clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.bounds().map(|b| b.syntax().clone())); + builder.finish(&mut mapping); + } + + Some(ast) + } + pub fn type_param( &self, name: ast::Name, @@ -96,24 +128,47 @@ pub fn struct_( generic_param_list: Option<ast::GenericParamList>, field_list: ast::FieldList, ) -> ast::Struct { - make::struct_(visibility, strukt_name, generic_param_list, field_list).clone_for_update() - } + let ast = make::struct_( + visibility.clone(), + strukt_name.clone(), + generic_param_list.clone(), + field_list.clone(), + ) + .clone_for_update(); - pub fn enum_( - &self, - attrs: impl IntoIterator<Item = ast::Attr>, - visibility: Option<ast::Visibility>, - enum_name: ast::Name, - generic_param_list: Option<ast::GenericParamList>, - where_clause: Option<ast::WhereClause>, - variant_list: ast::VariantList, - ) -> ast::Enum { - make::enum_(attrs, visibility, enum_name, generic_param_list, where_clause, variant_list) - .clone_for_update() + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(strukt_name.syntax().clone(), ast.name().unwrap().syntax().clone()); + if let Some(generic_param_list) = generic_param_list { + builder.map_node( + generic_param_list.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + builder + .map_node(field_list.syntax().clone(), ast.field_list().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast } pub fn unnamed_param(&self, ty: ast::Type) -> ast::Param { - make::unnamed_param(ty).clone_for_update() + let ast = make::unnamed_param(ty.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast } pub fn ty_fn_ptr<I: Iterator<Item = Param>>( @@ -123,7 +178,27 @@ pub fn ty_fn_ptr<I: Iterator<Item = Param>>( params: I, ret_type: Option<ast::RetType>, ) -> ast::FnPtrType { - make::ty_fn_ptr(is_unsafe, abi, params, ret_type).clone_for_update() + let (params, params_input) = iterator_input(params); + let ast = make::ty_fn_ptr(is_unsafe, abi.clone(), params.into_iter(), ret_type.clone()) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(abi) = abi { + builder.map_node(abi.syntax().clone(), ast.abi().unwrap().syntax().clone()); + } + builder.map_children( + params_input, + ast.param_list().unwrap().params().map(|p| p.syntax().clone()), + ); + if let Some(ret_type) = ret_type { + builder + .map_node(ret_type.syntax().clone(), ast.ret_type().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast } pub fn where_pred( @@ -131,18 +206,61 @@ pub fn where_pred( path: Either<ast::Lifetime, ast::Type>, bounds: impl IntoIterator<Item = ast::TypeBound>, ) -> ast::WherePred { - make::where_pred(path, bounds).clone_for_update() + let (bounds, bounds_input) = iterator_input(bounds); + let ast = make::where_pred(path.clone(), bounds).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + match &path { + Either::Left(lifetime) => { + builder.map_node( + lifetime.syntax().clone(), + ast.lifetime().unwrap().syntax().clone(), + ); + } + Either::Right(ty) => { + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + } + } + if let Some(type_bound_list) = ast.type_bound_list() { + builder.map_children( + bounds_input, + type_bound_list.bounds().map(|b| b.syntax().clone()), + ); + } + builder.finish(&mut mapping); + } + + ast } pub fn where_clause( &self, predicates: impl IntoIterator<Item = ast::WherePred>, ) -> ast::WhereClause { - make::where_clause(predicates).clone_for_update() + let (predicates, input) = iterator_input(predicates); + let ast = make::where_clause(predicates).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.predicates().map(|p| p.syntax().clone())); + builder.finish(&mut mapping); + } + + ast } pub fn impl_trait_type(&self, bounds: ast::TypeBoundList) -> ast::ImplTraitType { - make::impl_trait_type(bounds).clone_for_update() + let ast = make::impl_trait_type(bounds.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder + .map_node(bounds.syntax().clone(), ast.type_bound_list().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast } pub fn expr_field(&self, receiver: ast::Expr, field: &str) -> ast::FieldExpr { @@ -340,15 +458,53 @@ pub fn generic_ty_path_segment( name_ref: ast::NameRef, generic_args: impl IntoIterator<Item = ast::GenericArg>, ) -> ast::PathSegment { - make::generic_ty_path_segment(name_ref, generic_args).clone_for_update() + let (generic_args, input) = iterator_input(generic_args); + let ast = make::generic_ty_path_segment(name_ref.clone(), generic_args).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + builder.map_children( + input, + ast.generic_arg_list().unwrap().generic_args().map(|a| a.syntax().clone()), + ); + builder.finish(&mut mapping); + } + + ast } pub fn tail_only_block_expr(&self, tail_expr: ast::Expr) -> ast::BlockExpr { - make::tail_only_block_expr(tail_expr) + let ast = make::tail_only_block_expr(tail_expr.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let stmt_list = ast.stmt_list().unwrap(); + let mut builder = SyntaxMappingBuilder::new(stmt_list.syntax().clone()); + builder.map_node( + tail_expr.syntax().clone(), + stmt_list.tail_expr().unwrap().syntax().clone(), + ); + builder.finish(&mut mapping); + } + + ast } pub fn expr_bin_op(&self, lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr { - make::expr_bin_op(lhs, op, rhs) + let ast::Expr::BinExpr(ast) = + make::expr_bin_op(lhs.clone(), op, rhs.clone()).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(lhs.syntax().clone(), ast.lhs().unwrap().syntax().clone()); + builder.map_node(rhs.syntax().clone(), ast.rhs().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast.into() } pub fn ty_placeholder(&self) -> ast::Type { @@ -385,7 +541,23 @@ pub fn use_( visibility: Option<ast::Visibility>, use_tree: ast::UseTree, ) -> ast::Use { - make::use_(attrs, visibility, use_tree).clone_for_update() + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::use_(attrs, visibility.clone(), use_tree.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(use_tree.syntax().clone(), ast.use_tree().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast } pub fn use_tree( @@ -395,7 +567,25 @@ pub fn use_tree( alias: Option<ast::Rename>, add_star: bool, ) -> ast::UseTree { - make::use_tree(path, use_tree_list, alias, add_star).clone_for_update() + let ast = make::use_tree(path.clone(), use_tree_list.clone(), alias.clone(), add_star) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); + if let Some(use_tree_list) = use_tree_list { + builder.map_node( + use_tree_list.syntax().clone(), + ast.use_tree_list().unwrap().syntax().clone(), + ); + } + if let Some(alias) = alias { + builder.map_node(alias.syntax().clone(), ast.rename().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast } pub fn path_unqualified(&self, segment: ast::PathSegment) -> ast::Path { @@ -896,10 +1086,6 @@ pub fn expr_underscore(&self) -> ast::UnderscoreExpr { unreachable!() }; - if let Some(mut mapping) = self.mappings() { - SyntaxMappingBuilder::new(ast.syntax().clone()).finish(&mut mapping); - } - ast } @@ -1288,6 +1474,22 @@ pub fn record_expr( ast } + pub fn record_expr_field_list( + &self, + fields: impl IntoIterator<Item = ast::RecordExprField>, + ) -> ast::RecordExprFieldList { + let (fields, input) = iterator_input(fields); + let ast = make::record_expr_field_list(fields).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.fields().map(|f| f.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn record_expr_field( &self, name: ast::NameRef, @@ -1298,7 +1500,20 @@ pub fn record_expr_field( if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_node(name.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + if let Some(ast_name_ref) = ast.name_ref() { + // NameRef is a direct child + builder.map_node(name.syntax().clone(), ast_name_ref.syntax().clone()); + } else { + // NameRef is nested inside PathExpr > Path > PathSegment. + // map_node requires the output to be a direct child of the builder's parent, so + // we need a separate builder scoped to PathSegment. + let ast::Expr::PathExpr(path_expr) = ast.expr().unwrap() else { unreachable!() }; + let path_segment = path_expr.path().unwrap().segment().unwrap(); + let inner_name_ref = path_segment.name_ref().unwrap(); + let mut inner_builder = SyntaxMappingBuilder::new(path_segment.syntax().clone()); + inner_builder.map_node(name.syntax().clone(), inner_name_ref.syntax().clone()); + inner_builder.finish(&mut mapping); + } if let Some(expr) = expr { builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); } @@ -1503,8 +1718,10 @@ pub fn variant( } if let Some(discriminant) = discriminant { - builder - .map_node(discriminant.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.map_node( + discriminant.syntax().clone(), + ast.const_arg().unwrap().syntax().clone(), + ); } builder.finish(&mut mapping); @@ -1597,6 +1814,10 @@ pub fn assoc_item_list( ast } + pub fn assoc_item_list_empty(&self) -> ast::AssocItemList { + make::assoc_item_list(None).clone_for_update() + } + pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr { let ast = make::attr_outer(meta.clone()).clone_for_update(); @@ -1765,6 +1986,65 @@ pub fn ty_ref(&self, ty: ast::Type, is_mut: bool) -> ast::Type { } ast } + + pub fn field_from_idents<'a>( + &self, + parts: impl std::iter::IntoIterator<Item = &'a str>, + ) -> Option<ast::Expr> { + make::ext::field_from_idents(parts) + } + + pub fn expr_await(&self, expr: ast::Expr) -> ast::AwaitExpr { + let ast::Expr::AwaitExpr(ast) = make::expr_await(expr.clone()).clone_for_update() else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn expr_break(&self, label: Option<Lifetime>, expr: Option<ast::Expr>) -> ast::BreakExpr { + let ast::Expr::BreakExpr(ast) = + make::expr_break(label.clone(), expr.clone()).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(label) = label { + builder.map_node(label.syntax().clone(), ast.lifetime().unwrap().syntax().clone()); + } + if let Some(expr) = expr { + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn expr_continue(&self, label: Option<Lifetime>) -> ast::ContinueExpr { + let ast::Expr::ContinueExpr(ast) = make::expr_continue(label.clone()).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(label) = label { + builder.map_node(label.syntax().clone(), ast.lifetime().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } } // `ext` constructors
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs index ad08928..44f0a80 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
@@ -210,7 +210,7 @@ pub fn add_items(&self, editor: &mut SyntaxEditor, items: Vec<ast::AssocItem>) { normalize_ws_between_braces(editor, self.syntax()); (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly), "\n") } - None => (IndentLevel::single(), Position::last_child_of(self.syntax()), "\n"), + None => (IndentLevel::zero(), Position::last_child_of(self.syntax()), "\n"), }, }; @@ -242,7 +242,7 @@ pub fn add_variant(&self, editor: &mut SyntaxEditor, variant: &ast::Variant) { normalize_ws_between_braces(editor, self.syntax()); (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly)) } - None => (IndentLevel::single(), Position::last_child_of(self.syntax())), + None => (IndentLevel::zero(), Position::last_child_of(self.syntax())), }, }; let elements: Vec<SyntaxElement> = vec![
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index c34475b..86fb080 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -1503,6 +1503,19 @@ pub fn len(&self) -> usize { loop {} } } + + // region:default + impl<T> const Default for &[T] { + fn default() -> Self { + &[] + } + } + impl<T> const Default for &mut [T] { + fn default() -> Self { + &mut [] + } + } + // endregion:default } // endregion:slice
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 8460c2c..35fba5a 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
@@ -1380,9 +1380,9 @@ Override the command used for bench runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically replace the package name, target option (such as `--bin` or `--example`), the target name and -the test name (name of test function or test mod path). +the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). ## rust-analyzer.runnables.command {#runnables.command} @@ -1399,9 +1399,9 @@ Override the command used for bench runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically replace the package name, target option (such as `--bin` or `--example`), the target name and -the test name (name of test function or test mod path). +the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). ## rust-analyzer.runnables.extraArgs {#runnables.extraArgs} @@ -1444,9 +1444,9 @@ Override the command used for test runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically replace the package name, target option (such as `--bin` or `--example`), the target name and -the test name (name of test function or test mod path). +the arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`). ## rust-analyzer.rustc.source {#rustc.source}
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index be0bdc8..b51dc4d 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -738,9 +738,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -799,9 +799,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -1817,9 +1817,9 @@ ] }, "node_modules/@vscode/vsce/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -2060,9 +2060,9 @@ "license": "BSD-2-Clause" }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -3416,9 +3416,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -3697,9 +3697,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -3895,9 +3895,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4822,9 +4822,9 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -5463,9 +5463,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -6719,9 +6719,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", + "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", "dev": true, "license": "MIT", "engines": {
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index fc20597..1dd513c 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -2865,7 +2865,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.bench.overrideCommand": { - "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`).", "default": null, "type": [ "null", @@ -2894,7 +2894,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.doctest.overrideCommand": { - "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`).", "default": null, "type": [ "null", @@ -2948,7 +2948,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.test.overrideCommand": { - "markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", + "markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${executable_args}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe arguments passed to test binary args (includes `rust-analyzer.runnables.extraTestBinaryArgs`).", "default": null, "type": [ "null",
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index db94926..68f3871 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@ -eda4fc7733ee89e484d7120cafbd80dcb2fce66e +1174f784096deb8e4ba93f7e4b5ccb7bb4ba2c55
diff --git a/src/tools/rust-installer/Cargo.toml b/src/tools/rust-installer/Cargo.toml index cdd867c..0cb9fa7 100644 --- a/src/tools/rust-installer/Cargo.toml +++ b/src/tools/rust-installer/Cargo.toml
@@ -11,9 +11,9 @@ [dependencies] anyhow = "1.0.19" -flate2 = "1.0.1" +flate2 = { version = "1.1.9", default-features = false, features = ["zlib-rs"] } rayon = "1.0" -tar = "0.4.38" +tar = "0.4.45" walkdir = "2" xz2 = "0.1.4"
diff --git a/src/tools/rust-installer/install-template.sh b/src/tools/rust-installer/install-template.sh index c4f0c61..7079e29 100644 --- a/src/tools/rust-installer/install-template.sh +++ b/src/tools/rust-installer/install-template.sh
@@ -433,8 +433,8 @@ local _directive while read _directive; do - local _command=`echo $_directive | cut -f1 -d:` - local _file=`echo $_directive | cut -f2 -d:` + local _command="${_directive%%:*}" + local _file="${_directive#*:}" # Sanity checks if [ ! -n "$_command" ]; then critical_err "malformed installation directive"; fi @@ -541,8 +541,8 @@ local _directive while read _directive; do - local _command=`echo $_directive | cut -f1 -d:` - local _file=`echo $_directive | cut -f2 -d:` + local _command="${_directive%%:*}" + local _file="${_directive#*:}" # Sanity checks if [ ! -n "$_command" ]; then critical_err "malformed installation directive"; fi
diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs index 4741abb..50c0db8 100644 --- a/src/tools/rustfmt/src/matches.rs +++ b/src/tools/rustfmt/src/matches.rs
@@ -571,7 +571,7 @@ fn rewrite_match_body( // The `if ...` guard on a match arm. fn rewrite_guard( context: &RewriteContext<'_>, - guard: &Option<Box<ast::Expr>>, + guard: &Option<Box<ast::Guard>>, shape: Shape, // The amount of space used up on this line for the pattern in // the arm (excludes offset). @@ -586,7 +586,7 @@ fn rewrite_guard( .and_then(|s| s.sub_width_opt(5)); if !multiline_pattern { if let Some(cond_shape) = cond_shape { - if let Ok(cond_str) = guard.rewrite_result(context, cond_shape) { + if let Ok(cond_str) = guard.cond.rewrite_result(context, cond_shape) { if !cond_str.contains('\n') || pattern_width <= context.config.tab_spaces() { return Ok(format!(" if {cond_str}")); } @@ -597,9 +597,9 @@ fn rewrite_guard( // Not enough space to put the guard after the pattern, try a newline. // 3 = `if `, 5 = ` => {` let cond_shape = Shape::indented(shape.indent.block_indent(context.config), context.config) - .offset_left(3, guard.span)? - .sub_width(5, guard.span)?; - let cond_str = guard.rewrite_result(context, cond_shape)?; + .offset_left(3, guard.span())? + .sub_width(5, guard.span())?; + let cond_str = guard.cond.rewrite_result(context, cond_shape)?; Ok(format!( "{}if {}", cond_shape.indent.to_string_with_newline(context.config),
diff --git a/src/tools/rustfmt/src/vertical.rs b/src/tools/rustfmt/src/vertical.rs index 21e34d2..fd9a4a7 100644 --- a/src/tools/rustfmt/src/vertical.rs +++ b/src/tools/rustfmt/src/vertical.rs
@@ -198,7 +198,7 @@ fn struct_field_prefix_max_min_width<T: AlignedItem>( .rewrite_prefix(context, shape) .map(|field_str| trimmed_last_line_width(&field_str)) }) - .fold_ok((0, ::std::usize::MAX), |(max_len, min_len), len| { + .fold_ok((0, usize::MAX), |(max_len, min_len), len| { (cmp::max(max_len, len), cmp::min(min_len, len)) }) .unwrap_or((0, 0))
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 6048084..560d62e 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs
@@ -665,11 +665,11 @@ fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKin } // TODO(calebcartwright): consider enabling box_patterns feature gate - match (&ai.kind, visitor_kind) { - (ast::AssocItemKind::Const(c), AssocTraitItem) => { + match (&ai.kind, assoc_ctxt) { + (ast::AssocItemKind::Const(c), visit::AssocCtxt::Trait) => { self.visit_static(&StaticParts::from_trait_item(ai, c.ident)) } - (ast::AssocItemKind::Const(c), AssocImplItem) => { + (ast::AssocItemKind::Const(c), visit::AssocCtxt::Impl { .. }) => { self.visit_static(&StaticParts::from_impl_item(ai, c.ident)) } (ast::AssocItemKind::Fn(ref fn_kind), _) => { @@ -714,7 +714,11 @@ fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKin (ast::AssocItemKind::MacCall(ref mac), _) => { self.visit_mac(mac, MacroPosition::Item); } - _ => unreachable!(), + (ast::AssocItemKind::Delegation(_) | ast::AssocItemKind::DelegationMac(_), _) => { + // TODO(ytmimi) #![feature(fn_delegation)] + // add formatting for `AssocItemKind::Delegation` and `AssocItemKind::DelegationMac` + self.push_rewrite(ai.span, None); + } } }
diff --git a/src/tools/rustfmt/tests/target/issue_6513.rs b/src/tools/rustfmt/tests/target/issue_6513.rs new file mode 100644 index 0000000..827d4cc --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_6513.rs
@@ -0,0 +1,10 @@ +#![feature(fn_delegation)] + +struct Ty; +impl Ty { + reuse std::convert::identity; +} + +trait Trait { + reuse std::convert::identity; +}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 9e9d463..b0730de 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs
@@ -504,6 +504,7 @@ pub(crate) struct WorkspaceInfo<'a> { "zerotrie", "zerovec", "zerovec-derive", + "zlib-rs", // tidy-alphabetical-end ]; @@ -582,7 +583,7 @@ pub(crate) struct WorkspaceInfo<'a> { "cranelift-srcgen", "crc32fast", "equivalent", - "fallible-iterator", + "fnv", "foldhash", "gimli", "hashbrown", @@ -608,8 +609,8 @@ pub(crate) struct WorkspaceInfo<'a> { "syn", "target-lexicon", "unicode-ident", + "wasmtime-internal-core", "wasmtime-internal-jit-icache-coherence", - "wasmtime-internal-math", "windows-link", "windows-sys", "windows-targets",
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index f382502..3b23fe5 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt
@@ -117,7 +117,6 @@ ui/associated-types/issue-47139-1.rs ui/associated-types/issue-47139-2.rs ui/associated-types/issue-47385.rs -ui/associated-types/issue-47814.rs ui/associated-types/issue-48010.rs ui/associated-types/issue-48551.rs ui/associated-types/issue-50301.rs @@ -406,7 +405,6 @@ ui/closures/2229_closure_analysis/match/issue-87426.rs ui/closures/2229_closure_analysis/match/issue-87988.rs ui/closures/2229_closure_analysis/match/issue-88331.rs -ui/closures/2229_closure_analysis/migrations/issue-78720.rs ui/closures/2229_closure_analysis/migrations/issue-86753.rs ui/closures/2229_closure_analysis/migrations/issue-90024-adt-correct-subst.rs ui/closures/2229_closure_analysis/run_pass/issue-87378.rs @@ -1001,7 +999,6 @@ ui/fmt/issue-89173.rs ui/fmt/issue-91556.rs ui/fn/issue-1451.rs -ui/fn/issue-1900.rs ui/fn/issue-3044.rs ui/fn/issue-3099.rs ui/fn/issue-3904.rs
diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 6345cb8..b7b3855 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs
@@ -48,7 +48,7 @@ use crate::fmt_helpers::Hex; use crate::{UnicodeData, fmt_list}; -pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [(String, usize); 2]) { +pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [(String, usize); 3]) { let mut file = String::new(); file.push_str("\n\n"); @@ -59,7 +59,10 @@ file.push_str("\n\n"); let (upper_tables, upper_desc, upper_size) = generate_tables("UPPER", &data.to_upper); file.push_str(&upper_tables); - (file, [(lower_desc, lower_size), (upper_desc, upper_size)]) + file.push_str("\n\n"); + let (title_tables, title_desc, title_size) = generate_tables("TITLE", &data.to_title); + file.push_str(&title_tables); + (file, [(lower_desc, lower_size), (upper_desc, upper_size), (title_desc, title_size)]) } // So far, only planes 0 and 1 (Basic Multilingual Plane and Supplementary @@ -336,14 +339,10 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) } } -fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { - if input.is_ascii() { - return [ascii, '\0', '\0']; - } - +fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> { let (input_high, input_low) = deconstruct(input); let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else { - return [input, '\0', '\0']; + return None; }; let idx = l2_lut.singles.binary_search_by(|(range, _)| { @@ -357,6 +356,7 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { Ordering::Equal } }); + if let Ok(idx) = idx { // SAFETY: binary search guarantees that the index is in bounds. let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) }; @@ -365,7 +365,7 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { let output_low = input_low.wrapping_add_signed(output_delta); // SAFETY: Table data are guaranteed to be valid Unicode. let output = unsafe { reconstruct(input_high, output_low) }; - return [output, '\0', '\0']; + return Some([output, '\0', '\0']); } }; @@ -374,17 +374,36 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) }; // SAFETY: Table data are guaranteed to be valid Unicode. let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) }); - return output; + return Some(output); }; - [input, '\0', '\0'] + None } pub fn to_lower(c: char) -> [char; 3] { - lookup(c, c.to_ascii_lowercase(), &LOWERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Lowercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{C0}' { + return [c.to_ascii_lowercase(), '\0', '\0']; + } + + lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0']) } pub fn to_upper(c: char) -> [char; 3] { - lookup(c, c.to_ascii_uppercase(), &UPPERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Uppercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']) +} + +pub fn to_title(c: char) -> [char; 3] { + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Titlecased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0']) } ";
diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 4e7c40e..cdd137f 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs
@@ -100,32 +100,25 @@ struct UnicodeData { ranges: Vec<(&'static str, Vec<Range<u32>>)>, + /// Only stores mappings that are not to self to_upper: BTreeMap<u32, [u32; 3]>, + /// Only stores mappings that differ from `to_upper` + to_title: BTreeMap<u32, [u32; 3]>, + /// Only stores mappings that are not to self to_lower: BTreeMap<u32, [u32; 3]>, } -fn to_mapping(origin: u32, codepoints: Vec<ucd_parse::Codepoint>) -> Option<[u32; 3]> { - let mut a = None; - let mut b = None; - let mut c = None; - - for codepoint in codepoints { - if origin == codepoint.value() { - return None; - } - - if a.is_none() { - a = Some(codepoint.value()); - } else if b.is_none() { - b = Some(codepoint.value()); - } else if c.is_none() { - c = Some(codepoint.value()); - } else { - panic!("more than 3 mapped codepoints") - } +fn to_mapping( + if_different_from: &[ucd_parse::Codepoint], + codepoints: &[ucd_parse::Codepoint], +) -> Option<[u32; 3]> { + if codepoints == if_different_from { + return None; } - Some([a.unwrap(), b.unwrap_or(0), c.unwrap_or(0)]) + let mut ret = [ucd_parse::Codepoint::default(); 3]; + ret[0..codepoints.len()].copy_from_slice(codepoints); + Some(ret.map(ucd_parse::Codepoint::value)) } static UNICODE_DIRECTORY: &str = "unicode-downloads"; @@ -145,8 +138,7 @@ fn load_data() -> UnicodeData { } } - let mut to_lower = BTreeMap::new(); - let mut to_upper = BTreeMap::new(); + let [mut to_lower, mut to_upper, mut to_title] = [const { BTreeMap::new() }; 3]; for row in ucd_parse::UnicodeDataExpander::new( ucd_parse::parse::<_, ucd_parse::UnicodeData>(&UNICODE_DIRECTORY).unwrap(), ) { @@ -172,6 +164,11 @@ fn load_data() -> UnicodeData { { to_upper.insert(row.codepoint.value(), [mapped.value(), 0, 0]); } + if let Some(mapped) = row.simple_titlecase_mapping + && Some(mapped) != row.simple_uppercase_mapping + { + to_title.insert(row.codepoint.value(), [mapped.value(), 0, 0]); + } } for row in ucd_parse::parse::<_, ucd_parse::SpecialCaseMapping>(&UNICODE_DIRECTORY).unwrap() { @@ -181,12 +178,15 @@ fn load_data() -> UnicodeData { } let key = row.codepoint.value(); - if let Some(lower) = to_mapping(key, row.lowercase) { + if let Some(lower) = to_mapping(&[row.codepoint], &row.lowercase) { to_lower.insert(key, lower); } - if let Some(upper) = to_mapping(key, row.uppercase) { + if let Some(upper) = to_mapping(&[row.codepoint], &row.uppercase) { to_upper.insert(key, upper); } + if let Some(title) = to_mapping(&row.uppercase, &row.titlecase) { + to_title.insert(key, title); + } } // Filter out ASCII codepoints. @@ -207,7 +207,7 @@ fn load_data() -> UnicodeData { .collect(); properties.sort_by_key(|p| p.0); - UnicodeData { ranges: properties, to_lower, to_upper } + UnicodeData { ranges: properties, to_lower, to_title, to_upper } } fn main() { @@ -259,7 +259,7 @@ fn main() { total_bytes += emitter.bytes_used; } let (conversions, sizes) = case_mapping::generate_case_mapping(&unicode_data); - for (name, (desc, size)) in ["to_lower", "to_upper"].iter().zip(sizes) { + for (name, (desc, size)) in ["to_lower", "to_upper", "to_title"].iter().zip(sizes) { table_file.push_str(&format!("// {:16}: {:5} bytes, {desc}\n", name, size,)); total_bytes += size; } @@ -369,7 +369,11 @@ fn generate_tests(data: &UnicodeData) -> String { .unwrap(); } - for (name, lut) in ["TO_LOWER", "TO_UPPER"].iter().zip([&data.to_lower, &data.to_upper]) { + for (name, lut) in ["TO_LOWER", "TO_UPPER", "TO_TITLE"].iter().zip([ + &data.to_lower, + &data.to_upper, + &data.to_title, + ]) { let lut = lut .iter() .map(|(key, values)| {
diff --git a/tests/assembly-llvm/aarch64-arm-load-store.rs b/tests/assembly-llvm/aarch64-arm-load-store.rs new file mode 100644 index 0000000..8296194 --- /dev/null +++ b/tests/assembly-llvm/aarch64-arm-load-store.rs
@@ -0,0 +1,78 @@ +//@ assembly-output: emit-asm +// +//@ revisions: AARCH64 +//@[AARCH64] compile-flags: -Copt-level=3 +//@[AARCH64] only-aarch64-unknown-linux-gnu +// +//@ revisions: ARMV7 +//@[ARMV7] compile-flags: -Copt-level=3 +//@[ARMV7] only-armv7-unknown-linux-gnueabihf +//@[ARMV7] ignore-thumb +//@[ARMV7] ignore-android +#![crate_type = "lib"] +#![cfg_attr(target_arch = "arm", feature(arm_target_feature, stdarch_arm_neon_intrinsics))] + +#[cfg(target_arch = "aarch64")] +use std::arch::aarch64::*; +#[cfg(target_arch = "arm")] +use std::arch::arm::*; + +// Loads of 3 are error-prone because a `repr(simd)` type's size is always rounded up to the next +// power of 2. Hence, using `read_unaligned` and `write_unaligned` on such types is invalid, it +// would go out of bounds. +#[unsafe(no_mangle)] +#[cfg_attr(target_arch = "arm", target_feature(enable = "neon,v7"))] +fn test_vld3q_f32(ptr: *const f32) -> float32x4x3_t { + // AARCH64-LABEL: test_vld3q_f32 + // AARCH64: ld3 { v0.4s, v1.4s, v2.4s }, [x0] + // AARCH64: stp q0, q1, [x8] + // AARCH64: str q2, [x8, #32] + // AARCH64: ret + // + // ARMV7-LABEL: test_vld3q_f32 + // ARMV7: vld3.32 {d16, d18, d20}, [r1]! + // ARMV7: vld3.32 {d17, d19, d21}, [r1] + // ARMV7: vst1.32 {d16, d17}, [r0]! + // ARMV7: vst1.32 {d18, d19}, [r0]! + // ARMV7: vst1.64 {d20, d21}, [r0] + // ARMV7: bx lr + unsafe { vld3q_f32(ptr) } +} + +#[unsafe(no_mangle)] +#[cfg_attr(target_arch = "arm", target_feature(enable = "neon,v7"))] +fn test_vld3q_s32(ptr: *const i32) -> int32x4x3_t { + // AARCH64-LABEL: test_vld3q_s32 + // AARCH64: ld3 { v0.4s, v1.4s, v2.4s }, [x0] + // AARCH64: stp q0, q1, [x8] + // AARCH64: str q2, [x8, #32] + // AARCH64: ret + // + // ARMV7-LABEL: test_vld3q_s32 + // ARMV7: vld3.32 {d16, d18, d20}, [r1]! + // ARMV7: vld3.32 {d17, d19, d21}, [r1] + // ARMV7: vst1.32 {d16, d17}, [r0]! + // ARMV7: vst1.32 {d18, d19}, [r0]! + // ARMV7: vst1.64 {d20, d21}, [r0] + // ARMV7: bx lr + unsafe { vld3q_s32(ptr) } +} + +#[unsafe(no_mangle)] +#[cfg_attr(target_arch = "arm", target_feature(enable = "neon,v7"))] +fn test_vld3q_u32(ptr: *const u32) -> uint32x4x3_t { + // AARCH64-LABEL: test_vld3q_u32 + // AARCH64: ld3 { v0.4s, v1.4s, v2.4s }, [x0] + // AARCH64: stp q0, q1, [x8] + // AARCH64: str q2, [x8, #32] + // AARCH64: ret + // + // ARMV7-LABEL: test_vld3q_u32 + // ARMV7: vld3.32 {d16, d18, d20}, [r1]! + // ARMV7: vld3.32 {d17, d19, d21}, [r1] + // ARMV7: vst1.32 {d16, d17}, [r0]! + // ARMV7: vst1.32 {d18, d19}, [r0]! + // ARMV7: vst1.64 {d20, d21}, [r0] + // ARMV7: bx lr + unsafe { vld3q_u32(ptr) } +}
diff --git a/tests/assembly-llvm/bpf_unaligned.rs b/tests/assembly-llvm/bpf_unaligned.rs new file mode 100644 index 0000000..466c3e4 --- /dev/null +++ b/tests/assembly-llvm/bpf_unaligned.rs
@@ -0,0 +1,27 @@ +//@ add-minicore +//@ assembly-output: emit-asm +//@ compile-flags: --target bpfel-unknown-none -C target_feature=+allows-misaligned-mem-access +//@ min-llvm-version: 22 +//@ needs-llvm-components: bpf +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +// CHECK-LABEL: test_load_i64: +// CHECK: r0 = *(u64 *)(r1 + 0) +#[no_mangle] +pub unsafe fn test_load_i64(p: *const u64) -> u64 { + let mut tmp: u64 = 0; + copy_nonoverlapping(p as *const u8, &mut tmp as *mut u64 as *mut u8, 8); + tmp +} + +// CHECK-LABEL: test_store_i64: +// CHECK: *(u64 *)(r1 + 0) = r2 +#[no_mangle] +pub unsafe fn test_store_i64(p: *mut u64, v: u64) { + copy_nonoverlapping(&v as *const u64 as *const u8, p as *mut u8, 8); +}
diff --git a/tests/assembly-llvm/s390x-packedstack-toggle.rs b/tests/assembly-llvm/s390x-packedstack-toggle.rs new file mode 100644 index 0000000..d53f98b --- /dev/null +++ b/tests/assembly-llvm/s390x-packedstack-toggle.rs
@@ -0,0 +1,37 @@ +//@ add-minicore +//@ revisions: enable-packedstack default-packedstack +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-linux-gnu -Cforce-unwind-tables=no +//@ needs-llvm-components: systemz +//@[enable-packedstack] compile-flags: -Zpacked-stack +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extern_func() -> i32; +} + +// CHECK-LABEL: test_packedstack +#[no_mangle] +extern "C" fn test_packedstack() -> i32 { + // test the creation of call stack with and without packed-stack + + // without packed-stack we always reserve a least the maximal space of 160 bytes + // default-packedstack: stmg %r14, %r15, 112(%r15) + // default-packedstack-NEXT: aghi %r15, -160 + // default-packedstack-NEXT: brasl %r14, extern_func + + // with packed-stack only the actually needed registers are reserved on the stack + // enable-packedstack: stmg %r14, %r15, 144(%r15) + // enable-packedstack-NEXT: aghi %r15, -16 + // enable-packedstack-NEXT: brasl %r14, extern_func + unsafe { + extern_func(); + } + 1 + // CHECK: br %r{{.*}} +}
diff --git a/tests/assembly-llvm/sanitizer/hwasan-vs-khwasan.rs b/tests/assembly-llvm/sanitizer/hwasan-vs-khwasan.rs new file mode 100644 index 0000000..a4362b3 --- /dev/null +++ b/tests/assembly-llvm/sanitizer/hwasan-vs-khwasan.rs
@@ -0,0 +1,31 @@ +// Verifies that HWASAN and KHWASAN emit different assembly instrumentation on AArch64. +// +//@ add-minicore +//@ assembly-output: emit-asm +//@ revisions: hwasan khwasan +//@[hwasan] compile-flags: --target aarch64-unknown-linux-gnu -Zsanitizer=hwaddress +//@[hwasan] needs-llvm-components: aarch64 +//@[khwasan] compile-flags: --target aarch64-unknown-none -Zsanitizer=kernel-hwaddress +//@[khwasan] needs-llvm-components: aarch64 +//@ compile-flags: -Copt-level=1 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; + +// hwasan-LABEL: test: +// hwasan: adrp x{{[0-9]+}}, :gottprel:__hwasan_tls +// hwasan: mrs x{{[0-9]+}}, TPIDR_EL0 +// hwasan: bl __hwasan_check_x0_0_short_v2 + +// khwasan-LABEL: test: +// khwasan-NOT: __hwasan_tls +// khwasan: orr x{{[0-9]+}}, x0, #0xff00000000000000 +// khwasan: bl __hwasan_check_x0_67043328_fixed_0_short_v2 + +#[no_mangle] +pub fn test(b: &mut u8) -> u8 { + *b +}
diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index b7deb66..ce6629b 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs
@@ -709,6 +709,12 @@ //@ revisions: x86_64_unknown_linux_gnuasan //@ [x86_64_unknown_linux_gnuasan] compile-flags: --target x86_64-unknown-linux-gnuasan //@ [x86_64_unknown_linux_gnuasan] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_linux_gnumsan +//@ [x86_64_unknown_linux_gnumsan] compile-flags: --target x86_64-unknown-linux-gnumsan +//@ [x86_64_unknown_linux_gnumsan] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_linux_gnutsan +//@ [x86_64_unknown_linux_gnutsan] compile-flags: --target x86_64-unknown-linux-gnutsan +//@ [x86_64_unknown_linux_gnutsan] needs-llvm-components: x86 //@ revisions: x86_64_unknown_linux_musl //@ [x86_64_unknown_linux_musl] compile-flags: --target x86_64-unknown-linux-musl //@ [x86_64_unknown_linux_musl] needs-llvm-components: x86
diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index c91c5df..d84357e 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs
@@ -238,6 +238,8 @@ pub trait Sync {} impl Sync for () {} +impl<T, const N: usize> Sync for [T; N] {} + #[lang = "drop_in_place"] fn drop_in_place<T>(_: *mut T) {} @@ -277,6 +279,10 @@ trait Drop { fn drop(&mut self); } +#[rustc_nounwind] +#[rustc_intrinsic] +pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); + pub mod mem { #[rustc_nounwind] #[rustc_intrinsic]
diff --git a/tests/codegen-llvm/array-cmp.rs b/tests/codegen-llvm/array-cmp.rs index 0d33765..0106b9c 100644 --- a/tests/codegen-llvm/array-cmp.rs +++ b/tests/codegen-llvm/array-cmp.rs
@@ -39,16 +39,6 @@ pub fn compare() -> bool { // CHECK: %[[EQ00:.+]] = icmp eq i16 %[[A00]], %[[B00]] // CHECK-NEXT: br i1 %[[EQ00]], label %[[L01:.+]], label %[[EXIT_S:.+]] - // CHECK: [[L01]]: - // CHECK: %[[PA01:.+]] = getelementptr{{.+}}i8, ptr %a, {{i32|i64}} 2 - // CHECK: %[[PB01:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|i64}} 2 - // CHECK: %[[A01:.+]] = load i16, ptr %[[PA01]] - // CHECK: %[[B01:.+]] = load i16, ptr %[[PB01]] - // CHECK-NOT: cmp - // CHECK: %[[EQ01:.+]] = icmp eq i16 %[[A01]], %[[B01]] - // CHECK-NEXT: br i1 %[[EQ01]], label %[[L10:.+]], label %[[EXIT_U:.+]] - - // CHECK: [[L10]]: // CHECK: %[[PA10:.+]] = getelementptr{{.+}}i8, ptr %a, {{i32|i64}} 4 // CHECK: %[[PB10:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|i64}} 4 // CHECK: %[[A10:.+]] = load i16, ptr %[[PA10]] @@ -64,7 +54,16 @@ pub fn compare() -> bool { // CHECK: %[[B11:.+]] = load i16, ptr %[[PB11]] // CHECK-NOT: cmp // CHECK: %[[EQ11:.+]] = icmp eq i16 %[[A11]], %[[B11]] - // CHECK-NEXT: br i1 %[[EQ11]], label %[[DONE:.+]], label %[[EXIT_U]] + // CHECK-NEXT: br i1 %[[EQ11]], label %[[DONE:.+]], label %[[EXIT_U:.+]] + + // CHECK: [[L01]]: + // CHECK: %[[PA01:.+]] = getelementptr{{.+}}i8, ptr %a, {{i32|i64}} 2 + // CHECK: %[[PB01:.+]] = getelementptr{{.+}}i8, ptr %b, {{i32|i64}} 2 + // CHECK: %[[A01:.+]] = load i16, ptr %[[PA01]] + // CHECK: %[[B01:.+]] = load i16, ptr %[[PB01]] + // CHECK-NOT: cmp + // CHECK: %[[EQ01:.+]] = icmp eq i16 %[[A01]], %[[B01]] + // CHECK-NEXT: br i1 %[[EQ01]], label %{{.+}}, label %[[EXIT_U]] // CHECK: [[DONE]]: // CHECK: %[[RET:.+]] = phi i1 [ %{{.+}}, %[[EXIT_S]] ], [ %{{.+}}, %[[EXIT_U]] ], [ true, %[[L11]] ]
diff --git a/tests/codegen-llvm/bpf-allows-unaligned.rs b/tests/codegen-llvm/bpf-allows-unaligned.rs new file mode 100644 index 0000000..c7a70d5 --- /dev/null +++ b/tests/codegen-llvm/bpf-allows-unaligned.rs
@@ -0,0 +1,11 @@ +//@ only-bpf +#![crate_type = "lib"] +#![feature(bpf_target_feature)] +#![no_std] + +#[no_mangle] +#[target_feature(enable = "allows-misaligned-mem-access")] +// CHECK: define noundef zeroext i8 @foo(i8 noundef returned %arg) unnamed_addr #0 { +pub unsafe fn foo(arg: u8) -> u8 { + arg +}
diff --git a/tests/codegen-llvm/double_panic_wasm.rs b/tests/codegen-llvm/double_panic_wasm.rs deleted file mode 100644 index 1eafe60..0000000 --- a/tests/codegen-llvm/double_panic_wasm.rs +++ /dev/null
@@ -1,34 +0,0 @@ -//@ compile-flags: -C panic=unwind -Copt-level=0 -//@ needs-unwind -//@ only-wasm32 - -#![crate_type = "lib"] - -// Test that `panic_in_cleanup` is called on webassembly targets when a panic -// occurs in a destructor during unwinding. - -extern "Rust" { - fn may_panic(); -} - -struct PanicOnDrop; - -impl Drop for PanicOnDrop { - fn drop(&mut self) { - unsafe { may_panic() } - } -} - -// CHECK-LABEL: @double_panic -// CHECK: invoke void @may_panic() -// CHECK: invoke void @{{.+}}drop_in_place{{.+}} -// CHECK: unwind label %[[TERMINATE:.*]] -// -// CHECK: [[TERMINATE]]: -// CHECK: call void @{{.*panic_in_cleanup}} -// CHECK: unreachable -#[no_mangle] -pub fn double_panic() { - let _guard = PanicOnDrop; - unsafe { may_panic() } -}
diff --git a/tests/codegen-llvm/fromrangeiter-overflow-checks.rs b/tests/codegen-llvm/fromrangeiter-overflow-checks.rs index 4d27f11..8662a64 100644 --- a/tests/codegen-llvm/fromrangeiter-overflow-checks.rs +++ b/tests/codegen-llvm/fromrangeiter-overflow-checks.rs
@@ -2,7 +2,7 @@ // runtime check that panics after yielding the maximum value of the range bound type. That is // tested for by tests/ui/iterators/rangefrom-overflow-overflow-checks.rs // -// This test ensures that such a runtime check is *not* emitted when debug-assertions are +// This test ensures such runtime checks are optimized out when debug-assertions are // enabled, but overflow-checks are explicitly disabled. //@ revisions: DEBUG NOCHECKS @@ -11,17 +11,26 @@ #![crate_type = "lib"] #![feature(new_range_api)] -use std::range::{RangeFrom, RangeFromIter}; +#![feature(new_range_remainder)] -// CHECK-LABEL: @iterrangefrom_remainder( +use std::range::RangeFrom; + +// CHECK-LABEL: @rangefrom_increments( #[no_mangle] -pub unsafe fn iterrangefrom_remainder(x: RangeFromIter<i32>) -> RangeFrom<i32> { - // DEBUG: i32 noundef %x - // NOCHECKS: i32 noundef returned %x - // DEBUG: br i1 - // DEBUG: call core::panicking::panic_const::panic_const_add_overflow - // DEBUG: unreachable - // NOCHECKS-NOT: unreachable - // NOCHECKS: ret i32 %x - x.remainder() +pub unsafe fn rangefrom_increments(range: RangeFrom<i32>) -> RangeFrom<i32> { + // Iterator is contained entirely within this function, so the optimizer should + // be able to see that `exhausted` is never set and optimize out any branches. + + // CHECK: i32 noundef {{(signext )?}}%range + // DEBUG: switch i32 %range + // DEBUG: call core::panicking::panic_const::panic_const_add_overflow + // DEBUG: unreachable + // NOCHECKS-NOT: unreachable + // NOCHECKS: [[REM:%[a-z_0-9.]+]] = add i32 %range, 2 + // NOCHECKS-NEXT: ret i32 [[REM]] + + let mut iter = range.into_iter(); + let _ = iter.next(); + let _ = iter.next(); + iter.remainder() }
diff --git a/tests/codegen-llvm/packedstack.rs b/tests/codegen-llvm/packedstack.rs new file mode 100644 index 0000000..11a01e6 --- /dev/null +++ b/tests/codegen-llvm/packedstack.rs
@@ -0,0 +1,18 @@ +//@ add-minicore +//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-none-softfloat -Zpacked-stack +//@ needs-llvm-components: systemz +#![feature(s390x_target_feature)] +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] + +pub fn test_packedstack() { + // CHECK: @test_packedstack() unnamed_addr #0 +} + +// CHECK: attributes #0 = { {{.*}}"packed-stack"{{.*}} }
diff --git a/tests/codegen-llvm/sanitizer/hwasan-vs-khwasan.rs b/tests/codegen-llvm/sanitizer/hwasan-vs-khwasan.rs new file mode 100644 index 0000000..93932d8 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/hwasan-vs-khwasan.rs
@@ -0,0 +1,39 @@ +// Verifies that HWASAN and KHWASAN emit different instrumentation. +// +//@ add-minicore +//@ revisions: hwasan khwasan +//@[hwasan] compile-flags: --target aarch64-unknown-linux-gnu -Zsanitizer=hwaddress +//@[hwasan] needs-llvm-components: aarch64 +//@[khwasan] compile-flags: --target aarch64-unknown-none -Zsanitizer=kernel-hwaddress +//@[khwasan] needs-llvm-components: aarch64 +//@ compile-flags: -Copt-level=0 + +#![crate_type = "lib"] +#![feature(no_core, lang_items, sanitize)] +#![no_core] + +extern crate minicore; + +// hwasan-LABEL: define {{.*}} @test +// hwasan: @__hwasan_tls +// hwasan: call void @llvm.hwasan.check.memaccess.shortgranules +// hwasan: declare void @__hwasan_init() + +// The `__hwasan_tls` symbol is unconditionally declared by LLVM's `HWAddressSanitizer` pass. +// However, in kernel mode KHWASAN does not actually use it (because shadow mapping is fixed +// and the stack frame ring buffer is disabled). It remains an unused declaration in the LLVM IR +// and is optimized out before the final assembly/object file is generated, so it does not end +// up in the final binary. Thus, assert that it appears in the output, but not inside `test`. +// +// khwasan: @__hwasan_tls +// khwasan-LABEL: define {{.*}} @test +// khwasan-NOT: @__hwasan_tls +// +// Also test a few other things appear under the LABEL. +// +// khwasan-NOT: @__hwasan_init +// khwasan: call void @llvm.hwasan.check.memaccess.shortgranules +#[no_mangle] +pub fn test(b: &mut u8) -> u8 { + *b +}
diff --git a/tests/codegen-llvm/sanitizer/kasan-recover.rs b/tests/codegen-llvm/sanitizer/kasan-recover.rs new file mode 100644 index 0000000..f0f9180 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/kasan-recover.rs
@@ -0,0 +1,31 @@ +// Verifies that KernelAddressSanitizer recovery mode can be enabled +// with -Zsanitizer-recover=kernel-address. +// +//@ add-minicore +//@ revisions: KASAN KASAN-RECOVER +//@ compile-flags: -Copt-level=0 +//@ needs-llvm-components: x86 +//@ compile-flags: -Zsanitizer=kernel-address --target x86_64-unknown-none +//@[KASAN-RECOVER] compile-flags: -Zsanitizer-recover=kernel-address + +#![feature(no_core, sanitize, lang_items)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// KASAN-LABEL: define{{.*}}@penguin( +// KASAN: call void @__asan_report_load4( +// KASAN: unreachable +// KASAN: } + +// KASAN-RECOVER-LABEL: define{{.*}}@penguin( +// KASAN-RECOVER: call void @__asan_report_load4_noabort( +// KASAN-RECOVER-NOT: unreachable +// KASAN-RECOVER: } + +#[no_mangle] +pub unsafe fn penguin(p: *mut i32) -> i32 { + *p +}
diff --git a/tests/codegen-llvm/sanitizer/khwasan-lifetime-markers.rs b/tests/codegen-llvm/sanitizer/khwasan-lifetime-markers.rs new file mode 100644 index 0000000..26dc798 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/khwasan-lifetime-markers.rs
@@ -0,0 +1,20 @@ +// Verifies that `-Zsanitizer=kernel-hwaddress` enables lifetime markers. + +//@ add-minicore +//@ compile-flags: -Zsanitizer=kernel-hwaddress -Copt-level=0 +//@ compile-flags: --target aarch64-unknown-none +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// CHECK-LABEL: ; khwasan_lifetime_markers::test +// CHECK: call void @llvm.lifetime.start +// CHECK: call void @llvm.lifetime.end +pub fn test() { + let _x = [0u8; 10]; +}
diff --git a/tests/codegen-llvm/sanitizer/khwasan-recover.rs b/tests/codegen-llvm/sanitizer/khwasan-recover.rs new file mode 100644 index 0000000..452a0f5 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/khwasan-recover.rs
@@ -0,0 +1,34 @@ +// Verifies that KernelHWAddressSanitizer recovery mode can be enabled +// with -Zsanitizer-recover=kernel-hwaddress. +// +//@ add-minicore +//@ needs-llvm-components: aarch64 +//@ revisions: KHWASAN KHWASAN-RECOVER +//@ no-prefer-dynamic +//@ compile-flags: -Copt-level=0 +//@ compile-flags: -Zsanitizer=kernel-hwaddress --target aarch64-unknown-none +//@[KHWASAN-RECOVER] compile-flags: -Zsanitizer-recover=kernel-hwaddress + +#![feature(no_core, sanitize, lang_items)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// KHWASAN-LABEL: define{{.*}}@penguin( +// KHWASAN: call void @llvm.hwasan.check.memaccess +// KHWASAN: ret i32 +// KHWASAN: } +// KHWASAN: declare void @__hwasan_load4(i64) + +// KHWASAN-RECOVER-LABEL: define{{.*}}@penguin( +// KHWASAN-RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %{{[0-9]+}}) +// KHWASAN-RECOVER-NOT: unreachable +// KHWASAN-RECOVER: } +// KHWASAN-RECOVER: declare void @__hwasan_load4_noabort(i64) + +#[no_mangle] +pub unsafe fn penguin(p: *mut i32) -> i32 { + *p +}
diff --git a/tests/codegen-llvm/sanitizer/sanitize-off-hwasan-khwasan.rs b/tests/codegen-llvm/sanitizer/sanitize-off-hwasan-khwasan.rs new file mode 100644 index 0000000..313f480 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/sanitize-off-hwasan-khwasan.rs
@@ -0,0 +1,35 @@ +// Verifies that the `#[sanitize(hwaddress = "off")]` attribute also turns off +// the kernel hardware-assisted address sanitizer. +// +//@ add-minicore +//@ compile-flags: -Zsanitizer=kernel-hwaddress --target aarch64-unknown-none +//@ compile-flags: -Ctarget-feature=-crt-static -Copt-level=0 +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, sanitize, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// CHECK-NOT: sanitize_hwaddress +// CHECK-LABEL: define {{.*}} @unsanitized +// CHECK: start: +// CHECK-NOT: call void @llvm.hwasan.check.memaccess +// CHECK: } +#[sanitize(hwaddress = "off")] +#[no_mangle] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK: sanitize_hwaddress +// CHECK-LABEL: define {{.*}} @sanitized +// CHECK: start: +// CHECK: call void @llvm.hwasan.check.memaccess +// CHECK: } +#[no_mangle] +pub fn sanitized(b: &mut u8) -> u8 { + *b +}
diff --git a/tests/codegen-llvm/sanitizer/sanitize-off-khwasan-hwasan.rs b/tests/codegen-llvm/sanitizer/sanitize-off-khwasan-hwasan.rs new file mode 100644 index 0000000..a4491eb --- /dev/null +++ b/tests/codegen-llvm/sanitizer/sanitize-off-khwasan-hwasan.rs
@@ -0,0 +1,31 @@ +// Verifies that the `#[sanitize(kernel_hwaddress = "off")]` attribute also turns off +// the hardware-assisted address sanitizer. +// +//@ needs-sanitizer-hwaddress +//@ compile-flags: -Cunsafe-allow-abi-mismatch=sanitizer +//@ compile-flags: -Ctarget-feature=-crt-static +//@ compile-flags: -Zsanitizer=hwaddress -Copt-level=0 + +#![crate_type = "lib"] +#![feature(sanitize)] + +// CHECK-NOT: sanitize_hwaddress +// CHECK-LABEL: define {{.*}} @unsanitized +// CHECK: start: +// CHECK-NOT: call void @llvm.hwasan.check.memaccess +// CHECK: } +#[sanitize(kernel_hwaddress = "off")] +#[no_mangle] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK: sanitize_hwaddress +// CHECK-LABEL: define {{.*}} @sanitized +// CHECK: start: +// CHECK: call void @llvm.hwasan.check.memaccess +// CHECK: } +#[no_mangle] +pub fn sanitized(b: &mut u8) -> u8 { + *b +}
diff --git a/tests/codegen-llvm/sanitizer/sanitizer-recover.rs b/tests/codegen-llvm/sanitizer/sanitizer-recover.rs index b8a24e3..5e05b92 100644 --- a/tests/codegen-llvm/sanitizer/sanitizer-recover.rs +++ b/tests/codegen-llvm/sanitizer/sanitizer-recover.rs
@@ -5,7 +5,7 @@ //@ needs-sanitizer-memory //@ revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER MSAN-RECOVER-LTO //@ no-prefer-dynamic -//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer +//@ compile-flags: -Cunsafe-allow-abi-mismatch=sanitizer //@ compile-flags: -Ctarget-feature=-crt-static //@[ASAN] compile-flags: -Zsanitizer=address -Copt-level=0 //@[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -Copt-level=0
diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs index 8dd464a..94f7e16 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs
@@ -8,18 +8,18 @@ mod minisimd; use minisimd::*; -use std::intrinsics::simd::{simd_fmax, simd_fmin}; +use std::intrinsics::simd::*; // CHECK-LABEL: @fmin #[no_mangle] pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.minnum.v4f32 - simd_fmin(a, b) + // CHECK: call nsz <4 x float> @llvm.minimumnum.v4f32 + simd_minimum_number_nsz(a, b) } // CHECK-LABEL: @fmax #[no_mangle] pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.maxnum.v4f32 - simd_fmax(a, b) + // CHECK: call nsz <4 x float> @llvm.maximumnum.v4f32 + simd_maximum_number_nsz(a, b) }
diff --git a/tests/codegen-llvm/terminating-catchpad.rs b/tests/codegen-llvm/terminating-catchpad.rs index 7c98ea9..a2ec198 100644 --- a/tests/codegen-llvm/terminating-catchpad.rs +++ b/tests/codegen-llvm/terminating-catchpad.rs
@@ -9,10 +9,6 @@ // Ensure a catch-all generates: // - `catchpad ... [ptr null]` on Wasm (otherwise LLVM gets confused) // - `catchpad ... [ptr null, i32 64, ptr null]` on Windows (otherwise we catch SEH exceptions) -// -// Unlike on windows, on Wasm, we specifically do want to catch foreign -// exceptions. To catch only C++ exceptions we'd need to call -// @llvm.wasm.get.exception and @llvm.wasm.get.ehselector in the catchpad. #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "lib"] @@ -40,14 +36,8 @@ fn panic_cannot_unwind() -> ! { #[no_mangle] #[rustc_nounwind] pub fn doesnt_unwind() { - // CHECK: catchswitch within none [label %{{.*}}] unwind to caller // emscripten: %catchpad = catchpad within %catchswitch [ptr null] // wasi: %catchpad = catchpad within %catchswitch [ptr null] // seh: %catchpad = catchpad within %catchswitch [ptr null, i32 64, ptr null] - // - // We don't call these intrinsics on wasm targets so we generate a catch_all - // instruction which also picks up foreign exceptions - // NOT: @llvm.wasm.get.exception - // NOT: @llvm.wasm.get.ehselector unwinds(); }
diff --git a/tests/crashes/120033.rs b/tests/crashes/120033.rs deleted file mode 100644 index 7584f98..0000000 --- a/tests/crashes/120033.rs +++ /dev/null
@@ -1,16 +0,0 @@ -//@ known-bug: #120033 -#![feature(non_lifetime_binders)] -#![allow(sized_hierarchy_migration)] -#![feature(sized_hierarchy)] // added to keep parameters unconstrained - -pub trait Foo<T: std::marker::PointeeSized> { - type Bar<K: std::marker::PointeeSized>; -} - -pub struct Bar<T: ?AutoTrait> {} - -pub fn f<T1, T2>() -where - T1: for<T> Foo<usize, Bar = Bar<T>>, - T2: for<L, T> Foo<usize, Bar<T> = T1::Bar<T>>, -{}
diff --git a/tests/incremental/callee_caller_cross_crate/b.rs b/tests/incremental/callee_caller_cross_crate/b.rs index 78f3d8b..ebdecf5 100644 --- a/tests/incremental/callee_caller_cross_crate/b.rs +++ b/tests/incremental/callee_caller_cross_crate/b.rs
@@ -7,7 +7,7 @@ extern crate a; -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn call_function0() { a::function0(77); }
diff --git a/tests/incremental/change_add_field/struct_point.rs b/tests/incremental/change_add_field/struct_point.rs index 024812b..142a8e7 100644 --- a/tests/incremental/change_add_field/struct_point.rs +++ b/tests/incremental/change_add_field/struct_point.rs
@@ -70,7 +70,7 @@ pub fn x(&self) -> f32 { pub mod fn_with_type_in_sig { use point::Point; - #[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,fn_sig,optimized_mir", cfg="cfail2")] pub fn boop(p: Option<&Point>) -> f32 { p.map(|p| p.total()).unwrap_or(0.0) } @@ -86,7 +86,7 @@ pub fn boop(p: Option<&Point>) -> f32 { pub mod call_fn_with_type_in_sig { use fn_with_type_in_sig; - #[rustc_clean(except="typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,optimized_mir", cfg="cfail2")] pub fn bip() -> f32 { fn_with_type_in_sig::boop(None) } @@ -102,7 +102,7 @@ pub fn bip() -> f32 { pub mod fn_with_type_in_body { use point::Point; - #[rustc_clean(except="typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,optimized_mir", cfg="cfail2")] pub fn boop() -> f32 { Point::origin().total() } @@ -125,7 +125,7 @@ pub fn bip() -> f32 { pub mod fn_make_struct { use point::Point; - #[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,fn_sig,optimized_mir", cfg="cfail2")] pub fn make_origin(p: Point) -> Point { Point { ..p } } @@ -135,7 +135,7 @@ pub fn make_origin(p: Point) -> Point { pub mod fn_read_field { use point::Point; - #[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,fn_sig,optimized_mir", cfg="cfail2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -145,7 +145,7 @@ pub fn get_x(p: Point) -> f32 { pub mod fn_write_field { use point::Point; - #[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,fn_sig,optimized_mir", cfg="cfail2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; }
diff --git a/tests/incremental/change_crate_order/main.rs b/tests/incremental/change_crate_order/main.rs index 38a2541..b5e05c2 100644 --- a/tests/incremental/change_crate_order/main.rs +++ b/tests/incremental/change_crate_order/main.rs
@@ -19,7 +19,7 @@ use a::A; use b::B; -//? #[rustc_clean(label="typeck", cfg="rpass2")] +//? #[rustc_clean(label="typeck_root", cfg="rpass2")] pub fn main() { A + B; }
diff --git a/tests/incremental/change_private_fn/struct_point.rs b/tests/incremental/change_private_fn/struct_point.rs index 2c25603..eac1def 100644 --- a/tests/incremental/change_private_fn/struct_point.rs +++ b/tests/incremental/change_private_fn/struct_point.rs
@@ -54,8 +54,8 @@ pub mod fn_calls_methods_in_same_impl { // The cached result should actually be loaded from disk // (not just marked green) - for example, `DeadVisitor` // always runs during compilation as a "pass", and loads - // the typeck results for bodies. - #[rustc_clean(cfg="cfail2", loaded_from_disk="typeck")] + // the typeck_root results for bodies. + #[rustc_clean(cfg="cfail2", loaded_from_disk="typeck_root")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin();
diff --git a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs index 5c24199..e9778ed 100644 --- a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs
@@ -52,7 +52,7 @@ pub fn x(&self) -> f32 { pub mod fn_calls_changed_method { use point::Point; - #[rustc_clean(except="typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="typeck_root,optimized_mir", cfg="cfail2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_point(None);
diff --git a/tests/incremental/clean.rs b/tests/incremental/clean.rs index 1188b46..25aa25a 100644 --- a/tests/incremental/clean.rs +++ b/tests/incremental/clean.rs
@@ -36,14 +36,14 @@ pub fn y() { //[cfail2]~| ERROR `predicates_of(y)` should be dirty but is not //[cfail2]~| ERROR `type_of(y)` should be dirty but is not //[cfail2]~| ERROR `fn_sig(y)` should be dirty but is not - //[cfail2]~| ERROR `typeck(y)` should be clean but is not + //[cfail2]~| ERROR `typeck_root(y)` should be clean but is not x::x(); } } mod z { - #[rustc_clean(except="typeck", cfg="cfail2")] + #[rustc_clean(except="typeck_root", cfg="cfail2")] pub fn z() { - //[cfail2]~^ ERROR `typeck(z)` should be dirty but is not + //[cfail2]~^ ERROR `typeck_root(z)` should be dirty but is not } }
diff --git a/tests/incremental/const-generics/issue-64087.rs b/tests/incremental/const-generics/issue-64087.rs index 97f212b..787f2af 100644 --- a/tests/incremental/const-generics/issue-64087.rs +++ b/tests/incremental/const-generics/issue-64087.rs
@@ -6,4 +6,6 @@ fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed }
diff --git a/tests/incremental/hashes/call_expressions.rs b/tests/incremental/hashes/call_expressions.rs index d58bf04..f106519 100644 --- a/tests/incremental/hashes/call_expressions.rs +++ b/tests/incremental/hashes/call_expressions.rs
@@ -29,9 +29,9 @@ pub fn change_callee_function() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_callee_function() { callee2(1, 2) @@ -63,9 +63,9 @@ mod change_callee_indirectly_function { #[cfg(not(any(cfail1,cfail4)))] use super::callee2 as callee; - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub fn change_callee_indirectly_function() { callee(1, 2) @@ -87,9 +87,9 @@ pub fn change_callee_method() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_callee_method() { let s = Struct; @@ -125,9 +125,9 @@ pub fn change_ufcs_callee_method() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_ufcs_callee_method() { let s = Struct; @@ -163,9 +163,9 @@ pub fn change_to_ufcs() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] // One might think this would be expanded in the opt_hir_owner_nodes/Mir, but it actually // results in slightly different hir_owner/Mir. @@ -187,9 +187,9 @@ pub mod change_ufcs_callee_indirectly { #[cfg(not(any(cfail1,cfail4)))] use super::Struct2 as Struct; - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_ufcs_callee_indirectly() { let s = Struct;
diff --git a/tests/incremental/hashes/closure_expressions.rs b/tests/incremental/hashes/closure_expressions.rs index 3cda661..0d9f62c 100644 --- a/tests/incremental/hashes/closure_expressions.rs +++ b/tests/incremental/hashes/closure_expressions.rs
@@ -43,9 +43,9 @@ pub fn add_parameter() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_parameter() { let x = 0u32; @@ -61,9 +61,9 @@ pub fn change_parameter_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_parameter_pattern() { let _ = |(x,): (u32,)| x; @@ -96,9 +96,9 @@ pub fn add_type_ascription_to_parameter() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg = "cfail6")] pub fn add_type_ascription_to_parameter() { let closure = |x: u32| x + 1u32; @@ -115,9 +115,9 @@ pub fn change_parameter_type() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_parameter_type() { let closure = |x: u16| (x as u64) + 1;
diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs index 5962727..4c6971e 100644 --- a/tests/incremental/hashes/enum_constructors.rs +++ b/tests/incremental/hashes/enum_constructors.rs
@@ -63,9 +63,9 @@ pub fn change_field_order_struct_like() -> Enum { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] // FIXME(michaelwoerister):Interesting. I would have thought that that changes the MIR. And it // would if it were not all constants @@ -104,9 +104,9 @@ pub fn change_constructor_path_struct_like() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_path_struct_like() { let _ = Enum2::Struct { @@ -149,9 +149,9 @@ pub mod change_constructor_path_indirectly_struct_like { #[cfg(not(any(cfail1,cfail4)))] use super::Enum2 as TheEnum; - #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn function() -> TheEnum { TheEnum::Struct { @@ -211,12 +211,12 @@ pub fn change_constructor_path_tuple_like() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg="cfail2", - except="opt_hir_owner_nodes,typeck" + except="opt_hir_owner_nodes,typeck_root" )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( cfg="cfail5", - except="opt_hir_owner_nodes,typeck" + except="opt_hir_owner_nodes,typeck_root" )] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_path_tuple_like() { @@ -234,12 +234,12 @@ pub fn change_constructor_variant_tuple_like() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg="cfail2", - except="opt_hir_owner_nodes,typeck" + except="opt_hir_owner_nodes,typeck_root" )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( cfg="cfail5", - except="opt_hir_owner_nodes,typeck" + except="opt_hir_owner_nodes,typeck_root" )] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_variant_tuple_like() { @@ -254,9 +254,9 @@ pub mod change_constructor_path_indirectly_tuple_like { #[cfg(not(any(cfail1,cfail4)))] use super::Enum2 as TheEnum; - #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn function() -> TheEnum { TheEnum::Tuple(0, 1, 2) @@ -273,9 +273,9 @@ pub mod change_constructor_variant_indirectly_tuple_like { #[cfg(not(any(cfail1,cfail4)))] use super::Enum2::Tuple2 as Variant; - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn function() -> Enum2 { Variant(0, 1, 2) @@ -302,9 +302,9 @@ pub fn change_constructor_path_c_like() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_path_c_like() { let _x = Clike2::B; @@ -335,9 +335,9 @@ pub mod change_constructor_path_indirectly_c_like { #[cfg(not(any(cfail1,cfail4)))] use super::Clike2 as TheEnum; - #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn function() -> TheEnum { TheEnum::B
diff --git a/tests/incremental/hashes/for_loops.rs b/tests/incremental/hashes/for_loops.rs index 24717e0..d63f264 100644 --- a/tests/incremental/hashes/for_loops.rs +++ b/tests/incremental/hashes/for_loops.rs
@@ -79,9 +79,9 @@ pub fn change_iteration_variable_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_iteration_variable_pattern() { let mut _x = 0; @@ -129,9 +129,9 @@ pub fn add_break() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_break() { let mut _x = 0;
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 5b03f9e..8c06850 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs
@@ -26,12 +26,12 @@ pub fn add_parameter() {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn add_parameter(p: i32) {} @@ -56,12 +56,12 @@ pub fn type_of_parameter(p: i32) {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn type_of_parameter(p: i64) {} @@ -74,12 +74,12 @@ pub fn type_of_parameter_ref(p: &i32) {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn type_of_parameter_ref(p: &mut i32) {} @@ -92,12 +92,12 @@ pub fn order_of_parameters(p1: i32, p2: i64) {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn order_of_parameters(p2: i64, p1: i32) {} @@ -110,12 +110,12 @@ pub fn make_unsafe() {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, typeck, fn_sig" + except = "opt_hir_owner_nodes, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, typeck, fn_sig" + except = "opt_hir_owner_nodes, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub unsafe fn make_unsafe() {} @@ -126,9 +126,9 @@ pub unsafe fn make_unsafe() {} pub fn make_extern() {} #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck, fn_sig")] +#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck_root, fn_sig")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck, fn_sig")] +#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck_root, fn_sig")] #[rustc_clean(cfg = "cfail6")] pub extern "C" fn make_extern() {} @@ -303,9 +303,9 @@ pub fn return_impl_trait() -> i32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck, fn_sig")] +#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, typeck_root, fn_sig")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck, fn_sig, optimized_mir")] +#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck_root, fn_sig, optimized_mir")] #[rustc_clean(cfg = "cfail6")] pub fn return_impl_trait() -> impl Clone { 0 @@ -321,7 +321,7 @@ pub fn change_return_impl_trait() -> impl Clone { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg = "cfail6")] pub fn change_return_impl_trait() -> impl Copy { 0u32 @@ -340,12 +340,12 @@ pub mod change_return_type_indirectly { #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn indirect_return_type() -> ReturnType { @@ -363,12 +363,12 @@ pub mod change_parameter_type_indirectly { #[rustc_clean( cfg = "cfail2", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail3")] #[rustc_clean( cfg = "cfail5", - except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig" + except = "opt_hir_owner_nodes, optimized_mir, typeck_root, fn_sig" )] #[rustc_clean(cfg = "cfail6")] pub fn indirect_parameter_type(p: ParameterType) {}
diff --git a/tests/incremental/hashes/if_expressions.rs b/tests/incremental/hashes/if_expressions.rs index 6a24169..47a5083 100644 --- a/tests/incremental/hashes/if_expressions.rs +++ b/tests/incremental/hashes/if_expressions.rs
@@ -28,9 +28,9 @@ pub fn change_condition(x: bool) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_condition(x: bool) -> u32 { if !x { @@ -104,9 +104,9 @@ pub fn add_else_branch(x: bool) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_else_branch(x: bool) -> u32 { let mut ret = 1; @@ -132,9 +132,9 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_condition_if_let(x: Option<u32>) -> u32 { if let Some(_ ) = x { @@ -157,9 +157,9 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_then_branch_if_let(x: Option<u32>) -> u32 { if let Some(x) = x { @@ -210,9 +210,9 @@ pub fn add_else_branch_if_let(x: Option<u32>) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_else_branch_if_let(x: Option<u32>) -> u32 { let mut ret = 1;
diff --git a/tests/incremental/hashes/indexing_expressions.rs b/tests/incremental/hashes/indexing_expressions.rs index bfc64c9..cf05628 100644 --- a/tests/incremental/hashes/indexing_expressions.rs +++ b/tests/incremental/hashes/indexing_expressions.rs
@@ -75,9 +75,9 @@ fn add_lower_bound(slice: &[u32]) -> &[u32] { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn add_lower_bound(slice: &[u32]) -> &[u32] { &slice[3..4] @@ -92,9 +92,9 @@ fn add_upper_bound(slice: &[u32]) -> &[u32] { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn add_upper_bound(slice: &[u32]) -> &[u32] { &slice[3..7] @@ -109,9 +109,9 @@ fn change_mutability(slice: &mut [u32]) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn change_mutability(slice: &mut [u32]) -> u32 { (& slice[3..5])[0] @@ -126,9 +126,9 @@ fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] { &slice[3..=7]
diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs index 75c0939..ad871e5 100644 --- a/tests/incremental/hashes/inherent_impls.rs +++ b/tests/incremental/hashes/inherent_impls.rs
@@ -55,12 +55,12 @@ pub fn method_body() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,promoted_mir,typeck")] + #[rustc_clean(cfg="cfail2",except="opt_hir_owner_nodes,optimized_mir,promoted_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,promoted_mir,typeck")] + #[rustc_clean(cfg="cfail5",except="opt_hir_owner_nodes,optimized_mir,promoted_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn method_body() { println!("Hello, world!"); @@ -86,12 +86,12 @@ pub fn method_body_inlined() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] #[inline] pub fn method_body_inlined() { @@ -147,12 +147,12 @@ pub fn method_selfness() { } impl Foo { #[rustc_clean( cfg="cfail2", - except="opt_hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir", + except="opt_hir_owner_nodes,fn_sig,generics_of,typeck_root,associated_item,optimized_mir", )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( cfg="cfail5", - except="opt_hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir", + except="opt_hir_owner_nodes,fn_sig,generics_of,typeck_root,associated_item,optimized_mir", )] #[rustc_clean(cfg="cfail6")] pub fn method_selfness(&self) { } @@ -171,12 +171,12 @@ pub fn method_selfmutness(& self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn method_selfmutness(&mut self) { } } @@ -221,12 +221,12 @@ pub fn add_method_parameter(&self ) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_method_parameter(&self, _: i32) { } } @@ -271,12 +271,12 @@ pub fn change_method_return_type(&self) -> u16 { 0 } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_method_return_type(&self) -> u32 { 0 } } @@ -348,12 +348,12 @@ pub fn make_method_unsafe(&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail6")] pub unsafe fn make_method_unsafe(&self) { } } @@ -373,12 +373,12 @@ pub fn make_method_extern(&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail6")] pub extern "C" fn make_method_extern(&self) { } } @@ -398,12 +398,12 @@ pub extern "C" fn change_method_calling_convention(&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck")] + #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck_root")] #[rustc_clean(cfg="cfail6")] pub extern "system" fn change_method_calling_convention(&self) { } } @@ -432,18 +432,18 @@ pub fn add_lifetime_parameter_to_method (&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - // Warning: Note that `typeck` are coming up clean here. + // Warning: Note that `typeck_root` are coming up clean here. // The addition or removal of lifetime parameters that don't // appear in the arguments or fn body in any way does not, in - // fact, affect the `typeck` in any semantic way (at least + // fact, affect the `typeck_root` in any semantic way (at least // as of this writing). **However,** altering the order of - // lowering **can** cause it appear to affect the `typeck`: + // lowering **can** cause it appear to affect the `typeck_root`: // if we lower generics before the body, then the `HirId` for // things in the body will be affected. So if you start to see - // `typeck` appear dirty, that might be the cause. -nmatsakis + // `typeck_root` appear dirty, that might be the cause. -nmatsakis #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,generics_of")] @@ -481,17 +481,17 @@ pub fn add_type_parameter_to_method (&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - // Warning: Note that `typeck` are coming up clean here. + // Warning: Note that `typeck_root` are coming up clean here. // The addition or removal of type parameters that don't appear in // the arguments or fn body in any way does not, in fact, affect - // the `typeck` in any semantic way (at least as of this + // the `typeck_root` in any semantic way (at least as of this // writing). **However,** altering the order of lowering **can** - // cause it appear to affect the `typeck`: if we lower + // cause it appear to affect the `typeck_root`: if we lower // generics before the body, then the `HirId` for things in the - // body will be affected. So if you start to see `typeck` + // body will be affected. So if you start to see `typeck_root` // appear dirty, that might be the cause. -nmatsakis #[rustc_clean( cfg="cfail2", @@ -573,17 +573,17 @@ pub fn add_lifetime_bound_to_type_param_of_method<'a, T >(&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - // Warning: Note that `typeck` are coming up clean here. + // Warning: Note that `typeck_root` are coming up clean here. // The addition or removal of bounds that don't appear in the // arguments or fn body in any way does not, in fact, affect the - // `typeck` in any semantic way (at least as of this + // `typeck_root` in any semantic way (at least as of this // writing). **However,** altering the order of lowering **can** - // cause it appear to affect the `typeck`: if we lower + // cause it appear to affect the `typeck_root`: if we lower // generics before the body, then the `HirId` for things in the - // body will be affected. So if you start to see `typeck` + // body will be affected. So if you start to see `typeck_root` // appear dirty, that might be the cause. -nmatsakis #[rustc_clean( cfg="cfail2", @@ -622,17 +622,17 @@ pub fn add_trait_bound_to_type_param_of_method<T >(&self) { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - // Warning: Note that `typeck` are coming up clean here. + // Warning: Note that `typeck_root` are coming up clean here. // The addition or removal of bounds that don't appear in the // arguments or fn body in any way does not, in fact, affect the - // `typeck` in any semantic way (at least as of this + // `typeck_root` in any semantic way (at least as of this // writing). **However,** altering the order of lowering **can** - // cause it appear to affect the `typeck`: if we lower + // cause it appear to affect the `typeck_root`: if we lower // generics before the body, then the `HirId` for things in the - // body will be affected. So if you start to see `typeck` + // body will be affected. So if you start to see `typeck_root` // appear dirty, that might be the cause. -nmatsakis #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail3")] @@ -686,12 +686,12 @@ pub fn add_type_parameter_to_impl(&self) { } impl<T> Bar<T> { #[rustc_clean( cfg="cfail2", - except="generics_of,fn_sig,typeck,type_of,optimized_mir" + except="generics_of,fn_sig,typeck_root,type_of,optimized_mir" )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( cfg="cfail5", - except="generics_of,fn_sig,typeck,type_of,optimized_mir" + except="generics_of,fn_sig,typeck_root,type_of,optimized_mir" )] #[rustc_clean(cfg="cfail6")] pub fn add_type_parameter_to_impl(&self) { } @@ -711,9 +711,9 @@ pub fn change_impl_self_type(&self) { } #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] impl Bar<u64> { - #[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="fn_sig,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_impl_self_type(&self) { } }
diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs index b2e8938..155132b 100644 --- a/tests/incremental/hashes/let_expressions.rs +++ b/tests/incremental/hashes/let_expressions.rs
@@ -41,9 +41,9 @@ pub fn add_type() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_type() { let _x: u32 = 2u32; @@ -58,9 +58,9 @@ pub fn change_type() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_type() { let _x: u8 = 2; @@ -75,9 +75,9 @@ pub fn change_mutability_of_reference_type() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_mutability_of_reference_type() { let _x: &mut u64; @@ -92,9 +92,9 @@ pub fn change_mutability_of_slot() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -109,9 +109,9 @@ pub fn change_simple_binding_to_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_simple_binding_to_pattern() { let (_a, _b) = (0u8, 'x'); @@ -143,9 +143,9 @@ pub fn add_ref_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_ref_in_pattern() { let (ref _a, _b) = (1u8, 'y'); @@ -160,9 +160,9 @@ pub fn add_amp_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_amp_in_pattern() { let (&_a, _b) = (&1u8, 'y'); @@ -177,9 +177,9 @@ pub fn change_mutability_of_binding_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); @@ -194,9 +194,9 @@ pub fn add_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_initializer() { let _x: i16 = 3i16;
diff --git a/tests/incremental/hashes/loop_expressions.rs b/tests/incremental/hashes/loop_expressions.rs index a8b8921..da03fb1 100644 --- a/tests/incremental/hashes/loop_expressions.rs +++ b/tests/incremental/hashes/loop_expressions.rs
@@ -54,9 +54,9 @@ pub fn add_break() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_break() { let mut _x = 0; @@ -131,9 +131,9 @@ pub fn change_break_label() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_break_label() { let mut _x = 0; @@ -212,9 +212,9 @@ pub fn change_continue_to_break() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck_root, optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck, optimized_mir")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck_root, optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_continue_to_break() { let mut _x = 0;
diff --git a/tests/incremental/hashes/match_expressions.rs b/tests/incremental/hashes/match_expressions.rs index 0c7f847..b6d753a 100644 --- a/tests/incremental/hashes/match_expressions.rs +++ b/tests/incremental/hashes/match_expressions.rs
@@ -29,9 +29,9 @@ pub fn add_arm(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_arm(x: u32) -> u32 { match x { @@ -80,9 +80,9 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -105,9 +105,9 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -130,9 +130,9 @@ pub fn add_at_binding(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_at_binding(x: u32) -> u32 { match x { @@ -179,9 +179,9 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_simple_name_to_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -228,9 +228,9 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { // Ignore optimized_mir in cfail2, the only change to optimized MIR is a span. #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -251,9 +251,9 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -274,9 +274,9 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { match (&x, x & 1) { @@ -323,9 +323,9 @@ pub fn add_alternative_to_arm(x: u32) -> u32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_alternative_to_arm(x: u32) -> u32 { match x {
diff --git a/tests/incremental/hashes/struct_constructors.rs b/tests/incremental/hashes/struct_constructors.rs index b2f8d11..0efbd50 100644 --- a/tests/incremental/hashes/struct_constructors.rs +++ b/tests/incremental/hashes/struct_constructors.rs
@@ -60,9 +60,9 @@ pub fn change_field_order_regular_struct() -> RegularStruct { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_field_order_regular_struct() -> RegularStruct { RegularStruct { @@ -91,9 +91,9 @@ pub fn add_field_regular_struct() -> RegularStruct { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_field_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -128,9 +128,9 @@ pub fn change_field_label_regular_struct() -> RegularStruct { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_field_label_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -165,9 +165,9 @@ pub fn change_constructor_path_regular_struct() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_path_regular_struct() { let _ = RegularStruct2 { @@ -186,9 +186,9 @@ pub mod change_constructor_path_indirectly_regular_struct { #[cfg(not(any(cfail1,cfail4)))] use super::RegularStruct2 as Struct; - #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn function() -> Struct { Struct { @@ -229,9 +229,9 @@ pub fn change_constructor_path_tuple_struct() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_path_tuple_struct() { let _ = TupleStruct2(0, 1, 2); @@ -246,9 +246,9 @@ pub mod change_constructor_path_indirectly_tuple_struct { #[cfg(not(any(cfail1,cfail4)))] use super::TupleStruct2 as Struct; - #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail5", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail6")] - #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck")] + #[rustc_clean(cfg="cfail2", except="fn_sig,opt_hir_owner_nodes,optimized_mir,typeck_root")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Struct { Struct(0, 1, 2)
diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index 13334a0..0842fba 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs
@@ -353,12 +353,12 @@ fn method( self) {} #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitChangeModeSelfOwnToMut: Sized { - #[rustc_clean(except="opt_hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn method(mut self) {} }
diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index d4ac69a..3e13212 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs
@@ -76,12 +76,12 @@ fn method_name() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl ChangeMethodBodyTrait for Foo { - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn method_name() { () @@ -111,12 +111,12 @@ fn method_name() { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl ChangeMethodBodyTraitInlined for Foo { - #[rustc_clean(except="opt_hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] #[inline] fn method_name() { @@ -148,12 +148,12 @@ pub trait ChangeMethodSelfnessTrait { #[rustc_clean(cfg="cfail6")] impl ChangeMethodSelfnessTrait for Foo { #[rustc_clean( - except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir", + except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", cfg="cfail2", )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( - except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir", + except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", cfg="cfail5", )] #[rustc_clean(cfg="cfail6")] @@ -186,12 +186,12 @@ pub trait RemoveMethodSelfnessTrait { #[rustc_clean(cfg="cfail6")] impl RemoveMethodSelfnessTrait for Foo { #[rustc_clean( - except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir", + except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", cfg="cfail2", )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( - except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir", + except="opt_hir_owner_nodes,associated_item,generics_of,fn_sig,typeck_root,optimized_mir", cfg="cfail5", )] #[rustc_clean(cfg="cfail6")] @@ -222,12 +222,12 @@ pub trait ChangeMethodSelfmutnessTrait { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl ChangeMethodSelfmutnessTrait for Foo { - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn method_name(&mut self) {} } @@ -404,12 +404,12 @@ pub trait AddArgumentTrait { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl AddArgumentTrait for Foo { - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn method_name(&self, _x: u32) { } } @@ -438,12 +438,12 @@ pub trait ChangeArgumentTypeTrait { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl ChangeArgumentTypeTrait for Foo { - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="opt_hir_owner_nodes,fn_sig,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn method_name(&self, _x: char) { } } @@ -469,12 +469,12 @@ fn id(t: u32) -> u32 { t } #[rustc_clean(cfg="cfail6")] impl<TTT> AddTypeParameterToImpl<TTT> for Bar<TTT> { #[rustc_clean( - except="opt_hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir", + except="opt_hir_owner_nodes,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="cfail2", )] #[rustc_clean(cfg="cfail3")] #[rustc_clean( - except="opt_hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir", + except="opt_hir_owner_nodes,generics_of,fn_sig,type_of,typeck_root,optimized_mir", cfg="cfail5", )] #[rustc_clean(cfg="cfail6")] @@ -499,9 +499,9 @@ fn id(self) -> Self { self } #[rustc_clean(except="opt_hir_owner_nodes,impl_trait_header", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl ChangeSelfTypeOfImpl for u64 { - #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail2")] + #[rustc_clean(except="fn_sig,typeck_root,optimized_mir", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail5")] + #[rustc_clean(except="fn_sig,typeck_root,optimized_mir", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] fn id(self) -> Self { self } }
diff --git a/tests/incremental/hashes/unary_and_binary_exprs.rs b/tests/incremental/hashes/unary_and_binary_exprs.rs index fec167c..9154aa3 100644 --- a/tests/incremental/hashes/unary_and_binary_exprs.rs +++ b/tests/incremental/hashes/unary_and_binary_exprs.rs
@@ -418,9 +418,9 @@ pub fn type_cast(a: u8) -> u64 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes,optimized_mir,typeck", cfg="cfail2")] +#[rustc_clean(except="opt_hir_owner_nodes,optimized_mir,typeck_root", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,optimized_mir,typeck", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,optimized_mir,typeck_root", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub fn type_cast(a: u8) -> u64 { let b = a as u32;
diff --git a/tests/incremental/hashes/while_let_loops.rs b/tests/incremental/hashes/while_let_loops.rs index 1071ee8..62ff32f 100644 --- a/tests/incremental/hashes/while_let_loops.rs +++ b/tests/incremental/hashes/while_let_loops.rs
@@ -79,9 +79,9 @@ pub fn add_break() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_break() { let mut _x = 0;
diff --git a/tests/incremental/hashes/while_loops.rs b/tests/incremental/hashes/while_loops.rs index 57287cb..79e5145 100644 --- a/tests/incremental/hashes/while_loops.rs +++ b/tests/incremental/hashes/while_loops.rs
@@ -79,9 +79,9 @@ pub fn add_break() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes, optimized_mir, typeck_root")] #[rustc_clean(cfg="cfail6")] pub fn add_break() { let mut _x = 0;
diff --git a/tests/incremental/hygiene/auxiliary/cached_hygiene.rs b/tests/incremental/hygiene/auxiliary/cached_hygiene.rs index 67b54e6..d52a639 100644 --- a/tests/incremental/hygiene/auxiliary/cached_hygiene.rs +++ b/tests/incremental/hygiene/auxiliary/cached_hygiene.rs
@@ -13,7 +13,7 @@ macro_rules! first_macro { } } -#[rustc_clean(except="opt_hir_owner_nodes,typeck,optimized_mir", cfg="rpass2")] +#[rustc_clean(except="opt_hir_owner_nodes,typeck_root,optimized_mir", cfg="rpass2")] #[inline(always)] pub fn changed_fn() { // This will cause additional hygiene to be generate,
diff --git a/tests/incremental/ich_method_call_trait_scope.rs b/tests/incremental/ich_method_call_trait_scope.rs index 28234ca..58a56e6 100644 --- a/tests/incremental/ich_method_call_trait_scope.rs +++ b/tests/incremental/ich_method_call_trait_scope.rs
@@ -27,7 +27,7 @@ mod mod3 { #[cfg(rpass2)] use Trait2; - #[rustc_clean(except="typeck", cfg="rpass2")] + #[rustc_clean(except="typeck_root", cfg="rpass2")] fn bar() { ().method(); }
diff --git a/tests/incremental/ich_resolve_results.rs b/tests/incremental/ich_resolve_results.rs index 41c98bd..60d3fd9 100644 --- a/tests/incremental/ich_resolve_results.rs +++ b/tests/incremental/ich_resolve_results.rs
@@ -31,13 +31,13 @@ mod mod3 { use mod2::Foo; #[rustc_clean(cfg="rpass2")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="rpass3")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="rpass3")] fn in_expr() { Foo(0); } #[rustc_clean(cfg="rpass2")] - #[rustc_clean(except="opt_hir_owner_nodes,typeck", cfg="rpass3")] + #[rustc_clean(except="opt_hir_owner_nodes,typeck_root", cfg="rpass3")] fn in_type() { test::<Foo>(); }
diff --git a/tests/incremental/issue-42602.rs b/tests/incremental/issue-42602.rs index e75dd96..de1fd70 100644 --- a/tests/incremental/issue-42602.rs +++ b/tests/incremental/issue-42602.rs
@@ -1,7 +1,7 @@ // Regression test for #42602. It used to be that we had // a dep-graph like // -// typeck(foo) -> FnOnce -> typeck(bar) +// typeck_root(foo) -> FnOnce -> typeck_root(bar) // // This was fixed by improving the resolution of the `FnOnce` trait // selection node.
diff --git a/tests/incremental/rlib_cross_crate/b.rs b/tests/incremental/rlib_cross_crate/b.rs index 3373f80..c60e1c5 100644 --- a/tests/incremental/rlib_cross_crate/b.rs +++ b/tests/incremental/rlib_cross_crate/b.rs
@@ -13,7 +13,7 @@ extern crate a; -#[rustc_clean(except="typeck,optimized_mir", cfg="rpass2")] +#[rustc_clean(except="typeck_root,optimized_mir", cfg="rpass2")] #[rustc_clean(cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22;
diff --git a/tests/incremental/string_constant.rs b/tests/incremental/string_constant.rs index 4200df8..fad76d4 100644 --- a/tests/incremental/string_constant.rs +++ b/tests/incremental/string_constant.rs
@@ -7,7 +7,7 @@ #![crate_type = "rlib"] // Here the only thing which changes is the string constant in `x`. -// Therefore, the compiler deduces (correctly) that typeck is not +// Therefore, the compiler deduces (correctly) that typeck_root is not // needed even for callers of `x`. pub mod x {
diff --git a/tests/incremental/struct_add_field.rs b/tests/incremental/struct_add_field.rs index 2c26b38..e39935c 100644 --- a/tests/incremental/struct_add_field.rs +++ b/tests/incremental/struct_add_field.rs
@@ -22,12 +22,12 @@ pub struct Y { pub y: char } -#[rustc_clean(except="fn_sig,typeck", cfg="rpass2")] +#[rustc_clean(except="fn_sig,typeck_root", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 }
diff --git a/tests/incremental/struct_change_field_name.rs b/tests/incremental/struct_change_field_name.rs index 1519f8d..76f42b6 100644 --- a/tests/incremental/struct_change_field_name.rs +++ b/tests/incremental/struct_change_field_name.rs
@@ -26,7 +26,7 @@ pub struct Y { pub y: char } -#[rustc_clean(except="typeck", cfg="cfail2")] +#[rustc_clean(except="typeck_root", cfg="cfail2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; //[cfail2]~^ ERROR struct `X` has no field named `x` @@ -34,7 +34,7 @@ pub fn use_X() -> u32 { //[cfail2]~^ ERROR no field `x` on type `X` } -#[rustc_clean(except="typeck", cfg="cfail2")] +#[rustc_clean(except="typeck_root", cfg="cfail2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 //[cfail2]~^ ERROR no field `x` on type `X`
diff --git a/tests/incremental/struct_change_field_type.rs b/tests/incremental/struct_change_field_type.rs index 0291b34e3..9414790 100644 --- a/tests/incremental/struct_change_field_type.rs +++ b/tests/incremental/struct_change_field_type.rs
@@ -25,13 +25,13 @@ pub struct Y { pub y: char } -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_EmbedX(x: EmbedX) -> u32 { let x: X = X { x: 22 }; x.x as u32
diff --git a/tests/incremental/struct_change_field_type_cross_crate/b.rs b/tests/incremental/struct_change_field_type_cross_crate/b.rs index 5307d0a..ccd6047 100644 --- a/tests/incremental/struct_change_field_type_cross_crate/b.rs +++ b/tests/incremental/struct_change_field_type_cross_crate/b.rs
@@ -9,13 +9,13 @@ use a::*; -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 }
diff --git a/tests/incremental/struct_remove_field.rs b/tests/incremental/struct_remove_field.rs index 23ba273..eeb0dff 100644 --- a/tests/incremental/struct_remove_field.rs +++ b/tests/incremental/struct_remove_field.rs
@@ -26,12 +26,12 @@ pub struct Y { pub y: char } -#[rustc_clean(except="typeck,fn_sig", cfg="rpass2")] +#[rustc_clean(except="typeck_root,fn_sig", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 }
diff --git a/tests/incremental/type_alias_cross_crate/b.rs b/tests/incremental/type_alias_cross_crate/b.rs index 7fa7073..095312c6 100644 --- a/tests/incremental/type_alias_cross_crate/b.rs +++ b/tests/incremental/type_alias_cross_crate/b.rs
@@ -7,7 +7,7 @@ extern crate a; -#[rustc_clean(except="typeck", cfg="rpass2")] +#[rustc_clean(except="typeck_root", cfg="rpass2")] #[rustc_clean(cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22;
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff index 91a275e..9ac720a 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff index 68b2dcc..4b77c91 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff index 3fc9369..8e9e15e 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff index 0d59a27..915a5be 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index 743cd95..273fe41 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index fa6a636..30beb0c 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index 556453f..b41d129 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 9a025eb..cd515b5 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -17,12 +17,12 @@ let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 8 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { } } - scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 7 (inlined std::mem::Alignment::of::<[bool; 0]>) { } } }
diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 25f3230..b891416 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff
@@ -51,7 +51,7 @@ StorageLive(_12); StorageLive(_13); - _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; -+ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; ++ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; } bb1: {
diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 32fe7e2..0219db3 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff
@@ -51,7 +51,7 @@ StorageLive(_12); StorageLive(_13); - _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; -+ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; ++ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; } bb1: {
diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index cf850351..adc723a 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff
@@ -64,7 +64,9 @@ StorageDead(_1); return; } - } ++ } + -+ ALLOC0 (size: 8, align: 4) { .. } ++ ALLOC0 (size: 8, align: 4) { ++ 02 00 00 00 05 20 00 00 │ ..... .. + }
diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index dc5ea1a..c92bf7b 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff
@@ -64,7 +64,9 @@ StorageDead(_1); return; } - } ++ } + -+ ALLOC0 (size: 16, align: 8) { .. } ++ ALLOC0 (size: 16, align: 8) { ++ 02 00 00 00 00 00 00 00 05 20 00 00 00 00 00 00 │ ......... ...... + }
diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs index 8139056..45a3edc 100644 --- a/tests/mir-opt/enum_opt.rs +++ b/tests/mir-opt/enum_opt.rs
@@ -1,7 +1,8 @@ // skip-filecheck //@ test-mir-pass: EnumSizeOpt // EMIT_MIR_FOR_EACH_BIT_WIDTH -//@ compile-flags: -Zunsound-mir-opts -Zdump-mir-exclude-alloc-bytes +//@ compile-flags: -Zunsound-mir-opts +//@ ignore-endian-big // Tests that an enum with a variant with no data gets correctly transformed. pub enum NoData {
diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 3cd2e74..f6dbf8b 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff
@@ -64,7 +64,9 @@ StorageDead(_1); return; } - } ++ } + -+ ALLOC0 (size: 8, align: 4) { .. } ++ ALLOC0 (size: 8, align: 4) { ++ 05 20 00 00 01 00 00 00 │ . ...... + }
diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 10b0ec5..7900c3c 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff
@@ -64,7 +64,9 @@ StorageDead(_1); return; } - } ++ } + -+ ALLOC0 (size: 16, align: 8) { .. } ++ ALLOC0 (size: 16, align: 8) { ++ 05 20 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ . .............. + }
diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff index 86d48e6..d72f62f 100644 --- a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
@@ -7,14 +7,14 @@ let mut _2: *mut u8; scope 1 (inlined dangling_mut::<u8>) { scope 2 (inlined NonNull::<u8>::dangling) { - let _3: std::ptr::Alignment; + let _3: std::mem::Alignment; scope 3 { - scope 5 (inlined std::ptr::Alignment::as_nonzero) { + scope 5 (inlined std::mem::Alignment::as_nonzero_usize) { } scope 6 (inlined NonNull::<u8>::without_provenance) { } } - scope 4 (inlined std::ptr::Alignment::of::<u8>) { + scope 4 (inlined std::mem::Alignment::of::<u8>) { } } scope 7 (inlined NonNull::<u8>::as_ptr) { @@ -34,7 +34,7 @@ StorageLive(_3); - _3 = const <u8 as std::mem::SizedTypeProperties>::ALIGNMENT; - _2 = copy _3 as *mut u8 (Transmute); -+ _3 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}; ++ _3 = const std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }}; + _2 = const {0x1 as *mut u8}; StorageDead(_3); StorageLive(_4);
diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir index 1190f78..0cd241b 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir
@@ -48,9 +48,9 @@ } scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[u8; 1024]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -69,7 +69,7 @@ StorageLive(_3); _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); _3 = copy _2 as std::ptr::NonNull<u8> (Transmute); - _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; + _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; } bb1: {
diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir index 1190f78..0cd241b 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir
@@ -48,9 +48,9 @@ } scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[u8; 1024]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -69,7 +69,7 @@ StorageLive(_3); _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); _3 = copy _2 as std::ptr::NonNull<u8> (Transmute); - _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; + _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; } bb1: {
diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir index b5c2503..2b7c334 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir
@@ -42,16 +42,16 @@ } } scope 7 (inlined Layout::for_value_raw::<T>) { - let mut _3: std::ptr::Alignment; + let mut _3: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<T>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<T>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<T>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -69,7 +69,7 @@ bb0: { StorageLive(_4); _2 = copy (((*_1).0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>); - _3 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _3 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); switchInt(const <T as std::mem::SizedTypeProperties>::SIZE) -> [0: bb3, otherwise: bb1]; }
diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir index b5c2503..2b7c334 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir
@@ -42,16 +42,16 @@ } } scope 7 (inlined Layout::for_value_raw::<T>) { - let mut _3: std::ptr::Alignment; + let mut _3: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<T>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<T>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<T>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -69,7 +69,7 @@ bb0: { StorageLive(_4); _2 = copy (((*_1).0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>); - _3 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _3 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); switchInt(const <T as std::mem::SizedTypeProperties>::SIZE) -> [0: bb3, otherwise: bb1]; }
diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.rs b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs index 088339b..3d340eb 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.rs +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs
@@ -6,7 +6,7 @@ // EMIT_MIR drop_box_of_sized.drop_generic.PreCodegen.after.mir pub unsafe fn drop_generic<T: Copy>(x: *mut Box<T>) { // CHECK-LABEL: fn drop_generic - // CHECK: [[ALIGNMENT:_.+]] = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute) + // CHECK: [[ALIGNMENT:_.+]] = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute) // CHECK: alloc::alloc::__rust_dealloc({{.+}}, const <T as std::mem::SizedTypeProperties>::SIZE, move [[ALIGNMENT]]) std::ptr::drop_in_place(x) }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index 3bff170..cb6a774 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
@@ -46,16 +46,16 @@ } scope 7 (inlined Layout::for_value_raw::<[T]>) { let mut _5: usize; - let mut _6: std::ptr::Alignment; + let mut _6: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<[T]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[T]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[T]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -82,7 +82,7 @@ } bb1: { - _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); StorageDead(_4); switchInt(copy _5) -> [0: bb3, otherwise: bb2]; }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index 3bff170..cb6a774 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
@@ -46,16 +46,16 @@ } scope 7 (inlined Layout::for_value_raw::<[T]>) { let mut _5: usize; - let mut _6: std::ptr::Alignment; + let mut _6: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<[T]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[T]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[T]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -82,7 +82,7 @@ } bb1: { - _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); StorageDead(_4); switchInt(copy _5) -> [0: bb3, otherwise: bb2]; }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index 3bff170..cb6a774 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
@@ -46,16 +46,16 @@ } scope 7 (inlined Layout::for_value_raw::<[T]>) { let mut _5: usize; - let mut _6: std::ptr::Alignment; + let mut _6: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<[T]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[T]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[T]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -82,7 +82,7 @@ } bb1: { - _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); StorageDead(_4); switchInt(copy _5) -> [0: bb3, otherwise: bb2]; }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index 3bff170..cb6a774 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
@@ -46,16 +46,16 @@ } scope 7 (inlined Layout::for_value_raw::<[T]>) { let mut _5: usize; - let mut _6: std::ptr::Alignment; + let mut _6: std::mem::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } } scope 9 (inlined size_of_val_raw::<[T]>) { } - scope 10 (inlined std::ptr::Alignment::of_val_raw::<[T]>) { + scope 10 (inlined std::mem::Alignment::of_val_raw::<[T]>) { scope 11 { - scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 13 (inlined #[track_caller] std::mem::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { scope 15 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -82,7 +82,7 @@ } bb1: { - _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + _6 = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); StorageDead(_4); switchInt(copy _5) -> [0: bb3, otherwise: bb2]; }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs index 9e56b31..8f28bc7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
@@ -9,7 +9,7 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) { // CHECK-LABEL: fn generic_in_place(_1: *mut Box<[T]>) // CHECK: (inlined <Box<[T]> as Drop>::drop) // CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]> - // CHECK: [[ALIGN:_.+]] = const <T as std::mem::SizedTypeProperties>::ALIGN as std::ptr::Alignment (Transmute); + // CHECK: [[ALIGN:_.+]] = const <T as std::mem::SizedTypeProperties>::ALIGN as std::mem::Alignment (Transmute); // CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[ALIGN]]) -> std::ptr::drop_in_place(ptr) }
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index b48e6fc..babdc70 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
@@ -63,7 +63,7 @@ bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -73,8 +73,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; } bb4: {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff index d0e59c0..2f535c6 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
@@ -64,7 +64,7 @@ bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -74,8 +74,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x00000000): mem::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; } bb5: {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 18fc4ac..11d64d0 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
@@ -63,7 +63,7 @@ bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -73,8 +73,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; } bb4: {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff index c109fe7..f3f671b 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
@@ -64,7 +64,7 @@ bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -74,8 +74,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::mem::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): mem::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; } bb5: {
diff --git a/tests/pretty/asm-operand-order.pp b/tests/pretty/asm-operand-order.pp new file mode 100644 index 0000000..949c18c --- /dev/null +++ b/tests/pretty/asm-operand-order.pp
@@ -0,0 +1,19 @@ +#![feature(prelude_import)] +#![no_std] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; +//@ pretty-mode:expanded +//@ pp-exact:asm-operand-order.pp +//@ only-x86_64 + +use std::arch::asm; + +pub fn main() { + unsafe { + asm!("{0}", in(reg) 4, out("rax") _); + asm!("{0}", in(reg) 4, out("rax") _, options(nostack)); + asm!("{0} {1}", in(reg) 4, in(reg) 5, out("rax") _); + asm!("{0}", const 5, out("rax") _); + } +}
diff --git a/tests/pretty/asm-operand-order.rs b/tests/pretty/asm-operand-order.rs new file mode 100644 index 0000000..b0bdabd --- /dev/null +++ b/tests/pretty/asm-operand-order.rs
@@ -0,0 +1,14 @@ +//@ pretty-mode:expanded +//@ pp-exact:asm-operand-order.pp +//@ only-x86_64 + +use std::arch::asm; + +pub fn main() { + unsafe { + asm!("{val}", out("rax") _, val = in(reg) 4); + asm!("{val}", out("rax") _, val = in(reg) 4, options(nostack)); + asm!("{a} {b}", out("rax") _, a = in(reg) 4, b = in(reg) 5); + asm!("{val}", out("rax") _, val = const 5); + } +}
diff --git a/tests/pretty/autodiff/trait.pp b/tests/pretty/autodiff/trait.pp new file mode 100644 index 0000000..cb2fe0c --- /dev/null +++ b/tests/pretty/autodiff/trait.pp
@@ -0,0 +1,43 @@ +//@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// Just check it does not crash for now +// CHECK: ; +#![feature(autodiff)] +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +use std::autodiff::autodiff_reverse; + +struct Foo { + a: f64, +} + +trait MyTrait { + #[rustc_autodiff] + fn f(&self, x: f64) -> f64; + #[rustc_autodiff(Reverse, 1, Const, Active, Active)] + fn df(&self, x: f64, seed: f64) -> (f64, f64) { + std::hint::black_box(seed); + std::hint::black_box(x); + ::std::intrinsics::autodiff( + Self::f as for<'a> fn(&'a Self, _: f64) -> f64, + Self::df, + (self, x, seed), + ) + + } +} + +impl MyTrait for Foo { + fn f(&self, x: f64) -> f64 { + x.sin() + } +} + +fn main() { + let foo = Foo { a: 3.0f64 }; + dbg!(foo.df(2.0, 1.0)); + dbg!(2.0_f64.cos()); +}
diff --git a/tests/pretty/autodiff/trait.rs b/tests/pretty/autodiff/trait.rs new file mode 100644 index 0000000..a308cf3 --- /dev/null +++ b/tests/pretty/autodiff/trait.rs
@@ -0,0 +1,32 @@ +//@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// Just check it does not crash for now +// CHECK: ; +#![feature(autodiff)] +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +use std::autodiff::autodiff_reverse; + +struct Foo { + a: f64, +} + +trait MyTrait { + #[autodiff_reverse(df, Const, Active, Active)] + fn f(&self, x: f64) -> f64; +} + +impl MyTrait for Foo { + fn f(&self, x: f64) -> f64 { + x.sin() + } +} + +fn main() { + let foo = Foo { a: 3.0f64 }; + dbg!(foo.df(2.0, 1.0)); + dbg!(2.0_f64.cos()); +}
diff --git a/tests/pretty/or-pattern-paren.pp b/tests/pretty/or-pattern-paren.pp new file mode 100644 index 0000000..6ea94eb --- /dev/null +++ b/tests/pretty/or-pattern-paren.pp
@@ -0,0 +1,27 @@ +#![feature(prelude_import)] +#![no_std] +#![feature(box_patterns)] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +//@ pretty-compare-only +//@ pretty-mode:expanded +//@ pp-exact:or-pattern-paren.pp + +macro_rules! or_pat { ($($name:pat),+) => { $($name)|+ } } + +fn check_at(x: Option<i32>) { + match x { + Some(v @ (1 | 2 | 3)) => + + + { + ::std::io::_print(format_args!("{0}\n", v)); + } + _ => {} + } +} +fn check_ref(x: &i32) { match x { &(1 | 2 | 3) => {} _ => {} } } +fn check_box(x: Box<i32>) { match x { box (1 | 2 | 3) => {} _ => {} } } +fn main() { check_at(Some(2)); check_ref(&1); check_box(Box::new(1)); }
diff --git a/tests/pretty/or-pattern-paren.rs b/tests/pretty/or-pattern-paren.rs new file mode 100644 index 0000000..ea6a8f3 --- /dev/null +++ b/tests/pretty/or-pattern-paren.rs
@@ -0,0 +1,36 @@ +#![feature(box_patterns)] + +//@ pretty-compare-only +//@ pretty-mode:expanded +//@ pp-exact:or-pattern-paren.pp + +macro_rules! or_pat { + ($($name:pat),+) => { $($name)|+ } +} + +fn check_at(x: Option<i32>) { + match x { + Some(v @ or_pat!(1, 2, 3)) => println!("{v}"), + _ => {} + } +} + +fn check_ref(x: &i32) { + match x { + &or_pat!(1, 2, 3) => {} + _ => {} + } +} + +fn check_box(x: Box<i32>) { + match x { + box or_pat!(1, 2, 3) => {} + _ => {} + } +} + +fn main() { + check_at(Some(2)); + check_ref(&1); + check_box(Box::new(1)); +}
diff --git a/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/Cargo.toml b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/Cargo.toml new file mode 100644 index 0000000..4563b63 --- /dev/null +++ b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/Cargo.toml
@@ -0,0 +1,10 @@ +[workspace] + +[package] +edition = "2024" +name = "tester" +version = "0.1.0" + +[[example]] +doc-scrape-examples = true +name = "window"
diff --git a/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/examples/window.rs b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/examples/window.rs new file mode 100644 index 0000000..19d9ad8 --- /dev/null +++ b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/examples/window.rs
@@ -0,0 +1,24 @@ +#![allow(dead_code)] +use tester::Window; + +macro_rules! info { + ($s:literal, $x:expr) => {{ + let _ = $x; + }}; +} + +struct WindowState { + window: Window, +} + +impl WindowState { + fn takes_ref(&self) { + info!("{:?}", self.window.id()); + } + + fn takes_mut(&mut self) { + info!("{:?}", self.window.id()); + } +} + +fn main() {}
diff --git a/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/rmake.rs b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/rmake.rs new file mode 100644 index 0000000..67a328f --- /dev/null +++ b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/rmake.rs
@@ -0,0 +1,11 @@ +//! This test ensures that the call locations are not duplicated when generating scraped examples. +//! To ensure that, we check that this call doesn't fail. +//! Regression test for <https://github.com/rust-lang/rust/issues/153837>. + +use run_make_support::{cargo, htmldocck}; + +fn main() { + cargo().args(["rustdoc", "-Zunstable-options", "-Zrustdoc-scrape-examples"]).run(); + + htmldocck().arg("target/doc").arg("src/lib.rs").run(); +}
diff --git a/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/src/lib.rs b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/src/lib.rs new file mode 100644 index 0000000..8c86a37 --- /dev/null +++ b/tests/run-make-cargo/rustdoc-scrape-examples-duplicated-calls/src/lib.rs
@@ -0,0 +1,13 @@ +//@has tester/struct.Window.html +//@count - '//*[@class="docblock scraped-example-list"]//span[@class="highlight"]' 1 +//@has - '//*[@class="docblock scraped-example-list"]//span[@class="highlight"]' 'id' +//@count - '//*[@class="docblock scraped-example-list"]//span[@class="highlight focus"]' 1 +//@has - '//*[@class="docblock scraped-example-list"]//span[@class="highlight focus"]' 'id' + +pub struct Window {} + +impl Window { + pub fn id(&self) -> u64 { + todo!() + } +}
diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 5ba1a18..c8bde9c 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs
@@ -23,7 +23,7 @@ fn check_compression(compression: &str, to_find: &str) { } else { assert_contains( stderr, - format!("unknown debuginfo compression algorithm {compression}"), + format!("unsupported debuginfo compression algorithm {compression}"), ); } });
diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr index ef7fb70..42dc805 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.stderr +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr
@@ -46,11 +46,11 @@ | --------------- this is the trait that was imported = help: you can use `cargo tree` to explore your dependency tree -error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope +error[E0599]: no associated function or constant named `bar` found for struct `dep_2_reexport::Type` in the current scope --> replaced | LL | Type::bar(); - | ^^^ function or associated item not found in `dep_2_reexport::Type` + | ^^^ associated function or constant not found in `dep_2_reexport::Type` | note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced @@ -177,14 +177,14 @@ | this can't be annotated with `?` because it has type `Result<_, Error2>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait -help: the following other types implement trait `From<T>` +help: `dependency::OtherError` implements trait `From<T>` --> replaced | LL | impl From<()> for OtherError { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<()>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<()>` ... LL | impl From<i32> for OtherError { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<i32>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<i32>` = note: there are multiple different versions of crate `dependency` in the dependency graph = help: you can use `cargo tree` to explore your dependency tree
diff --git a/tests/run-make/incremental-finalize-fail/foo.rs b/tests/run-make/incremental-finalize-fail/foo.rs new file mode 100644 index 0000000..1f1e284 --- /dev/null +++ b/tests/run-make/incremental-finalize-fail/foo.rs
@@ -0,0 +1,5 @@ +poison::poison_finalize!(); + +pub fn hello() -> i32 { + 42 +}
diff --git a/tests/run-make/incremental-finalize-fail/poison/lib.rs b/tests/run-make/incremental-finalize-fail/poison/lib.rs new file mode 100644 index 0000000..e191cf7 --- /dev/null +++ b/tests/run-make/incremental-finalize-fail/poison/lib.rs
@@ -0,0 +1,87 @@ +//! A proc macro that sabotages the incremental compilation finalize step. +//! +//! When invoked, it locates the `-working` session directory inside the +//! incremental compilation directory (passed via POISON_INCR_DIR) and +//! makes it impossible to rename: +//! +//! - On Unix: removes write permission from the parent (crate) directory. +//! - On Windows: creates a file inside the -working directory and leaks +//! the file handle, preventing the directory from being renamed. + +extern crate proc_macro; + +use std::fs; +use std::path::PathBuf; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn poison_finalize(_input: TokenStream) -> TokenStream { + let incr_dir = std::env::var("POISON_INCR_DIR").expect("POISON_INCR_DIR must be set"); + + let crate_dir = find_crate_dir(&incr_dir); + let working_dir = find_working_dir(&crate_dir); + + #[cfg(unix)] + poison_unix(&crate_dir); + + #[cfg(windows)] + poison_windows(&working_dir); + + TokenStream::new() +} + +/// Remove write permission from the crate directory. +/// This causes rename() to fail with EACCES +#[cfg(unix)] +fn poison_unix(crate_dir: &PathBuf) { + use std::os::unix::fs::PermissionsExt; + let mut perms = fs::metadata(crate_dir).unwrap().permissions(); + perms.set_mode(0o555); // r-xr-xr-x + fs::set_permissions(crate_dir, perms).unwrap(); +} + +/// Create a file inside the -working directory and leak the +/// handle. Windows prevents renaming a directory when any file inside it +/// has an open handle. The handle stays open until the rustc process exits. +#[cfg(windows)] +fn poison_windows(working_dir: &PathBuf) { + let poison_file = working_dir.join("_poison_handle"); + let f = fs::File::create(&poison_file).unwrap(); + // Leak the handle so it stays open for the lifetime of the rustc process. + std::mem::forget(f); +} + +/// Find the crate directory for `foo` inside the incremental compilation dir. +/// +/// The incremental directory layout is: +/// {incr_dir}/{crate_name}-{stable_crate_id}/ +fn find_crate_dir(incr_dir: &str) -> PathBuf { + let mut dirs = fs::read_dir(incr_dir).unwrap().filter_map(|e| { + let e = e.ok()?; + let name = e.file_name(); + let name = name.to_str()?; + if e.file_type().ok()?.is_dir() && name.starts_with("foo-") { Some(e.path()) } else { None } + }); + + let first = + dirs.next().unwrap_or_else(|| panic!("no foo-* crate directory found in {incr_dir}")); + assert!( + dirs.next().is_none(), + "expected exactly one foo-* crate directory in {incr_dir}, found multiple" + ); + first +} + +/// Find the session directory ending in "-working" inside the crate directory +fn find_working_dir(crate_dir: &PathBuf) -> PathBuf { + for entry in fs::read_dir(crate_dir).unwrap() { + let entry = entry.unwrap(); + let name = entry.file_name(); + let name = name.to_str().unwrap().to_string(); + if name.starts_with("s-") && name.ends_with("-working") { + return entry.path(); + } + } + panic!("no -working session directory found in {}", crate_dir.display()); +}
diff --git a/tests/run-make/incremental-finalize-fail/rmake.rs b/tests/run-make/incremental-finalize-fail/rmake.rs new file mode 100644 index 0000000..96dae48 --- /dev/null +++ b/tests/run-make/incremental-finalize-fail/rmake.rs
@@ -0,0 +1,106 @@ +//@ ignore-cross-compile +//@ needs-crate-type: proc-macro + +//! Test that a failure to finalize the incremental compilation session directory +//! (i.e., the rename from "-working" to the SVH-based name) results in a +//! note, not an ICE, and that the compilation output is still produced. +//! +//! Strategy: +//! 1. Build the `poison` proc-macro crate +//! 2. Compile foo.rs with incremental compilation +//! The proc macro runs mid-compilation (after prepare_session_directory +//! but before finalize_session_directory) and sabotages the rename: +//! - On Unix: removes write permission from the crate directory, +//! so rename() fails with EACCES. +//! - On Windows: creates and leaks an open file handle inside the +//! -working directory, so rename() fails with ERROR_ACCESS_DENIED. +//! 3. Assert that stderr contains the finalize failure messages + +use std::fs; +use std::path::{Path, PathBuf}; + +use run_make_support::rustc; + +/// Guard that restores permissions on the incremental directory on drop, +/// to ensure cleanup is possible +struct IncrDirCleanup; + +fn main() { + let _cleanup = IncrDirCleanup; + + // Build the poison proc-macro crate + rustc().input("poison/lib.rs").crate_name("poison").crate_type("proc-macro").run(); + + let poison_dylib = find_proc_macro_dylib("poison"); + + // Incremental compile with the poison macro active + let out = rustc() + .input("foo.rs") + .crate_type("rlib") + .incremental("incr") + .extern_("poison", &poison_dylib) + .env("POISON_INCR_DIR", "incr") + .run(); + + out.assert_stderr_contains("note: did not finalize incremental compilation session directory"); + out.assert_stderr_contains( + "help: the next build will not be able to reuse work from this compilation", + ); + out.assert_stderr_not_contains("internal compiler error"); +} + +impl Drop for IncrDirCleanup { + fn drop(&mut self) { + let incr = Path::new("incr"); + if !incr.exists() { + return; + } + + #[cfg(unix)] + restore_permissions(incr); + } +} + +/// Recursively restore write permissions so rm -rf works after the chmod trick +#[cfg(unix)] +fn restore_permissions(path: &Path) { + use std::os::unix::fs::PermissionsExt; + if let Ok(entries) = fs::read_dir(path) { + for entry in entries.filter_map(|e| e.ok()) { + if entry.file_type().map_or(false, |ft| ft.is_dir()) { + let mut perms = match fs::metadata(entry.path()) { + Ok(m) => m.permissions(), + Err(_) => continue, + }; + perms.set_mode(0o755); + let _ = fs::set_permissions(entry.path(), perms); + } + } + } +} + +/// Locate the compiled proc-macro dylib by scanning the current directory. +fn find_proc_macro_dylib(name: &str) -> PathBuf { + let prefix = if cfg!(target_os = "windows") { "" } else { "lib" }; + + let ext: &str = if cfg!(target_os = "macos") { + "dylib" + } else if cfg!(target_os = "windows") { + "dll" + } else { + "so" + }; + + let lib_name = format!("{prefix}{name}.{ext}"); + + for entry in fs::read_dir(".").unwrap() { + let entry = entry.unwrap(); + let name = entry.file_name(); + let name = name.to_str().unwrap(); + if name == lib_name { + return entry.path(); + } + } + + panic!("could not find proc-macro dylib for `{name}`"); +}
diff --git a/tests/run-make/instrument-mcount-link-pg/main.rs b/tests/run-make/instrument-mcount-link-pg/main.rs new file mode 100644 index 0000000..47ad8c6 --- /dev/null +++ b/tests/run-make/instrument-mcount-link-pg/main.rs
@@ -0,0 +1,3 @@ +fn main() { + println!("Hello World!"); +}
diff --git a/tests/run-make/instrument-mcount-link-pg/rmake.rs b/tests/run-make/instrument-mcount-link-pg/rmake.rs new file mode 100644 index 0000000..184bd94 --- /dev/null +++ b/tests/run-make/instrument-mcount-link-pg/rmake.rs
@@ -0,0 +1,19 @@ +// When building a binary instrumented with mcount, verify the +// binary is linked with the correct crt to enable profiling. +// +//@ only-gnu +//@ ignore-cross-compile + +use run_make_support::{path, run, rustc}; + +fn main() { + // Compile instrumentation enabled binary, and verify -pg is passed + let link_args = + rustc().input("main.rs").arg("-Zinstrument-mcount").print("link-args").run().stdout_utf8(); + assert!(link_args.contains("\"-pg\"")); + + // Run it, and verify gmon.out is created + assert!(!path("gmon.out").exists()); + run("main"); + assert!(path("gmon.out").exists()); +}
diff --git a/tests/rustdoc-gui/item-info-overflow.goml b/tests/rustdoc-gui/item-info-overflow.goml index 2c4e06e..b53ffb0 100644 --- a/tests/rustdoc-gui/item-info-overflow.goml +++ b/tests/rustdoc-gui/item-info-overflow.goml
@@ -8,7 +8,7 @@ // Just to be sure we're comparing the correct "item-info": assert-text: ( ".item-info", - "Available on Android or Linux or Emscripten or DragonFly BSD", + "Available on Android or Linux or Emscripten or DragonFly BSD or FreeBSD or NetBSD or OpenBSD", STARTS_WITH, ) @@ -26,6 +26,6 @@ // Just to be sure we're comparing the correct "item-info": assert-text: ( "#impl-SimpleTrait-for-LongItemInfo2 .item-info", - "Available on Android or Linux or Emscripten or DragonFly BSD", + "Available on Android or Linux or Emscripten or DragonFly BSD or FreeBSD or NetBSD or OpenBSD", STARTS_WITH, )
diff --git a/tests/rustdoc-html/doc-cfg/all-targets.rs b/tests/rustdoc-html/doc-cfg/all-targets.rs new file mode 100644 index 0000000..4db41e1 --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/all-targets.rs
@@ -0,0 +1,139 @@ +#![feature(doc_cfg)] + +//@ has all_targets/fn.foo.html \ +// '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on GNU or Catalyst or mac ABI or MSVC or musl or Newlib or \ +// Neutrino 7.0 or Neutrino 7.1 or Neutrino 7.1 with io-sock or Neutrino 8.0 or \ +// OpenHarmony or relibc or SGX or Simulator or WASIp1 or WASIp2 or WASIp3 or \ +// uClibc or V5 or target_env=fake_env only.' +#[doc(cfg(any( + target_env = "gnu", + target_env = "macabi", + target_env = "mlibc", + target_env = "msvc", + target_env = "musl", + target_env = "newlib", + target_env = "nto70", + target_env = "nto71", + target_env = "nto71_iosock", + target_env = "nto80", + target_env = "ohos", + target_env = "relibc", + target_env = "sgx", + target_env = "sim", + target_env = "p1", + target_env = "p2", + target_env = "p3", + target_env = "uclibc", + target_env = "v5", + target_env = "fake_env", +)))] +pub fn foo() {} + +//@ has all_targets/fn.bar.html \ +// '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on AArch64 or AMG GPU or ARM or ARM64EC or AVR or BPF or C-SKY or \ +// Hexagon or LoongArch64 or LoongArch32 or Motorola 680x0 or MIPS or MIPS release \ +// 6 or MIPS-64 or MIPS-64 release 6 or MSP430 or NVidia GPU or PowerPC or \ +// PowerPC64 or RISC-V RV32 or RISC-V RV64 or s390x or SPARC or SPARC-64 or SPIR-V \ +// or WebAssembly or WebAssembly or x86 or x86-64 or Xtensa or \ +// target_arch=fake_arch only.' +#[doc(cfg(any( + target_arch = "aarch64", + target_arch = "amdgpu", + target_arch = "arm", + target_arch = "arm64ec", + target_arch = "avr", + target_arch = "bpf", + target_arch = "csky", + target_arch = "hexagon", + target_arch = "loongarch32", + target_arch = "loongarch64", + target_arch = "m68k", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "msp430", + target_arch = "nvptx64", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "spirv", + target_arch = "wasm32", + target_arch = "wasm64", + target_arch = "x86", + target_arch = "x86_64", + target_arch = "xtensa", + target_arch = "fake_arch", +)))] +pub fn bar() {} + +//@ has all_targets/fn.baz.html \ +// '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on AIX and AMD HSA and Android and CUDA and Cygwin and DragonFly \ +// BSD and Emscripten and ESP-IDF and FreeBSD and Fuchsia and Haiku and HelenOS \ +// and Hermit and Horizon and GNU/Hurd and illumos and iOS and L4Re and Linux \ +// and LynxOS-178 and macOS and Managarm and Motor OS and NetBSD and bare-metal \ +// and QNX Neutrino and NuttX and OpenBSD and Play Station Portable and Play \ +// Station 1 and QuRT and Redox OS and RTEMS OS and Solaris and SOLID ASP3 and \ +// TEEOS and Trusty and tvOS and UEFI and VEXos and visionOS and Play Station \ +// Vita and VxWorks and WASI and watchOS and Windows and Xous and zero knowledge \ +// Virtual Machine and target_os=unknown and target_os=fake_os only.' +#[doc(cfg(all( + target_os = "aix", + target_os = "amdhsa", + target_os = "android", + target_os = "cuda", + target_os = "cygwin", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "helenos", + target_os = "hermit", + target_os = "horizon", + target_os = "hurd", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "linux", + target_os = "lynxos178", + target_os = "macos", + target_os = "managarm", + target_os = "motor", + target_os = "netbsd", + target_os = "none", + target_os = "nto", + target_os = "nuttx", + target_os = "openbsd", + target_os = "psp", + target_os = "psx", + target_os = "qurt", + target_os = "redox", + target_os = "rtems", + target_os = "solaris", + target_os = "solid_asp3", + target_os = "teeos", + target_os = "trusty", + target_os = "tvos", + target_os = "uefi", + target_os = "vexos", + target_os = "visionos", + target_os = "vita", + target_os = "vxworks", + target_os = "wasi", + target_os = "watchos", + target_os = "windows", + target_os = "xous", + target_os = "zkvm", + target_os = "unknown", + target_os = "fake_os", +)))] +pub fn baz() {}
diff --git a/tests/rustdoc-html/doc-cfg/trait-impls-manual.rs b/tests/rustdoc-html/doc-cfg/trait-impls-manual.rs new file mode 100644 index 0000000..fbd96cc --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/trait-impls-manual.rs
@@ -0,0 +1,92 @@ +// This test ensures that `doc_cfg` feature is working as expected on trait impls. +// Regression test for <https://github.com/rust-lang/rust/issues/153655>. + +#![feature(doc_cfg)] +#![doc(auto_cfg(hide( + target_pointer_width = "64", +)))] + +#![crate_name = "foo"] + +pub trait Trait { + fn f(&self) {} +} + +pub trait Bob { + fn bob(&self) {} +} + +pub trait Foo { + fn foo(&self) {} +} + +pub struct X; + +//@has 'foo/struct.X.html' +//@count - '//*[@id="impl-Bob-for-X"]' 1 +//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 +//@count - '//*[@id="impl-Trait-for-X"]' 1 +//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 + +// If you need to update this XPath, in particular `item-info`, update all +// the others in this file. +//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 + +//@has 'foo/trait.Trait.html' +//@count - '//*[@id="impl-Trait-for-X"]' 1 +//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +#[doc(auto_cfg(hide(target_arch = "wasm32")))] +mod imp { + impl super::Trait for super::X { fn f(&self) {} } +} + +//@has 'foo/trait.Bob.html' +//@count - '//*[@id="impl-Bob-for-X"]' 1 +//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +#[doc(auto_cfg = false)] +mod imp2 { + impl super::Bob for super::X { fn bob(&self) {} } +} + +//@has 'foo/trait.Foo.html' +//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 +// We use this to force xpath tests to be updated if `item-info` class is changed. +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +mod imp3 { + impl super::Foo for super::X { fn foo(&self) {} } +} + +pub struct Y; + +//@has 'foo/struct.Y.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +#[doc(auto_cfg(hide(target_arch = "wasm32")))] +mod imp4 { + impl super::Y { pub fn plain_auto() {} } +} + +pub struct Z; + +//@has 'foo/struct.Z.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +#[doc(auto_cfg = false)] +mod imp5 { + impl super::Z { pub fn plain_auto() {} } +} + +// The "witness" which has the item info. +pub struct W; + +//@has 'foo/struct.W.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 1 +#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] +mod imp6 { + impl super::W { pub fn plain_auto() {} } +}
diff --git a/tests/rustdoc-html/doc-cfg/trait-impls.rs b/tests/rustdoc-html/doc-cfg/trait-impls.rs new file mode 100644 index 0000000..581d171 --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/trait-impls.rs
@@ -0,0 +1,92 @@ +// This test ensures that `doc_cfg` feature is working as expected on trait impls. +// Regression test for <https://github.com/rust-lang/rust/issues/153655>. + +#![feature(doc_cfg)] +#![doc(auto_cfg(hide( + target_pointer_width = "64", +)))] + +#![crate_name = "foo"] + +pub trait Trait { + fn f(&self) {} +} + +pub trait Bob { + fn bob(&self) {} +} + +pub trait Foo { + fn foo(&self) {} +} + +pub struct X; + +//@has 'foo/struct.X.html' +//@count - '//*[@id="impl-Bob-for-X"]' 1 +//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 +//@count - '//*[@id="impl-Trait-for-X"]' 1 +//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 + +// If you need to update this XPath, in particular `item-info`, update all +// the others in this file. +//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 + +//@has 'foo/trait.Trait.html' +//@count - '//*[@id="impl-Trait-for-X"]' 1 +//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +#[doc(auto_cfg(hide(target_arch = "wasm32")))] +mod imp { + impl super::Trait for super::X { fn f(&self) {} } +} + +//@has 'foo/trait.Bob.html' +//@count - '//*[@id="impl-Bob-for-X"]' 1 +//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +#[doc(auto_cfg = false)] +mod imp2 { + impl super::Bob for super::X { fn bob(&self) {} } +} + +//@has 'foo/trait.Foo.html' +//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 +// We use this to force xpath tests to be updated if `item-info` class is changed. +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +mod imp3 { + impl super::Foo for super::X { fn foo(&self) {} } +} + +pub struct Y; + +//@has 'foo/struct.Y.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +#[doc(auto_cfg(hide(target_arch = "wasm32")))] +mod imp4 { + impl super::Y { pub fn plain_auto() {} } +} + +pub struct Z; + +//@has 'foo/struct.Z.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +#[doc(auto_cfg = false)] +mod imp5 { + impl super::Z { pub fn plain_auto() {} } +} + +// The "witness" which has the item info. +pub struct W; + +//@has 'foo/struct.W.html' +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 +//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 1 +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +mod imp6 { + impl super::W { pub fn plain_auto() {} } +}
diff --git a/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs b/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs new file mode 100644 index 0000000..1c73678 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs
@@ -0,0 +1,10 @@ +//@ check-pass + +// Regression test for <https://github.com/rust-lang/rust/issues/154383>. +// Rustdoc used to ICE on the doc link attached to a `pub use` inside a +// private module. + +mod inner { + /// [std::vec::Vec] + pub use std::vec::Vec as MyVec; +}
diff --git a/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr b/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr new file mode 100644 index 0000000..8d8e8c6 --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr
@@ -0,0 +1,2 @@ +error: the `--emit=html-non-static-files` flag is not supported with `--output-format=json` +
diff --git a/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr b/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr new file mode 100644 index 0000000..bc1ddc1 --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr
@@ -0,0 +1,2 @@ +error: the `--emit=html-static-files` flag is not supported with `--output-format=json` +
diff --git a/tests/rustdoc-ui/output-format-json-emit-html.rs b/tests/rustdoc-ui/output-format-json-emit-html.rs new file mode 100644 index 0000000..7a99cbd --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.rs
@@ -0,0 +1,8 @@ +//@ revisions: html_static html_non_static +//@ check-fail +//@[html_static] compile-flags: -Z unstable-options --output-format=json --emit=html-static-files +//@[html_non_static] compile-flags: -Z unstable-options --output-format=json --emit=html-non-static-files +//[html_static]~? ERROR the `--emit=html-static-files` flag is not supported with `--output-format=json` +//[html_non_static]~? ERROR the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + +pub struct Foo;
diff --git a/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs new file mode 100644 index 0000000..b0f67a3 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs
@@ -0,0 +1,5 @@ +//@ compile-flags: -Z unstable-options --show-coverage --output-format=json --emit=html-non-static-files +//@ check-fail +//~? ERROR the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + +pub struct Foo;
diff --git a/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr new file mode 100644 index 0000000..8d8e8c6 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr
@@ -0,0 +1,2 @@ +error: the `--emit=html-non-static-files` flag is not supported with `--output-format=json` +
diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index 6a5d1b5..f7f0c98 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs
@@ -3,6 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" struct A; struct B;
diff --git a/tests/ui/README.md b/tests/ui/README.md index c14cbd9..a9e7f02 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md
@@ -36,6 +36,8 @@ [`annotate-snippets`]: https://github.com/rust-lang/annotate-snippets-rs +**FIXME**: merge this with `error-emitter` + ## `tests/ui/anon-params` These tests deal with anonymous parameters (no name, only type), a deprecated feature that becomes a hard error in Edition 2018. @@ -141,6 +143,8 @@ Tests for pattern binding in match expressions, let statements, and other binding contexts. E.g. binding modes and refutability. See [Patterns | Reference](https://doc.rust-lang.org/reference/patterns.html). +**FIXME**: quite some overlap with `tests/ui/pattern` and `tests/ui/match`. + ## `tests/ui/binop/`: Binary operators Tests for binary operators (such as `==`, `&&` or `^`). E.g. overloading, type checking, and diagnostics for invalid operations. @@ -272,7 +276,7 @@ Some traits' implementation must be compared with their definition, checking for problems such as the implementation having stricter requirements (such as needing to implement `Copy`). -This subdirectory is *not* intended comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`). +This subdirectory is *not* intended for comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`). ## `tests/ui/compile-flags/` @@ -448,6 +452,8 @@ Exercises diagnostics for disallowed struct destructuring. +**FIXME**: does this really need to be its own immediate subdirectory? + ## `tests/ui/dist` Tests that require distribution artifacts. @@ -508,7 +514,7 @@ ## `tests/ui/eii`: Externally Implementable Items -Exercises `eii` keyword. +Exercises the `#[eii]` attribute and related features. ## `tests/ui/entry-point/`: `main` function @@ -611,8 +617,6 @@ Anything to do with loops and `for`, `loop` and `while` keywords to express them. -**FIXME**: After `ui/for` is merged into this, also carry over its SUMMARY text. - ## `tests/ui/force-inlining/`: `#[rustc_force_inline]` Tests for `#[rustc_force_inline]`, which will force a function to always be labelled as inline by the compiler (it will be inserted at the point of its call instead of being used as a normal function call.) If the compiler is unable to inline the function, an error will be reported. See <https://github.com/rust-lang/rust/pull/134082>. @@ -730,6 +734,8 @@ Tests for diagnostics on infinitely recursive types without indirection. +**FIXME**: check for overlap with `structs-enums/enum-rec` and `structs-enums/struct-rec` + ## `tests/ui/inline-const/` These tests revolve around the inline `const` block that forces the compiler to const-eval its content. @@ -853,7 +859,9 @@ ## `tests/ui/loop-match` -Tests for `loop` with `match` expressions. +Tests for the `loop_match` feature to optimize `loop`s consisting of one big `match` expressions. + +See [Tracking issue for way to express intraprocedural finite state machines #132306](https://github.com/rust-lang/rust/issues/132306). ## `tests/ui/loops/` @@ -891,6 +899,8 @@ Broad category of tests on `match` constructs. +**FIXME**: many tests overlap with `tests/ui/bindings`, try to reduce duplication. + ## `tests/ui/methods/` A broad category for anything related to methods and method resolution. @@ -899,6 +909,8 @@ Certain mir-opt regression tests. +**FIXME**: many tests in this directory are not about MIR or optimizations, relocate these. + ## `tests/ui/mir-dataflow` Tests for MIR dataflow analysis. @@ -977,6 +989,8 @@ Tests that checks numeric types and their interactions, such as casting among them with `as` or providing the wrong numeric suffix. +**FIXME**: these tests could get moved to other directories, in particular `cast/` or `parser/`. + ## `tests/ui/object-lifetime/` Tests on lifetimes on objects, such as a lifetime bound not being able to be deduced from context, or checking that lifetimes are inherited properly. @@ -1308,7 +1322,7 @@ ## `tests/ui/str/` -Exercise `str` keyword and string slices. +Exercise `str` primitive and string slices. ## `tests/ui/structs/` @@ -1420,7 +1434,7 @@ ## `tests/ui/try-block/` -`#![feature(try_blocks)]`. See [Tracking issue for `?` operator and `try` blocks (RFC 243, `question_mark` & `try_blocks` features)](https://github.com/rust-lang/rust/issues/31436). +`#![feature(try_blocks)]` & `#![feature(try_blocks_heterogeneous)]`. See [Tracking Issue for homogeneous `try_blocks`](https://github.com/rust-lang/rust/issues/154391) & [Experimental Tracking Issue for Heterogeneous Try Blocks](https://github.com/rust-lang/rust/issues/149488). ## `tests/ui/try-trait/` @@ -1464,6 +1478,8 @@ `#![feature(unboxed_closures)]`, `Fn`, `FnMut` and `FnOnce` traits +**FIXME**: many tests have `unboxed-closure` in their name but only test normal closures, rename these. + See [Tracking issue for Fn traits (`unboxed_closures` & `fn_traits` feature)](https://github.com/rust-lang/rust/issues/29625). ## `tests/ui/underscore-lifetime/`: `'_` elided lifetime
diff --git a/tests/ui/asm/aarch64/aarch64-sve.rs b/tests/ui/asm/aarch64/aarch64-sve.rs index 81c82d5..a146d73 100644 --- a/tests/ui/asm/aarch64/aarch64-sve.rs +++ b/tests/ui/asm/aarch64/aarch64-sve.rs
@@ -1,13 +1,17 @@ -//@ only-aarch64 //@ build-pass -//@ needs-asm-support - +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![crate_type = "rlib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; // AArch64 test corresponding to arm64ec-sve.rs. -use std::arch::asm; - fn f(x: f64) { unsafe { asm!("", out("p0") _);
diff --git a/tests/ui/asm/aarch64/bad-options.rs b/tests/ui/asm/aarch64/bad-options.rs index 9e721d5..ebba925 100644 --- a/tests/ui/asm/aarch64/bad-options.rs +++ b/tests/ui/asm/aarch64/bad-options.rs
@@ -1,6 +1,13 @@ -//@ only-aarch64 +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::{asm, global_asm}; +extern crate minicore; +use minicore::*; fn main() { let mut foo = 0;
diff --git a/tests/ui/asm/aarch64/bad-options.stderr b/tests/ui/asm/aarch64/bad-options.stderr index 54ab7ca..8f3e464 100644 --- a/tests/ui/asm/aarch64/bad-options.stderr +++ b/tests/ui/asm/aarch64/bad-options.stderr
@@ -1,35 +1,35 @@ error: the `nomem` and `readonly` options are mutually exclusive - --> $DIR/bad-options.rs:8:18 + --> $DIR/bad-options.rs:15:18 | LL | asm!("", options(nomem, readonly)); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: the `pure` and `noreturn` options are mutually exclusive - --> $DIR/bad-options.rs:10:18 + --> $DIR/bad-options.rs:17:18 | LL | asm!("", options(pure, nomem, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm with the `pure` option must have at least one output - --> $DIR/bad-options.rs:10:18 + --> $DIR/bad-options.rs:17:18 | LL | asm!("", options(pure, nomem, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm with the `pure` option must have at least one output - --> $DIR/bad-options.rs:13:33 + --> $DIR/bad-options.rs:20:33 | LL | asm!("{}", in(reg) foo, options(pure, nomem)); | ^^^^^^^^^^^^^^^^^^^^ error: asm outputs are not allowed with the `noreturn` option - --> $DIR/bad-options.rs:15:20 + --> $DIR/bad-options.rs:22:20 | LL | asm!("{}", out(reg) foo, options(noreturn)); | ^^^^^^^^^^^^ error: asm with `clobber_abi` must specify explicit registers for outputs - --> $DIR/bad-options.rs:22:20 + --> $DIR/bad-options.rs:29:20 | LL | asm!("{}", out(reg) foo, clobber_abi("C")); | ^^^^^^^^^^^^ ---------------- clobber_abi @@ -37,48 +37,48 @@ | generic outputs error: the `nomem` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:28:25 + --> $DIR/bad-options.rs:35:25 | LL | global_asm!("", options(nomem)); | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly error: the `readonly` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:30:25 + --> $DIR/bad-options.rs:37:25 | LL | global_asm!("", options(readonly)); | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly error: the `noreturn` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:32:25 + --> $DIR/bad-options.rs:39:25 | LL | global_asm!("", options(noreturn)); | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly error: the `pure` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:34:25 + --> $DIR/bad-options.rs:41:25 | LL | global_asm!("", options(pure)); | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly error: the `nostack` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:36:25 + --> $DIR/bad-options.rs:43:25 | LL | global_asm!("", options(nostack)); | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly error: the `preserves_flags` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:38:25 + --> $DIR/bad-options.rs:45:25 | LL | global_asm!("", options(preserves_flags)); | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: invalid ABI for `clobber_abi` - --> $DIR/bad-options.rs:20:18 + --> $DIR/bad-options.rs:27:18 | LL | asm!("", clobber_abi("foo")); | ^^^^^^^^^^^^^^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi` + = note: the following ABIs are supported on this target: `C`, `system`, and `efiapi` error: aborting due to 13 previous errors
diff --git a/tests/ui/asm/aarch64/bad-reg.rs b/tests/ui/asm/aarch64/bad-reg.rs index b99e5fe..39a3e38 100644 --- a/tests/ui/asm/aarch64/bad-reg.rs +++ b/tests/ui/asm/aarch64/bad-reg.rs
@@ -1,7 +1,13 @@ -//@ only-aarch64 -//@ compile-flags: -C target-feature=+neon +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu -C target-feature=+neon +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; fn main() { let mut foo = 0; @@ -14,11 +20,11 @@ fn main() { asm!("", in("foo") foo); //~^ ERROR invalid register `foo`: unknown register asm!("{:z}", in(reg) foo); - //~^ ERROR invalid asm template modifier for this register class + //~^ ERROR invalid asm template modifier `z` for this register class asm!("{:r}", in(vreg) foo); - //~^ ERROR invalid asm template modifier for this register class + //~^ ERROR invalid asm template modifier `r` for this register class asm!("{:r}", in(vreg_low16) foo); - //~^ ERROR invalid asm template modifier for this register class + //~^ ERROR invalid asm template modifier `r` for this register class asm!("{:a}", const 0); //~^ ERROR asm template modifiers are not allowed for `const` arguments asm!("{:a}", sym main);
diff --git a/tests/ui/asm/aarch64/bad-reg.stderr b/tests/ui/asm/aarch64/bad-reg.stderr index c76722f..9f3d54e 100644 --- a/tests/ui/asm/aarch64/bad-reg.stderr +++ b/tests/ui/asm/aarch64/bad-reg.stderr
@@ -1,49 +1,49 @@ error: invalid register class `foo`: unknown register class - --> $DIR/bad-reg.rs:12:20 + --> $DIR/bad-reg.rs:18:20 | LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ | - = note: the following register classes are supported on this target: `reg`, `vreg`, `vreg_low16`, `preg` + = note: the following register classes are supported on this target: `reg`, `vreg`, `vreg_low16`, and `preg` error: invalid register `foo`: unknown register - --> $DIR/bad-reg.rs:14:18 + --> $DIR/bad-reg.rs:20:18 | LL | asm!("", in("foo") foo); | ^^^^^^^^^^^^^ -error: invalid asm template modifier for this register class - --> $DIR/bad-reg.rs:16:15 +error: invalid asm template modifier `z` for this register class + --> $DIR/bad-reg.rs:22:15 | LL | asm!("{:z}", in(reg) foo); | ^^^^ ----------- argument | | | template modifier | - = note: the `reg` register class supports the following template modifiers: `w`, `x` + = note: the `reg` register class supports the following template modifiers: `w` and `x` -error: invalid asm template modifier for this register class - --> $DIR/bad-reg.rs:18:15 +error: invalid asm template modifier `r` for this register class + --> $DIR/bad-reg.rs:24:15 | LL | asm!("{:r}", in(vreg) foo); | ^^^^ ------------ argument | | | template modifier | - = note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v` + = note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v` -error: invalid asm template modifier for this register class - --> $DIR/bad-reg.rs:20:15 +error: invalid asm template modifier `r` for this register class + --> $DIR/bad-reg.rs:26:15 | LL | asm!("{:r}", in(vreg_low16) foo); | ^^^^ ------------------ argument | | | template modifier | - = note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v` + = note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v` error: asm template modifiers are not allowed for `const` arguments - --> $DIR/bad-reg.rs:22:15 + --> $DIR/bad-reg.rs:28:15 | LL | asm!("{:a}", const 0); | ^^^^ ------- argument @@ -51,7 +51,7 @@ | template modifier error: asm template modifiers are not allowed for `sym` arguments - --> $DIR/bad-reg.rs:24:15 + --> $DIR/bad-reg.rs:30:15 | LL | asm!("{:a}", sym main); | ^^^^ -------- argument @@ -59,49 +59,49 @@ | template modifier error: invalid register `x29`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:26:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", in("x29") foo); | ^^^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", in("sp") foo); | ^^^^^^^^^^^^ error: invalid register `xzr`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", in("xzr") foo); | ^^^^^^^^^^^^^ error: invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", in("x19") foo); | ^^^^^^^^^^^^^ error: register class `preg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", in("p0") foo); | ^^^^^^^^^^^^ error: register class `preg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:39:20 + --> $DIR/bad-reg.rs:45:20 | LL | asm!("{}", in(preg) foo); | ^^^^^^^^^^^^ error: register class `preg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:42:20 + --> $DIR/bad-reg.rs:48:20 | LL | asm!("{}", out(preg) _); | ^^^^^^^^^^^ error: register `w0` conflicts with register `x0` - --> $DIR/bad-reg.rs:48:32 + --> $DIR/bad-reg.rs:54:32 | LL | asm!("", in("x0") foo, in("w0") bar); | ------------ ^^^^^^^^^^^^ register `w0` @@ -109,7 +109,7 @@ | register `x0` error: register `x0` conflicts with register `x0` - --> $DIR/bad-reg.rs:50:32 + --> $DIR/bad-reg.rs:56:32 | LL | asm!("", in("x0") foo, out("x0") bar); | ------------ ^^^^^^^^^^^^^ register `x0` @@ -117,13 +117,13 @@ | register `x0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", in("x0") foo, out("x0") bar); | ^^^^^^^^^^^^ error: register `q0` conflicts with register `v0` - --> $DIR/bad-reg.rs:53:32 + --> $DIR/bad-reg.rs:59:32 | LL | asm!("", in("v0") foo, in("q0") bar); | ------------ ^^^^^^^^^^^^ register `q0` @@ -131,7 +131,7 @@ | register `v0` error: register `q0` conflicts with register `v0` - --> $DIR/bad-reg.rs:55:32 + --> $DIR/bad-reg.rs:61:32 | LL | asm!("", in("v0") foo, out("q0") bar); | ------------ ^^^^^^^^^^^^^ register `q0` @@ -139,13 +139,13 @@ | register `v0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", in("v0") foo, out("q0") bar); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:35:27 + --> $DIR/bad-reg.rs:41:27 | LL | asm!("", in("p0") foo); | ^^^ @@ -153,7 +153,7 @@ = note: register class `preg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:39:29 + --> $DIR/bad-reg.rs:45:29 | LL | asm!("{}", in(preg) foo); | ^^^
diff --git a/tests/ui/asm/aarch64/duplicate-options.fixed b/tests/ui/asm/aarch64/duplicate-options.fixed index b221c7c..efddf95 100644 --- a/tests/ui/asm/aarch64/duplicate-options.fixed +++ b/tests/ui/asm/aarch64/duplicate-options.fixed
@@ -1,8 +1,14 @@ -//@ only-aarch64 -//@ needs-asm-support //@ run-rustfix +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ needs-asm-support +//@ ignore-backends: gcc +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; fn main() { unsafe {
diff --git a/tests/ui/asm/aarch64/duplicate-options.rs b/tests/ui/asm/aarch64/duplicate-options.rs index 44a4518..ee45e7b 100644 --- a/tests/ui/asm/aarch64/duplicate-options.rs +++ b/tests/ui/asm/aarch64/duplicate-options.rs
@@ -1,8 +1,14 @@ -//@ only-aarch64 -//@ needs-asm-support //@ run-rustfix +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ needs-asm-support +//@ ignore-backends: gcc +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; fn main() { unsafe {
diff --git a/tests/ui/asm/aarch64/duplicate-options.stderr b/tests/ui/asm/aarch64/duplicate-options.stderr index feb3838..06bd9ea 100644 --- a/tests/ui/asm/aarch64/duplicate-options.stderr +++ b/tests/ui/asm/aarch64/duplicate-options.stderr
@@ -1,53 +1,53 @@ error: the `nomem` option was already provided - --> $DIR/duplicate-options.rs:9:33 + --> $DIR/duplicate-options.rs:15:33 | LL | asm!("", options(nomem, nomem)); | ^^^^^ this option was already provided error: the `preserves_flags` option was already provided - --> $DIR/duplicate-options.rs:11:43 + --> $DIR/duplicate-options.rs:17:43 | LL | asm!("", options(preserves_flags, preserves_flags)); | ^^^^^^^^^^^^^^^ this option was already provided error: the `nostack` option was already provided - --> $DIR/duplicate-options.rs:13:61 + --> $DIR/duplicate-options.rs:19:61 | LL | asm!("", options(nostack, preserves_flags), options(nostack)); | ^^^^^^^ this option was already provided error: the `nostack` option was already provided - --> $DIR/duplicate-options.rs:15:35 + --> $DIR/duplicate-options.rs:21:35 | LL | asm!("", options(nostack, nostack), options(nostack), options(nostack)); | ^^^^^^^ this option was already provided error: the `nostack` option was already provided - --> $DIR/duplicate-options.rs:15:53 + --> $DIR/duplicate-options.rs:21:53 | LL | asm!("", options(nostack, nostack), options(nostack), options(nostack)); | ^^^^^^^ this option was already provided error: the `nostack` option was already provided - --> $DIR/duplicate-options.rs:15:71 + --> $DIR/duplicate-options.rs:21:71 | LL | asm!("", options(nostack, nostack), options(nostack), options(nostack)); | ^^^^^^^ this option was already provided error: the `noreturn` option was already provided - --> $DIR/duplicate-options.rs:22:38 + --> $DIR/duplicate-options.rs:28:38 | LL | options(preserves_flags, noreturn), | ^^^^^^^^ this option was already provided error: the `nomem` option was already provided - --> $DIR/duplicate-options.rs:23:21 + --> $DIR/duplicate-options.rs:29:21 | LL | options(nomem, nostack), | ^^^^^ this option was already provided error: the `noreturn` option was already provided - --> $DIR/duplicate-options.rs:24:21 + --> $DIR/duplicate-options.rs:30:21 | LL | options(noreturn), | ^^^^^^^^ this option was already provided
diff --git a/tests/ui/asm/aarch64/interpolated-idents.rs b/tests/ui/asm/aarch64/interpolated-idents.rs index 3d9cf76..d51fdbc 100644 --- a/tests/ui/asm/aarch64/interpolated-idents.rs +++ b/tests/ui/asm/aarch64/interpolated-idents.rs
@@ -1,6 +1,13 @@ -//@ only-aarch64 -//@ needs-asm-support -use std::arch::asm; +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; macro_rules! m { ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
diff --git a/tests/ui/asm/aarch64/interpolated-idents.stderr b/tests/ui/asm/aarch64/interpolated-idents.stderr index 74cb992..8537a5e 100644 --- a/tests/ui/asm/aarch64/interpolated-idents.stderr +++ b/tests/ui/asm/aarch64/interpolated-idents.stderr
@@ -1,5 +1,5 @@ error: the `nomem` and `readonly` options are mutually exclusive - --> $DIR/interpolated-idents.rs:13:13 + --> $DIR/interpolated-idents.rs:20:13 | LL | $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `pure` and `noreturn` options are mutually exclusive - --> $DIR/interpolated-idents.rs:13:13 + --> $DIR/interpolated-idents.rs:20:13 | LL | $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm outputs are not allowed with the `noreturn` option - --> $DIR/interpolated-idents.rs:10:32 + --> $DIR/interpolated-idents.rs:17:32 | LL | asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x, | ^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/aarch64/parse-error.rs b/tests/ui/asm/aarch64/parse-error.rs index 622f99a..f9ee9a1 100644 --- a/tests/ui/asm/aarch64/parse-error.rs +++ b/tests/ui/asm/aarch64/parse-error.rs
@@ -1,6 +1,13 @@ -//@ only-aarch64 +//@ add-minicore +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; fn main() { let mut foo = 0;
diff --git a/tests/ui/asm/aarch64/parse-error.stderr b/tests/ui/asm/aarch64/parse-error.stderr index ca21311..630f2a4 100644 --- a/tests/ui/asm/aarch64/parse-error.stderr +++ b/tests/ui/asm/aarch64/parse-error.stderr
@@ -1,11 +1,11 @@ error: explicit register arguments cannot have names - --> $DIR/parse-error.rs:9:18 + --> $DIR/parse-error.rs:16:18 | LL | asm!("", a = in("x0") foo); | ^^^^^^^^^^^^^^^^ error: positional arguments cannot follow named arguments or explicit register arguments - --> $DIR/parse-error.rs:15:35 + --> $DIR/parse-error.rs:22:35 | LL | asm!("{1}", in("x0") foo, const bar); | ------------ ^^^^^^^^^ positional argument @@ -13,7 +13,7 @@ | explicit register argument error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:11:45 + --> $DIR/parse-error.rs:18:45 | LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value @@ -25,7 +25,7 @@ | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:13:45 + --> $DIR/parse-error.rs:20:45 | LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value @@ -37,7 +37,7 @@ | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:15:41 + --> $DIR/parse-error.rs:22:41 | LL | asm!("{1}", in("x0") foo, const bar); | ^^^ non-constant value
diff --git a/tests/ui/asm/aarch64/srcloc.rs b/tests/ui/asm/aarch64/srcloc.rs index c635fa6..91a2ef3 100644 --- a/tests/ui/asm/aarch64/srcloc.rs +++ b/tests/ui/asm/aarch64/srcloc.rs
@@ -1,12 +1,19 @@ -//@ only-aarch64 +//@ add-minicore //@ build-fail //@ needs-asm-support -//@ compile-flags: -Ccodegen-units=1 +//@ compile-flags: --target aarch64-unknown-linux-gnu -Ccodegen-units=1 +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; // Checks that inline asm errors are mapped to the correct line in the source code. - +#[unsafe(no_mangle)] +#[rustfmt::skip] fn main() { unsafe { asm!("invalid_instruction");
diff --git a/tests/ui/asm/aarch64/srcloc.stderr b/tests/ui/asm/aarch64/srcloc.stderr index b47f19b..44ee44f 100644 --- a/tests/ui/asm/aarch64/srcloc.stderr +++ b/tests/ui/asm/aarch64/srcloc.stderr
@@ -1,5 +1,5 @@ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:12:15 + --> $DIR/srcloc.rs:19:15 | LL | asm!("invalid_instruction"); | ^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:16:13 + --> $DIR/srcloc.rs:23:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:21:13 + --> $DIR/srcloc.rs:28:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -35,18 +35,6 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:27:13 - | -LL | invalid_instruction - | ^^^^^^^^^^^^^^^^^^^ - | -note: instantiated into assembly here - --> <inline asm>:3:13 - | -LL | invalid_instruction - | ^ - -error: unrecognized instruction mnemonic --> $DIR/srcloc.rs:34:13 | LL | invalid_instruction @@ -59,7 +47,19 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:39:14 + --> $DIR/srcloc.rs:41:13 + | +LL | invalid_instruction + | ^^^^^^^^^^^^^^^^^^^ + | +note: instantiated into assembly here + --> <inline asm>:3:13 + | +LL | invalid_instruction + | ^ + +error: unrecognized instruction mnemonic + --> $DIR/srcloc.rs:46:14 | LL | asm!(concat!("invalid", "_", "instruction")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:43:14 + --> $DIR/srcloc.rs:50:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ @@ -83,37 +83,25 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:49:14 - | -LL | "invalid_instruction", - | ^^^^^^^^^^^^^^^^^^^ - | -note: instantiated into assembly here - --> <inline asm>:2:1 - | -LL | invalid_instruction - | ^ - -error: unrecognized instruction mnemonic --> $DIR/srcloc.rs:56:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ | note: instantiated into assembly here - --> <inline asm>:3:1 + --> <inline asm>:2:1 | LL | invalid_instruction | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:63:13 + --> $DIR/srcloc.rs:63:14 | -LL | concat!("invalid", "_", "instruction"), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | "invalid_instruction", + | ^^^^^^^^^^^^^^^^^^^ | note: instantiated into assembly here - --> <inline asm>:2:1 + --> <inline asm>:3:1 | LL | invalid_instruction | ^ @@ -131,7 +119,19 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:77:14 + --> $DIR/srcloc.rs:77:13 + | +LL | concat!("invalid", "_", "instruction"), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: instantiated into assembly here + --> <inline asm>:2:1 + | +LL | invalid_instruction + | ^ + +error: unrecognized instruction mnemonic + --> $DIR/srcloc.rs:84:14 | LL | "invalid_instruction1", | ^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:78:14 + --> $DIR/srcloc.rs:85:14 | LL | "invalid_instruction2", | ^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:84:13 + --> $DIR/srcloc.rs:91:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -170,7 +170,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:84:13 + --> $DIR/srcloc.rs:91:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -185,7 +185,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:93:13 + --> $DIR/srcloc.rs:100:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -200,7 +200,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:93:13 + --> $DIR/srcloc.rs:100:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -215,7 +215,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:97:13 + --> $DIR/srcloc.rs:104:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -230,7 +230,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:97:13 + --> $DIR/srcloc.rs:104:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -245,7 +245,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:108:13 + --> $DIR/srcloc.rs:115:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -260,7 +260,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:108:13 + --> $DIR/srcloc.rs:115:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -275,7 +275,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:112:13 + --> $DIR/srcloc.rs:119:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -290,7 +290,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:112:13 + --> $DIR/srcloc.rs:119:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -305,7 +305,7 @@ | ^ error: unrecognized instruction mnemonic - --> $DIR/srcloc.rs:125:14 + --> $DIR/srcloc.rs:132:14 | LL | "invalid_instruction" | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/aarch64/ttbr0_el2.rs b/tests/ui/asm/aarch64/ttbr0_el2.rs index a283d75..4032c70 100644 --- a/tests/ui/asm/aarch64/ttbr0_el2.rs +++ b/tests/ui/asm/aarch64/ttbr0_el2.rs
@@ -1,7 +1,15 @@ //! Regression test for #97724, recognising ttbr0_el2 as a valid armv8 system register -//@ only-aarch64 +//@ add-minicore //@ build-pass -use std::arch::asm; +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; static PT: [u64; 512] = [0; 512]; fn main() {
diff --git a/tests/ui/asm/x86_64/bad-clobber-abi.rs b/tests/ui/asm/x86_64/bad-clobber-abi.rs index 5205a08..1b27c42 100644 --- a/tests/ui/asm/x86_64/bad-clobber-abi.rs +++ b/tests/ui/asm/x86_64/bad-clobber-abi.rs
@@ -1,7 +1,12 @@ -//@ needs-asm-support -//@ only-x86_64 +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; // checks various modes of failure for the `clobber_abi` argument (after parsing)
diff --git a/tests/ui/asm/x86_64/bad-clobber-abi.stderr b/tests/ui/asm/x86_64/bad-clobber-abi.stderr index 46e91a3..a79506a 100644 --- a/tests/ui/asm/x86_64/bad-clobber-abi.stderr +++ b/tests/ui/asm/x86_64/bad-clobber-abi.stderr
@@ -1,21 +1,21 @@ error: invalid ABI for `clobber_abi` - --> $DIR/bad-clobber-abi.rs:11:18 + --> $DIR/bad-clobber-abi.rs:16:18 | LL | asm!("", clobber_abi("foo")); | ^^^^^^^^^^^^^^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64` error: invalid ABI for `clobber_abi` - --> $DIR/bad-clobber-abi.rs:13:35 + --> $DIR/bad-clobber-abi.rs:18:35 | LL | asm!("", clobber_abi("C", "foo")); | ^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64` error: `C` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:15:35 + --> $DIR/bad-clobber-abi.rs:20:35 | LL | asm!("", clobber_abi("C", "C")); | --- ^^^ @@ -23,7 +23,7 @@ | previously specified here error: `win64` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:18:39 + --> $DIR/bad-clobber-abi.rs:23:39 | LL | asm!("", clobber_abi("win64", "efiapi")); | ------- ^^^^^^^^ @@ -33,15 +33,15 @@ = note: these ABIs are equivalent on the current target error: invalid ABI for `clobber_abi` - --> $DIR/bad-clobber-abi.rs:20:35 + --> $DIR/bad-clobber-abi.rs:25:35 | LL | asm!("", clobber_abi("C", "foo", "C")); | ^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64` error: `C` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:20:42 + --> $DIR/bad-clobber-abi.rs:25:42 | LL | asm!("", clobber_abi("C", "foo", "C")); | --- ^^^ @@ -49,15 +49,15 @@ | previously specified here error: invalid ABI for `clobber_abi` - --> $DIR/bad-clobber-abi.rs:23:39 + --> $DIR/bad-clobber-abi.rs:28:39 | LL | asm!("", clobber_abi("win64", "foo", "efiapi")); | ^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64` error: `win64` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:23:46 + --> $DIR/bad-clobber-abi.rs:28:46 | LL | asm!("", clobber_abi("win64", "foo", "efiapi")); | ------- ^^^^^^^^ @@ -67,7 +67,7 @@ = note: these ABIs are equivalent on the current target error: `C` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:26:36 + --> $DIR/bad-clobber-abi.rs:31:36 | LL | asm!("", clobber_abi("C"), clobber_abi("C")); | ---------------- ^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ | previously specified here error: `win64` ABI specified multiple times - --> $DIR/bad-clobber-abi.rs:29:40 + --> $DIR/bad-clobber-abi.rs:34:40 | LL | asm!("", clobber_abi("win64"), clobber_abi("efiapi")); | -------------------- ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/x86_64/bad-options.rs b/tests/ui/asm/x86_64/bad-options.rs index 123febc..594ee60 100644 --- a/tests/ui/asm/x86_64/bad-options.rs +++ b/tests/ui/asm/x86_64/bad-options.rs
@@ -1,8 +1,13 @@ -//@ only-x86_64 - +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] #![feature(asm_unwind)] -use std::arch::{asm, global_asm}; +extern crate minicore; +use minicore::*; fn main() { let mut foo = 0;
diff --git a/tests/ui/asm/x86_64/bad-options.stderr b/tests/ui/asm/x86_64/bad-options.stderr index 366eb7c..576d5a1 100644 --- a/tests/ui/asm/x86_64/bad-options.stderr +++ b/tests/ui/asm/x86_64/bad-options.stderr
@@ -1,41 +1,41 @@ error: the `nomem` and `readonly` options are mutually exclusive - --> $DIR/bad-options.rs:10:18 + --> $DIR/bad-options.rs:15:18 | LL | asm!("", options(nomem, readonly)); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: the `pure` and `noreturn` options are mutually exclusive - --> $DIR/bad-options.rs:12:18 + --> $DIR/bad-options.rs:17:18 | LL | asm!("", options(pure, nomem, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm with the `pure` option must have at least one output - --> $DIR/bad-options.rs:12:18 + --> $DIR/bad-options.rs:17:18 | LL | asm!("", options(pure, nomem, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm with the `pure` option must have at least one output - --> $DIR/bad-options.rs:15:33 + --> $DIR/bad-options.rs:20:33 | LL | asm!("{}", in(reg) foo, options(pure, nomem)); | ^^^^^^^^^^^^^^^^^^^^ error: asm outputs are not allowed with the `noreturn` option - --> $DIR/bad-options.rs:17:20 + --> $DIR/bad-options.rs:22:20 | LL | asm!("{}", out(reg) foo, options(noreturn)); | ^^^^^^^^^^^^ error: asm labels are not allowed with the `may_unwind` option - --> $DIR/bad-options.rs:19:20 + --> $DIR/bad-options.rs:24:20 | LL | asm!("{}", label {}, options(may_unwind)); | ^^^^^^^^ error: asm with `clobber_abi` must specify explicit registers for outputs - --> $DIR/bad-options.rs:26:20 + --> $DIR/bad-options.rs:31:20 | LL | asm!("{}", out(reg) foo, clobber_abi("C")); | ^^^^^^^^^^^^ ---------------- clobber_abi @@ -43,7 +43,7 @@ | generic outputs error: asm with `clobber_abi` must specify explicit registers for outputs - --> $DIR/bad-options.rs:28:20 + --> $DIR/bad-options.rs:33:20 | LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); | ^^^^^^^^^^^^ ---------------- ---------------- clobber_abi @@ -52,51 +52,51 @@ | generic outputs error: the `nomem` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:35:25 + --> $DIR/bad-options.rs:40:25 | LL | global_asm!("", options(nomem)); | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly error: the `readonly` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:37:25 + --> $DIR/bad-options.rs:42:25 | LL | global_asm!("", options(readonly)); | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly error: the `noreturn` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:39:25 + --> $DIR/bad-options.rs:44:25 | LL | global_asm!("", options(noreturn)); | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly error: the `pure` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:41:25 + --> $DIR/bad-options.rs:46:25 | LL | global_asm!("", options(pure)); | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly error: the `nostack` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:43:25 + --> $DIR/bad-options.rs:48:25 | LL | global_asm!("", options(nostack)); | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly error: the `preserves_flags` option cannot be used with `global_asm!` - --> $DIR/bad-options.rs:45:25 + --> $DIR/bad-options.rs:50:25 | LL | global_asm!("", options(preserves_flags)); | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: invalid ABI for `clobber_abi` - --> $DIR/bad-options.rs:24:18 + --> $DIR/bad-options.rs:29:18 | LL | asm!("", clobber_abi("foo")); | ^^^^^^^^^^^^^^^^^^ | - = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64` error: `C` ABI specified multiple times - --> $DIR/bad-options.rs:28:52 + --> $DIR/bad-options.rs:33:52 | LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); | ---------------- ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/x86_64/bad-reg.experimental_reg.stderr b/tests/ui/asm/x86_64/bad-reg.experimental_reg.stderr index 133921b..fe2a53a 100644 --- a/tests/ui/asm/x86_64/bad-reg.experimental_reg.stderr +++ b/tests/ui/asm/x86_64/bad-reg.experimental_reg.stderr
@@ -4,7 +4,7 @@ LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ | - = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, and `tmm_reg` error: invalid register `foo`: unknown register --> $DIR/bad-reg.rs:22:18 @@ -12,7 +12,7 @@ LL | asm!("", in("foo") foo); | ^^^^^^^^^^^^^ -error: invalid asm template modifier for this register class +error: invalid asm template modifier `z` for this register class --> $DIR/bad-reg.rs:24:15 | LL | asm!("{:z}", in(reg) foo); @@ -20,9 +20,9 @@ | | | template modifier | - = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, `r` + = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, and `r` -error: invalid asm template modifier for this register class +error: invalid asm template modifier `r` for this register class --> $DIR/bad-reg.rs:26:15 | LL | asm!("{:r}", in(xmm_reg) foo); @@ -30,7 +30,7 @@ | | | template modifier | - = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, `z` + = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, and `z` error: asm template modifiers are not allowed for `const` arguments --> $DIR/bad-reg.rs:28:15
diff --git a/tests/ui/asm/x86_64/bad-reg.rs b/tests/ui/asm/x86_64/bad-reg.rs index 4b3005d..cc3def9 100644 --- a/tests/ui/asm/x86_64/bad-reg.rs +++ b/tests/ui/asm/x86_64/bad-reg.rs
@@ -1,7 +1,7 @@ //@ add-minicore -//@ only-x86_64 //@ revisions: stable experimental_reg -//@ compile-flags: -C target-feature=+avx2,+avx512f +//@ compile-flags: --target x86_64-unknown-linux-gnu -C target-feature=+avx2,+avx512f +//@ needs-llvm-components: x86 #![cfg_attr(experimental_reg, feature(asm_experimental_reg))] #![crate_type = "lib"] @@ -22,9 +22,9 @@ fn main() { asm!("", in("foo") foo); //~^ ERROR invalid register `foo`: unknown register asm!("{:z}", in(reg) foo); - //~^ ERROR invalid asm template modifier for this register class + //~^ ERROR invalid asm template modifier `z` for this register class asm!("{:r}", in(xmm_reg) foo); - //~^ ERROR invalid asm template modifier for this register class + //~^ ERROR invalid asm template modifier `r` for this register class asm!("{:a}", const 0); //~^ ERROR asm template modifiers are not allowed for `const` arguments asm!("{:a}", sym main);
diff --git a/tests/ui/asm/x86_64/bad-reg.stable.stderr b/tests/ui/asm/x86_64/bad-reg.stable.stderr index a1c2792..d8a3793 100644 --- a/tests/ui/asm/x86_64/bad-reg.stable.stderr +++ b/tests/ui/asm/x86_64/bad-reg.stable.stderr
@@ -4,7 +4,7 @@ LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ | - = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, and `tmm_reg` error: invalid register `foo`: unknown register --> $DIR/bad-reg.rs:22:18 @@ -12,7 +12,7 @@ LL | asm!("", in("foo") foo); | ^^^^^^^^^^^^^ -error: invalid asm template modifier for this register class +error: invalid asm template modifier `z` for this register class --> $DIR/bad-reg.rs:24:15 | LL | asm!("{:z}", in(reg) foo); @@ -20,9 +20,9 @@ | | | template modifier | - = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, `r` + = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, and `r` -error: invalid asm template modifier for this register class +error: invalid asm template modifier `r` for this register class --> $DIR/bad-reg.rs:26:15 | LL | asm!("{:r}", in(xmm_reg) foo); @@ -30,7 +30,7 @@ | | | template modifier | - = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, `z` + = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, and `z` error: asm template modifiers are not allowed for `const` arguments --> $DIR/bad-reg.rs:28:15
diff --git a/tests/ui/asm/x86_64/goto-block-safe.rs b/tests/ui/asm/x86_64/goto-block-safe.rs index b739e9f..1364425 100644 --- a/tests/ui/asm/x86_64/goto-block-safe.rs +++ b/tests/ui/asm/x86_64/goto-block-safe.rs
@@ -1,16 +1,22 @@ -//@ only-x86_64 +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 //@ needs-asm-support - +#![feature(no_core)] +#![no_core] #![deny(unreachable_code)] -use std::arch::asm; +extern crate minicore; +use minicore::*; + +unsafe fn such_unsafe() {} fn goto_fallthough() { unsafe { asm!( "/* {} */", label { - core::hint::unreachable_unchecked(); + such_unsafe() //~^ ERROR [E0133] } )
diff --git a/tests/ui/asm/x86_64/goto-block-safe.stderr b/tests/ui/asm/x86_64/goto-block-safe.stderr index ee7313b..3f9afdd 100644 --- a/tests/ui/asm/x86_64/goto-block-safe.stderr +++ b/tests/ui/asm/x86_64/goto-block-safe.stderr
@@ -1,11 +1,11 @@ -error[E0133]: call to unsafe function `unreachable_unchecked` is unsafe and requires unsafe function or block - --> $DIR/goto-block-safe.rs:13:17 +error[E0133]: call to unsafe function `such_unsafe` is unsafe and requires unsafe function or block + --> $DIR/goto-block-safe.rs:19:17 | LL | unsafe { | ------ items do not inherit unsafety from separate enclosing items ... -LL | core::hint::unreachable_unchecked(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function +LL | such_unsafe() + | ^^^^^^^^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior
diff --git a/tests/ui/asm/x86_64/goto.stderr b/tests/ui/asm/x86_64/goto.stderr index da3f7d6..e5bfb43 100644 --- a/tests/ui/asm/x86_64/goto.stderr +++ b/tests/ui/asm/x86_64/goto.stderr
@@ -22,9 +22,11 @@ --> $DIR/goto.rs:71:25 | LL | let mut value = false; - | ^^^^^ + | ^^^^^ this value is reassigned later and never used +... +LL | value = true; + | ------------ `value` is overwritten here before the previous value is read | - = help: maybe it is overwritten before being read? = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default warning: 2 warnings emitted
diff --git a/tests/ui/asm/x86_64/interpolated-idents.rs b/tests/ui/asm/x86_64/interpolated-idents.rs index 4f349c5..97908026 100644 --- a/tests/ui/asm/x86_64/interpolated-idents.rs +++ b/tests/ui/asm/x86_64/interpolated-idents.rs
@@ -1,6 +1,12 @@ -//@ only-x86_64 +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; macro_rules! m { ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
diff --git a/tests/ui/asm/x86_64/interpolated-idents.stderr b/tests/ui/asm/x86_64/interpolated-idents.stderr index a91bc76..1fb817e 100644 --- a/tests/ui/asm/x86_64/interpolated-idents.stderr +++ b/tests/ui/asm/x86_64/interpolated-idents.stderr
@@ -1,5 +1,5 @@ error: the `nomem` and `readonly` options are mutually exclusive - --> $DIR/interpolated-idents.rs:13:13 + --> $DIR/interpolated-idents.rs:19:13 | LL | $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `pure` and `noreturn` options are mutually exclusive - --> $DIR/interpolated-idents.rs:13:13 + --> $DIR/interpolated-idents.rs:19:13 | LL | $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm outputs are not allowed with the `noreturn` option - --> $DIR/interpolated-idents.rs:10:32 + --> $DIR/interpolated-idents.rs:16:32 | LL | asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x, | ^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/x86_64/issue-82869.rs b/tests/ui/asm/x86_64/issue-82869.rs index 448ebd9..4af09cb 100644 --- a/tests/ui/asm/x86_64/issue-82869.rs +++ b/tests/ui/asm/x86_64/issue-82869.rs
@@ -1,10 +1,14 @@ -//@ needs-asm-support -//@ only-x86_64 -// Make sure rustc doesn't ICE on asm! for a foreign architecture. - +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 #![crate_type = "rlib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; + +// Make sure rustc doesn't ICE on asm! for a foreign architecture. pub unsafe fn aarch64(a: f64, b: f64) -> f64 { let c;
diff --git a/tests/ui/asm/x86_64/issue-82869.stderr b/tests/ui/asm/x86_64/issue-82869.stderr index 56e4909..56699ac 100644 --- a/tests/ui/asm/x86_64/issue-82869.stderr +++ b/tests/ui/asm/x86_64/issue-82869.stderr
@@ -1,21 +1,21 @@ error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:11:32 + --> $DIR/issue-82869.rs:15:32 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^^ | - = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, and `tmm_reg` error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:11:45 + --> $DIR/issue-82869.rs:15:45 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^ | - = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, and `tmm_reg` error: invalid register `d0`: unknown register - --> $DIR/issue-82869.rs:11:57 + --> $DIR/issue-82869.rs:15:57 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | _________________________________________________________^
diff --git a/tests/ui/asm/x86_64/issue-89875.rs b/tests/ui/asm/x86_64/issue-89875.rs index 0252859..a45ef1b 100644 --- a/tests/ui/asm/x86_64/issue-89875.rs +++ b/tests/ui/asm/x86_64/issue-89875.rs
@@ -1,9 +1,16 @@ //@ build-pass +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 //@ needs-asm-support -//@ only-x86_64 +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; +#[unsafe(no_mangle)] #[target_feature(enable = "avx")] fn foo() { unsafe { @@ -13,5 +20,3 @@ fn foo() { ); } } - -fn main() {}
diff --git a/tests/ui/asm/x86_64/issue-96797.rs b/tests/ui/asm/x86_64/issue-96797.rs index 531e167..9978a48 100644 --- a/tests/ui/asm/x86_64/issue-96797.rs +++ b/tests/ui/asm/x86_64/issue-96797.rs
@@ -1,13 +1,17 @@ +//@ add-minicore //@ build-pass -//@ compile-flags: -O -//@ needs-asm-support -//@ only-x86_64 -//@ only-linux +//@ compile-flags: --target x86_64-unknown-linux-gnu -O +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; // regression test for #96797 -use std::arch::global_asm; - #[no_mangle] fn my_func() {}
diff --git a/tests/ui/asm/x86_64/srcloc.rs b/tests/ui/asm/x86_64/srcloc.rs index f4ffa8c..e73854a 100644 --- a/tests/ui/asm/x86_64/srcloc.rs +++ b/tests/ui/asm/x86_64/srcloc.rs
@@ -1,12 +1,19 @@ -//@ only-x86_64 +//@ add-minicore //@ build-fail -//@ compile-flags: -Ccodegen-units=1 +//@ compile-flags: --target x86_64-unknown-linux-gnu -Ccodegen-units=1 +//@ needs-llvm-components: x86 //@ ignore-backends: gcc +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; // Checks that inline asm errors are mapped to the correct line in the source code. +#[unsafe(no_mangle)] +#[rustfmt::skip] fn main() { unsafe { asm!("invalid_instruction");
diff --git a/tests/ui/asm/x86_64/srcloc.stderr b/tests/ui/asm/x86_64/srcloc.stderr index b207912..d2ab93f 100644 --- a/tests/ui/asm/x86_64/srcloc.stderr +++ b/tests/ui/asm/x86_64/srcloc.stderr
@@ -1,5 +1,5 @@ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:12:15 + --> $DIR/srcloc.rs:19:15 | LL | asm!("invalid_instruction"); | ^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:16:13 + --> $DIR/srcloc.rs:23:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:21:13 + --> $DIR/srcloc.rs:28:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -35,18 +35,6 @@ | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:27:13 - | -LL | invalid_instruction - | ^^^^^^^^^^^^^^^^^^^ - | -note: instantiated into assembly here - --> <inline asm>:4:13 - | -LL | invalid_instruction - | ^^^^^^^^^^^^^^^^^^^ - -error: invalid instruction mnemonic 'invalid_instruction' --> $DIR/srcloc.rs:34:13 | LL | invalid_instruction @@ -59,7 +47,19 @@ | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:39:14 + --> $DIR/srcloc.rs:41:13 + | +LL | invalid_instruction + | ^^^^^^^^^^^^^^^^^^^ + | +note: instantiated into assembly here + --> <inline asm>:4:13 + | +LL | invalid_instruction + | ^^^^^^^^^^^^^^^^^^^ + +error: invalid instruction mnemonic 'invalid_instruction' + --> $DIR/srcloc.rs:46:14 | LL | asm!(concat!("invalid", "_", "instruction")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ | ^^^^^^^^^^^^^^^^^^^ warning: scale factor without index register is ignored - --> $DIR/srcloc.rs:42:15 + --> $DIR/srcloc.rs:49:15 | LL | asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ | ^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:46:14 + --> $DIR/srcloc.rs:53:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ @@ -95,37 +95,25 @@ | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:52:14 - | -LL | "invalid_instruction", - | ^^^^^^^^^^^^^^^^^^^ - | -note: instantiated into assembly here - --> <inline asm>:3:1 - | -LL | invalid_instruction - | ^^^^^^^^^^^^^^^^^^^ - -error: invalid instruction mnemonic 'invalid_instruction' --> $DIR/srcloc.rs:59:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ | note: instantiated into assembly here - --> <inline asm>:4:1 + --> <inline asm>:3:1 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:66:13 + --> $DIR/srcloc.rs:66:14 | -LL | concat!("invalid", "_", "instruction"), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | "invalid_instruction", + | ^^^^^^^^^^^^^^^^^^^ | note: instantiated into assembly here - --> <inline asm>:3:1 + --> <inline asm>:4:1 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -142,8 +130,20 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ +error: invalid instruction mnemonic 'invalid_instruction' + --> $DIR/srcloc.rs:80:13 + | +LL | concat!("invalid", "_", "instruction"), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: instantiated into assembly here + --> <inline asm>:3:1 + | +LL | invalid_instruction + | ^^^^^^^^^^^^^^^^^^^ + error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:80:14 + --> $DIR/srcloc.rs:87:14 | LL | "invalid_instruction1", | ^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:81:14 + --> $DIR/srcloc.rs:88:14 | LL | "invalid_instruction2", | ^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:87:13 + --> $DIR/srcloc.rs:94:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -182,7 +182,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:87:13 + --> $DIR/srcloc.rs:94:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -197,7 +197,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:96:13 + --> $DIR/srcloc.rs:103:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -212,7 +212,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:96:13 + --> $DIR/srcloc.rs:103:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -227,7 +227,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:100:13 + --> $DIR/srcloc.rs:107:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -242,7 +242,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:100:13 + --> $DIR/srcloc.rs:107:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -257,7 +257,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:111:13 + --> $DIR/srcloc.rs:118:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -272,7 +272,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:111:13 + --> $DIR/srcloc.rs:118:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -287,7 +287,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:115:13 + --> $DIR/srcloc.rs:122:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -302,7 +302,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:115:13 + --> $DIR/srcloc.rs:122:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -317,7 +317,7 @@ | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:128:14 + --> $DIR/srcloc.rs:135:14 | LL | "invalid_instruction" | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/x86_64/target-feature-attr.rs b/tests/ui/asm/x86_64/target-feature-attr.rs index 2193117..ada5fec 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.rs +++ b/tests/ui/asm/x86_64/target-feature-attr.rs
@@ -1,15 +1,20 @@ -//@ only-x86_64 +//@ add-minicore // Set the base cpu explicitly, in case the default has been changed. -//@ compile-flags: -C target-cpu=x86-64 +//@ compile-flags: --target x86_64-unknown-linux-gnu -C target-cpu=x86-64 +//@ needs-llvm-components: x86 +#![crate_type = "rlib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; #[target_feature(enable = "avx")] unsafe fn foo() { let mut x = 1; let y = 2; asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); - assert_eq!(x, 3); + let _ = x; } unsafe fn bar() { @@ -19,7 +24,7 @@ unsafe fn bar() { //~^ ERROR: register class `ymm_reg` requires the `avx` target feature //~| ERROR: register class `ymm_reg` requires the `avx` target feature //~| ERROR: register class `ymm_reg` requires the `avx` target feature - assert_eq!(x, 3); + let _ = x; } #[target_feature(enable = "avx512bw")]
diff --git a/tests/ui/asm/x86_64/target-feature-attr.stderr b/tests/ui/asm/x86_64/target-feature-attr.stderr index c852726..625f104 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.stderr +++ b/tests/ui/asm/x86_64/target-feature-attr.stderr
@@ -1,23 +1,23 @@ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:40 + --> $DIR/target-feature-attr.rs:23:40 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:55 + --> $DIR/target-feature-attr.rs:23:55 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:70 + --> $DIR/target-feature-attr.rs:23:70 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^^^^^^ error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f - --> $DIR/target-feature-attr.rs:33:23 + --> $DIR/target-feature-attr.rs:38:23 | LL | asm!("/* {0} */", in(kreg) x); | ^^^^^^^^^^
diff --git a/tests/ui/asm/x86_64/x86_64_parse_error.rs b/tests/ui/asm/x86_64/x86_64_parse_error.rs index 3df0feb..3d01141 100644 --- a/tests/ui/asm/x86_64/x86_64_parse_error.rs +++ b/tests/ui/asm/x86_64/x86_64_parse_error.rs
@@ -1,6 +1,12 @@ -//@ only-x86_64 +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] -use std::arch::asm; +extern crate minicore; +use minicore::*; fn main() { let mut foo = 0; @@ -14,6 +20,6 @@ fn main() { //~^ ERROR attempt to use a non-constant value in a constant asm!("{1}", in("eax") foo, const bar); //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments - //~^^ ERROR attempt to use a non-constant value in a constant + //~| ERROR attempt to use a non-constant value in a constant } }
diff --git a/tests/ui/asm/x86_64/x86_64_parse_error.stderr b/tests/ui/asm/x86_64/x86_64_parse_error.stderr index dfa3e1d..30d2c57 100644 --- a/tests/ui/asm/x86_64/x86_64_parse_error.stderr +++ b/tests/ui/asm/x86_64/x86_64_parse_error.stderr
@@ -1,11 +1,11 @@ error: explicit register arguments cannot have names - --> $DIR/x86_64_parse_error.rs:9:18 + --> $DIR/x86_64_parse_error.rs:15:18 | LL | asm!("", a = in("eax") foo); | ^^^^^^^^^^^^^^^^^ error: positional arguments cannot follow named arguments or explicit register arguments - --> $DIR/x86_64_parse_error.rs:15:36 + --> $DIR/x86_64_parse_error.rs:21:36 | LL | asm!("{1}", in("eax") foo, const bar); | ------------- ^^^^^^^^^ positional argument @@ -13,7 +13,7 @@ | explicit register argument error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/x86_64_parse_error.rs:11:46 + --> $DIR/x86_64_parse_error.rs:17:46 | LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value @@ -25,7 +25,7 @@ | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/x86_64_parse_error.rs:13:46 + --> $DIR/x86_64_parse_error.rs:19:46 | LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value @@ -37,7 +37,7 @@ | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/x86_64_parse_error.rs:15:42 + --> $DIR/x86_64_parse_error.rs:21:42 | LL | asm!("{1}", in("eax") foo, const bar); | ^^^ non-constant value
diff --git a/tests/ui/associated-consts/associated-const-no-item.rs b/tests/ui/associated-consts/associated-const-no-item.rs index 024d14e..116f1aa 100644 --- a/tests/ui/associated-consts/associated-const-no-item.rs +++ b/tests/ui/associated-consts/associated-const-no-item.rs
@@ -3,7 +3,7 @@ } const X: i32 = <i32>::ID; -//~^ ERROR no associated item named `ID` found +//~^ ERROR no associated function or constant named `ID` found fn main() { assert_eq!(1, X);
diff --git a/tests/ui/associated-consts/associated-const-no-item.stderr b/tests/ui/associated-consts/associated-const-no-item.stderr index 7ded05b..40cd779 100644 --- a/tests/ui/associated-consts/associated-const-no-item.stderr +++ b/tests/ui/associated-consts/associated-const-no-item.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `ID` found for type `i32` in the current scope +error[E0599]: no associated function or constant named `ID` found for type `i32` in the current scope --> $DIR/associated-const-no-item.rs:5:23 | LL | const X: i32 = <i32>::ID; - | ^^ associated item not found in `i32` + | ^^ associated function or constant not found in `i32` | = help: items from traits can only be used if the trait is implemented and in scope note: `Foo` defines an item `ID`, perhaps you need to implement it
diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs index cb0b8a1..c260ab1 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs
@@ -1,9 +1,6 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct OnDiskDirEntry<'a>(&'a ());
diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr index b69a1b7..a90b1f6 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr
@@ -1,35 +1,10 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:3:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:5:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information - error: the constant `2` is not of type `usize` - --> $DIR/type-const-in-array-len-wrong-type.rs:13:26 + --> $DIR/type-const-in-array-len-wrong-type.rs:10:26 | LL | fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i64` | = note: the length of array `[char; 2]` must be type `usize` -error: aborting due to 1 previous error; 3 warnings emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/associated-consts/type-const-in-array-len.rs b/tests/ui/associated-consts/type-const-in-array-len.rs index d33eaca..7a809cef 100644 --- a/tests/ui/associated-consts/type-const-in-array-len.rs +++ b/tests/ui/associated-consts/type-const-in-array-len.rs
@@ -1,9 +1,7 @@ //@ check-pass #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete // Test case from #138226: generic impl with multiple type parameters struct Foo<A, B>(A, B);
diff --git a/tests/ui/associated-consts/type-const-in-array-len.stderr b/tests/ui/associated-consts/type-const-in-array-len.stderr deleted file mode 100644 index 546995d..0000000 --- a/tests/ui/associated-consts/type-const-in-array-len.stderr +++ /dev/null
@@ -1,19 +0,0 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len.rs:3:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len.rs:5:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information - -warning: 2 warnings emitted -
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs index a33d492..0de9821 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
@@ -7,5 +7,5 @@ impl Fail<i32> { fn main() { Fail::<()>::C - //~^ ERROR no associated item named `C` found for struct `Fail<()>` in the current scope + //~^ ERROR no associated function or constant named `C` found for struct `Fail<()>` in the current scope }
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr index b17682e..0ddde32 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
@@ -7,16 +7,16 @@ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0599]: no associated item named `C` found for struct `Fail<()>` in the current scope +error[E0599]: no associated function or constant named `C` found for struct `Fail<()>` in the current scope --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:9:17 | LL | struct Fail<T>; - | -------------- associated item `C` not found for this struct + | -------------- associated function or constant `C` not found for this struct ... LL | Fail::<()>::C - | ^ associated item not found in `Fail<()>` + | ^ associated function or constant not found in `Fail<()>` | - = note: the associated item was found for `Fail<i32>` + = note: the associated function or constant was found for `Fail<i32>` error: aborting due to 2 previous errors
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs index d891b7b..e4f2bbf 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
@@ -14,5 +14,5 @@ impl Fail<i32, i32> { fn main() { Fail::<i32, u32>::C //~^ ERROR: type mismatch - //~| ERROR no associated item named `C` found for struct `Fail<i32, u32>` in the current scope + //~| ERROR no associated function or constant named `C` found for struct `Fail<i32, u32>` in the current scope }
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr index d0c7df9..04568b8 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
@@ -15,16 +15,16 @@ LL | struct Fail<T: Proj<Assoc = U>, U>(T); | ^^^^^^^^^ required by this bound in `Fail` -error[E0599]: no associated item named `C` found for struct `Fail<i32, u32>` in the current scope +error[E0599]: no associated function or constant named `C` found for struct `Fail<i32, u32>` in the current scope --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23 | LL | struct Fail<T: Proj<Assoc = U>, U>(T); - | ---------------------------------- associated item `C` not found for this struct + | ---------------------------------- associated function or constant `C` not found for this struct ... LL | Fail::<i32, u32>::C - | ^ associated item not found in `Fail<i32, u32>` + | ^ associated function or constant not found in `Fail<i32, u32>` | - = note: the associated item was found for `Fail<i32, i32>` + = note: the associated function or constant was found for `Fail<i32, i32>` error: aborting due to 2 previous errors
diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs index e5c1f47..27b3b93 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs
@@ -2,7 +2,6 @@ // Regression test for #146467. #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct Foo<T>(T);
diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr index 4c0726d..b06add2 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr
@@ -1,20 +1,11 @@ -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:8:6 | LL | impl<'a> Foo<fn(&())> { | ^^ unconstrained lifetime parameter error[E0308]: mismatched types - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:11 | LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -23,12 +14,12 @@ found struct `Foo<for<'a> fn(&'a ())>` error: higher-ranked subtype error - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:1 | LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0207, E0308. For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/associated-inherent-types/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr index 12cc3ae..bf329c6 100644 --- a/tests/ui/associated-inherent-types/inference-fail.stderr +++ b/tests/ui/associated-inherent-types/inference-fail.stderr
@@ -2,7 +2,7 @@ --> $DIR/inference-fail.rs:10:12 | LL | let _: S<_>::P = (); - | ^^^^^^^ cannot infer type + | ^^^^^^^ cannot infer type for type parameter `T` error: aborting due to 1 previous error
diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs index 3f72679..b7f8586 100644 --- a/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs +++ b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct D<T> { a: T
diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr b/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr deleted file mode 100644 index 93064f5..0000000 --- a/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/variance-computation-requires-equality.rs:3:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/associated-item/associated-item-enum.rs b/tests/ui/associated-item/associated-item-enum.rs index 30ba258..3a5c058 100644 --- a/tests/ui/associated-item/associated-item-enum.rs +++ b/tests/ui/associated-item/associated-item-enum.rs
@@ -14,7 +14,7 @@ fn misspellable_trait() {} } fn main() { - Enum::mispellable(); //~ ERROR no variant or associated item - Enum::mispellable_trait(); //~ ERROR no variant or associated item - Enum::MISPELLABLE; //~ ERROR no variant or associated item + Enum::mispellable(); //~ ERROR no variant, associated function, or constant + Enum::mispellable_trait(); //~ ERROR no variant, associated function, or constant + Enum::MISPELLABLE; //~ ERROR no variant, associated function, or constant }
diff --git a/tests/ui/associated-item/associated-item-enum.stderr b/tests/ui/associated-item/associated-item-enum.stderr index c3ce7c3..6cb53e5 100644 --- a/tests/ui/associated-item/associated-item-enum.stderr +++ b/tests/ui/associated-item/associated-item-enum.stderr
@@ -1,39 +1,39 @@ -error[E0599]: no variant or associated item named `mispellable` found for enum `Enum` in the current scope +error[E0599]: no variant, associated function, or constant named `mispellable` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:17:11 | LL | enum Enum { Variant } - | --------- variant or associated item `mispellable` not found for this enum + | --------- variant, associated function, or constant `mispellable` not found for this enum ... LL | Enum::mispellable(); - | ^^^^^^^^^^^ variant or associated item not found in `Enum` + | ^^^^^^^^^^^ variant, associated function, or constant not found in `Enum` | help: there is an associated function `misspellable` with a similar name | LL | Enum::misspellable(); | + -error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope +error[E0599]: no variant, associated function, or constant named `mispellable_trait` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:18:11 | LL | enum Enum { Variant } - | --------- variant or associated item `mispellable_trait` not found for this enum + | --------- variant, associated function, or constant `mispellable_trait` not found for this enum ... LL | Enum::mispellable_trait(); - | ^^^^^^^^^^^^^^^^^ variant or associated item not found in `Enum` + | ^^^^^^^^^^^^^^^^^ variant, associated function, or constant not found in `Enum` | help: there is an associated function `misspellable_trait` with a similar name | LL | Enum::misspellable_trait(); | + -error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `Enum` in the current scope +error[E0599]: no variant, associated function, or constant named `MISPELLABLE` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:19:11 | LL | enum Enum { Variant } - | --------- variant or associated item `MISPELLABLE` not found for this enum + | --------- variant, associated function, or constant `MISPELLABLE` not found for this enum ... LL | Enum::MISPELLABLE; - | ^^^^^^^^^^^ variant or associated item not found in `Enum` + | ^^^^^^^^^^^ variant, associated function, or constant not found in `Enum` | help: there is an associated constant `MISSPELLABLE` with a similar name |
diff --git a/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.rs b/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.rs new file mode 100644 index 0000000..f588d6d --- /dev/null +++ b/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.rs
@@ -0,0 +1,21 @@ +// issue: <https://github.com/rust-lang/rust/issues/142797> + +struct SomeStruct { + some_field: u64, +} + +trait SomeTrait { + type SomeType; + fn foo(); +} + +impl SomeTrait for bool { + type SomeType = SomeStruct; + + fn foo() { + let ss = Self::SomeType; + //~^ ERROR no associated function or constant named `SomeType` found for type `bool` in the current scope + } +} + +fn main() {}
diff --git a/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.stderr b/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.stderr new file mode 100644 index 0000000..83b915c --- /dev/null +++ b/tests/ui/associated-types/associated-type-as-value-in-impl-issue-142797.stderr
@@ -0,0 +1,9 @@ +error[E0599]: no associated function or constant named `SomeType` found for type `bool` in the current scope + --> $DIR/associated-type-as-value-in-impl-issue-142797.rs:16:24 + | +LL | let ss = Self::SomeType; + | ^^^^^^^^ associated function or constant not found in `bool` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/associated-types/associated-type-as-value.rs b/tests/ui/associated-types/associated-type-as-value.rs index ddc8082..7fefc48 100644 --- a/tests/ui/associated-types/associated-type-as-value.rs +++ b/tests/ui/associated-types/associated-type-as-value.rs
@@ -1,7 +1,7 @@ //! regression test for <https://github.com/rust-lang/rust/issues/38919> fn foo<T: Iterator>() { - T::Item; //~ ERROR no associated item named `Item` found + T::Item; //~ ERROR no associated function or constant named `Item` found } fn main() { }
diff --git a/tests/ui/associated-types/associated-type-as-value.stderr b/tests/ui/associated-types/associated-type-as-value.stderr index c553582..0015ebe 100644 --- a/tests/ui/associated-types/associated-type-as-value.stderr +++ b/tests/ui/associated-types/associated-type-as-value.stderr
@@ -1,10 +1,10 @@ -error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope +error[E0599]: no associated function or constant named `Item` found for type parameter `T` in the current scope --> $DIR/associated-type-as-value.rs:4:8 | LL | fn foo<T: Iterator>() { - | - associated item `Item` not found for this type parameter + | - associated function or constant `Item` not found for this type parameter LL | T::Item; - | ^^^^ associated item not found in `T` + | ^^^^ associated function or constant not found in `T` error: aborting due to 1 previous error
diff --git a/tests/ui/associated-types/associated-type-call.fixed b/tests/ui/associated-types/associated-type-call.fixed index d450b3b..f2df780 100644 --- a/tests/ui/associated-types/associated-type-call.fixed +++ b/tests/ui/associated-types/associated-type-call.fixed
@@ -15,7 +15,7 @@ fn f() { T(); - //~^ ERROR no associated item named `Assoc` found for unit type `()` in the current scope + //~^ ERROR no associated function or constant named `Assoc` found for unit type `()` in the current scope } }
diff --git a/tests/ui/associated-types/associated-type-call.rs b/tests/ui/associated-types/associated-type-call.rs index ffe540c..88d0172 100644 --- a/tests/ui/associated-types/associated-type-call.rs +++ b/tests/ui/associated-types/associated-type-call.rs
@@ -15,7 +15,7 @@ impl Trait for () { fn f() { <Self>::Assoc(); - //~^ ERROR no associated item named `Assoc` found for unit type `()` in the current scope + //~^ ERROR no associated function or constant named `Assoc` found for unit type `()` in the current scope } }
diff --git a/tests/ui/associated-types/associated-type-call.stderr b/tests/ui/associated-types/associated-type-call.stderr index eaef775..94cfc24 100644 --- a/tests/ui/associated-types/associated-type-call.stderr +++ b/tests/ui/associated-types/associated-type-call.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `Assoc` found for unit type `()` in the current scope +error[E0599]: no associated function or constant named `Assoc` found for unit type `()` in the current scope --> $DIR/associated-type-call.rs:17:17 | LL | <Self>::Assoc(); - | ^^^^^ associated item not found in `()` + | ^^^^^ associated function or constant not found in `()` | help: to construct a value of type `T`, use the explicit path |
diff --git a/tests/ui/associated-types/defaults-specialization.rs b/tests/ui/associated-types/defaults-specialization.rs index 553705b..d0ed718 100644 --- a/tests/ui/associated-types/defaults-specialization.rs +++ b/tests/ui/associated-types/defaults-specialization.rs
@@ -1,7 +1,6 @@ //! Tests the interaction of associated type defaults and specialization. #![feature(associated_type_defaults, specialization)] -//~^ WARN the feature `specialization` is incomplete trait Tr { type Ty = u8;
diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index d22d9ce..2e880a7 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr
@@ -1,21 +1,11 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/defaults-specialization.rs:3:38 - | -LL | #![feature(associated_type_defaults, specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0053]: method `make` has an incompatible type for trait - --> $DIR/defaults-specialization.rs:19:18 + --> $DIR/defaults-specialization.rs:18:18 | LL | fn make() -> u8 { 0 } | ^^ expected associated type, found `u8` | note: type in trait - --> $DIR/defaults-specialization.rs:9:18 + --> $DIR/defaults-specialization.rs:8:18 | LL | fn make() -> Self::Ty { | ^^^^^^^^ @@ -28,7 +18,7 @@ | error[E0053]: method `make` has an incompatible type for trait - --> $DIR/defaults-specialization.rs:35:18 + --> $DIR/defaults-specialization.rs:34:18 | LL | default type Ty = bool; | --------------- associated type is `default` and may be overridden @@ -37,7 +27,7 @@ | ^^^^ expected associated type, found `bool` | note: type in trait - --> $DIR/defaults-specialization.rs:9:18 + --> $DIR/defaults-specialization.rs:8:18 | LL | fn make() -> Self::Ty { | ^^^^^^^^ @@ -50,7 +40,7 @@ | error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:10:9 + --> $DIR/defaults-specialization.rs:9:9 | LL | type Ty = u8; | ------- associated type defaults can't be assumed inside the trait defining them @@ -64,7 +54,7 @@ found type `u8` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:26:29 + --> $DIR/defaults-specialization.rs:25:29 | LL | fn make() -> Self::Ty { 0u8 } | -------- ^^^ expected associated type, found `u8` @@ -79,7 +69,7 @@ see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:44:29 + --> $DIR/defaults-specialization.rs:43:29 | LL | default type Ty = bool; | --------------- associated type is `default` and may be overridden @@ -95,7 +85,7 @@ see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:87:32 + --> $DIR/defaults-specialization.rs:86:32 | LL | let _: <B<()> as Tr>::Ty = 0u8; | ----------------- ^^^ expected associated type, found `u8` @@ -105,13 +95,13 @@ = note: expected associated type `<B<()> as Tr>::Ty` found type `u8` help: a method is available that returns `<B<()> as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:88:32 + --> $DIR/defaults-specialization.rs:87:32 | LL | let _: <B<()> as Tr>::Ty = true; | ----------------- ^^^^ expected associated type, found `bool` @@ -121,7 +111,7 @@ = note: expected associated type `<B<()> as Tr>::Ty` found type `bool` help: a method is available that returns `<B<()> as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` @@ -129,7 +119,7 @@ see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:89:33 + --> $DIR/defaults-specialization.rs:88:33 | LL | let _: <B2<()> as Tr>::Ty = 0u8; | ------------------ ^^^ expected associated type, found `u8` @@ -139,13 +129,13 @@ = note: expected associated type `<B2<()> as Tr>::Ty` found type `u8` help: a method is available that returns `<B2<()> as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:90:33 + --> $DIR/defaults-specialization.rs:89:33 | LL | let _: <B2<()> as Tr>::Ty = true; | ------------------ ^^^^ expected associated type, found `bool` @@ -155,14 +145,14 @@ = note: expected associated type `<B2<()> as Tr>::Ty` found type `bool` help: a method is available that returns `<B2<()> as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` = note: the associated type `<B2<()> as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2<()>` shadows this definition see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 9 previous errors Some errors have detailed explanations: E0053, E0308. For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/associated-types/invalid-ctor.fixed b/tests/ui/associated-types/invalid-ctor.fixed index eba3820..7598010 100644 --- a/tests/ui/associated-types/invalid-ctor.fixed +++ b/tests/ui/associated-types/invalid-ctor.fixed
@@ -15,7 +15,7 @@ fn mk() -> Self::Out { Constructor(1) - //~^ ERROR no associated item named `Out` found for unit type `()` + //~^ ERROR no associated function or constant named `Out` found for unit type `()` } }
diff --git a/tests/ui/associated-types/invalid-ctor.rs b/tests/ui/associated-types/invalid-ctor.rs index 73335c0..82ec17d 100644 --- a/tests/ui/associated-types/invalid-ctor.rs +++ b/tests/ui/associated-types/invalid-ctor.rs
@@ -15,7 +15,7 @@ impl Trait for () { fn mk() -> Self::Out { Self::Out(1) - //~^ ERROR no associated item named `Out` found for unit type `()` + //~^ ERROR no associated function or constant named `Out` found for unit type `()` } }
diff --git a/tests/ui/associated-types/invalid-ctor.stderr b/tests/ui/associated-types/invalid-ctor.stderr index 0b3bf31..50dc718 100644 --- a/tests/ui/associated-types/invalid-ctor.stderr +++ b/tests/ui/associated-types/invalid-ctor.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `Out` found for unit type `()` in the current scope +error[E0599]: no associated function or constant named `Out` found for unit type `()` in the current scope --> $DIR/invalid-ctor.rs:17:15 | LL | Self::Out(1) - | ^^^ associated item not found in `()` + | ^^^ associated function or constant not found in `()` | help: to construct a value of type `Constructor`, use the explicit path |
diff --git a/tests/ui/associated-types/issue-43924.rs b/tests/ui/associated-types/issue-43924.rs index 63ebbdd..dfc8461 100644 --- a/tests/ui/associated-types/issue-43924.rs +++ b/tests/ui/associated-types/issue-43924.rs
@@ -13,5 +13,5 @@ impl Foo<u64> for () {} fn main() { assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false"); - //~^ ERROR no function or associated item named `default` found for trait object + //~^ ERROR no associated function or constant named `default` found for trait object }
diff --git a/tests/ui/associated-types/issue-43924.stderr b/tests/ui/associated-types/issue-43924.stderr index 196ad85..5bf8ee7 100644 --- a/tests/ui/associated-types/issue-43924.stderr +++ b/tests/ui/associated-types/issue-43924.stderr
@@ -10,11 +10,11 @@ LL | type Out: Default + ToString + ?Sized = dyn ToString; | ^^^^^^^ required by this bound in `Foo::Out` -error[E0599]: no function or associated item named `default` found for trait object `(dyn ToString + 'static)` in the current scope +error[E0599]: no associated function or constant named `default` found for trait object `(dyn ToString + 'static)` in the current scope --> $DIR/issue-43924.rs:15:39 | LL | assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false"); - | ^^^^^^^ function or associated item not found in `(dyn ToString + 'static)` + | ^^^^^^^ associated function or constant not found in `(dyn ToString + 'static)` error: aborting due to 2 previous errors
diff --git a/tests/ui/associated-types/issue-47814.rs b/tests/ui/associated-types/issue-47814.rs deleted file mode 100644 index 90e8a3b..0000000 --- a/tests/ui/associated-types/issue-47814.rs +++ /dev/null
@@ -1,13 +0,0 @@ -struct ArpIPv4<'a> { - s: &'a u8 -} - -impl<'a> ArpIPv4<'a> { - const LENGTH: usize = 20; - - pub fn to_buffer() -> [u8; Self::LENGTH] { //~ ERROR generic `Self` types are currently not permitted in anonymous constants - unimplemented!() - } -} - -pub fn main() {}
diff --git a/tests/ui/associated-types/issue-47814.stderr b/tests/ui/associated-types/issue-47814.stderr deleted file mode 100644 index 7382426..0000000 --- a/tests/ui/associated-types/issue-47814.stderr +++ /dev/null
@@ -1,14 +0,0 @@ -error: generic `Self` types are currently not permitted in anonymous constants - --> $DIR/issue-47814.rs:8:32 - | -LL | pub fn to_buffer() -> [u8; Self::LENGTH] { - | ^^^^ - | -note: not a concrete type - --> $DIR/issue-47814.rs:5:10 - | -LL | impl<'a> ArpIPv4<'a> { - | ^^^^^^^^^^^ - -error: aborting due to 1 previous error -
diff --git a/tests/ui/associated-types/issue-64855-2.rs b/tests/ui/associated-types/issue-64855-2.rs index 20b8ff1..5509ebb 100644 --- a/tests/ui/associated-types/issue-64855-2.rs +++ b/tests/ui/associated-types/issue-64855-2.rs
@@ -3,6 +3,6 @@ // also inadvertently a test for the (non-)co-inductiveness of WF predicates. pub struct Bar<'a>(&'a Self) where Self: ; -//~^ ERROR overflow evaluating the requirement `Bar<'a> well-formed` +//~^ ERROR overflow evaluating whether `Bar<'a>` is well-formed fn main() {}
diff --git a/tests/ui/associated-types/issue-64855-2.stderr b/tests/ui/associated-types/issue-64855-2.stderr index 22292a8..75da645 100644 --- a/tests/ui/associated-types/issue-64855-2.stderr +++ b/tests/ui/associated-types/issue-64855-2.stderr
@@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `Bar<'a> well-formed` +error[E0275]: overflow evaluating whether `Bar<'a>` is well-formed --> $DIR/issue-64855-2.rs:5:36 | LL | pub struct Bar<'a>(&'a Self) where Self: ;
diff --git a/tests/ui/associated-types/issue-64855.rs b/tests/ui/associated-types/issue-64855.rs index 5d325b9..003f11f 100644 --- a/tests/ui/associated-types/issue-64855.rs +++ b/tests/ui/associated-types/issue-64855.rs
@@ -8,6 +8,6 @@ pub trait Foo { pub struct Bar<T>(<Self as Foo>::Type) where Self: ; //~^ ERROR the trait bound `Bar<T>: Foo` is not satisfied -//~| ERROR overflow evaluating the requirement `Bar<T> well-formed` +//~| ERROR overflow evaluating whether `Bar<T>` is well-formed fn main() {}
diff --git a/tests/ui/associated-types/issue-64855.stderr b/tests/ui/associated-types/issue-64855.stderr index 4358ab4..9472dbf 100644 --- a/tests/ui/associated-types/issue-64855.stderr +++ b/tests/ui/associated-types/issue-64855.stderr
@@ -15,7 +15,7 @@ LL | pub trait Foo { | ^^^^^^^^^^^^^ -error[E0275]: overflow evaluating the requirement `Bar<T> well-formed` +error[E0275]: overflow evaluating whether `Bar<T>` is well-formed --> $DIR/issue-64855.rs:9:46 | LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.rs b/tests/ui/async-await/async-drop/foreign-fundamental.rs index 1c192fc..44be204 100644 --- a/tests/ui/async-await/async-drop/foreign-fundamental.rs +++ b/tests/ui/async-await/async-drop/foreign-fundamental.rs
@@ -1,7 +1,6 @@ //@ edition: 2018 #![feature(async_drop)] -//~^ WARN the feature `async_drop` is incomplete use std::future::AsyncDrop; use std::pin::Pin;
diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.stderr b/tests/ui/async-await/async-drop/foreign-fundamental.stderr index 7b52329..78bfdf6 100644 --- a/tests/ui/async-await/async-drop/foreign-fundamental.stderr +++ b/tests/ui/async-await/async-drop/foreign-fundamental.stderr
@@ -1,24 +1,15 @@ -warning: the feature `async_drop` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/foreign-fundamental.rs:3:12 - | -LL | #![feature(async_drop)] - | ^^^^^^^^^^ - | - = note: see issue #126482 <https://github.com/rust-lang/rust/issues/126482> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions - --> $DIR/foreign-fundamental.rs:11:20 + --> $DIR/foreign-fundamental.rs:10:20 | LL | impl AsyncDrop for &Foo { | ^^^^ must be a struct, enum, or union in the current crate error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions - --> $DIR/foreign-fundamental.rs:16:20 + --> $DIR/foreign-fundamental.rs:15:20 | LL | impl AsyncDrop for Pin<Foo> { | ^^^^^^^^ must be a struct, enum, or union in the current crate -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0120`.
diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr index 6689539..0f39052 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr
@@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mut-is-pointer-like.rs:6:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/mut-is-pointer-like.rs:35:29 | @@ -24,6 +15,6 @@ | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` = help: consider moving `async_dispatch` to another trait -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr index 338479d..c7d0d14d 100644 --- a/tests/ui/async-await/dyn/works.stderr +++ b/tests/ui/async-await/dyn/works.stderr
@@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/works.rs:6:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/works.rs:27:21 | @@ -24,6 +15,6 @@ = help: consider moving `async_dispatch` to another trait = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr index a465f91..4835c17 100644 --- a/tests/ui/async-await/dyn/wrong-size.stderr +++ b/tests/ui/async-await/dyn/wrong-size.stderr
@@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-size.rs:4:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/wrong-size.rs:21:17 | @@ -24,6 +15,6 @@ = help: consider moving `async_dispatch` to another trait = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/gat-is-send-across-await.rs b/tests/ui/async-await/gat-is-send-across-await.rs new file mode 100644 index 0000000..43b7774 --- /dev/null +++ b/tests/ui/async-await/gat-is-send-across-await.rs
@@ -0,0 +1,23 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/111852>. + +//@ edition:2018 +//@ check-pass + +#![allow(unused)] + +trait G: Send { + type Gat<'l>: Send + where + Self: 'l; + + fn as_gat(&self) -> Self::Gat<'_>; +} + +fn a(g: impl G) { + let _: &dyn Send = &async move { + let _gat = g.as_gat(); + async{}.await + }; +} + +fn main() { }
diff --git a/tests/ui/attributes/malformed-reprs.stderr b/tests/ui/attributes/malformed-reprs.stderr index 504ba91..6e77c6e 100644 --- a/tests/ui/attributes/malformed-reprs.stderr +++ b/tests/ui/attributes/malformed-reprs.stderr
@@ -6,12 +6,6 @@ | = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html#representations> -error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/malformed-reprs.rs:9:14 - | -LL | #[repr(align(0))] - | ^ - error: `repr` attribute cannot be used at crate level --> $DIR/malformed-reprs.rs:4:1 | @@ -19,7 +13,7 @@ | ^^^^^^^^ ... LL | enum Foo {} - | --- the inner attribute doesn't annotate this enum + | ----------- the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute | @@ -27,6 +21,12 @@ LL + #[repr] | +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/malformed-reprs.rs:9:14 + | +LL | #[repr(align(0))] + | ^ + error[E0084]: unsupported representation for zero-variant enum --> $DIR/malformed-reprs.rs:9:1 |
diff --git a/tests/ui/attributes/rustc_confusables_assoc_fn.rs b/tests/ui/attributes/rustc_confusables_assoc_fn.rs new file mode 100644 index 0000000..6a93f7b --- /dev/null +++ b/tests/ui/attributes/rustc_confusables_assoc_fn.rs
@@ -0,0 +1,22 @@ +#![feature(rustc_attrs)] + +struct S; + +impl S { + #[rustc_confusables("bar")] + fn foo() {} + + #[rustc_confusables("baz")] + fn qux(&self, x: i32) {} +} + +fn main() { + S::bar(); + //~^ ERROR no associated function or constant named `bar` + //~| HELP you might have meant to use `foo` + + let s = S; + s.baz(10); + //~^ ERROR no method named `baz` + //~| HELP you might have meant to use `qux` +}
diff --git a/tests/ui/attributes/rustc_confusables_assoc_fn.stderr b/tests/ui/attributes/rustc_confusables_assoc_fn.stderr new file mode 100644 index 0000000..da5cf27 --- /dev/null +++ b/tests/ui/attributes/rustc_confusables_assoc_fn.stderr
@@ -0,0 +1,33 @@ +error[E0599]: no associated function or constant named `bar` found for struct `S` in the current scope + --> $DIR/rustc_confusables_assoc_fn.rs:14:8 + | +LL | struct S; + | -------- associated function or constant `bar` not found for this struct +... +LL | S::bar(); + | ^^^ associated function or constant not found in `S` + | +help: you might have meant to use `foo` + | +LL - S::bar(); +LL + S::foo(); + | + +error[E0599]: no method named `baz` found for struct `S` in the current scope + --> $DIR/rustc_confusables_assoc_fn.rs:19:7 + | +LL | struct S; + | -------- method `baz` not found for this struct +... +LL | s.baz(10); + | ^^^ method not found in `S` + | +help: you might have meant to use `qux` + | +LL - s.baz(10); +LL + s.qux(10); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/auto-traits/pre-cfg.rs b/tests/ui/auto-traits/pre-cfg.rs deleted file mode 100644 index 4820a53..0000000 --- a/tests/ui/auto-traits/pre-cfg.rs +++ /dev/null
@@ -1,8 +0,0 @@ -//@ check-pass - -#[cfg(false)] -auto trait Foo {} -//~^ WARN `auto` traits are unstable -//~| WARN unstable syntax can change at any point in the future, causing a hard error! - -fn main() {}
diff --git a/tests/ui/borrowck/dbg-issue-120327.rs b/tests/ui/borrowck/dbg-issue-120327.rs index 2de43f6..45605ac 100644 --- a/tests/ui/borrowck/dbg-issue-120327.rs +++ b/tests/ui/borrowck/dbg-issue-120327.rs
@@ -1,67 +1,44 @@ +//! Diagnostic test for <https://github.com/rust-lang/rust/issues/120327>: suggest borrowing +//! variables passed to `dbg!` that are later used. +//@ dont-require-annotations: HELP + fn s() -> String { let a = String::new(); - dbg!(a); + dbg!(a); //~ HELP consider borrowing instead of transferring ownership return a; //~ ERROR use of moved value: } fn m() -> String { let a = String::new(); - dbg!(1, 2, a, 1, 2); + dbg!(1, 2, a, 1, 2); //~ HELP consider borrowing instead of transferring ownership return a; //~ ERROR use of moved value: } fn t(a: String) -> String { let b: String = "".to_string(); - dbg!(a, b); + dbg!(a, b); //~ HELP consider borrowing instead of transferring ownership return b; //~ ERROR use of moved value: } fn x(a: String) -> String { let b: String = "".to_string(); - dbg!(a, b); + dbg!(a, b); //~ HELP consider borrowing instead of transferring ownership return a; //~ ERROR use of moved value: } -macro_rules! my_dbg { - () => { - eprintln!("[{}:{}:{}]", file!(), line!(), column!()) - }; - ($val:expr $(,)?) => { - match $val { - tmp => { - eprintln!("[{}:{}:{}] {} = {:#?}", - file!(), line!(), column!(), stringify!($val), &tmp); - tmp - } - } - }; - ($($val:expr),+ $(,)?) => { - ($(my_dbg!($val)),+,) - }; -} - -fn test_my_dbg() -> String { - let b: String = "".to_string(); - my_dbg!(b, 1); - return b; //~ ERROR use of moved value: -} - -fn test_not_macro() -> String { - let a = String::new(); - let _b = match a { - tmp => { - eprintln!("dbg: {}", tmp); - tmp - } - }; - return a; //~ ERROR use of moved value: +fn two_of_them(a: String) -> String { + dbg!(a, a); //~ ERROR use of moved value + //~| HELP consider borrowing instead of transferring ownership + //~| HELP consider borrowing instead of transferring ownership + return a; //~ ERROR use of moved value } fn get_expr(_s: String) {} +// The suggestion is purely syntactic; applying it here will result in a type error. fn test() { let a: String = "".to_string(); - let _res = get_expr(dbg!(a)); + let _res = get_expr(dbg!(a)); //~ HELP consider borrowing instead of transferring ownership let _l = a.len(); //~ ERROR borrow of moved value }
diff --git a/tests/ui/borrowck/dbg-issue-120327.stderr b/tests/ui/borrowck/dbg-issue-120327.stderr index efacc0c..e7a7151 100644 --- a/tests/ui/borrowck/dbg-issue-120327.stderr +++ b/tests/ui/borrowck/dbg-issue-120327.stderr
@@ -1,112 +1,133 @@ error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:4:12 + --> $DIR/dbg-issue-120327.rs:8:12 | LL | let a = String::new(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | dbg!(a); - | ------- value moved here + | - value moved here LL | return a; | ^ value used here after move | +help: consider cloning the value if the performance cost is acceptable + | +LL | dbg!(a.clone()); + | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(&a); | + error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:10:12 + --> $DIR/dbg-issue-120327.rs:14:12 | LL | let a = String::new(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | dbg!(1, 2, a, 1, 2); - | ------------------- value moved here + | - value moved here LL | return a; | ^ value used here after move | +help: consider cloning the value if the performance cost is acceptable + | +LL | dbg!(1, 2, a.clone(), 1, 2); + | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(1, 2, &a, 1, 2); | + error[E0382]: use of moved value: `b` - --> $DIR/dbg-issue-120327.rs:16:12 + --> $DIR/dbg-issue-120327.rs:20:12 | LL | let b: String = "".to_string(); | - move occurs because `b` has type `String`, which does not implement the `Copy` trait LL | dbg!(a, b); - | ---------- value moved here + | - value moved here LL | return b; | ^ value used here after move | +help: consider cloning the value if the performance cost is acceptable + | +LL | dbg!(a, b.clone()); + | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(a, &b); | + error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:22:12 + --> $DIR/dbg-issue-120327.rs:26:12 | LL | fn x(a: String) -> String { | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | let b: String = "".to_string(); LL | dbg!(a, b); - | ---------- value moved here + | - value moved here LL | return a; | ^ value used here after move | +help: consider cloning the value if the performance cost is acceptable + | +LL | dbg!(a.clone(), b); + | ++++++++ help: consider borrowing instead of transferring ownership | LL | dbg!(&a, b); | + -error[E0382]: use of moved value: `b` - --> $DIR/dbg-issue-120327.rs:46:12 +error[E0382]: use of moved value: `a` + --> $DIR/dbg-issue-120327.rs:30:13 | -LL | tmp => { - | --- value moved here -... -LL | let b: String = "".to_string(); - | - move occurs because `b` has type `String`, which does not implement the `Copy` trait -LL | my_dbg!(b, 1); -LL | return b; - | ^ value used here after move +LL | fn two_of_them(a: String) -> String { + | - move occurs because `a` has type `String`, which does not implement the `Copy` trait +LL | dbg!(a, a); + | - ^ value used here after move + | | + | value moved here | +help: consider cloning the value if the performance cost is acceptable + | +LL | dbg!(a.clone(), a); + | ++++++++ help: consider borrowing instead of transferring ownership | -LL | my_dbg!(&b, 1); - | + -help: borrow this binding in the pattern to avoid moving the value - | -LL | ref tmp => { - | +++ +LL | dbg!(&a, a); + | + error[E0382]: use of moved value: `a` - --> $DIR/dbg-issue-120327.rs:57:12 + --> $DIR/dbg-issue-120327.rs:33:12 | -LL | let a = String::new(); - | - move occurs because `a` has type `String`, which does not implement the `Copy` trait -LL | let _b = match a { -LL | tmp => { - | --- value moved here +LL | fn two_of_them(a: String) -> String { + | - move occurs because `a` has type `String`, which does not implement the `Copy` trait +LL | dbg!(a, a); + | - value moved here ... LL | return a; | ^ value used here after move | -help: borrow this binding in the pattern to avoid moving the value +help: consider cloning the value if the performance cost is acceptable | -LL | ref tmp => { - | +++ +LL | dbg!(a, a.clone()); + | ++++++++ +help: consider borrowing instead of transferring ownership + | +LL | dbg!(a, &a); + | + error[E0382]: borrow of moved value: `a` - --> $DIR/dbg-issue-120327.rs:65:14 + --> $DIR/dbg-issue-120327.rs:42:14 | LL | let a: String = "".to_string(); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait LL | let _res = get_expr(dbg!(a)); - | ------- value moved here + | - value moved here LL | let _l = a.len(); | ^ value borrowed here after move | +help: consider cloning the value if the performance cost is acceptable + | +LL | let _res = get_expr(dbg!(a.clone())); + | ++++++++ help: consider borrowing instead of transferring ownership | LL | let _res = get_expr(dbg!(&a));
diff --git a/tests/ui/borrowck/generic_const_early_param.rs b/tests/ui/borrowck/generic_const_early_param.rs index 0d07b68..e5fab59 100644 --- a/tests/ui/borrowck/generic_const_early_param.rs +++ b/tests/ui/borrowck/generic_const_early_param.rs
@@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete struct DataWrapper<'static> { //~^ ERROR invalid lifetime parameter name: `'static`
diff --git a/tests/ui/borrowck/generic_const_early_param.stderr b/tests/ui/borrowck/generic_const_early_param.stderr index 6447f92..a9ee438 100644 --- a/tests/ui/borrowck/generic_const_early_param.stderr +++ b/tests/ui/borrowck/generic_const_early_param.stderr
@@ -1,11 +1,11 @@ error[E0262]: invalid lifetime parameter name: `'static` - --> $DIR/generic_const_early_param.rs:4:20 + --> $DIR/generic_const_early_param.rs:3:20 | LL | struct DataWrapper<'static> { | ^^^^^^^ 'static is a reserved lifetime name error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:6:12 + --> $DIR/generic_const_early_param.rs:5:12 | LL | data: &'a [u8; Self::SIZE], | ^^ undeclared lifetime @@ -16,7 +16,7 @@ | +++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:10:18 + --> $DIR/generic_const_early_param.rs:9:18 | LL | impl DataWrapper<'a> { | ^^ undeclared lifetime @@ -26,16 +26,7 @@ LL | impl<'a> DataWrapper<'a> { | ++++ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/generic_const_early_param.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0261, E0262. For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 06a7f47..06384c2 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr
@@ -17,6 +17,7 @@ `addsubiw` `adx` `aes` +`allows-misaligned-mem-access` `altivec` `alu32` `amx-avx512`
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index efa0a7f..0ba2f0b 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -120,7 +120,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread` + = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `kernel-hwaddress`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index f697662..58cdc25 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
@@ -80,9 +80,10 @@ --> $DIR/liveness.rs:74:13 | LL | e.x = Some("e1"); - | ^^^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | +LL | e.x = Some("e2"); + | ---------------- `e.x` is overwritten here before the previous value is read warning: value assigned to `e.x` is never read --> $DIR/liveness.rs:76:13 @@ -104,9 +105,10 @@ --> $DIR/liveness.rs:77:13 | LL | b = Some("e1"); - | ^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | +LL | b = Some("e2"); + | -------------- `b` is overwritten here before the previous value is read warning: value assigned to `b` is never read --> $DIR/liveness.rs:79:13 @@ -120,17 +122,17 @@ --> $DIR/liveness.rs:68:13 | LL | d.x = Some("d1"); - | ^^^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | d.x = Some("d2"); + | ---------------- `d.x` is overwritten here before the previous value is read warning: value assigned to `a` is never read --> $DIR/liveness.rs:70:13 | LL | a = Some("d1"); - | ^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | a = Some("d2"); + | -------------- `a` is overwritten here before the previous value is read warning: 16 warnings emitted
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.rs similarity index 76% rename from tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs rename to tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.rs index 3e72eec..2df8931 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.rs
@@ -1,3 +1,4 @@ +// Regression test for https://github.com/rust-lang/rust/issues/83176. //@ run-pass #![warn(rust_2021_incompatible_closure_captures)]
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.stderr similarity index 87% rename from tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr rename to tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.stderr index 2609e29..595173b 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/nested-copy-drops-83176.stderr
@@ -1,5 +1,5 @@ warning: irrefutable `if let` pattern - --> $DIR/issue-78720.rs:7:8 + --> $DIR/nested-copy-drops-83176.rs:8:8 | LL | if let a = "" { | ^^^^^^^^^^
diff --git a/tests/ui/closures/binder/const-bound.rs b/tests/ui/closures/binder/const-bound.rs index 10d869f..e6984ed 100644 --- a/tests/ui/closures/binder/const-bound.rs +++ b/tests/ui/closures/binder/const-bound.rs
@@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for<const N: i32> || -> () {};
diff --git a/tests/ui/closures/binder/const-bound.stderr b/tests/ui/closures/binder/const-bound.stderr index b805879..a577880 100644 --- a/tests/ui/closures/binder/const-bound.stderr +++ b/tests/ui/closures/binder/const-bound.stderr
@@ -1,23 +1,14 @@ error: late-bound const parameters cannot be used currently - --> $DIR/const-bound.rs:5:15 + --> $DIR/const-bound.rs:4:15 | LL | for<const N: i32> || -> () {}; | ^ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-bound.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound const parameter not allowed on closures - --> $DIR/const-bound.rs:5:9 + --> $DIR/const-bound.rs:4:9 | LL | for<const N: i32> || -> () {}; | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors
diff --git a/tests/ui/closures/binder/type-bound-2.rs b/tests/ui/closures/binder/type-bound-2.rs index f4edcda..064fbf9 100644 --- a/tests/ui/closures/binder/type-bound-2.rs +++ b/tests/ui/closures/binder/type-bound-2.rs
@@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for<T> || -> () {};
diff --git a/tests/ui/closures/binder/type-bound-2.stderr b/tests/ui/closures/binder/type-bound-2.stderr index 6609b326..6fd7d57 100644 --- a/tests/ui/closures/binder/type-bound-2.stderr +++ b/tests/ui/closures/binder/type-bound-2.stderr
@@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-bound-2.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on closures - --> $DIR/type-bound-2.rs:5:9 + --> $DIR/type-bound-2.rs:4:9 | LL | for<T> || -> () {}; | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/closures/binder/type-bound.rs b/tests/ui/closures/binder/type-bound.rs index 59a3353..9fc60b3 100644 --- a/tests/ui/closures/binder/type-bound.rs +++ b/tests/ui/closures/binder/type-bound.rs
@@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for<T> || -> T {};
diff --git a/tests/ui/closures/binder/type-bound.stderr b/tests/ui/closures/binder/type-bound.stderr index 2243113..11dc328 100644 --- a/tests/ui/closures/binder/type-bound.stderr +++ b/tests/ui/closures/binder/type-bound.stderr
@@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-bound.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on closures - --> $DIR/type-bound.rs:5:9 + --> $DIR/type-bound.rs:4:9 | LL | for<T> || -> T {}; | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-17734.rs b/tests/ui/codegen/box-str-drop-glue.rs similarity index 84% rename from tests/ui/issues/issue-17734.rs rename to tests/ui/codegen/box-str-drop-glue.rs index 984adee..6a25db7 100644 --- a/tests/ui/issues/issue-17734.rs +++ b/tests/ui/codegen/box-str-drop-glue.rs
@@ -1,3 +1,4 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/17734> //@ run-pass // Test that generating drop glue for Box<str> doesn't ICE
diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.rs b/tests/ui/codegen/freeze-on-polymorphic-projection.rs index f382a37..4744fa5 100644 --- a/tests/ui/codegen/freeze-on-polymorphic-projection.rs +++ b/tests/ui/codegen/freeze-on-polymorphic-projection.rs
@@ -2,7 +2,6 @@ //@ compile-flags: -Copt-level=1 --crate-type=lib #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete pub unsafe trait Storage { type Handle;
diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr deleted file mode 100644 index 903cb2f..0000000 --- a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/freeze-on-polymorphic-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/coercion/fudge-inference/input-ty-closure-param-fn-trait-bounds.rs b/tests/ui/coercion/fudge-inference/input-ty-closure-param-fn-trait-bounds.rs deleted file mode 100644 index 91dc8e3..0000000 --- a/tests/ui/coercion/fudge-inference/input-ty-closure-param-fn-trait-bounds.rs +++ /dev/null
@@ -1,17 +0,0 @@ -//@ check-pass - -// Regression test for <https://github.com/rust-lang/rust/issues/153816> - -struct Inv<T, U>(*mut (T, U)); - -fn pass_through<F>(_: F) -> Inv<F, F> { - todo!() -} - -fn map(_: Inv<impl FnOnce(), impl Fn()>) {} - -fn traverse() { - map(pass_through(|| ())) -} - -fn main() {}
diff --git a/tests/ui/coercion/fudge-inference/input-ty-higher-ranked-fn-trait.rs b/tests/ui/coercion/fudge-inference/input-ty-higher-ranked-fn-trait.rs deleted file mode 100644 index 241a177..0000000 --- a/tests/ui/coercion/fudge-inference/input-ty-higher-ranked-fn-trait.rs +++ /dev/null
@@ -1,21 +0,0 @@ -//@ check-pass - -// Regression test for <https://github.com/rust-lang/rust/issues/153849> - -#[expect(dead_code)] -// Must be invariant -pub struct Server<T>(*mut T); -impl<T> Server<T> { - fn new(_: T) -> Self - where - // Must be higher-ranked - T: Fn(&mut i32), - { - todo!() - } -} - -fn main() { - // Must have a type annotation - let _: Server<_> = Server::new(|_| ()); -}
diff --git a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs index 7e53695..a3dc9b5 100644 --- a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs +++ b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs
@@ -5,7 +5,6 @@ // since they are using a different infcx which doesn't preserve the intercrate flag. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Assoc { type Output;
diff --git a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr deleted file mode 100644 index 56eb21c..0000000 --- a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coherence-doesnt-use-infcx-evaluate.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs index d74d3a2..7f0e547 100644 --- a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs +++ b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs
@@ -4,7 +4,6 @@ // // No we expect to run into a more user-friendly cycle error instead. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Trait<T> { type Assoc; } //~^ ERROR E0391
diff --git a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr index 9f813d6..3d4d191 100644 --- a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr +++ b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
@@ -1,27 +1,17 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:6:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0391]: cycle detected when building specialization graph of trait `Trait` - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1 | LL | trait Trait<T> { type Assoc; } | ^^^^^^^^^^^^^^ | = note: ...which immediately requires building specialization graph of trait `Trait` again note: cycle used when coherence checking all impls of trait `Trait` - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1 | LL | trait Trait<T> { type Assoc; } | ^^^^^^^^^^^^^^ = 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 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/coherence/generalize-associated-type-alias.rs b/tests/ui/coherence/generalize-associated-type-alias.rs new file mode 100644 index 0000000..f333a0d --- /dev/null +++ b/tests/ui/coherence/generalize-associated-type-alias.rs
@@ -0,0 +1,22 @@ +// Regression test for https://github.com/rust-lang/rust/issues/154189. +#![feature(unboxed_closures)] + +trait ToUnit<'a> { + type Unit; +} + +impl ToUnit<'_> for *const u32 { + type Unit = (); +} + +trait Overlap<T> {} + +type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; + +impl<T> Overlap<T> for T {} + +impl<'a, T> Overlap<(&'a (), Assoc<'a, T>)> for T {} +//~^ ERROR the trait bound `*const T: ToUnit<'a>` is not satisfied +//~| ERROR the trait bound `T: Overlap<(&'a (), _)>` is not satisfied + +fn main() {}
diff --git a/tests/ui/coherence/generalize-associated-type-alias.stderr b/tests/ui/coherence/generalize-associated-type-alias.stderr new file mode 100644 index 0000000..e65205d --- /dev/null +++ b/tests/ui/coherence/generalize-associated-type-alias.stderr
@@ -0,0 +1,28 @@ +error[E0277]: the trait bound `*const T: ToUnit<'a>` is not satisfied + --> $DIR/generalize-associated-type-alias.rs:18:13 + | +LL | impl<'a, T> Overlap<(&'a (), Assoc<'a, T>)> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | impl<'a, T> Overlap<(&'a (), Assoc<'a, T>)> for T where *const T: ToUnit<'a> {} + | ++++++++++++++++++++++++++ + +error[E0277]: the trait bound `T: Overlap<(&'a (), _)>` is not satisfied + --> $DIR/generalize-associated-type-alias.rs:18:49 + | +LL | impl<'a, T> Overlap<(&'a (), Assoc<'a, T>)> for T {} + | ^ the trait `Overlap<(&'a (), _)>` is not implemented for `T` + | +help: the trait `Overlap<(&'a (), _)>` is not implemented for `T` + but trait `Overlap<(&(), ())>` is implemented for `u32` + --> $DIR/generalize-associated-type-alias.rs:18:1 + | +LL | impl<'a, T> Overlap<(&'a (), Assoc<'a, T>)> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: for that trait implementation, expected `u32`, found `T` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.rs b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs index f0424e7..ff3999f 100644 --- a/tests/ui/coherence/negative-coherence/regions-in-canonical.rs +++ b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(adt_const_params, unsized_const_params)] -//~^ WARN the feature `unsized_const_params` is incomplete #![feature(with_negative_coherence, negative_impls)] pub trait A<const K: &'static str> {}
diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr b/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr deleted file mode 100644 index 7204491..0000000 --- a/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/regions-in-canonical.rs:3:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 52794b1..381f5c6 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 |
diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 9fa443e..40811a6 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr
@@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. } error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 |
diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs index b754b1c..c50bbce 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs
@@ -3,7 +3,7 @@ use std::marker::PhantomData; #[derive(PartialEq, Default)] -//~^ ERROR conflicting implementations of trait `PartialEq` for type `Interval<_>` +//~^ ERROR conflicting implementations of trait `PartialEq<Interval<_>>` for type `Interval<_>` pub(crate) struct Interval<T>(PhantomData<T>); // This impl overlaps with the `derive` unless we reject the nested
diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr index 620694a..a9a99fb 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
@@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `PartialEq` for type `Interval<_>` +error[E0119]: conflicting implementations of trait `PartialEq<Interval<_>>` for type `Interval<_>` --> $DIR/warn-when-cycle-is-error-in-coherence.rs:5:10 | LL | #[derive(PartialEq, Default)]
diff --git a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs index e90426e..8825d53 100644 --- a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs +++ b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs
@@ -1,6 +1,5 @@ //@ check-pass #![feature(adt_const_params, lazy_type_alias)] -//~^ WARN: the feature `lazy_type_alias` is incomplete pub type Matrix = [usize; 1]; const EMPTY_MATRIX: Matrix = [0; 1];
diff --git a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr deleted file mode 100644 index 4f51334..0000000 --- a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/alias_const_param_ty-1.rs:2:30 - | -LL | #![feature(adt_const_params, lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs index e364368..3f092d0 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs
@@ -15,5 +15,5 @@ fn call() {} fn main() { Wrapper::<function>::call; - //~^ ERROR: the function or associated item `call` exists for struct `Wrapper<function>`, + //~^ ERROR: the associated function or constant `call` exists for struct `Wrapper<function>`, }
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr index b13f76e..4d469de 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr
@@ -15,14 +15,14 @@ LL | struct Wrapper<const F: fn()>; | ^^^^ -error[E0599]: the function or associated item `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied --> $DIR/non_valtreeable_const_arg-2.rs:17:26 | LL | struct Wrapper<const F: fn()>; - | ----------------------------- function or associated item `call` not found for this struct because it doesn't satisfy `Wrapper<function>: Fn<_>` + | ----------------------------- associated function or constant `call` not found for this struct because it doesn't satisfy `Wrapper<function>: Fn<_>` ... LL | Wrapper::<function>::call; - | ^^^^ function or associated item cannot be called on `Wrapper<function>` due to unsatisfied trait bounds + | ^^^^ associated function or constant cannot be called on `Wrapper<function>` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `Wrapper<function>: Fn<_>`
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs index 81b1ec6..9e2212b 100644 --- a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs
@@ -2,7 +2,6 @@ #![feature(adt_const_params)] #![feature(unsized_const_params)] -//~^ WARN the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes #[derive(Clone)] struct S<const L: [u8]>;
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr index d538bb0..8112613 100644 --- a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr
@@ -1,22 +1,13 @@ error: free constant item without body - --> $DIR/unsized-anon-const-err-2.rs:10:1 + --> $DIR/unsized-anon-const-err-2.rs:9:1 | LL | const A: [u8]; | ^^^^^^^^^^^^^- | | | help: provide a definition for the constant: `= <expr>;` -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unsized-anon-const-err-2.rs:4:12 - | -LL | #![feature(unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-anon-const-err-2.rs:10:10 + --> $DIR/unsized-anon-const-err-2.rs:9:10 | LL | const A: [u8]; | ^^^^ doesn't have a size known at compile-time @@ -25,7 +16,7 @@ = note: statics and constants must have a statically known size error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-anon-const-err-2.rs:14:31 + --> $DIR/unsized-anon-const-err-2.rs:13:31 | LL | impl<const N: i32> Copy for S<A> {} | ^ doesn't have a size known at compile-time @@ -34,7 +25,7 @@ = note: statics and constants must have a statically known size error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-anon-const-err-2.rs:17:33 + --> $DIR/unsized-anon-const-err-2.rs:16:33 | LL | impl<const M: usize> Copy for S<A> {} | ^ doesn't have a size known at compile-time @@ -43,7 +34,7 @@ = note: statics and constants must have a statically known size error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates - --> $DIR/unsized-anon-const-err-2.rs:14:6 + --> $DIR/unsized-anon-const-err-2.rs:13:6 | LL | impl<const N: i32> Copy for S<A> {} | ^^^^^^^^^^^^ unconstrained const parameter @@ -52,7 +43,7 @@ = note: proving the result of expressions other than the parameter are unique is not supported error[E0207]: the const parameter `M` is not constrained by the impl trait, self type, or predicates - --> $DIR/unsized-anon-const-err-2.rs:17:6 + --> $DIR/unsized-anon-const-err-2.rs:16:6 | LL | impl<const M: usize> Copy for S<A> {} | ^^^^^^^^^^^^^^ unconstrained const parameter @@ -60,7 +51,7 @@ = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 6 previous errors Some errors have detailed explanations: E0207, E0277. For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr new file mode 100644 index 0000000..f62023b --- /dev/null +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.eager.stderr
@@ -0,0 +1,133 @@ +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:15:1 + | +LL | type ArrLen<const B: bool> = [(); B]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:19:1 + | +LL | type ConstArg<const B: bool> = Foo<B>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Foo` + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:32:1 + | +LL | type Alias<const B: bool> = <() as IdentityWithUnused<B>>::This; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `IdentityWithUnused` + --> $DIR/check_const_arg_type_in_free_alias.rs:24:26 + | +LL | trait IdentityWithUnused<const N: usize> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `IdentityWithUnused` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:38:1 + | +LL | type UseFree<const B: bool> = Free<B>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:58:1 + | +LL | type IndirectArr<const B: bool> = Wrap<Wrap<[(); B]>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:62:1 + | +LL | type IndirectConstArg<const B: bool> = Wrap<Wrap<Foo<B>>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Foo` + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:17:24 + | +LL | type AnonArrLen = [(); true]; + | ^^^^ expected `usize`, found `bool` + | + = note: array length can only be `usize` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:21:25 + | +LL | type AnonConstArg = Foo<true>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:34:44 + | +LL | type AnonAlias = <() as IdentityWithUnused<true>>::This; + | ^^^^ expected `usize`, found `bool` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:40:25 + | +LL | type AnonUseFree = Free<true>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + | +LL | type Free<const N: usize> = [(); N]; + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:53:45 + | +LL | type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; + | ^^^^^^^ expected `bool`, found `usize` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + | +LL | type UseFree<const B: bool> = Free<B>; + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:60:39 + | +LL | type AnonIndirectArr = Wrap<Wrap<[(); true]>>; + | ^^^^ expected `usize`, found `bool` + | + = note: array length can only be `usize` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:64:43 + | +LL | type AnonIndirectConstArg = Wrap<Wrap<Foo<true>>>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr new file mode 100644 index 0000000..b9adb4e --- /dev/null +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.lazy.stderr
@@ -0,0 +1,151 @@ +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:15:1 + | +LL | type ArrLen<const B: bool> = [(); B]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:17:24 + | +LL | type AnonArrLen = [(); true]; + | ^^^^ expected `usize`, found `bool` + | + = note: array length can only be `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:19:1 + | +LL | type ConstArg<const B: bool> = Foo<B>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Foo` + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:21:25 + | +LL | type AnonConstArg = Foo<true>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:32:1 + | +LL | type Alias<const B: bool> = <() as IdentityWithUnused<B>>::This; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required for `()` to implement `IdentityWithUnused<B>` + --> $DIR/check_const_arg_type_in_free_alias.rs:28:25 + | +LL | impl<T, const N: usize> IdentityWithUnused<N> for T { + | -------------- ^^^^^^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:34:44 + | +LL | type AnonAlias = <() as IdentityWithUnused<true>>::This; + | ^^^^ expected `usize`, found `bool` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:38:1 + | +LL | type UseFree<const B: bool> = Free<B>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a bound on the type alias `Free` + --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + | +LL | type Free<const N: usize> = [(); N]; + | ^^^^^^^^^^^^^^ required by this bound + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:40:25 + | +LL | type AnonUseFree = Free<true>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:37:11 + | +LL | type Free<const N: usize> = [(); N]; + | ^^^^^^^^^^^^^^ + +error: the constant `N` is not of type `bool` + --> $DIR/check_const_arg_type_in_free_alias.rs:51:1 + | +LL | type UseFreeIndirectlyCorrect<const N: usize> = UseFree<N>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `usize` + | +note: required by a bound on the type alias `UseFree` + --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + | +LL | type UseFree<const B: bool> = Free<B>; + | ^^^^^^^^^^^^^ required by this bound + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:53:45 + | +LL | type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; + | ^^^^^^^ expected `bool`, found `usize` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:38:14 + | +LL | type UseFree<const B: bool> = Free<B>; + | ^^^^^^^^^^^^^ + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:58:1 + | +LL | type IndirectArr<const B: bool> = Wrap<Wrap<[(); B]>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:60:39 + | +LL | type AnonIndirectArr = Wrap<Wrap<[(); true]>>; + | ^^^^ expected `usize`, found `bool` + | + = note: array length can only be `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_free_alias.rs:62:1 + | +LL | type IndirectConstArg<const B: bool> = Wrap<Wrap<Foo<B>>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Foo` + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_free_alias.rs:64:43 + | +LL | type AnonIndirectConstArg = Wrap<Wrap<Foo<true>>>; + | ^^^^ expected `usize`, found `bool` + | +note: expected because of the type of the const parameter + --> $DIR/check_const_arg_type_in_free_alias.rs:13:12 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^ + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs b/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs new file mode 100644 index 0000000..12e277f --- /dev/null +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.rs
@@ -0,0 +1,67 @@ +//@ revisions: eager lazy +#![cfg_attr(lazy, feature(lazy_type_alias))] +#![cfg_attr(lazy, expect(incomplete_features))] + +// We currently do not check free type aliases for well formedness. +// However, previously we desugared all const arguments to anon +// consts which resulted in us happening to check that they were +// of the correct type. Nowadays we don't necessarily lower to a +// const argument, but to continue erroring on such code we special +// case `ConstArgHasType` clauses to be checked for free type aliases +// even though we ignore the rest of the wf requirements. + +struct Foo<const N: usize>; + +type ArrLen<const B: bool> = [(); B]; +//~^ ERROR: the constant `B` is not of type +type AnonArrLen = [(); true]; +//~^ ERROR: mismatched types +type ConstArg<const B: bool> = Foo<B>; +//~^ ERROR: the constant `B` is not of type +type AnonConstArg = Foo<true>; +//~^ ERROR: mismatched types + +trait IdentityWithUnused<const N: usize> { + type This; +} + +impl<T, const N: usize> IdentityWithUnused<N> for T { + type This = T; +} + +type Alias<const B: bool> = <() as IdentityWithUnused<B>>::This; +//~^ ERROR: the constant `B` is not of type +type AnonAlias = <() as IdentityWithUnused<true>>::This; +//~^ ERROR: mismatched types + +type Free<const N: usize> = [(); N]; +type UseFree<const B: bool> = Free<B>; +//~^ ERROR: the constant `B` is not of type +type AnonUseFree = Free<true>; +//~^ ERROR: mismatched types + +// This previously emitted an error before we stopped using +// anon consts. Now, as free aliases don't exist after ty +// lowering, we don't emit an error because we only see `N` +// being used as an argument to an array length. +// +// Free type aliases are not allowed to have unused generic +// parameters so this shouldn't be able to cause code to +// pass that should error. +type UseFreeIndirectlyCorrect<const N: usize> = UseFree<N>; +//[lazy]~^ ERROR: the constant `N` is not of type +type AnonUseFreeIndirectlyCorrect = UseFree<1_usize>; +//~^ ERROR: mismatched types + +struct Wrap<T>(T); + +type IndirectArr<const B: bool> = Wrap<Wrap<[(); B]>>; +//~^ ERROR: the constant `B` is not of type +type AnonIndirectArr = Wrap<Wrap<[(); true]>>; +//~^ ERROR: mismatched types +type IndirectConstArg<const B: bool> = Wrap<Wrap<Foo<B>>>; +//~^ ERROR: the constant `B` is not of type +type AnonIndirectConstArg = Wrap<Wrap<Foo<true>>>; +//~^ ERROR: mismatched types + +fn main() {}
diff --git a/tests/ui/const-generics/check_const_arg_type_in_trait_object.rs b/tests/ui/const-generics/check_const_arg_type_in_trait_object.rs new file mode 100644 index 0000000..f5c5350 --- /dev/null +++ b/tests/ui/const-generics/check_const_arg_type_in_trait_object.rs
@@ -0,0 +1,36 @@ +// We currently do not check trait objects for well formedness. +// However, previously we desugared all const arguments to anon +// consts which resulted in us happening to check that they were +// of the correct type. Nowadays we don't necessarily lower to a +// const argument, but to continue erroring on such code we special +// case `ConstArgHasType` clauses to be checked for trait objects +// even though we ignore the rest of the wf requirements. + +trait Object<const N: usize> {} +trait Object2<T> {} +trait Object3<'a: 'static, const N: usize> {} + +struct Wrap<T>(T); + +fn arg<const B: bool, const N: usize>( + param: &dyn Object<B>, + //~^ ERROR: the constant `B` is not of type + anon: &dyn Object<true>, + //~^ ERROR: mismatched types +) { +} + +fn indirect<const B: bool, const N: usize>( + param: &dyn Object2<Wrap<[(); B]>>, + //~^ ERROR: the constant `B` is not of type + anon: &dyn Object2<Wrap<[(); true]>>, + //~^ ERROR: mismatched types +) { +} + +// the 'a: 'static bound should *not* have its error reported (at least, until we implement checking +// all wf things for dyn objects) +fn binder<const B: bool>(param: &dyn for<'a> Object3<'a, B>) {} +//~^ ERROR: the constant `B` is not of type + +fn main() {}
diff --git a/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr new file mode 100644 index 0000000..4e228f6 --- /dev/null +++ b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr
@@ -0,0 +1,49 @@ +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_trait_object.rs:18:23 + | +LL | anon: &dyn Object<true>, + | ^^^^ expected `usize`, found `bool` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_trait_object.rs:16:12 + | +LL | param: &dyn Object<B>, + | ^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Object` + --> $DIR/check_const_arg_type_in_trait_object.rs:9:14 + | +LL | trait Object<const N: usize> {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Object` + +error[E0308]: mismatched types + --> $DIR/check_const_arg_type_in_trait_object.rs:26:34 + | +LL | anon: &dyn Object2<Wrap<[(); true]>>, + | ^^^^ expected `usize`, found `bool` + | + = note: array length can only be `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_trait_object.rs:24:12 + | +LL | param: &dyn Object2<Wrap<[(); B]>>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | + = note: the length of array `[(); B]` must be type `usize` + +error: the constant `B` is not of type `usize` + --> $DIR/check_const_arg_type_in_trait_object.rs:33:33 + | +LL | fn binder<const B: bool>(param: &dyn for<'a> Object3<'a, B>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | +note: required by a const generic parameter in `Object3` + --> $DIR/check_const_arg_type_in_trait_object.rs:11:28 + | +LL | trait Object3<'a: 'static, const N: usize> {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Object3` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/defaults/concrete-const-param-type.rs b/tests/ui/const-generics/defaults/concrete-const-param-type.rs index c411f81..a2eb37b 100644 --- a/tests/ui/const-generics/defaults/concrete-const-param-type.rs +++ b/tests/ui/const-generics/defaults/concrete-const-param-type.rs
@@ -1,6 +1,4 @@ #![feature(generic_const_parameter_types, unsized_const_params, adt_const_params)] -//~^ WARN the feature `generic_const_parameter_types` is incomplete -//~| WARN the feature `unsized_const_params` is incomplete // Make sure that we test the const param type of default const parameters // if both the type of the default and the type of the parameter are concrete.
diff --git a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr index ad077f8..805d5a1 100644 --- a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr +++ b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr
@@ -1,25 +1,8 @@ -warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/concrete-const-param-type.rs:1:12 - | -LL | #![feature(generic_const_parameter_types, unsized_const_params, adt_const_params)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/concrete-const-param-type.rs:1:43 - | -LL | #![feature(generic_const_parameter_types, unsized_const_params, adt_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - error: the constant `N` is not of type `u64` - --> $DIR/concrete-const-param-type.rs:9:26 + --> $DIR/concrete-const-param-type.rs:7:26 | LL | struct Foo<const N: u32, const M: u64 = N>; | ^^^^^^^^^^^^^^^^ expected `u64`, found `u32` -error: aborting due to 1 previous error; 2 warnings emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr index 791bb19..3377f4c 100644 --- a/tests/ui/const-generics/exhaustive-value.stderr +++ b/tests/ui/const-generics/exhaustive-value.stderr
@@ -4,15 +4,15 @@ LL | <() as Foo<N>>::test() | ^^ the trait `Foo<N>` is not implemented for `()` | - = help: the following other types implement trait `Foo<N>`: - `()` implements `Foo<0>` - `()` implements `Foo<100>` - `()` implements `Foo<101>` - `()` implements `Foo<102>` - `()` implements `Foo<103>` - `()` implements `Foo<104>` - `()` implements `Foo<105>` - `()` implements `Foo<106>` + = help: `()` implements trait `Foo<N>`: + Foo<0> + Foo<100> + Foo<101> + Foo<102> + Foo<103> + Foo<104> + Foo<105> + Foo<106> and 248 others error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs index 5d538d2..1516b05 100644 --- a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs +++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs
@@ -9,6 +9,6 @@ struct S<const N: U>() where S<{ U }>:; -//~^ ERROR: overflow evaluating the requirement `S<{ U }> well-formed` +//~^ ERROR: overflow evaluating whether `S<{ U }>` is well-formed fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr index b244acb..1eb2890 100644 --- a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr +++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr
@@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed` +error[E0275]: overflow evaluating whether `S<{ U }>` is well-formed --> $DIR/adt_wf_hang.rs:11:5 | LL | S<{ U }>:;
diff --git a/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.rs b/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.rs index 2ce998e..5008179 100644 --- a/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.rs +++ b/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.rs
@@ -1,7 +1,7 @@ // issue: rust-lang/rust#114463 // ICE cannot convert `ReFree ..` to a region vid #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + fn bug<'a>() { [(); (|_: &'a u8| (), 0).1]; //~^ ERROR cannot capture late-bound lifetime in constant
diff --git a/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.stderr b/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.stderr index e484540..a468ba6 100644 --- a/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.stderr +++ b/tests/ui/const-generics/generic_const_exprs/cannot-convert-refree-ice-114463.stderr
@@ -1,12 +1,3 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cannot-convert-refree-ice-114463.rs:3:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error: cannot capture late-bound lifetime in constant --> $DIR/cannot-convert-refree-ice-114463.rs:6:16 | @@ -15,5 +6,5 @@ LL | [(); (|_: &'a u8| (), 0).1]; | ^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs index a6988a4..679f6b7 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs
@@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete fn foo<T>() { let _ = [0u8; { const { std::mem::size_of::<T>() } }];
diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr index db547e6..78d1540 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr
@@ -1,14 +1,5 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-block-is-poly.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error: overly complex generic constant - --> $DIR/const-block-is-poly.rs:5:19 + --> $DIR/const-block-is-poly.rs:4:19 | LL | let _ = [0u8; { const { std::mem::size_of::<T>() } }]; | ^^----------------------------------^^ @@ -18,5 +9,5 @@ = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs index e48d559..c5f4bbb 100644 --- a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs +++ b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use pub fn y<'a, U: 'a>() -> impl IntoIterator<Item = impl IntoIterator<Item = [u8; { 1 + 2 }]> + 'a> { [[[1, 2, 3]]]
diff --git a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr deleted file mode 100644 index faaede1..0000000 --- a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/double-opaque-parent-predicates.rs:3:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs index 79e9834..298cfb5 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs
@@ -18,4 +18,5 @@ impl<const N: usize> Foo<N> for () { fn main() { use_dyn(&()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed }
diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr index f9904c9..a124fbc 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr
@@ -14,6 +14,27 @@ LL | use_dyn::<N>(&()); | +++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/dyn-compatibility-ok-infer-err.rs:19:5 + | +LL | use_dyn(&()); + | ^^^^^^^ --- type must be known at this point + | | + | cannot infer the value of the const parameter `N` declared on the function `use_dyn` + | +note: required for `()` to implement `Foo<_>` + --> $DIR/dyn-compatibility-ok-infer-err.rs:8:22 + | +LL | impl<const N: usize> Foo<N> for () { + | -------------- ^^^^^^ ^^ + | | + | unsatisfied trait bound introduced here + = note: required for the cast from `&()` to `&dyn Foo<_>` +help: consider specifying the generic argument + | +LL | use_dyn::<N>(&()); + | +++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs b/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs index b61d2dc..d2b8d94 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs +++ b/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs
@@ -1,7 +1,6 @@ //@ build-pass #![feature(generic_const_exprs)] -//~^ WARNING the feature `generic_const_exprs` is incomplete trait Generic { const ASSOC: usize;
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr deleted file mode 100644 index 8eb1fcc..0000000 --- a/tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/eval-try-unify.rs:3:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.rs b/tests/ui/const-generics/generic_const_exprs/issue-69654.rs index 9b36699..058f404 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.rs
@@ -15,5 +15,5 @@ fn foo() {} fn main() { Foo::foo(); - //~^ ERROR the function or associated item + //~^ ERROR the associated function or constant }
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr index 7fa0d8c..9b5e556 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr
@@ -11,14 +11,14 @@ LL | impl<const T: /* Type */> Bar<T> for [u8; T] {} | +++++ ++++++++++++ -error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 | LL | struct Foo<const N: usize> {} - | -------------------------- function or associated item `foo` not found for this struct + | -------------------------- associated function or constant `foo` not found for this struct ... LL | Foo::foo(); - | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `Foo<_>` due to unsatisfied trait bounds | note: trait bound `[u8; _]: Bar<[(); _]>` was not satisfied --> $DIR/issue-69654.rs:11:14
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 0d39290..99decb3 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
@@ -27,5 +27,5 @@ pub fn new(val: T) -> Inline<T> { fn main() { let dst = Inline::<dyn Debug>::new(0); //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time - //~| ERROR the function or associated item `new` exists for struct `Inline<dyn Debug>` + //~| ERROR the associated function or constant `new` exists for struct `Inline<dyn Debug>` }
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 ac1bfc8..bad736b4 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -15,14 +15,14 @@ LL | struct Inline<T: ?Sized> | ++++++++ -error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied --> $DIR/issue-80742.rs:28:36 | LL | struct Inline<T> - | ---------------- function or associated item `new` not found for this struct + | ---------------- associated function or constant `new` not found for this struct ... LL | let dst = Inline::<dyn Debug>::new(0); - | ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds | note: trait bound `dyn Debug: Sized` was not satisfied --> $DIR/issue-80742.rs:18:6
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs index 443d0a2..965e074 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs
@@ -1,8 +1,6 @@ //@ check-pass #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] -//~^ WARN the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] -//~^^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] pub struct Changes<const CHANGES: &'static [&'static str]> where
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr deleted file mode 100644 index b6b2975..0000000 --- a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr +++ /dev/null
@@ -1,19 +0,0 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-97047-ice-1.rs:3:30 - | -LL | #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-97047-ice-1.rs:3:52 - | -LL | #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - -warning: 2 warnings emitted -
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs index 6a91b52..728d132 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs
@@ -1,8 +1,6 @@ //@ check-pass #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] -//~^ WARN the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] -//~^^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] pub struct Changes<const CHANGES: &'static [&'static str]> where
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr deleted file mode 100644 index c0c7dcc..0000000 --- a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr +++ /dev/null
@@ -1,19 +0,0 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-97047-ice-2.rs:3:30 - | -LL | #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-97047-ice-2.rs:3:52 - | -LL | #![feature(adt_const_params, unsized_const_params, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - -warning: 2 warnings emitted -
diff --git a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs index 734a378..85af36e 100644 --- a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs +++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs
@@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete trait B { type U<T>;
diff --git a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr index 1036b72..b11eb10 100644 --- a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr +++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr
@@ -1,18 +1,9 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mismatched-gat-subst-kind.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0747]: constant provided when a type was expected - --> $DIR/mismatched-gat-subst-kind.rs:8:13 + --> $DIR/mismatched-gat-subst-kind.rs:7:13 | LL | fn f<T: B<U<1i32> = ()>>() {} | ^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs index 9af351e..6e382de 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
@@ -1,6 +1,5 @@ // Regression test for #133271. #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete struct Foo; impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index 37eb895..d58bc67 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
@@ -1,5 +1,5 @@ error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add` - --> $DIR/post-analysis-user-facing-param-env.rs:12:5 + --> $DIR/post-analysis-user-facing-param-env.rs:11:5 | LL | / fn unimplemented(self, _: &Foo) -> Self::Output { LL | | @@ -7,17 +7,8 @@ LL | | } | |_____^ not a member of trait `std::ops::Add` -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/post-analysis-user-facing-param-env.rs:2:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `Output`, `add` - --> $DIR/post-analysis-user-facing-param-env.rs:6:1 + --> $DIR/post-analysis-user-facing-param-env.rs:5:1 | LL | / impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo LL | | @@ -30,7 +21,7 @@ = help: implement the missing item: `fn add(self, _: &'a Foo) -> <Self as Add<&'a Foo>>::Output { todo!() }` error[E0207]: the const parameter `NUM` is not constrained by the impl trait, self type, or predicates - --> $DIR/post-analysis-user-facing-param-env.rs:6:10 + --> $DIR/post-analysis-user-facing-param-env.rs:5:10 | LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo | ^^^^^^^^^^^^^^^^ unconstrained const parameter @@ -38,7 +29,7 @@ = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0207, E0407. For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs index afb086a..1e1ef0d 100644 --- a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs
@@ -17,5 +17,5 @@ struct Inline<T> fn main() { let dst = Inline::<dyn Debug>::new(0); //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time - //~| ERROR no function or associated item named `new` found for struct `Inline<T>` + //~| ERROR no associated function or constant named `new` found for struct `Inline<T>` }
diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr index bcc253e..c73c216 100644 --- a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr
@@ -15,14 +15,14 @@ LL | struct Inline<T: ?Sized> | ++++++++ -error[E0599]: no function or associated item named `new` found for struct `Inline<T>` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `Inline<T>` in the current scope --> $DIR/size_of-dyn-trait-3.rs:18:36 | LL | struct Inline<T> - | ---------------- function or associated item `new` not found for this struct + | ---------------- associated function or constant `new` not found for this struct ... LL | let dst = Inline::<dyn Debug>::new(0); - | ^^^ function or associated item not found in `Inline<dyn Debug>` + | ^^^ associated function or constant not found in `Inline<dyn Debug>` error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs index d3ae863..d605c83 100644 --- a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs +++ b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs
@@ -5,7 +5,6 @@ #![feature(with_negative_coherence)] #![feature(min_specialization)] #![feature(generic_const_exprs)] -//~^ WARNING the feature `generic_const_exprs` is incomplete #![crate_type = "lib"] trait Trait {}
diff --git a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr deleted file mode 100644 index f17b248..0000000 --- a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-fuzzing-ice-133639.rs:7:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs index d3bc544..4de1616 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs
@@ -1,8 +1,6 @@ // Ensure that we actually treat `N`'s type as `&'a u32` in MIR typeck. #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)] -//~^ WARN the feature `unsized_const_params` is incomplete -//~| WARN the feature `generic_const_parameter_types` is incomplete fn foo<'a, const N: &'a u32>() { let b: &'static u32 = N;
diff --git a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr index 3dc7ce4..0b7a43a 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr
@@ -1,27 +1,10 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/check-type-in-mir.rs:3:12 - | -LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/check-type-in-mir.rs:3:52 - | -LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information - error: lifetime may not live long enough - --> $DIR/check-type-in-mir.rs:8:12 + --> $DIR/check-type-in-mir.rs:6:12 | LL | fn foo<'a, const N: &'a u32>() { | -- lifetime `'a` defined here LL | let b: &'static u32 = N; | ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` -error: aborting due to 1 previous error; 2 warnings emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr index 2d47797..7e61566 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
@@ -1,14 +1,5 @@ -warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/references-parent-generics.rs:3:27 - | -LL | #![cfg_attr(feat, feature(generic_const_parameter_types))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information - = note: `#[warn(incomplete_features)]` on by default - error: `Self` is forbidden as the type of a const generic parameter - --> $DIR/references-parent-generics.rs:7:25 + --> $DIR/references-parent-generics.rs:6:25 | LL | type Assoc<const N: Self>; | ^^^^ @@ -16,10 +7,10 @@ = note: the only supported types are integers, `bool`, and `char` error: anonymous constants referencing generics are not yet supported - --> $DIR/references-parent-generics.rs:15:21 + --> $DIR/references-parent-generics.rs:14:21 | LL | let x: T::Assoc<3>; | ^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr index 68ce173..ac25a4e 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
@@ -1,5 +1,5 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/references-parent-generics.rs:7:25 + --> $DIR/references-parent-generics.rs:6:25 | LL | type Assoc<const N: Self>; | ^^^^ the type must not depend on the parameter `Self`
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs index b91050d..6eadb60 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
@@ -1,7 +1,6 @@ //@ revisions: feat nofeat #![cfg_attr(feat, feature(generic_const_parameter_types))] -//[feat]~^ WARN the feature `generic_const_parameter_types` is incomplete trait Foo { type Assoc<const N: Self>;
diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index 77d1fe1..47c594e 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs
@@ -10,5 +10,6 @@ fn main() { for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } }
diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 96f6496..3763cd7 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr
@@ -14,6 +14,24 @@ LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i)); | ++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/issue-77092.rs:11:26 + | +LL | println!("{:?}", take_array_from_mut(&mut arr, i)); + | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` + | | + | required by this formatting parameter + | + = note: required for `[i32; _]` to implement `Debug` + = note: 1 redundant requirement hidden + = note: required for `&mut [i32; _]` to implement `Debug` +note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL +help: consider specifying the generic arguments + | +LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i)); + | ++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/const-generics/invalid-path-in-const.rs b/tests/ui/const-generics/invalid-path-in-const.rs index 51eb860..a3c622a 100644 --- a/tests/ui/const-generics/invalid-path-in-const.rs +++ b/tests/ui/const-generics/invalid-path-in-const.rs
@@ -1,4 +1,4 @@ fn main() { fn f(a: [u8; u32::DOESNOTEXIST]) {} - //~^ ERROR no associated item named `DOESNOTEXIST` found for type `u32` + //~^ ERROR no associated function or constant named `DOESNOTEXIST` found for type `u32` }
diff --git a/tests/ui/const-generics/invalid-path-in-const.stderr b/tests/ui/const-generics/invalid-path-in-const.stderr index 31528ab..83c90a2 100644 --- a/tests/ui/const-generics/invalid-path-in-const.stderr +++ b/tests/ui/const-generics/invalid-path-in-const.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `DOESNOTEXIST` found for type `u32` in the current scope +error[E0599]: no associated function or constant named `DOESNOTEXIST` found for type `u32` in the current scope --> $DIR/invalid-path-in-const.rs:2:23 | LL | fn f(a: [u8; u32::DOESNOTEXIST]) {} - | ^^^^^^^^^^^^ associated item not found in `u32` + | ^^^^^^^^^^^^ associated function or constant not found in `u32` error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr index 759a40c..1a5f77b 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr
@@ -1,20 +1,24 @@ error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:8:35 | -LL | const SIZE: usize; - | - help: add `type` before `const` for `Tr::SIZE`: `type` -... LL | fn mk_array<T: Tr>(_x: T) -> [(); T::SIZE] { | ^^^^^^^ + | +help: add `type` before `const` for `Tr::SIZE` + | +LL | type const SIZE: usize; + | ++++ error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:10:10 | -LL | const SIZE: usize; - | - help: add `type` before `const` for `Tr::SIZE`: `type` -... LL | [(); T::SIZE] | ^^^^^^^ + | +help: add `type` before `const` for `Tr::SIZE` + | +LL | type const SIZE: usize; + | ++++ error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs index 6a4ee3e..ec74a6e 100644 --- a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs
@@ -6,14 +6,14 @@ struct U; #[derive(ConstParamTy, PartialEq, Eq)] -//~^ ERROR overflow evaluating the requirement `S<U> well-formed` -//~| ERROR overflow evaluating the requirement `S<U> well-formed` +//~^ ERROR overflow evaluating whether `S<U>` is well-formed +//~| ERROR overflow evaluating whether `S<U>` is well-formed struct S<const N: U>() where S<{ U }>:; -//~^ ERROR overflow evaluating the requirement `S<U> well-formed` -//~| ERROR overflow evaluating the requirement `S<U> well-formed` -//~| ERROR overflow evaluating the requirement `S<U> well-formed` +//~^ ERROR overflow evaluating whether `S<U>` is well-formed +//~| ERROR overflow evaluating whether `S<U>` is well-formed +//~| ERROR overflow evaluating whether `S<U>` is well-formed fn main() {}
diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr index 4c5ad64..bb393ca 100644 --- a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr
@@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `S<U> well-formed` +error[E0275]: overflow evaluating whether `S<U>` is well-formed --> $DIR/const-ctor-overflow-eval.rs:14:5 | LL | S<{ U }>:; @@ -13,7 +13,7 @@ LL | S<{ U }>:; | ^^^^^^^^ required by this bound in `S` -error[E0275]: overflow evaluating the requirement `S<U> well-formed` +error[E0275]: overflow evaluating whether `S<U>` is well-formed --> $DIR/const-ctor-overflow-eval.rs:14:5 | LL | S<{ U }>:; @@ -29,7 +29,7 @@ | ^^^^^^^^ required by this bound in `S` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0275]: overflow evaluating the requirement `S<U> well-formed` +error[E0275]: overflow evaluating whether `S<U>` is well-formed --> $DIR/const-ctor-overflow-eval.rs:14:5 | LL | S<{ U }>:; @@ -45,7 +45,7 @@ | ^^^^^^^^ required by this bound in `S` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0275]: overflow evaluating the requirement `S<U> well-formed` +error[E0275]: overflow evaluating whether `S<U>` is well-formed --> $DIR/const-ctor-overflow-eval.rs:8:24 | LL | #[derive(ConstParamTy, PartialEq, Eq)] @@ -60,7 +60,7 @@ LL | S<{ U }>:; | ^^^^^^^^ required by this bound in `S` -error[E0275]: overflow evaluating the requirement `S<U> well-formed` +error[E0275]: overflow evaluating whether `S<U>` is well-formed --> $DIR/const-ctor-overflow-eval.rs:8:35 | LL | #[derive(ConstParamTy, PartialEq, Eq)]
diff --git a/tests/ui/const-generics/mgca/free-const-recursive.rs b/tests/ui/const-generics/mgca/free-const-recursive.rs new file mode 100644 index 0000000..8d75c1a --- /dev/null +++ b/tests/ui/const-generics/mgca/free-const-recursive.rs
@@ -0,0 +1,13 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/153831> +//@ check-fail +//@compile-flags: -Znext-solver=globally --emit=obj +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +type const A: () = A; +//~^ ERROR type mismatch resolving `A normalizes-to _` +//~| ERROR the constant `A` is not of type `()` + +fn main() { + A; +}
diff --git a/tests/ui/const-generics/mgca/free-const-recursive.stderr b/tests/ui/const-generics/mgca/free-const-recursive.stderr new file mode 100644 index 0000000..d0f1027 --- /dev/null +++ b/tests/ui/const-generics/mgca/free-const-recursive.stderr
@@ -0,0 +1,15 @@ +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/free-const-recursive.rs:7:1 + | +LL | type const A: () = A; + | ^^^^^^^^^^^^^^^^ types differ + +error: the constant `A` is not of type `()` + --> $DIR/free-const-recursive.rs:7:1 + | +LL | type const A: () = A; + | ^^^^^^^^^^^^^^^^ expected `()`, found a different `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/const-generics/mgca/projection-const-recursive.rs b/tests/ui/const-generics/mgca/projection-const-recursive.rs new file mode 100644 index 0000000..c9b5039 --- /dev/null +++ b/tests/ui/const-generics/mgca/projection-const-recursive.rs
@@ -0,0 +1,19 @@ +//! See also <https://github.com/rust-lang/rust/issues/153831> +//@ check-fail +//@compile-flags: -Znext-solver=globally --emit=obj +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + type const A: (); +} + +impl Trait for () { + type const A: () = <() as Trait>::A; + //~^ ERROR type mismatch resolving `<() as Trait>::A normalizes-to _` + //~| ERROR the constant `<() as Trait>::A` is not of type `()` +} + +fn main() { + <() as Trait>::A; +}
diff --git a/tests/ui/const-generics/mgca/projection-const-recursive.stderr b/tests/ui/const-generics/mgca/projection-const-recursive.stderr new file mode 100644 index 0000000..d9c6010 --- /dev/null +++ b/tests/ui/const-generics/mgca/projection-const-recursive.stderr
@@ -0,0 +1,15 @@ +error[E0271]: type mismatch resolving `<() as Trait>::A normalizes-to _` + --> $DIR/projection-const-recursive.rs:12:5 + | +LL | type const A: () = <() as Trait>::A; + | ^^^^^^^^^^^^^^^^ types differ + +error: the constant `<() as Trait>::A` is not of type `()` + --> $DIR/projection-const-recursive.rs:12:5 + | +LL | type const A: () = <() as Trait>::A; + | ^^^^^^^^^^^^^^^^ expected `()`, found a different `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs index 715caef..c828843 100644 --- a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs +++ b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs
@@ -6,7 +6,6 @@ // It should now produce a proper type error. #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete struct S;
diff --git a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr index baf587a..fcf02621 100644 --- a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr
@@ -1,19 +1,10 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/struct-ctor-in-array-len.rs:8:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - = note: `#[warn(incomplete_features)]` on by default - error: the constant `S` is not of type `usize` - --> $DIR/struct-ctor-in-array-len.rs:14:14 + --> $DIR/struct-ctor-in-array-len.rs:13:14 | LL | let _b = [0; S]; | ^^^^^^ expected `usize`, found `S` | = note: the length of array `[{integer}; S]` must be type `usize` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs index 1c3274f..4d96d23 100644 --- a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs +++ b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs
@@ -1,7 +1,6 @@ // Make sure we don't ICE when encountering an fn item during lowering in mGCA. #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete trait A<T> {}
diff --git a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr index 89fc827..de64bf7 100644 --- a/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr +++ b/tests/ui/const-generics/mgca/unexpected-fn-item-in-array.stderr
@@ -1,19 +1,10 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unexpected-fn-item-in-array.rs:3:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - = note: `#[warn(incomplete_features)]` on by default - error: the constant `fn_item` is not of type `usize` - --> $DIR/unexpected-fn-item-in-array.rs:8:6 + --> $DIR/unexpected-fn-item-in-array.rs:7:6 | LL | impl A<[usize; fn_item]> for () {} | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found fn item | = note: the length of array `[usize; fn_item]` must be type `usize` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.stderr b/tests/ui/const-generics/mgca/unmarked-free-const.stderr index 76875d8..dd33de4 100644 --- a/tests/ui/const-generics/mgca/unmarked-free-const.stderr +++ b/tests/ui/const-generics/mgca/unmarked-free-const.stderr
@@ -1,11 +1,13 @@ error: use of `const` in the type system not defined as `type const` --> $DIR/unmarked-free-const.rs:9:18 | -LL | const N: usize = 4; - | - help: add `type` before `const` for `N`: `type` -... LL | let x = [(); N]; | ^ + | +help: add `type` before `const` for `N` + | +LL | type const N: usize = 4; + | ++++ error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr index 9392a17..ec39cc2 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
@@ -56,7 +56,7 @@ ff __ __ __ │ .░░░ } -error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:42:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); @@ -67,7 +67,7 @@ 42 │ B } -error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:44:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index 9392a17..ec39cc2 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
@@ -56,7 +56,7 @@ ff __ __ __ │ .░░░ } -error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:42:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); @@ -67,7 +67,7 @@ 42 │ B } -error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:44:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
diff --git a/tests/ui/const-generics/occurs-check/unify-fixpoint.rs b/tests/ui/const-generics/occurs-check/unify-fixpoint.rs index 02bc909..950757e 100644 --- a/tests/ui/const-generics/occurs-check/unify-fixpoint.rs +++ b/tests/ui/const-generics/occurs-check/unify-fixpoint.rs
@@ -4,8 +4,7 @@ //@ compile-flags: -Zunstable-options //@ check-pass -#![feature(generic_const_exprs)] //~ WARN the feature `generic_const_exprs` is incomplete - +#![feature(generic_const_exprs)] fn bind<const N: usize>(value: [u8; N + 2]) -> [u8; N * 2] { todo!()
diff --git a/tests/ui/const-generics/occurs-check/unify-fixpoint.stderr b/tests/ui/const-generics/occurs-check/unify-fixpoint.stderr deleted file mode 100644 index 8b63e8c..0000000 --- a/tests/ui/const-generics/occurs-check/unify-fixpoint.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unify-fixpoint.rs:7:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs index 21efe4c..bb20c04 100644 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.rs +++ b/tests/ui/const-generics/ogca/coherence-ambiguous.rs
@@ -1,5 +1,4 @@ -// FIXME(ogca): this should ERROR not pass!! -//@ check-pass +//@ check-fail #![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] #![expect(incomplete_features)] @@ -12,8 +11,8 @@ trait Trait {} impl Trait for [(); FOO::<1>] {} impl Trait for [(); BAR::<1>] {} -// FIXME(ogca): this should ERROR! +//~^ ERROR conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` impl Trait for [(); BAR::<2>] {} -// FIXME(ogca): this should ERROR! +//~^ ERROR conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` fn main() {}
diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.stderr b/tests/ui/const-generics/ogca/coherence-ambiguous.stderr new file mode 100644 index 0000000..919a0c8 --- /dev/null +++ b/tests/ui/const-generics/ogca/coherence-ambiguous.stderr
@@ -0,0 +1,20 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` + --> $DIR/coherence-ambiguous.rs:13:1 + | +LL | impl Trait for [(); FOO::<1>] {} + | ----------------------------- first implementation here +LL | impl Trait for [(); BAR::<1>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); FOO::<1>]` + +error[E0119]: conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` + --> $DIR/coherence-ambiguous.rs:15:1 + | +LL | impl Trait for [(); FOO::<1>] {} + | ----------------------------- first implementation here +... +LL | impl Trait for [(); BAR::<2>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); FOO::<1>]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs index 808d960..49c8885 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs
@@ -4,6 +4,8 @@ pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } pub struct SmallCString<const N: usize> {}
diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr index c80efd6..1557b83 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr
@@ -7,7 +7,7 @@ | type must be known at this point | note: required by a const generic parameter in `SmallCString` - --> $DIR/try-from-with-const-genericsrs-98299.rs:9:25 + --> $DIR/try-from-with-const-genericsrs-98299.rs:11:25 | LL | pub struct SmallCString<const N: usize> {} | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` @@ -16,6 +16,46 @@ LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); | +++++++++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------ ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 + | +LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); + | +++++++++++++++++ + +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------------------- ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 + | +LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); + | +++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index 70ae00a..fb74be3 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &[u32]: encountered a null reference --> $DIR/forbidden_slices.rs:16:1 | LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) }; @@ -9,7 +9,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &[()]: encountered a null reference --> $DIR/forbidden_slices.rs:18:1 | LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; @@ -20,7 +20,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &[u32]: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/forbidden_slices.rs:22:1 | LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) }; @@ -31,7 +31,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/forbidden_slices.rs:26:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; @@ -42,7 +42,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/forbidden_slices.rs:28:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) }; @@ -55,7 +55,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/forbidden_slices.rs:30:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; @@ -66,7 +66,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u16]: at .<deref>[1], encountered uninitialized memory, but expected an integer --> $DIR/forbidden_slices.rs:33:1 | LL | pub static S7: &[u16] = unsafe { @@ -77,7 +77,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &[u64]: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/forbidden_slices.rs:41:1 | LL | pub static S8: &[u64] = unsafe { @@ -88,7 +88,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &[u32]: encountered a null reference --> $DIR/forbidden_slices.rs:48:1 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; @@ -111,7 +111,7 @@ LL | from_ptr_range(ptr..ptr.add(2)) // errors inside libcore | ^^^^^^^^^^ evaluation of `R2` failed here -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/forbidden_slices.rs:57:1 | LL | pub static R4: &[u8] = unsafe { @@ -122,7 +122,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/forbidden_slices.rs:62:1 | LL | pub static R5: &[u8] = unsafe { @@ -135,7 +135,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/forbidden_slices.rs:67:1 | LL | pub static R6: &[bool] = unsafe { @@ -146,7 +146,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type &[u16]: encountered an unaligned reference (required 2 byte alignment but found 1) --> $DIR/forbidden_slices.rs:72:1 | LL | pub static R7: &[u16] = unsafe {
diff --git a/tests/ui/consts/const-bound.rs b/tests/ui/consts/const-bound.rs deleted file mode 100644 index 00a833b..0000000 --- a/tests/ui/consts/const-bound.rs +++ /dev/null
@@ -1,19 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -// Make sure const bounds work on things, and test that a few types -// are const. - - -fn foo<T: Sync>(x: T) -> T { x } - -struct F { field: isize } - -pub fn main() { - /*foo(1); - foo("hi".to_string()); - foo(vec![1, 2, 3]); - foo(F{field: 42}); - foo((1, 2)); - foo(@1);*/ - foo(Box::new(1)); -}
diff --git a/tests/ui/consts/const-enum-tuple.rs b/tests/ui/consts/const-enum-tuple.rs deleted file mode 100644 index fe6b54a..0000000 --- a/tests/ui/consts/const-enum-tuple.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -enum E { V16(u16), V32(u32) } -static C: (E, u16, u16) = (E::V16(0xDEAD), 0x600D, 0xBAD); - -pub fn main() { - let (_, n, _) = C; - assert!(n != 0xBAD); - assert_eq!(n, 0x600D); -}
diff --git a/tests/ui/consts/const-enum-tuple2.rs b/tests/ui/consts/const-enum-tuple2.rs deleted file mode 100644 index 7132099..0000000 --- a/tests/ui/consts/const-enum-tuple2.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -enum E { V0, V16(u16) } -static C: (E, u16, u16) = (E::V0, 0x600D, 0xBAD); - -pub fn main() { - let (_, n, _) = C; - assert!(n != 0xBAD); - assert_eq!(n, 0x600D); -}
diff --git a/tests/ui/consts/const-enum-tuplestruct2.rs b/tests/ui/consts/const-enum-tuplestruct2.rs deleted file mode 100644 index dc44532..0000000 --- a/tests/ui/consts/const-enum-tuplestruct2.rs +++ /dev/null
@@ -1,12 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -enum E { V0, V16(u16) } -struct S(E, u16, u16); -static C: S = S(E::V0, 0x600D, 0xBAD); - -pub fn main() { - let S(_, n, _) = C; - assert!(n != 0xBAD); - assert_eq!(n, 0x600D); -}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr index 239bca5..f8d6cc1 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &i32: at .<deref>, encountered uninitialized memory, but expected an integer --> $DIR/alloc_intrinsic_uninit.rs:7:1 | LL | const BAR: &i32 = unsafe {
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr index 3c6d66a..f7b652f 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &i32: at .<deref>, encountered uninitialized memory, but expected an integer --> $DIR/alloc_intrinsic_uninit.rs:7:1 | LL | const BAR: &i32 = 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 152eeab..0942924 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a dangling reference (use-after-free) +error[E0080]: constructing invalid value of type &u8: encountered a dangling reference (use-after-free) --> $DIR/dealloc_intrinsic_dangling.rs:11:1 | LL | const _X: &'static u8 = unsafe {
diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index acbf19d..65f815f 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum: at .<enum-tag>, encountered 0x00000001, but expected a valid enum tag --> $DIR/raw-bytes.rs:23:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; @@ -9,7 +9,7 @@ 01 00 00 00 │ .... } -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum2: at .<enum-tag>, encountered 0x00000000, but expected a valid enum tag --> $DIR/raw-bytes.rs:31:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; @@ -20,7 +20,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/raw-bytes.rs:45:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; @@ -31,7 +31,7 @@ 01 │ . } -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x03, but expected a valid enum tag +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered 0x03, but expected a valid enum tag --> $DIR/raw-bytes.rs:47:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; @@ -42,7 +42,7 @@ 03 │ . } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) +error[E0080]: constructing invalid value of type Option<(char, char)>: at .<enum-variant(Some)>.0.1, encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) --> $DIR/raw-bytes.rs:53:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); @@ -53,7 +53,7 @@ 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<u8>: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:58:1 | LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) }; @@ -64,7 +64,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<u8>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ 00 │ . } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<usize>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) }; @@ -86,7 +86,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered 42, but expected something in the range 10..=30 +error[E0080]: constructing invalid value of type RestrictedRange1: encountered 42, but expected something in the range 10..=30 --> $DIR/raw-bytes.rs:69:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; @@ -97,7 +97,7 @@ 2a 00 00 00 │ *... } -error[E0080]: constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 +error[E0080]: constructing invalid value of type RestrictedRange2: encountered 20, but expected something less or equal to 10, or greater or equal to 30 --> $DIR/raw-bytes.rs:75:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; @@ -108,7 +108,7 @@ 14 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<dyn Send>: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:78:1 | LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe { @@ -119,7 +119,7 @@ 00 00 00 00 ╾ALLOC_ID╼ │ ....╾──╼ } -error[E0080]: constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type &u16: encountered an unaligned reference (required 2 byte alignment but found 1) --> $DIR/raw-bytes.rs:85:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; @@ -130,7 +130,7 @@ ╾ALLOC_ID╼ │ ╾──╼ } -error[E0080]: constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type Box<u16>: encountered an unaligned box (required 2 byte alignment but found 1) --> $DIR/raw-bytes.rs:88:1 | LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; @@ -141,7 +141,7 @@ ╾ALLOC_ID╼ │ ╾──╼ } -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &u16: encountered a null reference --> $DIR/raw-bytes.rs:91:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; @@ -152,7 +152,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered a null box +error[E0080]: constructing invalid value of type Box<u16>: encountered a null box --> $DIR/raw-bytes.rs:94:1 | LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; @@ -163,7 +163,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type &u8: encountered a dangling reference (0x539[noalloc] has no provenance) --> $DIR/raw-bytes.rs:97:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; @@ -174,7 +174,7 @@ 39 05 00 00 │ 9... } -error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type Box<u8>: encountered a dangling box (0x539[noalloc] has no provenance) --> $DIR/raw-bytes.rs:100:1 | LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; @@ -185,7 +185,7 @@ 39 05 00 00 │ 9... } -error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered null pointer, but expected a function pointer --> $DIR/raw-bytes.rs:103:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; @@ -196,7 +196,7 @@ 00 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered 0xd[noalloc], but expected a function pointer --> $DIR/raw-bytes.rs:105:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; @@ -207,7 +207,7 @@ 0d 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered ALLOC3<imm>, but expected a function pointer --> $DIR/raw-bytes.rs:107:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; @@ -218,7 +218,7 @@ ╾ALLOC_ID╼ │ ╾──╼ } -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type Bar +error[E0080]: constructing invalid value of type &Bar: encountered a reference pointing to uninhabited type Bar --> $DIR/raw-bytes.rs:113:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; @@ -229,7 +229,7 @@ 01 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &str: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:137:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -240,7 +240,7 @@ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type (&str,): at .0, encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:139:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); @@ -251,7 +251,7 @@ ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼.... } -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &MyStr: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:141:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; @@ -262,7 +262,7 @@ ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &str: at .<deref>, encountered uninitialized memory, but expected a string --> $DIR/raw-bytes.rs:144:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -273,7 +273,7 @@ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered uninitialized memory, but expected a string --> $DIR/raw-bytes.rs:146:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -284,7 +284,7 @@ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>.0: encountered a pointer, but expected a string +error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered a pointer, but expected a string --> $DIR/raw-bytes.rs:148:1 | LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) }; @@ -297,7 +297,7 @@ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &[u8]: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:152:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -308,7 +308,7 @@ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u32]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:154:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; @@ -319,7 +319,7 @@ ╾ALLOC_ID╼ ff ff ff 7f │ ╾──╼.... } -error[E0080]: constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Box<[u8]>: encountered a dangling box (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:157:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -330,7 +330,7 @@ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &[bool; 1]: at .<deref>[0], encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:160:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -347,7 +347,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.0, encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:164:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -364,7 +364,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.1[0], encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:167:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); @@ -381,7 +381,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .0: encountered ALLOC17<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC17<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:171:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; @@ -392,7 +392,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC19<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC19<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:174:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; @@ -403,7 +403,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered 0x4[noalloc], but expected a vtable pointer --> $DIR/raw-bytes.rs:177:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; @@ -414,7 +414,7 @@ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .0: encountered ALLOC22<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC22<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:179:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; @@ -425,7 +425,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &dyn Trait: at .<deref>.<dyn-downcast(bool)>, encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:182:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; @@ -436,7 +436,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered null pointer, but expected a vtable pointer --> $DIR/raw-bytes.rs:185:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; @@ -447,7 +447,7 @@ ╾ALLOC_ID╼ 00 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value: encountered ALLOC27<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered ALLOC27<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:187:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; @@ -458,7 +458,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] +error[E0080]: constructing invalid value of type &[!; 1]: encountered a reference pointing to uninhabited type [!; 1] --> $DIR/raw-bytes.rs:191:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -469,7 +469,7 @@ 01 00 00 00 │ .... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/raw-bytes.rs:192:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -480,7 +480,7 @@ 01 00 00 00 01 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/raw-bytes.rs:193:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; @@ -491,7 +491,7 @@ 01 00 00 00 2a 00 00 00 │ ....*... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:196:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; @@ -502,7 +502,7 @@ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/raw-bytes.rs:199:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; @@ -515,7 +515,7 @@ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/raw-bytes.rs:202:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; @@ -526,7 +526,7 @@ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u16]: at .<deref>[1], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:206:1 | LL | pub static S7: &[u16] = unsafe { @@ -537,7 +537,7 @@ ╾ALLOC_ID+0x2╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:213:1 | LL | pub static R4: &[u8] = unsafe { @@ -548,7 +548,7 @@ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/raw-bytes.rs:218:1 | LL | pub static R5: &[u8] = unsafe { @@ -561,7 +561,7 @@ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/raw-bytes.rs:223:1 | LL | pub static R6: &[bool] = unsafe {
diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 52d32fd..d117de2 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x0000000000000001, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum: at .<enum-tag>, encountered 0x0000000000000001, but expected a valid enum tag --> $DIR/raw-bytes.rs:23:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; @@ -9,7 +9,7 @@ 01 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum2: at .<enum-tag>, encountered 0x0000000000000000, but expected a valid enum tag --> $DIR/raw-bytes.rs:31:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; @@ -20,7 +20,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/raw-bytes.rs:45:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; @@ -31,7 +31,7 @@ 01 │ . } -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x03, but expected a valid enum tag +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered 0x03, but expected a valid enum tag --> $DIR/raw-bytes.rs:47:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; @@ -42,7 +42,7 @@ 03 │ . } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) +error[E0080]: constructing invalid value of type Option<(char, char)>: at .<enum-variant(Some)>.0.1, encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) --> $DIR/raw-bytes.rs:53:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); @@ -53,7 +53,7 @@ 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<u8>: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:58:1 | LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) }; @@ -64,7 +64,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<u8>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ 00 │ . } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<usize>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) }; @@ -86,7 +86,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered 42, but expected something in the range 10..=30 +error[E0080]: constructing invalid value of type RestrictedRange1: encountered 42, but expected something in the range 10..=30 --> $DIR/raw-bytes.rs:69:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; @@ -97,7 +97,7 @@ 2a 00 00 00 │ *... } -error[E0080]: constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 +error[E0080]: constructing invalid value of type RestrictedRange2: encountered 20, but expected something less or equal to 10, or greater or equal to 30 --> $DIR/raw-bytes.rs:75:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; @@ -108,7 +108,7 @@ 14 00 00 00 │ .... } -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<dyn Send>: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:78:1 | LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe { @@ -119,7 +119,7 @@ 00 00 00 00 00 00 00 00 ╾ALLOC_ID╼ │ ........╾──────╼ } -error[E0080]: constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type &u16: encountered an unaligned reference (required 2 byte alignment but found 1) --> $DIR/raw-bytes.rs:85:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; @@ -130,7 +130,7 @@ ╾ALLOC_ID╼ │ ╾──────╼ } -error[E0080]: constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type Box<u16>: encountered an unaligned box (required 2 byte alignment but found 1) --> $DIR/raw-bytes.rs:88:1 | LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; @@ -141,7 +141,7 @@ ╾ALLOC_ID╼ │ ╾──────╼ } -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &u16: encountered a null reference --> $DIR/raw-bytes.rs:91:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; @@ -152,7 +152,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered a null box +error[E0080]: constructing invalid value of type Box<u16>: encountered a null box --> $DIR/raw-bytes.rs:94:1 | LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; @@ -163,7 +163,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type &u8: encountered a dangling reference (0x539[noalloc] has no provenance) --> $DIR/raw-bytes.rs:97:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; @@ -174,7 +174,7 @@ 39 05 00 00 00 00 00 00 │ 9....... } -error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type Box<u8>: encountered a dangling box (0x539[noalloc] has no provenance) --> $DIR/raw-bytes.rs:100:1 | LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; @@ -185,7 +185,7 @@ 39 05 00 00 00 00 00 00 │ 9....... } -error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered null pointer, but expected a function pointer --> $DIR/raw-bytes.rs:103:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; @@ -196,7 +196,7 @@ 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered 0xd[noalloc], but expected a function pointer --> $DIR/raw-bytes.rs:105:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; @@ -207,7 +207,7 @@ 0d 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered ALLOC3<imm>, but expected a function pointer --> $DIR/raw-bytes.rs:107:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; @@ -218,7 +218,7 @@ ╾ALLOC_ID╼ │ ╾──────╼ } -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type Bar +error[E0080]: constructing invalid value of type &Bar: encountered a reference pointing to uninhabited type Bar --> $DIR/raw-bytes.rs:113:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; @@ -229,7 +229,7 @@ 01 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &str: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:137:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -240,7 +240,7 @@ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type (&str,): at .0, encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:139:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); @@ -251,7 +251,7 @@ ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ } -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &MyStr: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:141:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; @@ -262,7 +262,7 @@ ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &str: at .<deref>, encountered uninitialized memory, but expected a string --> $DIR/raw-bytes.rs:144:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -273,7 +273,7 @@ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered uninitialized memory, but expected a string --> $DIR/raw-bytes.rs:146:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -284,7 +284,7 @@ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>.0: encountered a pointer, but expected a string +error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered a pointer, but expected a string --> $DIR/raw-bytes.rs:148:1 | LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) }; @@ -297,7 +297,7 @@ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &[u8]: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:152:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -308,7 +308,7 @@ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u32]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/raw-bytes.rs:154:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; @@ -319,7 +319,7 @@ ╾ALLOC_ID╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........ } -error[E0080]: constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Box<[u8]>: encountered a dangling box (going beyond the bounds of its allocation) --> $DIR/raw-bytes.rs:157:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -330,7 +330,7 @@ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &[bool; 1]: at .<deref>[0], encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:160:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -347,7 +347,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.0, encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:164:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -364,7 +364,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.1[0], encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:167:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); @@ -381,7 +381,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .0: encountered ALLOC17<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC17<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:171:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; @@ -392,7 +392,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC19<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC19<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:174:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; @@ -403,7 +403,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered 0x4[noalloc], but expected a vtable pointer --> $DIR/raw-bytes.rs:177:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; @@ -414,7 +414,7 @@ ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .0: encountered ALLOC22<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC22<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:179:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; @@ -425,7 +425,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &dyn Trait: at .<deref>.<dyn-downcast(bool)>, encountered 0x03, but expected a boolean --> $DIR/raw-bytes.rs:182:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; @@ -436,7 +436,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered null pointer, but expected a vtable pointer --> $DIR/raw-bytes.rs:185:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; @@ -447,7 +447,7 @@ ╾ALLOC_ID╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value: encountered ALLOC27<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered ALLOC27<imm>, but expected a vtable pointer --> $DIR/raw-bytes.rs:187:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; @@ -458,7 +458,7 @@ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] +error[E0080]: constructing invalid value of type &[!; 1]: encountered a reference pointing to uninhabited type [!; 1] --> $DIR/raw-bytes.rs:191:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -469,7 +469,7 @@ 01 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/raw-bytes.rs:192:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -480,7 +480,7 @@ 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/raw-bytes.rs:193:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; @@ -491,7 +491,7 @@ 01 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00 │ ........*....... } -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:196:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; @@ -502,7 +502,7 @@ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/raw-bytes.rs:199:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; @@ -515,7 +515,7 @@ ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/raw-bytes.rs:202:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; @@ -526,7 +526,7 @@ ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u16]: at .<deref>[1], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:206:1 | LL | pub static S7: &[u16] = unsafe { @@ -537,7 +537,7 @@ ╾ALLOC_ID+0x2╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered uninitialized memory, but expected an integer --> $DIR/raw-bytes.rs:213:1 | LL | pub static R4: &[u8] = unsafe { @@ -548,7 +548,7 @@ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type &[u8]: at .<deref>[0], encountered a pointer, but expected an integer --> $DIR/raw-bytes.rs:218:1 | LL | pub static R5: &[u8] = unsafe { @@ -561,7 +561,7 @@ ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean +error[E0080]: constructing invalid value of type &[bool]: at .<deref>[0], encountered 0x11, but expected a boolean --> $DIR/raw-bytes.rs:223:1 | LL | pub static R6: &[bool] = unsafe {
diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 274b1ae..d63e1d5 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs
@@ -83,10 +83,10 @@ enum UninhDiscriminant { }; const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; -//~^ ERROR constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +//~^ ERROR encountered an unaligned reference (required 2 byte alignment but found 1) const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; -//~^ ERROR constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +//~^ ERROR encountered an unaligned box (required 2 byte alignment but found 1) const NULL: &u16 = unsafe { mem::transmute(0usize) }; //~^ ERROR constructing invalid value
diff --git a/tests/ui/consts/const-eval/transmute-const.stderr b/tests/ui/consts/const-eval/transmute-const.stderr index 53665c1..3b064c9 100644 --- a/tests/ui/consts/const-eval/transmute-const.stderr +++ b/tests/ui/consts/const-eval/transmute-const.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x03, but expected a boolean --> $DIR/transmute-const.rs:4:1 | LL | static FOO: bool = unsafe { mem::transmute(3u8) };
diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index da63af3..a5ac10c 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x01, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum: at .<enum-tag>, encountered 0x01, but expected a valid enum tag --> $DIR/ub-enum.rs:30:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; @@ -27,7 +27,7 @@ = 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[E0080]: constructing invalid value at .<enum-tag>: encountered 0x0, but expected a valid enum tag +error[E0080]: constructing invalid value of type Enum2: at .<enum-tag>, encountered 0x0, but expected a valid enum tag --> $DIR/ub-enum.rs:48:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; @@ -75,7 +75,7 @@ = 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[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/ub-enum.rs:83:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; @@ -86,7 +86,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x03, but expected a valid enum tag +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered 0x03, but expected a valid enum tag --> $DIR/ub-enum.rs:85:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; @@ -97,7 +97,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) +error[E0080]: constructing invalid value of type Option<(char, char)>: at .<enum-variant(Some)>.0.1, encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) --> $DIR/ub-enum.rs:93:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); @@ -108,13 +108,13 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type Result<(i32, Never), (i32, !)>: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/ub-enum.rs:98:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA1` failed here -error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type Result<(i32, !), (i32, Never)>: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/ub-enum.rs:100:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
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 1e4d425..2d2d97d 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered ALLOC1<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC1<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:18:1 | LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = @@ -9,7 +9,7 @@ ╾ALLOC0<imm>╼ ╾ALLOC1<imm>╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC3<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:22:1 | LL | const INVALID_VTABLE_SIZE: &dyn Trait = @@ -20,7 +20,7 @@ ╾ALLOC2<imm>╼ ╾ALLOC3<imm>╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC5<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC5<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:31:1 | LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> = @@ -31,7 +31,7 @@ ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC7<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC7<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:35:1 | LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> = @@ -42,7 +42,7 @@ ╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC9<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC9<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:40:1 | LL | const INVALID_VTABLE_UB: W<&dyn Trait> = @@ -53,7 +53,7 @@ ╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼ │ ╾──╼╾──╼ } -error[E0080]: constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Wide<'_>: at .1, encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/ub-incorrect-vtable.rs:86:1 | LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
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 a068991..4c8a180 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered ALLOC1<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC1<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:18:1 | LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = @@ -9,7 +9,7 @@ ╾ALLOC0<imm>╼ ╾ALLOC1<imm>╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC3<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:22:1 | LL | const INVALID_VTABLE_SIZE: &dyn Trait = @@ -20,7 +20,7 @@ ╾ALLOC2<imm>╼ ╾ALLOC3<imm>╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC5<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC5<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:31:1 | LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> = @@ -31,7 +31,7 @@ ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC7<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC7<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:35:1 | LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> = @@ -42,7 +42,7 @@ ╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .0: encountered ALLOC9<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC9<imm>, but expected a vtable pointer --> $DIR/ub-incorrect-vtable.rs:40:1 | LL | const INVALID_VTABLE_UB: W<&dyn Trait> = @@ -53,7 +53,7 @@ ╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼ │ ╾──────╼╾──────╼ } -error[E0080]: constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Wide<'_>: at .1, encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/ub-incorrect-vtable.rs:86:1 | LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
diff --git a/tests/ui/consts/const-eval/ub-int-array.rs b/tests/ui/consts/const-eval/ub-int-array.rs index eebbcca..151019c 100644 --- a/tests/ui/consts/const-eval/ub-int-array.rs +++ b/tests/ui/consts/const-eval/ub-int-array.rs
@@ -18,7 +18,7 @@ const fn new(t: T) -> Self { } const UNINIT_INT_0: [u32; 3] = unsafe { - //~^ ERROR invalid value at [0] + //~^ ERROR invalid value of type [u32; 3]: at [0] mem::transmute([ MaybeUninit { uninit: () }, // Constants chosen to achieve endianness-independent hex dump. @@ -27,7 +27,7 @@ const fn new(t: T) -> Self { ]) }; const UNINIT_INT_1: [u32; 3] = unsafe { - //~^ ERROR invalid value at [1] + //~^ ERROR invalid value of type [u32; 3]: at [1] mem::transmute([ MaybeUninit::new(0u8), MaybeUninit::new(0u8), @@ -44,7 +44,7 @@ const fn new(t: T) -> Self { ]) }; const UNINIT_INT_2: [u32; 3] = unsafe { - //~^ ERROR invalid value at [2] + //~^ ERROR invalid value of type [u32; 3]: at [2] mem::transmute([ MaybeUninit::new(0u8), MaybeUninit::new(0u8),
diff --git a/tests/ui/consts/const-eval/ub-int-array.stderr b/tests/ui/consts/const-eval/ub-int-array.stderr index 065bfd2..253358f 100644 --- a/tests/ui/consts/const-eval/ub-int-array.stderr +++ b/tests/ui/consts/const-eval/ub-int-array.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at [0]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type [u32; 3]: at [0], encountered uninitialized memory, but expected an integer --> $DIR/ub-int-array.rs:20:1 | LL | const UNINIT_INT_0: [u32; 3] = unsafe { @@ -9,7 +9,7 @@ __ __ __ __ 11 11 11 11 22 22 22 22 │ ░░░░...."""" } -error[E0080]: constructing invalid value at [1]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type [u32; 3]: at [1], encountered uninitialized memory, but expected an integer --> $DIR/ub-int-array.rs:29:1 | LL | const UNINIT_INT_1: [u32; 3] = unsafe { @@ -20,7 +20,7 @@ 00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░. } -error[E0080]: constructing invalid value at [2]: encountered uninitialized memory, but expected an integer +error[E0080]: constructing invalid value of type [u32; 3]: at [2], encountered uninitialized memory, but expected an integer --> $DIR/ub-int-array.rs:46:1 | LL | const UNINIT_INT_2: [u32; 3] = unsafe {
diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index be5c6f7..8f18385 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<u8>: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:16:1 | LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) }; @@ -15,7 +15,7 @@ LL | let out_of_bounds_ptr = &ptr[255]; | ^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_PTR` failed here -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<u8>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) }; @@ -26,7 +26,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonZero<usize>: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:28:1 | LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) }; @@ -47,7 +47,7 @@ __ │ ░ } -error[E0080]: constructing invalid value: encountered 42, but expected something in the range 10..=30 +error[E0080]: constructing invalid value of type RestrictedRange1: encountered 42, but expected something in the range 10..=30 --> $DIR/ub-nonnull.rs:44:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; @@ -58,7 +58,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 +error[E0080]: constructing invalid value of type RestrictedRange2: encountered 20, but expected something less or equal to 10, or greater or equal to 30 --> $DIR/ub-nonnull.rs:50:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; @@ -69,7 +69,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type NonNull<dyn Send>: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:53:1 | LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe { @@ -80,7 +80,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a maybe-null pointer, but expected something that is definitely non-zero +error[E0080]: constructing invalid value of type NonNull<()>: encountered a maybe-null pointer, but expected something that is definitely non-zero --> $DIR/ub-nonnull.rs:61:1 | LL | const MAYBE_NULL_PTR: NonNull<()> = unsafe { mem::transmute((&raw const S).wrapping_add(4)) };
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index f7421ee..5cc3277 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs
@@ -16,10 +16,10 @@ union MaybeUninit<T: Copy> { } const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; -//~^ ERROR constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +//~^ ERROR encountered an unaligned reference (required 2 byte alignment but found 1) const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; -//~^ ERROR constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +//~^ ERROR encountered an unaligned box (required 2 byte alignment but found 1) const NULL: &u16 = unsafe { mem::transmute(0usize) }; //~^ ERROR invalid value
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 349a98f..17ddea0 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type &u16: encountered an unaligned reference (required 2 byte alignment but found 1) --> $DIR/ub-ref-ptr.rs:18:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; @@ -9,7 +9,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +error[E0080]: constructing invalid value of type Box<u16>: encountered an unaligned box (required 2 byte alignment but found 1) --> $DIR/ub-ref-ptr.rs:21:1 | LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; @@ -20,7 +20,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a null reference +error[E0080]: constructing invalid value of type &u16: encountered a null reference --> $DIR/ub-ref-ptr.rs:24:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; @@ -31,7 +31,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a null box +error[E0080]: constructing invalid value of type Box<u16>: encountered a null box --> $DIR/ub-ref-ptr.rs:27:1 | LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; @@ -42,7 +42,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a maybe-null box +error[E0080]: constructing invalid value of type Box<()>: encountered a maybe-null box --> $DIR/ub-ref-ptr.rs:30:1 | LL | const MAYBE_NULL_BOX: Box<()> = unsafe { mem::transmute({ @@ -92,7 +92,7 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type &u8: encountered a dangling reference (0x539[noalloc] has no provenance) --> $DIR/ub-ref-ptr.rs:48:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; @@ -103,7 +103,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) +error[E0080]: constructing invalid value of type Box<u8>: encountered a dangling box (0x539[noalloc] has no provenance) --> $DIR/ub-ref-ptr.rs:51:1 | LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; @@ -124,7 +124,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered null pointer, but expected a function pointer --> $DIR/ub-ref-ptr.rs:57:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; @@ -145,7 +145,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered 0xd[noalloc], but expected a function pointer --> $DIR/ub-ref-ptr.rs:61:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; @@ -156,7 +156,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered ALLOC3<imm>, but expected a function pointer --> $DIR/ub-ref-ptr.rs:63:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; @@ -167,7 +167,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC4+0xa, but expected a function pointer +error[E0080]: constructing invalid value of type fn(): encountered ALLOC4+0xa, but expected a function pointer --> $DIR/ub-ref-ptr.rs:65:1 | LL | const MAYBE_NULL_FN_PTR: fn() = unsafe { mem::transmute({ @@ -184,7 +184,7 @@ LL | ptr.read(); | ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here -error[E0080]: constructing invalid value: encountered a pointer with unknown absolute address, but expected something that is definitely greater or equal to 1000 +error[E0080]: constructing invalid value of type High: encountered a pointer with unknown absolute address, but expected something that is definitely greater or equal to 1000 --> $DIR/ub-ref-ptr.rs:84:1 | LL | const INVALID_VALUE_PTR: High = unsafe { mem::transmute(&S) };
diff --git a/tests/ui/consts/const-eval/ub-uninhabit.stderr b/tests/ui/consts/const-eval/ub-uninhabit.stderr index aca0b13..244cb96 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.stderr +++ b/tests/ui/consts/const-eval/ub-uninhabit.stderr
@@ -1,10 +1,10 @@ -error[E0080]: constructing invalid value: encountered a value of uninhabited type `Bar` +error[E0080]: constructing invalid value of type Bar: encountered a value of uninhabited type `Bar` --> $DIR/ub-uninhabit.rs:20:35 | LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_BAD_BAD` failed here -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type Bar +error[E0080]: constructing invalid value of type &Bar: encountered a reference pointing to uninhabited type Bar --> $DIR/ub-uninhabit.rs:23:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; @@ -15,13 +15,13 @@ HEX_DUMP } -error[E0080]: constructing invalid value at [0]: encountered a value of uninhabited type `Bar` +error[E0080]: constructing invalid value of type [Bar; 1]: at [0], encountered a value of uninhabited type `Bar` --> $DIR/ub-uninhabit.rs:26:42 | LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_BAD_ARRAY` failed here -error[E0080]: constructing invalid value: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type !: encountered a value of the never type `!` --> $DIR/ub-uninhabit.rs:32:16 | LL | let _val = intrinsics::read_via_copy(ptr);
diff --git a/tests/ui/consts/const-eval/ub-upvars.32bit.stderr b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr index 89512c0..2e5797c 100644 --- a/tests/ui/consts/const-eval/ub-upvars.32bit.stderr +++ b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.<captured-var(bad_ref)>: encountered a null reference +error[E0080]: constructing invalid value of type &dyn FnOnce(): at .<deref>.<dyn-downcast({closure@$DIR/ub-upvars.rs:10:5: 10:12})>.<captured-var(bad_ref)>, encountered a null reference --> $DIR/ub-upvars.rs:7:1 | LL | const BAD_UPVAR: &dyn FnOnce() = &{
diff --git a/tests/ui/consts/const-eval/ub-upvars.64bit.stderr b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr index bf8de48..c45ad78 100644 --- a/tests/ui/consts/const-eval/ub-upvars.64bit.stderr +++ b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.<captured-var(bad_ref)>: encountered a null reference +error[E0080]: constructing invalid value of type &dyn FnOnce(): at .<deref>.<dyn-downcast({closure@$DIR/ub-upvars.rs:10:5: 10:12})>.<captured-var(bad_ref)>, encountered a null reference --> $DIR/ub-upvars.rs:7:1 | LL | const BAD_UPVAR: &dyn FnOnce() = &{
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr index c505e5c..9603710 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &str: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/ub-wide-ptr.rs:40:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -9,7 +9,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type (&str,): at .0, encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/ub-wide-ptr.rs:42:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); @@ -38,7 +38,7 @@ = 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[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &MyStr: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/ub-wide-ptr.rs:50:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; @@ -49,7 +49,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &str: at .<deref>, encountered uninitialized memory, but expected a string --> $DIR/ub-wide-ptr.rs:54:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -60,7 +60,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialized memory, but expected a string +error[E0080]: constructing invalid value of type &MyStr: at .<deref>.0, encountered uninitialized memory, but expected a string --> $DIR/ub-wide-ptr.rs:57:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; @@ -81,7 +81,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type &[u8]: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/ub-wide-ptr.rs:70:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -92,7 +92,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u32]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/ub-wide-ptr.rs:73:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; @@ -112,7 +112,7 @@ = 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[E0080]: constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Box<[u8]>: encountered a dangling box (going beyond the bounds of its allocation) --> $DIR/ub-wide-ptr.rs:79:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; @@ -132,7 +132,7 @@ = 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[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &[bool; 1]: at .<deref>[0], encountered 0x03, but expected a boolean --> $DIR/ub-wide-ptr.rs:86:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -149,7 +149,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.0, encountered 0x03, but expected a boolean --> $DIR/ub-wide-ptr.rs:92:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -166,7 +166,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &MySlice<[bool; 1]>: at .<deref>.1[0], encountered 0x03, but expected a boolean --> $DIR/ub-wide-ptr.rs:95:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); @@ -193,7 +193,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered ALLOC12<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC12<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:110:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; @@ -204,7 +204,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered ALLOC14<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC14<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:113:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; @@ -215,7 +215,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered 0x4[noalloc], but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:116:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; @@ -226,7 +226,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC17<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC17<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:118:1 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; @@ -237,7 +237,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC19<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC19<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:120:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; @@ -248,7 +248,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC21<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type &dyn Trait: encountered ALLOC21<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:122:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; @@ -259,7 +259,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered ALLOC23<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type W<&dyn Trait>: at .0, encountered ALLOC23<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:124:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; @@ -270,7 +270,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type &dyn Trait: at .<deref>.<dyn-downcast(bool)>, encountered 0x03, but expected a boolean --> $DIR/ub-wide-ptr.rs:128:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; @@ -281,7 +281,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered null pointer, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:132:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; @@ -292,7 +292,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC28<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered ALLOC28<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:134:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; @@ -303,7 +303,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered null pointer, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:141:1 | LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { @@ -314,7 +314,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC31<imm>, but expected a vtable pointer +error[E0080]: constructing invalid value of type *const dyn Trait: encountered ALLOC31<imm>, but expected a vtable pointer --> $DIR/ub-wide-ptr.rs:145:1 | LL | static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe {
diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr index fb2311b..95960d1 100644 --- a/tests/ui/consts/const-eval/union-ub.32bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered 0x2a, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x2a, but expected a boolean --> $DIR/union-ub.rs:33:1 | LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool };
diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr index fb2311b..95960d1 100644 --- a/tests/ui/consts/const-eval/union-ub.64bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered 0x2a, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x2a, but expected a boolean --> $DIR/union-ub.rs:33:1 | LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool };
diff --git a/tests/ui/consts/const-eval/valid-const.rs b/tests/ui/consts/const-eval/valid-const.rs index 777484c..6f92997 100644 --- a/tests/ui/consts/const-eval/valid-const.rs +++ b/tests/ui/consts/const-eval/valid-const.rs
@@ -1,10 +1,12 @@ //@ check-pass // // Some constants that *are* valid +#![feature(maybe_dangling)] use std::mem; use std::ptr::NonNull; use std::num::NonZero; +use std::mem::MaybeDangling; const NON_NULL_PTR1: NonNull<u8> = unsafe { mem::transmute(1usize) }; const NON_NULL_PTR2: NonNull<u8> = unsafe { mem::transmute(&0) }; @@ -14,4 +16,6 @@ const UNIT: () = (); +const INVALID_INSIDE_MAYBE_DANGLING: MaybeDangling<&bool> = unsafe { std::mem::transmute(&5u8) }; + fn main() {}
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 848c65f..cd59e7b 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type !: encountered a value of the never type `!` --> $DIR/validate_uninhabited_zsts.rs:17:33 | LL | const FOO: [empty::Empty; 3] = [foo(); 3]; @@ -10,7 +10,7 @@ LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here -error[E0080]: constructing invalid value at .0: encountered a value of uninhabited type `Void` +error[E0080]: constructing invalid value of type empty::Empty: at .0, encountered a value of uninhabited type `Void` --> $DIR/validate_uninhabited_zsts.rs:20:42 | LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 8f54b4e..9b289f4 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr
@@ -28,7 +28,7 @@ | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut u16: encountered mutable reference or box pointing to read-only memory --> $DIR/mut_ref_in_final.rs:27:1 | LL | const IMMUT_MUT_REF: &mut u16 = unsafe { mem::transmute(&13) }; @@ -39,7 +39,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut u16: encountered mutable reference or box pointing to read-only memory --> $DIR/mut_ref_in_final.rs:29:1 | LL | static IMMUT_MUT_REF_STATIC: &mut u16 = unsafe { mem::transmute(&13) }; @@ -120,7 +120,7 @@ = note: to avoid accidentally creating global mutable state, such temporaries must be immutable = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance) +error[E0080]: constructing invalid value of type Option<&mut i32>: at .<enum-variant(Some)>.0, encountered a dangling reference (0x2a[noalloc] has no provenance) --> $DIR/mut_ref_in_final.rs:86:5 | LL | const INT2PTR: Option<&mut i32> = helper_int2ptr(); @@ -131,7 +131,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance) +error[E0080]: constructing invalid value of type Option<&mut i32>: at .<enum-variant(Some)>.0, encountered a dangling reference (0x2a[noalloc] has no provenance) --> $DIR/mut_ref_in_final.rs:87:5 | LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); @@ -142,7 +142,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free) +error[E0080]: constructing invalid value of type Option<&mut i32>: at .<enum-variant(Some)>.0, encountered a dangling reference (use-after-free) --> $DIR/mut_ref_in_final.rs:93:5 | LL | const DANGLING: Option<&mut i32> = helper_dangling(); @@ -153,7 +153,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free) +error[E0080]: constructing invalid value of type Option<&mut i32>: at .<enum-variant(Some)>.0, encountered a dangling reference (use-after-free) --> $DIR/mut_ref_in_final.rs:94:5 | LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling();
diff --git a/tests/ui/consts/const-needs_drop-monomorphic.rs b/tests/ui/consts/const-needs_drop-monomorphic.rs index 7402c68..f68eb4b 100644 --- a/tests/ui/consts/const-needs_drop-monomorphic.rs +++ b/tests/ui/consts/const-needs_drop-monomorphic.rs
@@ -9,7 +9,7 @@ fn assert() {} } fn f<T>() { Bool::<{ std::mem::needs_drop::<T>() }>::assert(); - //~^ ERROR no function or associated item named `assert` found + //~^ ERROR no associated function or constant named `assert` found //~| ERROR unconstrained generic constant } fn main() {
diff --git a/tests/ui/consts/const-needs_drop-monomorphic.stderr b/tests/ui/consts/const-needs_drop-monomorphic.stderr index 17f197c..12ea559 100644 --- a/tests/ui/consts/const-needs_drop-monomorphic.stderr +++ b/tests/ui/consts/const-needs_drop-monomorphic.stderr
@@ -9,14 +9,14 @@ LL | fn f<T>() where [(); { std::mem::needs_drop::<T>() } as usize]: { | +++++++++++++++++++++++++++++++++++++++++++++++++++++ -error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::<T>() }>` in the current scope +error[E0599]: no associated function or constant named `assert` found for struct `Bool<{ std::mem::needs_drop::<T>() }>` in the current scope --> $DIR/const-needs_drop-monomorphic.rs:11:46 | LL | struct Bool<const B: bool> {} - | -------------------------- function or associated item `assert` not found for this struct + | -------------------------- associated function or constant `assert` not found for this struct ... LL | Bool::<{ std::mem::needs_drop::<T>() }>::assert(); - | ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::<T>() }>` due to unsatisfied trait bounds + | ^^^^^^ associated function or constant cannot be called on `Bool<{ std::mem::needs_drop::<T>() }>` due to unsatisfied trait bounds error: aborting due to 2 previous errors
diff --git a/tests/ui/consts/const.rs b/tests/ui/consts/const.rs deleted file mode 100644 index 1f1c6e3..0000000 --- a/tests/ui/consts/const.rs +++ /dev/null
@@ -1,6 +0,0 @@ -//@ run-pass -#![allow(non_upper_case_globals)] - -static i: isize = 10; - -pub fn main() { println!("{}", i); }
diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs index f02e780..59bd040 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs
@@ -14,7 +14,7 @@ fn main() { } match None { - <Defaulted as consts::AssocConst>::SOME => panic!(), + <Defaulted as consts::AssocConst>::SOME => panic!(), //~^ ERROR constant of non-structural type `CustomEq` in a pattern _ => {} }
diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index 7cada88..452c3ee 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr
@@ -7,28 +7,38 @@ ::: $DIR/auxiliary/consts.rs:1:1 | LL | pub struct CustomEq; - | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + | ------------------- `CustomEq` is not usable in patterns ... LL | pub const SOME: Option<CustomEq> = Some(CustomEq); | -------------------------------- constant defined here | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - consts::SOME => panic!(), +LL + binding if binding == consts::SOME => panic!(), + | error: constant of non-structural type `CustomEq` in a pattern --> $DIR/cross-crate-fail.rs:17:9 | -LL | <Defaulted as consts::AssocConst>::SOME => panic!(), +LL | <Defaulted as consts::AssocConst>::SOME => panic!(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | ::: $DIR/auxiliary/consts.rs:1:1 | LL | pub struct CustomEq; - | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + | ------------------- `CustomEq` is not usable in patterns ... LL | const SOME: Option<CustomEq> = Some(CustomEq); | ---------------------------- constant defined here | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - <Defaulted as consts::AssocConst>::SOME => panic!(), +LL + binding if binding == <Defaulted as consts::AssocConst>::SOME => panic!(), + | error: aborting due to 2 previous errors
diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index 154c94c..24bc201 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr
@@ -11,6 +11,11 @@ | ^^^^^^^ constant of non-structural type | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - BAR_BAZ => panic!(), +LL + binding if binding == BAR_BAZ => panic!(), + | error: aborting due to 1 previous error
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index fa16d0b..402e4aa 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
@@ -14,6 +14,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; +LL + match Derive::Some(NoDerive) { binding if binding == ENUM => dbg!(ENUM), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:65:28 @@ -31,6 +36,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; +LL + match Some(NoDerive) { binding if binding == FIELD => dbg!(FIELD), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:71:27 @@ -48,6 +58,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; +LL + match Some(NoDerive) {binding if binding == INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:76:36 @@ -65,6 +80,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; +LL + match (None, Some(NoDerive)) { binding if binding == TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:81:28 @@ -82,6 +102,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; +LL + match Some(NoDerive) { binding if binding == TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:86:36 @@ -99,6 +124,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; +LL + match [None, Some(NoDerive)] { binding if binding == ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:91:33 @@ -116,6 +146,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; +LL + match [Some(NoDerive); 2] { binding if binding == REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:97:28 @@ -134,6 +169,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; +LL + match Some(NoDerive) { binding if binding == NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:102:28 @@ -151,6 +191,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; +LL + match Some(NoDerive) { binding if binding == BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; + | error: constant of non-structural type `NoDerive` in a pattern --> $DIR/reject_non_structural.rs:107:29 @@ -168,6 +213,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; +LL + match &Some(NoDerive) { binding if binding == ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; + | error: aborting due to 10 previous errors
diff --git a/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.rs b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.rs new file mode 100644 index 0000000..71a2d06 --- /dev/null +++ b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.rs
@@ -0,0 +1,50 @@ +//@ edition:2024 +// #42753 +mod partial_eq { + struct S; + impl PartialEq<S> for S { + fn eq(&self, _: &S) -> bool { + true + } + } + + const C: S = S; + const V: Vec<()> = vec![]; + + fn foo() { + match Some(S) { + Some(C) => {} //~ ERROR: constant of non-structural type + Some(C) if true => {} //~ ERROR: constant of non-structural type + None => {} + } + if let Some(C) = Some(S) {} //~ ERROR: constant of non-structural type + if let Some(C) = Some(S) && let Some(1) = Some(2) {} //~ ERROR: constant of non-structural type + let Some(C) = Some(S) else { return; }; //~ ERROR: constant of non-structural type + match vec![] { + V => {} //~ ERROR: constant of non-structural type + _ => {} + } + if let V = vec![] {} //~ ERROR: constant of non-structural type + let V = vec![] else { return; }; //~ ERROR: constant of non-structural type + let V = Vec::new() else { return; }; //~ ERROR: constant of non-structural type + } +} + +mod not_partial_eq { + struct S; + + const C: S = S; + + fn foo() { + match Some(S) { + Some(C) => {} //~ ERROR: constant of non-structural type + Some(C) if true => {} //~ ERROR: constant of non-structural type + None => {} + } + if let Some(C) = Some(S) {} //~ ERROR: constant of non-structural type + if let Some(C) = Some(S) && let Some(1) = Some(2) {} //~ ERROR: constant of non-structural type + let Some(C) = Some(S) else { return; }; //~ ERROR: constant of non-structural type + } +} + +fn main() {}
diff --git a/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr new file mode 100644 index 0000000..38440af --- /dev/null +++ b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr
@@ -0,0 +1,282 @@ +error: constant of non-structural type `partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:16:18 + | +LL | struct S; + | -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: S = S; + | ---------- constant defined here +... +LL | Some(C) => {} + | ^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5 + | +LL | impl PartialEq<S> for S { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - Some(C) => {} +LL + Some(binding) if binding == C => {} + | + +error: constant of non-structural type `partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:17:18 + | +LL | struct S; + | -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: S = S; + | ---------- constant defined here +... +LL | Some(C) if true => {} + | ^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5 + | +LL | impl PartialEq<S> for S { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add a check for equality to the condition of the match arm + | +LL - Some(C) if true => {} +LL + Some(binding) if true && binding == C => {} + | + +error: constant of non-structural type `partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:20:21 + | +LL | struct S; + | -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: S = S; + | ---------- constant defined here +... +LL | if let Some(C) = Some(S) {} + | ^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5 + | +LL | impl PartialEq<S> for S { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: check for equality instead of pattern matching + | +LL - if let Some(C) = Some(S) {} +LL + if let Some(binding) = Some(S) && binding == C {} + | + +error: constant of non-structural type `partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:21:21 + | +LL | struct S; + | -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: S = S; + | ---------- constant defined here +... +LL | if let Some(C) = Some(S) && let Some(1) = Some(2) {} + | ^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5 + | +LL | impl PartialEq<S> for S { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: check for equality instead of pattern matching + | +LL - if let Some(C) = Some(S) && let Some(1) = Some(2) {} +LL + if let Some(binding) = Some(S) && binding == C && let Some(1) = Some(2) {} + | + +error: constant of non-structural type `partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:22:18 + | +LL | struct S; + | -------- `partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: S = S; + | ---------- constant defined here +... +LL | let Some(C) = Some(S) else { return; }; + | ^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:5:5 + | +LL | impl PartialEq<S> for S { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: check for equality instead of pattern matching + | +LL - let Some(C) = Some(S) else { return; }; +LL + if Some(C) == Some(S) { return; }; + | + +error: constant of non-structural type `Vec<()>` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:24:13 + | +LL | const V: Vec<()> = vec![]; + | ---------------- constant defined here +... +LL | V => {} + | ^ constant of non-structural type + | + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec<()>` is not usable in patterns + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - V => {} +LL + binding if binding == V => {} + | + +error: constant of non-structural type `Vec<()>` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:27:16 + | +LL | const V: Vec<()> = vec![]; + | ---------------- constant defined here +... +LL | if let V = vec![] {} + | ^ constant of non-structural type + | + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec<()>` is not usable in patterns + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + +error: constant of non-structural type `Vec<()>` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:28:13 + | +LL | const V: Vec<()> = vec![]; + | ---------------- constant defined here +... +LL | let V = vec![] else { return; }; + | ^ constant of non-structural type + | + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec<()>` is not usable in patterns + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + +error: constant of non-structural type `Vec<()>` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:29:13 + | +LL | const V: Vec<()> = vec![]; + | ---------------- constant defined here +... +LL | let V = Vec::new() else { return; }; + | ^ constant of non-structural type + | + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec<()>` is not usable in patterns + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: check for equality instead of pattern matching + | +LL - let V = Vec::new() else { return; }; +LL + if V == Vec::new() { return; }; + | + +error: constant of non-structural type `not_partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:40:18 + | +LL | struct S; + | -------- `not_partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: S = S; + | ---------- constant defined here +... +LL | Some(C) => {} + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - Some(C) => {} +LL + Some(binding) if binding == C => {} + | + +error: constant of non-structural type `not_partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:41:18 + | +LL | struct S; + | -------- `not_partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: S = S; + | ---------- constant defined here +... +LL | Some(C) if true => {} + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a check for equality to the condition of the match arm + | +LL - Some(C) if true => {} +LL + Some(binding) if true && binding == C => {} + | + +error: constant of non-structural type `not_partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:44:21 + | +LL | struct S; + | -------- `not_partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: S = S; + | ---------- constant defined here +... +LL | if let Some(C) = Some(S) {} + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: check for equality instead of pattern matching + | +LL - if let Some(C) = Some(S) {} +LL + if let Some(binding) = Some(S) && binding == C {} + | + +error: constant of non-structural type `not_partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:45:21 + | +LL | struct S; + | -------- `not_partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: S = S; + | ---------- constant defined here +... +LL | if let Some(C) = Some(S) && let Some(1) = Some(2) {} + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: check for equality instead of pattern matching + | +LL - if let Some(C) = Some(S) && let Some(1) = Some(2) {} +LL + if let Some(binding) = Some(S) && binding == C && let Some(1) = Some(2) {} + | + +error: constant of non-structural type `not_partial_eq::S` in a pattern + --> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:46:18 + | +LL | struct S; + | -------- `not_partial_eq::S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: S = S; + | ---------- constant defined here +... +LL | let Some(C) = Some(S) else { return; }; + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: check for equality instead of pattern matching + | +LL - let Some(C) = Some(S) else { return; }; +LL + if Some(C) == Some(S) { return; }; + | + +error: aborting due to 14 previous errors +
diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index 226a9de..b0150fc 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>: encountered 0x0a, but expected a boolean +error[E0080]: constructing invalid value of type &bool: at .<deref>, encountered 0x0a, but expected a boolean --> $DIR/const_refs_to_static_fail_invalid.rs:10:5 | LL | const C: &bool = unsafe { std::mem::transmute(&S) };
diff --git a/tests/ui/consts/const_transmute_type_id7.rs b/tests/ui/consts/const_transmute_type_id7.rs index 73b8187..6863b88 100644 --- a/tests/ui/consts/const_transmute_type_id7.rs +++ b/tests/ui/consts/const_transmute_type_id7.rs
@@ -2,6 +2,7 @@ //! (see <https://github.com/rust-lang/rust/issues/146748>) // Strip out raw byte dumps to make comparison platform-independent: +//@ normalize-stderr: "\[&\(\); \d\]" -> "ARRAY" //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
diff --git a/tests/ui/consts/const_transmute_type_id7.stderr b/tests/ui/consts/const_transmute_type_id7.stderr index 6649758..a1c37f2 100644 --- a/tests/ui/consts/const_transmute_type_id7.stderr +++ b/tests/ui/consts/const_transmute_type_id7.stderr
@@ -1,5 +1,5 @@ -error[E0080]: constructing invalid value at [0]: encountered a maybe-null reference - --> $DIR/const_transmute_type_id7.rs:13:1 +error[E0080]: constructing invalid value of type ARRAY: at [0], encountered a maybe-null reference + --> $DIR/const_transmute_type_id7.rs:14:1 | LL | const A: [&(); 16 / size_of::<*const ()>()] = unsafe { transmute(TypeId::of::<i32>()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
diff --git a/tests/ui/consts/dangling-alloc-id-ice.stderr b/tests/ui/consts/dangling-alloc-id-ice.stderr index 4b034c8..5b92bef 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.stderr +++ b/tests/ui/consts/dangling-alloc-id-ice.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a dangling reference (use-after-free) +error[E0080]: constructing invalid value of type &(): encountered a dangling reference (use-after-free) --> $DIR/dangling-alloc-id-ice.rs:12:1 | LL | const FOO: &() = {
diff --git a/tests/ui/consts/dangling-zst-ice-issue-126393.stderr b/tests/ui/consts/dangling-zst-ice-issue-126393.stderr index 248db69..0824afd 100644 --- a/tests/ui/consts/dangling-zst-ice-issue-126393.stderr +++ b/tests/ui/consts/dangling-zst-ice-issue-126393.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a dangling reference (use-after-free) +error[E0080]: constructing invalid value of type &Wrapper: encountered a dangling reference (use-after-free) --> $DIR/dangling-zst-ice-issue-126393.rs:7:1 | LL | pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
diff --git a/tests/ui/consts/escaping-bound-var.rs b/tests/ui/consts/escaping-bound-var.rs index a538d60..03162c7 100644 --- a/tests/ui/consts/escaping-bound-var.rs +++ b/tests/ui/consts/escaping-bound-var.rs
@@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete fn test<'a>( _: &'a (),
diff --git a/tests/ui/consts/escaping-bound-var.stderr b/tests/ui/consts/escaping-bound-var.stderr index bb0d285..046c58b 100644 --- a/tests/ui/consts/escaping-bound-var.stderr +++ b/tests/ui/consts/escaping-bound-var.stderr
@@ -1,14 +1,5 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/escaping-bound-var.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error: cannot capture late-bound lifetime in constant - --> $DIR/escaping-bound-var.rs:7:13 + --> $DIR/escaping-bound-var.rs:6:13 | LL | fn test<'a>( | -- lifetime defined here @@ -17,7 +8,7 @@ | ^^ error[E0308]: mismatched types - --> $DIR/escaping-bound-var.rs:6:6 + --> $DIR/escaping-bound-var.rs:5:6 | LL | fn test<'a>( | ---- implicitly returns `()` as its body has no tail or `return` expression @@ -33,6 +24,6 @@ 1 }]`, found `()` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
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 96c1666..a55a90d 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
@@ -1,10 +1,10 @@ -error[E0080]: constructing invalid value: encountered 0x03, but expected a boolean +error[E0080]: constructing invalid value of type bool: encountered 0x03, but expected a boolean --> $DIR/detect-extra-ub.rs:30:20 | LL | let _x: bool = transmute(3u8); | ^^^^^^^^^^^^^^ evaluation of `INVALID_BOOL` failed here -error[E0080]: constructing invalid value: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type usize: encountered a pointer, but expected an integer --> $DIR/detect-extra-ub.rs:35:21 | LL | let _x: usize = transmute(&3u8); @@ -13,7 +13,7 @@ = 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[E0080]: constructing invalid value at .<enum-tag>: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type PtrSizedEnum: at .<enum-tag>, encountered a pointer, but expected an integer --> $DIR/detect-extra-ub.rs:40:28 | LL | let _x: PtrSizedEnum = transmute(&3u8); @@ -22,7 +22,7 @@ = 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[E0080]: constructing invalid value at .0: encountered a pointer, but expected an integer +error[E0080]: constructing invalid value of type (usize, usize): at .0, encountered a pointer, but expected an integer --> $DIR/detect-extra-ub.rs:46:30 | LL | let _x: (usize, usize) = transmute(x); @@ -31,13 +31,13 @@ = 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[E0080]: constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) +error[E0080]: constructing invalid value of type &u32: encountered an unaligned reference (required 4 byte alignment but found 1) --> $DIR/detect-extra-ub.rs:51:20 | LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ evaluation of `UNALIGNED_PTR` failed here -error[E0080]: constructing invalid value: encountered a maybe-null function pointer +error[E0080]: constructing invalid value of type fn(): encountered a maybe-null function pointer --> $DIR/detect-extra-ub.rs:57:20 | LL | let _x: fn() = transmute({ @@ -49,13 +49,13 @@ LL | | }); | |______^ evaluation of `MAYBE_NULL_FN_PTR` failed here -error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant +error[E0080]: constructing invalid value of type UninhDiscriminant: at .<enum-tag>, encountered an uninhabited enum variant --> $DIR/detect-extra-ub.rs:68:13 | LL | let v = *addr_of!(data).cast::<UninhDiscriminant>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINHABITED_VARIANT` failed here -error[E0080]: constructing invalid value at [0]: encountered a partial pointer or a mix of pointers +error[E0080]: constructing invalid value of type [*const u8; 2]: at [0], encountered a partial pointer or a mix of pointers --> $DIR/detect-extra-ub.rs:87:16 | LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); @@ -64,7 +64,7 @@ = 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[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u8]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/detect-extra-ub.rs:101:16 | LL | let _val = &*slice;
diff --git a/tests/ui/consts/interior-mut-const-via-union.32bit.stderr b/tests/ui/consts/interior-mut-const-via-union.32bit.stderr index 17b3238..64a178b 100644 --- a/tests/ui/consts/interior-mut-const-via-union.32bit.stderr +++ b/tests/ui/consts/interior-mut-const-via-union.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.y.<enum-variant(B)>.0: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &S: at .<deref>.y.<enum-variant(B)>.0, encountered `UnsafeCell` in read-only memory --> $DIR/interior-mut-const-via-union.rs:34:1 | LL | fn main() {
diff --git a/tests/ui/consts/interior-mut-const-via-union.64bit.stderr b/tests/ui/consts/interior-mut-const-via-union.64bit.stderr index c4f78e7..f230156 100644 --- a/tests/ui/consts/interior-mut-const-via-union.64bit.stderr +++ b/tests/ui/consts/interior-mut-const-via-union.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.y.<enum-variant(B)>.0: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &S: at .<deref>.y.<enum-variant(B)>.0, encountered `UnsafeCell` in read-only memory --> $DIR/interior-mut-const-via-union.rs:34:1 | LL | fn main() {
diff --git a/tests/ui/consts/issue-104396.rs b/tests/ui/consts/issue-104396.rs index f44abc3..dc0789e 100644 --- a/tests/ui/consts/issue-104396.rs +++ b/tests/ui/consts/issue-104396.rs
@@ -2,7 +2,6 @@ //@ check-pass #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete #[inline(always)] fn from_fn_1<const N: usize, F: FnMut(usize) -> f32>(mut f: F) -> [f32; N] {
diff --git a/tests/ui/consts/issue-104396.stderr b/tests/ui/consts/issue-104396.stderr deleted file mode 100644 index 5856bee..0000000 --- a/tests/ui/consts/issue-104396.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-104396.rs:4:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/consts/issue-63952.32bit.stderr b/tests/ui/consts/issue-63952.32bit.stderr index cf97ed6..eb57a2f 100644 --- a/tests/ui/consts/issue-63952.32bit.stderr +++ b/tests/ui/consts/issue-63952.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u8]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/issue-63952.rs:17:1 | LL | const SLICE_WAY_TOO_LONG: &[u8] = unsafe {
diff --git a/tests/ui/consts/issue-63952.64bit.stderr b/tests/ui/consts/issue-63952.64bit.stderr index 4cea967..da1d05e 100644 --- a/tests/ui/consts/issue-63952.64bit.stderr +++ b/tests/ui/consts/issue-63952.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object +error[E0080]: constructing invalid value of type &[u8]: encountered invalid reference metadata: slice is bigger than largest supported object --> $DIR/issue-63952.rs:17:1 | LL | const SLICE_WAY_TOO_LONG: &[u8] = unsafe {
diff --git a/tests/ui/consts/issue-64506.stderr b/tests/ui/consts/issue-64506.stderr index 9fce07c..bd4f8f9 100644 --- a/tests/ui/consts/issue-64506.stderr +++ b/tests/ui/consts/issue-64506.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .inner: encountered a value of uninhabited type `AnonPipe` +error[E0080]: constructing invalid value of type ChildStdin: at .inner, encountered a value of uninhabited type `AnonPipe` --> $DIR/issue-64506.rs:16:22 | LL | let x = unsafe { Foo { b: () }.a };
diff --git a/tests/ui/consts/issue-79690.64bit.stderr b/tests/ui/consts/issue-79690.64bit.stderr index 2653ff2..c3f89d2 100644 --- a/tests/ui/consts/issue-79690.64bit.stderr +++ b/tests/ui/consts/issue-79690.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation) +error[E0080]: constructing invalid value of type Fat<'_>: at .1, encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/issue-79690.rs:30:1 | LL | const G: Fat = unsafe { Transmute { t: FOO }.u };
diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index 5008a2e..5861583 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr
@@ -9,9 +9,14 @@ | --> $SRC_DIR/alloc/src/borrow.rs:LL:COL | - = note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + = note: `Cow<'_, str>` is not usable in patterns | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - FOO => todo!(), +LL + binding if binding == FOO => todo!(), + | error: aborting due to 1 previous error
diff --git a/tests/ui/consts/issue-90762.rs b/tests/ui/consts/issue-90762.rs index db40e50..cc06036 100644 --- a/tests/ui/consts/issue-90762.rs +++ b/tests/ui/consts/issue-90762.rs
@@ -27,5 +27,5 @@ fn main() { for (i, b) in FOO.iter().enumerate() { assert!(b.load(Ordering::Relaxed), "{} not set", i); } - assert_eq!(BAR.fetch_add(1, Ordering::Relaxed), usize::max_value()); + assert_eq!(BAR.fetch_add(1, Ordering::Relaxed), usize::MAX); }
diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr index 95e96bb..d0742e1 100644 --- a/tests/ui/consts/match_ice.stderr +++ b/tests/ui/consts/match_ice.stderr
@@ -11,6 +11,11 @@ | ^ constant of non-structural type | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - C => {} +LL + binding if binding == C => {} + | error: aborting due to 1 previous error
diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr index 4187a9e..68c6dd1 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &&mut u32: at .<deref>, encountered mutable reference or box pointing to read-only memory --> $DIR/mutable_references.rs:13:1 | LL | static FOO: &&mut u32 = &&mut 42; @@ -9,7 +9,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/mutable_references.rs:15:1 | LL | static OH_YES: &mut i32 = &mut 42; @@ -32,7 +32,7 @@ LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/mutable_references.rs:25:1 | LL | const BLUNT: &mut i32 = &mut 42; @@ -43,7 +43,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type Meh: at .x.<deref>, encountered `UnsafeCell` in read-only memory --> $DIR/mutable_references.rs:40:1 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; @@ -54,7 +54,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type Meh: at .x.<deref>, encountered `UnsafeCell` in read-only memory --> $DIR/mutable_references.rs:45:1 | LL | const MUH: Meh = Meh { @@ -65,7 +65,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &dyn Sync: at .<deref>.<dyn-downcast(Synced)>.x, encountered `UnsafeCell` in read-only memory --> $DIR/mutable_references.rs:56:1 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; @@ -76,7 +76,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/mutable_references.rs:62:1 | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr index d7c668a..ab21696 100644 --- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &Atomic<i32>: at .<deref>.v, encountered `UnsafeCell` in read-only memory --> $DIR/static-no-inner-mut.rs:8:1 | LL | static REF: &AtomicI32 = &AtomicI32::new(42); @@ -9,7 +9,7 @@ ╾ALLOC0╼ │ ╾──╼ } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/static-no-inner-mut.rs:11:1 | LL | static REFMUT: &mut i32 = &mut 0; @@ -20,7 +20,7 @@ ╾ALLOC1╼ │ ╾──╼ } -error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &Atomic<i32>: at .<deref>.v, encountered `UnsafeCell` in read-only memory --> $DIR/static-no-inner-mut.rs:15:1 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; @@ -31,7 +31,7 @@ ╾ALLOC2╼ │ ╾──╼ } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/static-no-inner-mut.rs:17:1 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr index f3bb499..673c1b3 100644 --- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &Atomic<i32>: at .<deref>.v, encountered `UnsafeCell` in read-only memory --> $DIR/static-no-inner-mut.rs:8:1 | LL | static REF: &AtomicI32 = &AtomicI32::new(42); @@ -9,7 +9,7 @@ ╾ALLOC0╼ │ ╾──────╼ } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/static-no-inner-mut.rs:11:1 | LL | static REFMUT: &mut i32 = &mut 0; @@ -20,7 +20,7 @@ ╾ALLOC1╼ │ ╾──────╼ } -error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type &Atomic<i32>: at .<deref>.v, encountered `UnsafeCell` in read-only memory --> $DIR/static-no-inner-mut.rs:15:1 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; @@ -31,7 +31,7 @@ ╾ALLOC2╼ │ ╾──────╼ } -error[E0080]: constructing invalid value: encountered mutable reference or box pointing to read-only memory +error[E0080]: constructing invalid value of type &mut i32: encountered mutable reference or box pointing to read-only memory --> $DIR/static-no-inner-mut.rs:17:1 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.rs b/tests/ui/consts/refs_check_const_eq-issue-88384.rs index 46cb627..506bec3 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.rs +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.rs
@@ -1,6 +1,5 @@ #![feature(fn_traits)] #![feature(adt_const_params, unsized_const_params)] -//~^ WARNING the feature `unsized_const_params` is incomplete #[derive(PartialEq, Eq)] struct CompileTimeSettings {
diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr index 62c5c52..ac4cb05 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr
@@ -1,14 +1,5 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/refs_check_const_eq-issue-88384.rs:2:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/refs_check_const_eq-issue-88384.rs:10:21 + --> $DIR/refs_check_const_eq-issue-88384.rs:9:21 | LL | struct Foo<const T: CompileTimeSettings>; | ^^^^^^^^^^^^^^^^^^^ @@ -20,7 +11,7 @@ | error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/refs_check_const_eq-issue-88384.rs:13:15 + --> $DIR/refs_check_const_eq-issue-88384.rs:12:15 | LL | impl<const T: CompileTimeSettings> Foo<T> { | ^^^^^^^^^^^^^^^^^^^ @@ -31,6 +22,6 @@ LL | struct CompileTimeSettings { | -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs index 721920b..8fabaa4 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs
@@ -1,6 +1,5 @@ #![deny(elided_lifetimes_in_associated_constant)] #![feature(generic_const_items)] -//~^ WARN the feature `generic_const_items` is incomplete struct A; impl A {
diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr index 3680ef6..fe858d6 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr
@@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/generic-associated-const.rs:15:29 + --> $DIR/generic-associated-const.rs:14:29 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^ expected named lifetime parameter @@ -9,23 +9,14 @@ LL | const GAC_LIFETIME<'a>: &'a str = ""; | ++ -warning: the feature `generic_const_items` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/generic-associated-const.rs:2:12 - | -LL | #![feature(generic_const_items)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information - = note: `#[warn(incomplete_features)]` on by default - error: `&` without an explicit lifetime name cannot be used here - --> $DIR/generic-associated-const.rs:8:29 + --> $DIR/generic-associated-const.rs:7:29 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^ | note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/generic-associated-const.rs:8:24 + --> $DIR/generic-associated-const.rs:7:24 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^^ @@ -41,6 +32,6 @@ LL | const GAC_LIFETIME<'a>: &'static str = ""; | +++++++ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/consts/trait_specialization.rs b/tests/ui/consts/trait_specialization.rs index 1360fab..1ea56b5 100644 --- a/tests/ui/consts/trait_specialization.rs +++ b/tests/ui/consts/trait_specialization.rs
@@ -4,7 +4,7 @@ // Tests that specialization does not cause optimizations running on polymorphic MIR to resolve // to a `default` implementation. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Marker {}
diff --git a/tests/ui/consts/trait_specialization.stderr b/tests/ui/consts/trait_specialization.stderr deleted file mode 100644 index ce52cf1..0000000 --- a/tests/ui/consts/trait_specialization.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait_specialization.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/consts/validate_never_arrays.stderr b/tests/ui/consts/validate_never_arrays.stderr index 3c405e8..517b632 100644 --- a/tests/ui/consts/validate_never_arrays.stderr +++ b/tests/ui/consts/validate_never_arrays.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] +error[E0080]: constructing invalid value of type &[!; 1]: encountered a reference pointing to uninhabited type [!; 1] --> $DIR/validate_never_arrays.rs:6:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -9,7 +9,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/validate_never_arrays.rs:9:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; @@ -20,7 +20,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of the never type `!` +error[E0080]: constructing invalid value of type &[!]: at .<deref>[0], encountered a value of the never type `!` --> $DIR/validate_never_arrays.rs:10:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
diff --git a/tests/ui/contracts/incomplete-feature.rs b/tests/ui/contracts/incomplete-feature.rs index f1351e2..c10774b 100644 --- a/tests/ui/contracts/incomplete-feature.rs +++ b/tests/ui/contracts/incomplete-feature.rs
@@ -4,6 +4,7 @@ // This test specifically checks that the [incomplete_features] warning is // emitted when the `contracts` feature gate is enabled, so that it can be // marked as `expect`ed in other tests in order to reduce duplication. +#![warn(incomplete_features)] #![feature(contracts)] //~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core;
diff --git a/tests/ui/contracts/incomplete-feature.stderr b/tests/ui/contracts/incomplete-feature.stderr index 7683926..137b13f 100644 --- a/tests/ui/contracts/incomplete-feature.stderr +++ b/tests/ui/contracts/incomplete-feature.stderr
@@ -1,11 +1,15 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/incomplete-feature.rs:7:12 + --> $DIR/incomplete-feature.rs:8:12 | LL | #![feature(contracts)] | ^^^^^^^^^ | = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/incomplete-feature.rs:7:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted
diff --git a/tests/ui/coverage-attr/bad-syntax.rs b/tests/ui/coverage-attr/bad-syntax.rs index 062e82e..ef7b41d 100644 --- a/tests/ui/coverage-attr/bad-syntax.rs +++ b/tests/ui/coverage-attr/bad-syntax.rs
@@ -6,12 +6,12 @@ // Tests the error messages produced (or not produced) by various unusual // uses of the `#[coverage(..)]` attribute. -#[coverage(off)] //~ ERROR multiple `coverage` attributes #[coverage(off)] +#[coverage(off)] //~ ERROR multiple `coverage` attributes fn multiple_consistent() {} -#[coverage(off)] //~ ERROR multiple `coverage` attributes -#[coverage(on)] +#[coverage(off)] +#[coverage(on)] //~ ERROR multiple `coverage` attributes fn multiple_inconsistent() {} #[coverage] //~ ERROR malformed `coverage` attribute input
diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index ecf3ed8..4a35622 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr
@@ -1,26 +1,26 @@ error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:9:1 + --> $DIR/bad-syntax.rs:10:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/bad-syntax.rs:10:1 + --> $DIR/bad-syntax.rs:9:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:13:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here --> $DIR/bad-syntax.rs:14:1 | LL | #[coverage(on)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:13:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ error[E0539]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:17:1
diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.rs b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.rs index 0a7ec5a..5d801f2 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.rs +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.rs
@@ -7,7 +7,7 @@ impl<'a> InvariantRef<'a, ()> { pub const NEW: Self = InvariantRef::new(&()); - //~^ ERROR: no function or associated item named `new` found + //~^ ERROR: no associated function or constant named `new` found } trait Trait {
diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index ae5d0e8..6cf844f 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr
@@ -43,14 +43,14 @@ LL | impl<'a> Trait for Z { | ++++ -error[E0599]: no function or associated item named `new` found for struct `InvariantRef<'a, T>` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 | LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); - | -------------------------------------- function or associated item `new` not found for this struct + | -------------------------------------- associated function or constant `new` not found for this struct ... LL | pub const NEW: Self = InvariantRef::new(&()); - | ^^^ function or associated item not found in `InvariantRef<'_, _>` + | ^^^ associated function or constant not found in `InvariantRef<'_, _>` error[E0277]: the trait bound `u8: Trait` is not satisfied --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12
diff --git a/tests/ui/delegation/explicit-paths-pass.rs b/tests/ui/delegation/explicit-paths-pass.rs index dd0ee2c..7efbb37 100644 --- a/tests/ui/delegation/explicit-paths-pass.rs +++ b/tests/ui/delegation/explicit-paths-pass.rs
@@ -17,11 +17,8 @@ impl Trait for F {} mod to_reuse { pub fn foo(x: i32) -> i32 { x + 1 } - pub fn zero_args() -> i32 { 15 } } -reuse to_reuse::zero_args { self } - struct S(F); impl Trait for S { reuse Trait::bar { self.0 } @@ -49,5 +46,4 @@ fn main() { #[inline] reuse to_reuse::foo; assert_eq!(43, foo(42)); - assert_eq!(15, zero_args()); }
diff --git a/tests/ui/delegation/generics/const-type-ice-153433.rs b/tests/ui/delegation/generics/const-type-ice-153433.rs new file mode 100644 index 0000000..edd6d05 --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153433.rs
@@ -0,0 +1,8 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +fn main() { + fn foo<const N: dyn for<'a> Foo>() {} + //~^ ERROR: cannot find trait `Foo` in this scope + reuse foo as bar; +}
diff --git a/tests/ui/delegation/generics/const-type-ice-153433.stderr b/tests/ui/delegation/generics/const-type-ice-153433.stderr new file mode 100644 index 0000000..3b537e2 --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153433.stderr
@@ -0,0 +1,9 @@ +error[E0405]: cannot find trait `Foo` in this scope + --> $DIR/const-type-ice-153433.rs:5:33 + | +LL | fn foo<const N: dyn for<'a> Foo>() {} + | ^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/delegation/generics/const-type-ice-153499.rs b/tests/ui/delegation/generics/const-type-ice-153499.rs new file mode 100644 index 0000000..debda0d --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153499.rs
@@ -0,0 +1,13 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait<'a, T, const F: fn(&CStr) -> usize> { + //~^ ERROR: cannot find type `CStr` in this scope + //~| ERROR: using function pointers as const generic parameters is forbidden + fn foo<'x: 'x, A, B>(&self) {} +} + +reuse Trait::foo; +//~^ ERROR: using function pointers as const generic parameters is forbidden + +fn main() {}
diff --git a/tests/ui/delegation/generics/const-type-ice-153499.stderr b/tests/ui/delegation/generics/const-type-ice-153499.stderr new file mode 100644 index 0000000..02fd719 --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153499.stderr
@@ -0,0 +1,30 @@ +error[E0425]: cannot find type `CStr` in this scope + --> $DIR/const-type-ice-153499.rs:4:33 + | +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::ffi::CStr; + | + +error: using function pointers as const generic parameters is forbidden + --> $DIR/const-type-ice-153499.rs:4:29 + | +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/const-type-ice-153499.rs:10:14 + | +LL | reuse Trait::foo; + | ^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/delegation/generics/const-type-ice-154334.rs b/tests/ui/delegation/generics/const-type-ice-154334.rs new file mode 100644 index 0000000..91cf1d3a --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-154334.rs
@@ -0,0 +1,11 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib + +#![feature(min_generic_const_args)] +#![feature(fn_delegation)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] +trait Trait<'a, T, const N: str> { + fn foo<'v, A, B>(&self) {} +} +reuse Trait::foo;
diff --git a/tests/ui/delegation/generics/mapping/free-to-free-pass.rs b/tests/ui/delegation/generics/mapping/free-to-free-pass.rs index aafdd56..c67e4c0 100644 --- a/tests/ui/delegation/generics/mapping/free-to-free-pass.rs +++ b/tests/ui/delegation/generics/mapping/free-to-free-pass.rs
@@ -78,18 +78,16 @@ pub fn check<T: Clone, U: Clone>() { } } -// FIXME(fn_delegation): Uncomment this test when impl Traits in function params are supported +mod test_7 { + fn foo<T, U>(t: T, u: U, f: impl FnOnce(T, U) -> U) -> U { + f(t, u) + } -// mod test_7 { -// fn foo<T, U>(t: T, u: U, f: impl FnOnce(T, U) -> U) -> U { -// f(t, u) -// } - -// pub fn check() { -// reuse foo as bar; -// assert_eq!(bar::<i32, i32>(1, 2, |x, y| y), 2); -// } -// } + pub fn check() { + reuse foo as bar; + assert_eq!(bar::<i32, i32>(1, 2, |_, y| y), 2); + } +} // Testing reuse of local fn with delegation parent generic params specified, // late-bound lifetimes + types + consts, reusing with user args, @@ -126,7 +124,7 @@ pub fn main() { test_4::check::<i32, String>(); test_5::check::<i32, String>(); test_6::check::<i32, String>(); - // test_7::check(); + test_7::check(); test_8::check::<i32, String>(); test_9::check::<String, i32>(); }
diff --git a/tests/ui/delegation/generics/synth-params-ice-143498.rs b/tests/ui/delegation/generics/synth-params-ice-143498.rs new file mode 100644 index 0000000..652059b --- /dev/null +++ b/tests/ui/delegation/generics/synth-params-ice-143498.rs
@@ -0,0 +1,27 @@ +//@ compile-flags: -Z deduplicate-diagnostics=yes +//@ edition:2024 + +#![feature(fn_delegation)] +#![feature(iter_advance_by)] +#![feature(iter_array_chunks)] +#![feature(iterator_try_collect)] +#![feature(iterator_try_reduce)] +#![feature(iter_collect_into)] +#![feature(iter_intersperse)] +#![feature(iter_is_partitioned)] +#![feature(iter_map_windows)] +#![feature(iter_next_chunk)] +#![feature(iter_order_by)] +#![feature(iter_partition_in_place)] +#![feature(trusted_random_access)] +#![feature(try_find)] +#![allow(incomplete_features)] + +impl X { +//~^ ERROR: cannot find type `X` in this scope + reuse< std::fmt::Debug as Iterator >::*; + //~^ ERROR: expected method or associated constant, found associated type `Iterator::Item` + //~| ERROR: expected a type, found a trait +} + +pub fn main() {}
diff --git a/tests/ui/delegation/generics/synth-params-ice-143498.stderr b/tests/ui/delegation/generics/synth-params-ice-143498.stderr new file mode 100644 index 0000000..14b0399 --- /dev/null +++ b/tests/ui/delegation/generics/synth-params-ice-143498.stderr
@@ -0,0 +1,27 @@ +error[E0425]: cannot find type `X` in this scope + --> $DIR/synth-params-ice-143498.rs:20:6 + | +LL | impl X { + | ^ not found in this scope + +error[E0575]: expected method or associated constant, found associated type `Iterator::Item` + --> $DIR/synth-params-ice-143498.rs:22:10 + | +LL | reuse< std::fmt::Debug as Iterator >::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a method or associated constant + +error[E0782]: expected a type, found a trait + --> $DIR/synth-params-ice-143498.rs:22:12 + | +LL | reuse< std::fmt::Debug as Iterator >::*; + | ^^^^^^^^^^^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | reuse< dyn std::fmt::Debug as Iterator >::*; + | +++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0575, E0782. +For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/delegation/inner-attr.rs b/tests/ui/delegation/inner-attr.rs index 6c99680..5011187 100644 --- a/tests/ui/delegation/inner-attr.rs +++ b/tests/ui/delegation/inner-attr.rs
@@ -4,5 +4,6 @@ fn a() {} reuse a as b { #![rustc_dummy] self } //~ ERROR an inner attribute is not permitted in this context +//~^ ERROR: this function takes 0 arguments but 1 argument was supplied fn main() {}
diff --git a/tests/ui/delegation/inner-attr.stderr b/tests/ui/delegation/inner-attr.stderr index 257ab76..226a48e 100644 --- a/tests/ui/delegation/inner-attr.stderr +++ b/tests/ui/delegation/inner-attr.stderr
@@ -3,11 +3,29 @@ | LL | reuse a as b { #![rustc_dummy] self } | ^^^^^^^^^^^^^^^ -LL | +... LL | fn main() {} | ------------ the inner attribute doesn't annotate this function | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -error: aborting due to 1 previous error +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/inner-attr.rs:6:7 + | +LL | reuse a as b { #![rustc_dummy] self } + | ^ ---- unexpected argument + | +note: function defined here + --> $DIR/inner-attr.rs:4:4 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { #![rustc_dummy] self } +LL + reuse self } + | +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.rs b/tests/ui/delegation/zero-args-delegations-ice-154332.rs new file mode 100644 index 0000000..c684803 --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs
@@ -0,0 +1,30 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod test_ice { + fn a() {} + + reuse a as b { //~ ERROR: this function takes 0 arguments but 1 argument was supplied + let closure = || { + fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} + + reuse foo::<String, 1, String> as bar; + bar(&"".to_string(), &"".to_string()); + }; + + closure(); + } +} + +mod test_2 { + mod to_reuse { + pub fn zero_args() -> i32 { + 15 + } + } + + reuse to_reuse::zero_args { self } + //~^ ERROR: this function takes 0 arguments but 1 argument was supplied +} + +fn main() {}
diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr new file mode 100644 index 0000000..dcac56e --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr
@@ -0,0 +1,43 @@ +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:7:11 + | +LL | reuse a as b { + | ___________^______- +LL | | let closure = || { +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | closure(); +LL | | } + | |_____- unexpected argument of type `()` + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:5:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:26:21 + | +LL | reuse to_reuse::zero_args { self } + | ^^^^^^^^^ ---- unexpected argument + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:21:16 + | +LL | pub fn zero_args() -> i32 { + | ^^^^^^^^^ +help: remove the extra argument + | +LL - reuse to_reuse::zero_args { self } +LL + reuse to_reuse::zero_argself } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.rs b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.rs index e04975f..8b87499 100644 --- a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.rs +++ b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.rs
@@ -26,7 +26,7 @@ mod x { mod y { use crate::Foo; - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn use_char_assoc() { // Careful here: in the representation, <char as Foo>::T gets // normalized away, so at a certain point we had no edge to
diff --git a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr index b037205..1a56d31 100644 --- a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr +++ b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr
@@ -1,8 +1,8 @@ error: OK --> $DIR/dep-graph-assoc-type-codegen.rs:29:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 1 previous error
diff --git a/tests/ui/dep-graph/dep-graph-caller-callee.rs b/tests/ui/dep-graph/dep-graph-caller-callee.rs index df959a9..43d10cd 100644 --- a/tests/ui/dep-graph/dep-graph-caller-callee.rs +++ b/tests/ui/dep-graph/dep-graph-caller-callee.rs
@@ -18,7 +18,7 @@ mod y { use crate::x; // These dependencies SHOULD exist: - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn y() { x::x(); } @@ -29,7 +29,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(typeck)] //~ ERROR no path + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path pub fn z() { y::y(); }
diff --git a/tests/ui/dep-graph/dep-graph-caller-callee.stderr b/tests/ui/dep-graph/dep-graph-caller-callee.stderr index 33fe91b..379e23f 100644 --- a/tests/ui/dep-graph/dep-graph-caller-callee.stderr +++ b/tests/ui/dep-graph/dep-graph-caller-callee.stderr
@@ -1,14 +1,14 @@ error: OK --> $DIR/dep-graph-caller-callee.rs:21:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ -error: no path from `x` to `typeck` +error: no path from `x` to `typeck_root` --> $DIR/dep-graph-caller-callee.rs:32:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 2 previous errors
diff --git a/tests/ui/dep-graph/dep-graph-struct-signature.rs b/tests/ui/dep-graph/dep-graph-struct-signature.rs index 080a1b5..abef7d2 100644 --- a/tests/ui/dep-graph/dep-graph-struct-signature.rs +++ b/tests/ui/dep-graph/dep-graph-struct-signature.rs
@@ -34,11 +34,11 @@ trait Bar { } #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn some_fn(x: WillChange) { } #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn new_foo(x: u32, y: u32) -> WillChange { WillChange { x: x, y: y } } @@ -46,14 +46,14 @@ fn new_foo(x: u32, y: u32) -> WillChange { #[rustc_then_this_would_need(type_of)] //~ ERROR OK impl WillChange { #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn new(x: u32, y: u32) -> WillChange { loop { } } } #[rustc_then_this_would_need(type_of)] //~ ERROR OK impl WillChange { #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn method(&self, x: u32) { } } @@ -82,6 +82,6 @@ trait A { fn b(x: WontChange) { } #[rustc_then_this_would_need(fn_sig)] //~ ERROR no path from `WillChange` - #[rustc_then_this_would_need(typeck)] //~ ERROR no path from `WillChange` + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path from `WillChange` fn c(x: u32) { } }
diff --git a/tests/ui/dep-graph/dep-graph-struct-signature.stderr b/tests/ui/dep-graph/dep-graph-struct-signature.stderr index 98efedc..24d35b8 100644 --- a/tests/ui/dep-graph/dep-graph-struct-signature.stderr +++ b/tests/ui/dep-graph/dep-graph-struct-signature.stderr
@@ -25,8 +25,8 @@ error: OK --> $DIR/dep-graph-struct-signature.rs:37:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-struct-signature.rs:40:34 @@ -37,8 +37,8 @@ error: OK --> $DIR/dep-graph-struct-signature.rs:41:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-struct-signature.rs:46:34 @@ -88,11 +88,11 @@ LL | #[rustc_then_this_would_need(fn_sig)] | ^^^^^^ -error: no path from `WillChange` to `typeck` +error: no path from `WillChange` to `typeck_root` --> $DIR/dep-graph-struct-signature.rs:85:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-struct-signature.rs:32:38 @@ -115,8 +115,8 @@ error: OK --> $DIR/dep-graph-struct-signature.rs:49:38 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-struct-signature.rs:55:38 @@ -127,8 +127,8 @@ error: OK --> $DIR/dep-graph-struct-signature.rs:56:38 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 22 previous errors
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs index 397a8c6..ccdd2ff 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs
@@ -30,7 +30,7 @@ impl Bar for char { } mod y { use crate::{Foo, Bar}; - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn with_char() { char::method('a'); } @@ -39,7 +39,7 @@ pub fn with_char() { mod z { use crate::y; - #[rustc_then_this_would_need(typeck)] //~ ERROR no path + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path pub fn z() { y::with_char(); }
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr index 293f918..9802d5a 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr
@@ -1,14 +1,14 @@ error: OK --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ -error: no path from `x::<impl Foo for u32>` to `typeck` +error: no path from `x::<impl Foo for u32>` to `typeck_root` --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 2 previous errors
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.rs b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.rs index 859505a..c86923c 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.rs +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.rs
@@ -29,7 +29,7 @@ impl Bar for char { } mod y { use crate::{Foo, Bar}; - #[rustc_then_this_would_need(typeck)] //~ ERROR no path + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path pub fn call_bar() { char::bar('a'); } @@ -38,7 +38,7 @@ pub fn call_bar() { mod z { use crate::y; - #[rustc_then_this_would_need(typeck)] //~ ERROR no path + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path pub fn z() { y::call_bar(); }
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr index 46cb0e9..7d7ff05 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr
@@ -1,14 +1,14 @@ -error: no path from `x::<impl Foo for char>` to `typeck` +error: no path from `x::<impl Foo for char>` to `typeck_root` --> $DIR/dep-graph-trait-impl-two-traits.rs:32:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ -error: no path from `x::<impl Foo for char>` to `typeck` +error: no path from `x::<impl Foo for char>` to `typeck_root` --> $DIR/dep-graph-trait-impl-two-traits.rs:41:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 2 previous errors
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl.rs b/tests/ui/dep-graph/dep-graph-trait-impl.rs index 80925dd..952ccf61 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl.rs +++ b/tests/ui/dep-graph/dep-graph-trait-impl.rs
@@ -25,22 +25,22 @@ impl Foo for u32 { } mod y { use crate::Foo; - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn with_char() { char::method('a'); } - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn take_foo_with_char() { take_foo::<char>('a'); } - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn with_u32() { u32::method(22); } - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK pub fn take_foo_with_u32() { take_foo::<u32>(22); } @@ -53,7 +53,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(typeck)] //~ ERROR no path + #[rustc_then_this_would_need(typeck_root)] //~ ERROR no path pub fn z() { y::with_char(); y::with_u32();
diff --git a/tests/ui/dep-graph/dep-graph-trait-impl.stderr b/tests/ui/dep-graph/dep-graph-trait-impl.stderr index a5fce64..8a205fe 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl.stderr
@@ -1,32 +1,32 @@ error: OK --> $DIR/dep-graph-trait-impl.rs:28:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-trait-impl.rs:33:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-trait-impl.rs:38:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-trait-impl.rs:43:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ -error: no path from `x::<impl Foo for char>` to `typeck` +error: no path from `x::<impl Foo for char>` to `typeck_root` --> $DIR/dep-graph-trait-impl.rs:56:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 5 previous errors
diff --git a/tests/ui/dep-graph/dep-graph-type-alias.rs b/tests/ui/dep-graph/dep-graph-type-alias.rs index 1796ebd..8d0407a 100644 --- a/tests/ui/dep-graph/dep-graph-type-alias.rs +++ b/tests/ui/dep-graph/dep-graph-type-alias.rs
@@ -42,7 +42,7 @@ trait Trait { #[rustc_then_this_would_need(type_of)] //~ ERROR no path impl SomeType { #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK - #[rustc_then_this_would_need(typeck)] //~ ERROR OK + #[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn method(&self, _: TypeAlias) {} } @@ -50,7 +50,7 @@ fn method(&self, _: TypeAlias) {} type TypeAlias2 = TypeAlias; #[rustc_then_this_would_need(fn_sig)] //~ ERROR OK -#[rustc_then_this_would_need(typeck)] //~ ERROR OK +#[rustc_then_this_would_need(typeck_root)] //~ ERROR OK fn function(_: TypeAlias) { }
diff --git a/tests/ui/dep-graph/dep-graph-type-alias.stderr b/tests/ui/dep-graph/dep-graph-type-alias.stderr index 9f24c11..63312a5 100644 --- a/tests/ui/dep-graph/dep-graph-type-alias.stderr +++ b/tests/ui/dep-graph/dep-graph-type-alias.stderr
@@ -49,8 +49,8 @@ error: OK --> $DIR/dep-graph-type-alias.rs:53:30 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: OK --> $DIR/dep-graph-type-alias.rs:36:34 @@ -67,8 +67,8 @@ error: OK --> $DIR/dep-graph-type-alias.rs:45:34 | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^ +LL | #[rustc_then_this_would_need(typeck_root)] + | ^^^^^^^^^^^ error: aborting due to 12 previous errors
diff --git a/tests/ui/derives/issue-36617.stderr b/tests/ui/derives/issue-36617.stderr index 3de1d87..f76c5df 100644 --- a/tests/ui/derives/issue-36617.stderr +++ b/tests/ui/derives/issue-36617.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^ ... LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute | @@ -20,7 +20,7 @@ | ^^^^^^^^ ... LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute | @@ -35,7 +35,7 @@ | ^^^^^^^^^^^^^ ... LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute | @@ -50,7 +50,7 @@ | ^^^^^^^^^ ... LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute | @@ -65,7 +65,7 @@ | ^^^^^^^^^^^^^^^^^^^^ ... LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/destructuring-assignment/warn-unused-duplication.stderr b/tests/ui/destructuring-assignment/warn-unused-duplication.stderr index e166251..5982413 100644 --- a/tests/ui/destructuring-assignment/warn-unused-duplication.stderr +++ b/tests/ui/destructuring-assignment/warn-unused-duplication.stderr
@@ -2,9 +2,10 @@ --> $DIR/warn-unused-duplication.rs:9:6 | LL | (a, a) = (0, 1); - | ^ + | ^ - `a` is overwritten here before the previous value is read + | | + | this value is reassigned later and never used | - = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/warn-unused-duplication.rs:3:9 |
diff --git a/tests/ui/did_you_mean/bad-assoc-pat.rs b/tests/ui/did_you_mean/bad-assoc-pat.rs index 3f912f7..911eeb0 100644 --- a/tests/ui/did_you_mean/bad-assoc-pat.rs +++ b/tests/ui/did_you_mean/bad-assoc-pat.rs
@@ -2,25 +2,25 @@ match 0u8 { [u8]::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found (u8, u8)::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found _::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found } match &0u8 { &(u8,)::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found } } macro_rules! pat { ($ty: ty) => ($ty::AssocItem) //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found } macro_rules! ty { () => (u8) @@ -31,6 +31,6 @@ fn check_macros() { pat!(u8) => {} ty!()::AssocItem => {} //~^ ERROR missing angle brackets in associated item path - //~| ERROR no associated item named `AssocItem` found + //~| ERROR no associated function or constant named `AssocItem` found } }
diff --git a/tests/ui/did_you_mean/bad-assoc-pat.stderr b/tests/ui/did_you_mean/bad-assoc-pat.stderr index 8bdeb8f..aff3d97 100644 --- a/tests/ui/did_you_mean/bad-assoc-pat.stderr +++ b/tests/ui/did_you_mean/bad-assoc-pat.stderr
@@ -68,46 +68,46 @@ LL | ($ty: ty) => (<$ty>::AssocItem) | + + -error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for slice `[u8]` in the current scope --> $DIR/bad-assoc-pat.rs:3:15 | LL | [u8]::AssocItem => {} - | ^^^^^^^^^ associated item not found in `[u8]` + | ^^^^^^^^^ associated function or constant not found in `[u8]` -error[E0599]: no associated item named `AssocItem` found for tuple `(u8, u8)` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for tuple `(u8, u8)` in the current scope --> $DIR/bad-assoc-pat.rs:6:19 | LL | (u8, u8)::AssocItem => {} - | ^^^^^^^^^ associated item not found in `(u8, u8)` + | ^^^^^^^^^ associated function or constant not found in `(u8, u8)` -error[E0599]: no associated item named `AssocItem` found for type `_` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for type `_` in the current scope --> $DIR/bad-assoc-pat.rs:9:12 | LL | _::AssocItem => {} - | ^^^^^^^^^ associated item not found in `_` + | ^^^^^^^^^ associated function or constant not found in `_` -error[E0599]: no associated item named `AssocItem` found for tuple `(u8,)` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for tuple `(u8,)` in the current scope --> $DIR/bad-assoc-pat.rs:14:17 | LL | &(u8,)::AssocItem => {} - | ^^^^^^^^^ associated item not found in `(u8,)` + | ^^^^^^^^^ associated function or constant not found in `(u8,)` -error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for type `u8` in the current scope --> $DIR/bad-assoc-pat.rs:21:24 | LL | ($ty: ty) => ($ty::AssocItem) - | ^^^^^^^^^ associated item not found in `u8` + | ^^^^^^^^^ associated function or constant not found in `u8` ... LL | pat!(u8) => {} | -------- in this macro invocation | = note: this error originates in the macro `pat` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0599]: no associated item named `AssocItem` found for type `u8` in the current scope +error[E0599]: no associated function or constant named `AssocItem` found for type `u8` in the current scope --> $DIR/bad-assoc-pat.rs:32:16 | LL | ty!()::AssocItem => {} - | ^^^^^^^^^ associated item not found in `u8` + | ^^^^^^^^^ associated function or constant not found in `u8` error: aborting due to 12 previous errors
diff --git a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr index 4a38546..0c07e5a 100644 --- a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr +++ b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
@@ -11,14 +11,14 @@ | LL | struct Bar; | ^^^^^^^^^^ -help: the following other types implement trait `Foo<A>` +help: `Bar` implements trait `Foo<A>` --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:15:1 | LL | impl Foo<i32> for Bar {} - | ^^^^^^^^^^^^^^^^^^^^^ `Bar` implements `Foo<i32>` + | ^^^^^^^^^^^^^^^^^^^^^ `Foo<i32>` LL | LL | impl Foo<u8> for Bar {} - | ^^^^^^^^^^^^^^^^^^^^ `Bar` implements `Foo<u8>` + | ^^^^^^^^^^^^^^^^^^^^ `Foo<u8>` error: aborting due to 1 previous error
diff --git a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index 8d1c05e..cb4ca90 100644 --- a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -11,13 +11,13 @@ | LL | struct Bar; | ^^^^^^^^^^ - = help: the following other types implement trait `Foo<A>`: - `Bar` implements `Foo<i16>` - `Bar` implements `Foo<i32>` - `Bar` implements `Foo<i8>` - `Bar` implements `Foo<u16>` - `Bar` implements `Foo<u32>` - `Bar` implements `Foo<u8>` + = help: `Bar` implements trait `Foo<A>`: + Foo<i16> + Foo<i32> + Foo<i8> + Foo<u16> + Foo<u32> + Foo<u8> error: aborting due to 1 previous error
diff --git a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index 8bacae9..4bb816b 100644 --- a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -6,12 +6,12 @@ | | | required by a bound introduced by this call | - = help: the following other types implement trait `Foo<B>`: - `i8` implements `Foo<bool>` - `i8` implements `Foo<u16>` - `i8` implements `Foo<u32>` - `i8` implements `Foo<u64>` - `i8` implements `Foo<u8>` + = help: `i8` implements trait `Foo<B>`: + Foo<bool> + Foo<u16> + Foo<u32> + Foo<u64> + Foo<u8> error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:25:21 @@ -21,17 +21,17 @@ | | | required by a bound introduced by this call | -help: the following other types implement trait `Foo<B>` +help: `u8` implements trait `Foo<B>` --> $DIR/issue-39802-show-5-trait-impls.rs:11:1 | LL | impl Foo<u16> for u8 {} - | ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u16>` + | ^^^^^^^^^^^^^^^^^^^^ `Foo<u16>` LL | impl Foo<u32> for u8 {} - | ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u32>` + | ^^^^^^^^^^^^^^^^^^^^ `Foo<u32>` LL | impl Foo<u64> for u8 {} - | ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u64>` + | ^^^^^^^^^^^^^^^^^^^^ `Foo<u64>` LL | impl Foo<bool> for u8 {} - | ^^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<bool>` + | ^^^^^^^^^^^^^^^^^^^^^ `Foo<bool>` error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:26:21 @@ -41,13 +41,13 @@ | | | required by a bound introduced by this call | - = help: the following other types implement trait `Foo<B>`: - `bool` implements `Foo<bool>` - `bool` implements `Foo<i8>` - `bool` implements `Foo<u16>` - `bool` implements `Foo<u32>` - `bool` implements `Foo<u64>` - `bool` implements `Foo<u8>` + = help: `bool` implements trait `Foo<B>`: + Foo<bool> + Foo<i8> + Foo<u16> + Foo<u32> + Foo<u64> + Foo<u8> error: aborting due to 3 previous errors
diff --git a/tests/ui/issues/issue-4735.rs b/tests/ui/drop/drop-noncopyable-raw-pointer.rs similarity index 83% rename from tests/ui/issues/issue-4735.rs rename to tests/ui/drop/drop-noncopyable-raw-pointer.rs index 1ca145b..8e980a2 100644 --- a/tests/ui/issues/issue-4735.rs +++ b/tests/ui/drop/drop-noncopyable-raw-pointer.rs
@@ -1,3 +1,4 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/4735> //@ run-pass use std::mem::transmute;
diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.rs b/tests/ui/dropck/dropck-after-failed-type-lowering.rs index 2441e26..ee55e0d 100644 --- a/tests/ui/dropck/dropck-after-failed-type-lowering.rs +++ b/tests/ui/dropck/dropck-after-failed-type-lowering.rs
@@ -3,11 +3,12 @@ trait B { type C<'a>; fn d<E>() -> F<E> { + //~^ ERROR: the trait bound `E: B` is not satisfied todo!() } } struct F<G> { - h: Option<<G as B>::C>, + h: Option<<G as B>::C>, //~ ERROR: the trait bound `G: B` is not satisfied //~^ ERROR missing generics for associated type `B::C` }
diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.stderr b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr index 56ea72de..0922d2e 100644 --- a/tests/ui/dropck/dropck-after-failed-type-lowering.stderr +++ b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr
@@ -1,5 +1,5 @@ error[E0107]: missing generics for associated type `B::C` - --> $DIR/dropck-after-failed-type-lowering.rs:10:25 + --> $DIR/dropck-after-failed-type-lowering.rs:11:25 | LL | h: Option<<G as B>::C>, | ^ expected 1 lifetime argument @@ -14,6 +14,24 @@ LL | h: Option<<G as B>::C<'a>>, | ++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `G: B` is not satisfied + --> $DIR/dropck-after-failed-type-lowering.rs:11:8 + | +LL | h: Option<<G as B>::C>, + | ^^^^^^^^^^^^^^^^^^^ the trait `B` is not implemented for `G` + | +help: consider restricting type parameter `G` with trait `B` + | +LL | struct F<G: B> { + | +++ -For more information about this error, try `rustc --explain E0107`. +error[E0277]: the trait bound `E: B` is not satisfied + --> $DIR/dropck-after-failed-type-lowering.rs:5:18 + | +LL | fn d<E>() -> F<E> { + | ^^^^ the trait `B` is not implemented for `E` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0277. +For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs b/tests/ui/enum/auxiliary/namespaced_enum_emulate_flat.rs similarity index 100% rename from tests/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs rename to tests/ui/enum/auxiliary/namespaced_enum_emulate_flat.rs
diff --git a/tests/ui/structs-enums/auxiliary/namespaced_enums.rs b/tests/ui/enum/auxiliary/namespaced_enums.rs similarity index 100% rename from tests/ui/structs-enums/auxiliary/namespaced_enums.rs rename to tests/ui/enum/auxiliary/namespaced_enums.rs
diff --git a/tests/ui/structs-enums/enum-clike-ffi-as-int.rs b/tests/ui/enum/enum-clike-ffi-as-int.rs similarity index 100% rename from tests/ui/structs-enums/enum-clike-ffi-as-int.rs rename to tests/ui/enum/enum-clike-ffi-as-int.rs
diff --git a/tests/ui/structs-enums/enum-discrim-manual-sizing.rs b/tests/ui/enum/enum-discrim-manual-sizing.rs similarity index 100% rename from tests/ui/structs-enums/enum-discrim-manual-sizing.rs rename to tests/ui/enum/enum-discrim-manual-sizing.rs
diff --git a/tests/ui/structs-enums/enum-discrim-range-overflow.rs b/tests/ui/enum/enum-discrim-range-overflow.rs similarity index 95% rename from tests/ui/structs-enums/enum-discrim-range-overflow.rs rename to tests/ui/enum/enum-discrim-range-overflow.rs index 91be801..641e556 100644 --- a/tests/ui/structs-enums/enum-discrim-range-overflow.rs +++ b/tests/ui/enum/enum-discrim-range-overflow.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(overflowing_literals)]
diff --git a/tests/ui/structs-enums/enum-discrim-width-stuff.rs b/tests/ui/enum/enum-discrim-width-stuff.rs similarity index 100% rename from tests/ui/structs-enums/enum-discrim-width-stuff.rs rename to tests/ui/enum/enum-discrim-width-stuff.rs
diff --git a/tests/ui/enum/enum-discriminant-missing-variant.rs b/tests/ui/enum/enum-discriminant-missing-variant.rs index 1bdbfb1..45c2b37 100644 --- a/tests/ui/enum/enum-discriminant-missing-variant.rs +++ b/tests/ui/enum/enum-discriminant-missing-variant.rs
@@ -1,6 +1,6 @@ //! regression test for issue <https://github.com/rust-lang/rust/issues/23217> pub enum SomeEnum { - B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found + B = SomeEnum::A, //~ ERROR no variant, associated function, or constant named `A` found } fn main() {}
diff --git a/tests/ui/enum/enum-discriminant-missing-variant.stderr b/tests/ui/enum/enum-discriminant-missing-variant.stderr index ef98a93..653a87a 100644 --- a/tests/ui/enum/enum-discriminant-missing-variant.stderr +++ b/tests/ui/enum/enum-discriminant-missing-variant.stderr
@@ -1,10 +1,10 @@ -error[E0599]: no variant or associated item named `A` found for enum `SomeEnum` in the current scope +error[E0599]: no variant, associated function, or constant named `A` found for enum `SomeEnum` in the current scope --> $DIR/enum-discriminant-missing-variant.rs:3:19 | LL | pub enum SomeEnum { - | ----------------- variant or associated item `A` not found for this enum + | ----------------- variant, associated function, or constant `A` not found for this enum LL | B = SomeEnum::A, - | ^ variant or associated item not found in `SomeEnum` + | ^ variant, associated function, or constant not found in `SomeEnum` | help: there is a variant with a similar name |
diff --git a/tests/ui/structs-enums/enum-disr-val-pretty.rs b/tests/ui/enum/enum-disr-val-pretty.rs similarity index 100% rename from tests/ui/structs-enums/enum-disr-val-pretty.rs rename to tests/ui/enum/enum-disr-val-pretty.rs
diff --git a/tests/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs b/tests/ui/enum/enum-nullable-simplifycfg-misopt.rs similarity index 100% rename from tests/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs rename to tests/ui/enum/enum-nullable-simplifycfg-misopt.rs
diff --git a/tests/ui/structs-enums/enum-univariant-repr.rs b/tests/ui/enum/enum-univariant-repr.rs similarity index 100% rename from tests/ui/structs-enums/enum-univariant-repr.rs rename to tests/ui/enum/enum-univariant-repr.rs
diff --git a/tests/ui/structs-enums/enum-variants.rs b/tests/ui/enum/enum-variants.rs similarity index 100% rename from tests/ui/structs-enums/enum-variants.rs rename to tests/ui/enum/enum-variants.rs
diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs b/tests/ui/enum/namespaced-enum-emulate-flat-xc.rs similarity index 100% rename from tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs rename to tests/ui/enum/namespaced-enum-emulate-flat-xc.rs
diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs b/tests/ui/enum/namespaced-enum-emulate-flat.rs similarity index 96% rename from tests/ui/structs-enums/namespaced-enum-emulate-flat.rs rename to tests/ui/enum/namespaced-enum-emulate-flat.rs index 774cfa1..2bc23d9 100644 --- a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs +++ b/tests/ui/enum/namespaced-enum-emulate-flat.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] pub use Foo::*;
diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs b/tests/ui/enum/namespaced-enum-glob-import-xcrate.rs similarity index 100% rename from tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs rename to tests/ui/enum/namespaced-enum-glob-import-xcrate.rs
diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import.rs b/tests/ui/enum/namespaced-enum-glob-import.rs similarity index 96% rename from tests/ui/structs-enums/namespaced-enum-glob-import.rs rename to tests/ui/enum/namespaced-enum-glob-import.rs index 82742a9..52bfa9d 100644 --- a/tests/ui/structs-enums/namespaced-enum-glob-import.rs +++ b/tests/ui/enum/namespaced-enum-glob-import.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] mod m2 {
diff --git a/tests/ui/structs-enums/namespaced-enums-xcrate.rs b/tests/ui/enum/namespaced-enums-xcrate.rs similarity index 100% rename from tests/ui/structs-enums/namespaced-enums-xcrate.rs rename to tests/ui/enum/namespaced-enums-xcrate.rs
diff --git a/tests/ui/structs-enums/namespaced-enums.rs b/tests/ui/enum/namespaced-enums.rs similarity index 92% rename from tests/ui/structs-enums/namespaced-enums.rs rename to tests/ui/enum/namespaced-enums.rs index 3e2e0b5..f3f1a3b 100644 --- a/tests/ui/structs-enums/namespaced-enums.rs +++ b/tests/ui/enum/namespaced-enums.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] enum Foo {
diff --git a/tests/ui/structs-enums/struct-like-variant-construct.rs b/tests/ui/enum/struct-like-variant-construct.rs similarity index 100% rename from tests/ui/structs-enums/struct-like-variant-construct.rs rename to tests/ui/enum/struct-like-variant-construct.rs
diff --git a/tests/ui/structs-enums/struct-like-variant-match.rs b/tests/ui/enum/struct-like-variant-match.rs similarity index 100% rename from tests/ui/structs-enums/struct-like-variant-match.rs rename to tests/ui/enum/struct-like-variant-match.rs
diff --git a/tests/ui/error-codes/E0520.rs b/tests/ui/error-codes/E0520.rs index ead78b7..b746ca6 100644 --- a/tests/ui/error-codes/E0520.rs +++ b/tests/ui/error-codes/E0520.rs
@@ -1,5 +1,4 @@ #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait SpaceLlama { fn fly(&self);
diff --git a/tests/ui/error-codes/E0520.stderr b/tests/ui/error-codes/E0520.stderr index 8331920..c47b3e7 100644 --- a/tests/ui/error-codes/E0520.stderr +++ b/tests/ui/error-codes/E0520.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/E0520.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `fly` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/E0520.rs:17:5 + --> $DIR/E0520.rs:16:5 | LL | impl<T: Clone> SpaceLlama for T { | ------------------------------- parent `impl` is here @@ -19,6 +9,6 @@ | = note: to specialize, `fly` in the parent `impl` must be marked `default` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/error-codes/E0599.stderr b/tests/ui/error-codes/E0599.stderr index 5c1c71d..724bce4 100644 --- a/tests/ui/error-codes/E0599.stderr +++ b/tests/ui/error-codes/E0599.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no associated item named `NotEvenReal` found for struct `Foo` in the current scope +error[E0599]: no associated function or constant named `NotEvenReal` found for struct `Foo` in the current scope --> $DIR/E0599.rs:4:20 | LL | struct Foo; - | ---------- associated item `NotEvenReal` not found for this struct + | ---------- associated function or constant `NotEvenReal` not found for this struct ... LL | || if let Foo::NotEvenReal() = Foo {}; - | ^^^^^^^^^^^ associated item not found in `Foo` + | ^^^^^^^^^^^ associated function or constant not found in `Foo` error: aborting due to 1 previous error
diff --git a/tests/ui/error-codes/E0771.rs b/tests/ui/error-codes/E0771.rs index a932c5e..6d86d4a 100644 --- a/tests/ui/error-codes/E0771.rs +++ b/tests/ui/error-codes/E0771.rs
@@ -1,5 +1,4 @@ #![feature(adt_const_params, unsized_const_params)] -//~^ WARN the feature `unsized_const_params` is incomplete fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0770
diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr index dfeaa34..9378207 100644 --- a/tests/ui/error-codes/E0771.stderr +++ b/tests/ui/error-codes/E0771.stderr
@@ -1,18 +1,9 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/E0771.rs:4:41 + --> $DIR/E0771.rs:3:41 | LL | fn function_with_str<'a, const STRING: &'a str>() {} | ^^ the type must not depend on the parameter `'a` -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/E0771.rs:1:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg index 39631e0..1e86213 100644 --- a/tests/ui/error-emitter/multiline-removal-suggestion.svg +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg
@@ -1,4 +1,4 @@ -<svg width="2322px" height="4322px" xmlns="http://www.w3.org/2000/svg"> +<svg width="2288px" height="3890px" xmlns="http://www.w3.org/2000/svg"> <style> .fg { fill: #AAAAAA } .bg { fill: #000000 } @@ -129,375 +129,327 @@ </tspan> <tspan x="10px" y="982px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> </tspan> - <tspan x="10px" y="1000px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::IntoIter = _`</tspan> + <tspan x="10px" y="1000px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="1018px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> + <tspan x="10px" y="1018px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="1036px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::Item = _`</tspan> + <tspan x="10px" y="1036px"> </tspan> - <tspan x="10px" y="1054px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> + <tspan x="10px" y="1054px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="1072px"><tspan> `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>>: IntoIterator`</tspan> + <tspan x="10px" y="1072px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:32:6</tspan> </tspan> - <tspan x="10px" y="1090px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> + <tspan x="10px" y="1090px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1108px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> + <tspan x="10px" y="1108px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> </tspan> - <tspan x="10px" y="1126px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator`</tspan> + <tspan x="10px" y="1126px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="1144px"> + <tspan x="10px" y="1144px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1162px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="1162px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="1180px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:32:6</tspan> + <tspan x="10px" y="1180px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="1198px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1198px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> </tspan> - <tspan x="10px" y="1216px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> + <tspan x="10px" y="1216px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="1234px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="1234px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> </tspan> <tspan x="10px" y="1252px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1270px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="1270px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="1288px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="1288px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- .map(|t| (is_true, t))</tspan> </tspan> - <tspan x="10px" y="1306px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> + <tspan x="10px" y="1306px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="1324px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> + <tspan x="10px" y="1324px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1342px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> + <tspan x="10px" y="1342px"> </tspan> - <tspan x="10px" y="1360px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1360px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="1378px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="1378px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:28:2</tspan> </tspan> - <tspan x="10px" y="1396px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- .map(|t| (is_true, t))</tspan> + <tspan x="10px" y="1396px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1414px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="1414px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="1432px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1432px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="1450px"> + <tspan x="10px" y="1450px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="1468px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="1468px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|t| (is_true, t))</tspan> </tspan> - <tspan x="10px" y="1486px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:28:2</tspan> + <tspan x="10px" y="1486px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .flatten()</tspan> </tspan> - <tspan x="10px" y="1504px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1504px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> </tspan> - <tspan x="10px" y="1522px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="1522px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="1540px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> + <tspan x="10px" y="1540px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1558px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="1558px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="1576px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|t| (is_true, t))</tspan> + <tspan x="10px" y="1576px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="1594px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .flatten()</tspan> + <tspan x="10px" y="1594px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> </tspan> - <tspan x="10px" y="1612px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> + <tspan x="10px" y="1612px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="1630px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="1630px"> </tspan> - <tspan x="10px" y="1648px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1648px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>`, but its trait bounds were not satisfied</tspan> </tspan> - <tspan x="10px" y="1666px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="1666px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:35:4</tspan> </tspan> - <tspan x="10px" y="1684px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="1684px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1702px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> + <tspan x="10px" y="1702px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="1720px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> + <tspan x="10px" y="1720px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="1738px"> + <tspan x="10px" y="1738px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="1756px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>`, but its trait bounds were not satisfied</tspan> + <tspan x="10px" y="1756px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t))</tspan> </tspan> - <tspan x="10px" y="1774px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:35:4</tspan> + <tspan x="10px" y="1774px"><tspan class="fg-bright-blue bold">...</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1792px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1792px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> </tspan> - <tspan x="10px" y="1810px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="1810px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> </tspan> - <tspan x="10px" y="1828px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> + <tspan x="10px" y="1828px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> </tspan> - <tspan x="10px" y="1846px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="1846px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> </tspan> - <tspan x="10px" y="1864px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t))</tspan> + <tspan x="10px" y="1864px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1882px"><tspan class="fg-bright-blue bold">...</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1882px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="1900px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> + <tspan x="10px" y="1900px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> </tspan> - <tspan x="10px" y="1918px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> + <tspan x="10px" y="1918px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="1936px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> + <tspan x="10px" y="1936px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="1954px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> + <tspan x="10px" y="1954px"> </tspan> - <tspan x="10px" y="1972px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1972px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="1990px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="1990px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:43:7</tspan> </tspan> - <tspan x="10px" y="2008px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> + <tspan x="10px" y="2008px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2026px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::IntoIter = _`</tspan> + <tspan x="10px" y="2026px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> }).flatten()</tspan> </tspan> - <tspan x="10px" y="2044px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> + <tspan x="10px" y="2044px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="2062px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::Item = _`</tspan> + <tspan x="10px" y="2062px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2080px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> + <tspan x="10px" y="2080px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="2098px"><tspan> `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>>: IntoIterator`</tspan> + <tspan x="10px" y="2098px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="2116px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> + <tspan x="10px" y="2116px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> </tspan> - <tspan x="10px" y="2134px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> + <tspan x="10px" y="2134px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="2152px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator`</tspan> + <tspan x="10px" y="2152px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> </tspan> - <tspan x="10px" y="2170px"> + <tspan x="10px" y="2170px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2188px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="2188px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan><tspan class="fg-bright-red">.map(|t| {</tspan> </tspan> - <tspan x="10px" y="2206px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:43:7</tspan> + <tspan x="10px" y="2206px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- (is_true, t)</tspan> </tspan> - <tspan x="10px" y="2224px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2224px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- })</tspan><tspan>.flatten()</tspan> </tspan> - <tspan x="10px" y="2242px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> }).flatten()</tspan> + <tspan x="10px" y="2242px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter().flatten()</tspan> </tspan> - <tspan x="10px" y="2260px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="2260px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2278px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2278px"> </tspan> - <tspan x="10px" y="2296px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="2296px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="2314px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="2314px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:39:2</tspan> </tspan> - <tspan x="10px" y="2332px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> + <tspan x="10px" y="2332px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2350px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> + <tspan x="10px" y="2350px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="2368px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> + <tspan x="10px" y="2368px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="2386px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2386px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter().map(|t| {</tspan> </tspan> - <tspan x="10px" y="2404px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan><tspan class="fg-bright-red">.map(|t| {</tspan> + <tspan x="10px" y="2404px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> (is_true, t)</tspan> </tspan> - <tspan x="10px" y="2422px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- (is_true, t)</tspan> + <tspan x="10px" y="2422px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> }).flatten()</tspan> </tspan> - <tspan x="10px" y="2440px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- })</tspan><tspan>.flatten()</tspan> + <tspan x="10px" y="2440px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> </tspan> - <tspan x="10px" y="2458px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter().flatten()</tspan> + <tspan x="10px" y="2458px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> <tspan x="10px" y="2476px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2494px"> + <tspan x="10px" y="2494px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="2512px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="2512px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="2530px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:39:2</tspan> + <tspan x="10px" y="2530px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> </tspan> - <tspan x="10px" y="2548px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2548px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="2566px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="2566px"> </tspan> - <tspan x="10px" y="2584px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> + <tspan x="10px" y="2584px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>`, but its trait bounds were not satisfied</tspan> </tspan> - <tspan x="10px" y="2602px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter().map(|t| {</tspan> + <tspan x="10px" y="2602px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:46:4</tspan> </tspan> - <tspan x="10px" y="2620px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> (is_true, t)</tspan> + <tspan x="10px" y="2620px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2638px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> }).flatten()</tspan> + <tspan x="10px" y="2638px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="2656px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> + <tspan x="10px" y="2656px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="2674px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="2674px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter().map(|t| {</tspan> </tspan> - <tspan x="10px" y="2692px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2692px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> (is_true, t)</tspan> </tspan> - <tspan x="10px" y="2710px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="2710px"><tspan class="fg-bright-blue bold">...</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2728px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="2728px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> </tspan> - <tspan x="10px" y="2746px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> + <tspan x="10px" y="2746px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> </tspan> - <tspan x="10px" y="2764px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> + <tspan x="10px" y="2764px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> </tspan> - <tspan x="10px" y="2782px"> + <tspan x="10px" y="2782px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> </tspan> - <tspan x="10px" y="2800px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>`, but its trait bounds were not satisfied</tspan> + <tspan x="10px" y="2800px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2818px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:46:4</tspan> + <tspan x="10px" y="2818px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2836px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2836px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> </tspan> - <tspan x="10px" y="2854px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="2854px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="2872px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> + <tspan x="10px" y="2872px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="2890px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter().map(|t| {</tspan> + <tspan x="10px" y="2890px"> </tspan> - <tspan x="10px" y="2908px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> (is_true, t)</tspan> + <tspan x="10px" y="2908px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="2926px"><tspan class="fg-bright-blue bold">...</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="2926px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:53:28</tspan> </tspan> - <tspan x="10px" y="2944px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> + <tspan x="10px" y="2944px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="2962px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> + <tspan x="10px" y="2962px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> </tspan> - <tspan x="10px" y="2980px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> + <tspan x="10px" y="2980px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="2998px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> + <tspan x="10px" y="2998px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3016px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3016px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="3034px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3034px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="3052px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> + <tspan x="10px" y="3052px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> </tspan> - <tspan x="10px" y="3070px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::IntoIter = _`</tspan> + <tspan x="10px" y="3070px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="3088px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> + <tspan x="10px" y="3088px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> </tspan> - <tspan x="10px" y="3106px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::Item = _`</tspan> + <tspan x="10px" y="3106px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3124px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> + <tspan x="10px" y="3124px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="3142px"><tspan> `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>>: IntoIterator`</tspan> + <tspan x="10px" y="3142px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- .map(|t| (is_true, t))</tspan><tspan>.flatten()</tspan> </tspan> - <tspan x="10px" y="3160px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> + <tspan x="10px" y="3160px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter().flatten()</tspan> </tspan> - <tspan x="10px" y="3178px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> + <tspan x="10px" y="3178px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3196px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator`</tspan> + <tspan x="10px" y="3196px"> </tspan> - <tspan x="10px" y="3214px"> + <tspan x="10px" y="3214px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="3232px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="3232px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:50:2</tspan> </tspan> - <tspan x="10px" y="3250px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:53:28</tspan> + <tspan x="10px" y="3250px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3268px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3268px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="3286px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> + <tspan x="10px" y="3286px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="3304px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="3304px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="3322px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3322px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> </tspan> - <tspan x="10px" y="3340px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="3340px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> </tspan> - <tspan x="10px" y="3358px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="3358px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> </tspan> - <tspan x="10px" y="3376px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `flatten`</tspan> + <tspan x="10px" y="3376px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3394px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL</tspan> + <tspan x="10px" y="3394px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> </tspan> - <tspan x="10px" y="3412px"><tspan class="fg-bright-cyan bold">help</tspan><tspan>: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds</tspan> + <tspan x="10px" y="3412px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> </tspan> - <tspan x="10px" y="3430px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3430px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> </tspan> - <tspan x="10px" y="3448px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- </tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="3448px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> </tspan> - <tspan x="10px" y="3466px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-red">- .map(|t| (is_true, t))</tspan><tspan>.flatten()</tspan> + <tspan x="10px" y="3466px"> </tspan> - <tspan x="10px" y="3484px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-green">+ </tspan><tspan> ts.into_iter().flatten()</tspan> + <tspan x="10px" y="3484px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>`, but its trait bounds were not satisfied</tspan> </tspan> - <tspan x="10px" y="3502px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3502px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:56:4</tspan> </tspan> - <tspan x="10px" y="3520px"> + <tspan x="10px" y="3520px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3538px"><tspan class="fg-bright-red bold">error[E0277]</tspan><tspan class="bold">: `(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="3538px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> </tspan> - <tspan x="10px" y="3556px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:50:2</tspan> + <tspan x="10px" y="3556px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> </tspan> - <tspan x="10px" y="3574px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3574px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter()</tspan> </tspan> - <tspan x="10px" y="3592px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="3592px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> </tspan> - <tspan x="10px" y="3610px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> + <tspan x="10px" y="3610px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> })</tspan> </tspan> - <tspan x="10px" y="3628px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> ts.into_iter()</tspan> + <tspan x="10px" y="3628px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> </tspan> - <tspan x="10px" y="3646px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> + <tspan x="10px" y="3646px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> </tspan> - <tspan x="10px" y="3664px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|</tspan><tspan> })</tspan> + <tspan x="10px" y="3664px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> </tspan> - <tspan x="10px" y="3682px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">|__________^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">`(bool, HashSet<u8>)` is not an iterator</tspan> + <tspan x="10px" y="3682px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> </tspan> <tspan x="10px" y="3700px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3718px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`</tspan> + <tspan x="10px" y="3718px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> - <tspan x="10px" y="3736px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: required for `(bool, HashSet<u8>)` to implement `IntoIterator`</tspan> + <tspan x="10px" y="3736px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> </tspan> - <tspan x="10px" y="3754px"><tspan class="fg-bright-green bold">note</tspan><tspan>: required by a bound in `Flatten`</tspan> + <tspan x="10px" y="3754px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> </tspan> - <tspan x="10px" y="3772px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL</tspan> + <tspan x="10px" y="3772px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> </tspan> <tspan x="10px" y="3790px"> </tspan> - <tspan x="10px" y="3808px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: the method `collect` exists for struct `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>`, but its trait bounds were not satisfied</tspan> + <tspan x="10px" y="3808px"><tspan class="fg-bright-red bold">error</tspan><tspan class="bold">: aborting due to 12 previous errors</tspan> </tspan> - <tspan x="10px" y="3826px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/multiline-removal-suggestion.rs:56:4</tspan> + <tspan x="10px" y="3826px"> </tspan> - <tspan x="10px" y="3844px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> + <tspan x="10px" y="3844px"><tspan class="bold">Some errors have detailed explanations: E0277, E0599.</tspan> </tspan> - <tspan x="10px" y="3862px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">/</tspan><tspan> hm.into_iter()</tspan> + <tspan x="10px" y="3862px"><tspan class="bold">For more information about an error, try `rustc --explain E0277`.</tspan> </tspan> - <tspan x="10px" y="3880px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|(is_true, ts)| {</tspan> -</tspan> - <tspan x="10px" y="3898px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> ts.into_iter()</tspan> -</tspan> - <tspan x="10px" y="3916px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .map(|t| (is_true, t)).flatten()</tspan> -</tspan> - <tspan x="10px" y="3934px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> })</tspan> -</tspan> - <tspan x="10px" y="3952px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .flatten()</tspan> -</tspan> - <tspan x="10px" y="3970px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> .collect()</tspan> -</tspan> - <tspan x="10px" y="3988px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">-</tspan><tspan class="fg-bright-red bold">^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">method cannot be called due to unsatisfied trait bounds</tspan> -</tspan> - <tspan x="10px" y="4006px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|_________|</tspan> -</tspan> - <tspan x="10px" y="4024px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> -</tspan> - <tspan x="10px" y="4042px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> -</tspan> - <tspan x="10px" y="4060px"><tspan> </tspan><tspan class="fg-bright-blue bold">= </tspan><tspan class="bold">note</tspan><tspan>: the following trait bounds were not satisfied:</tspan> -</tspan> - <tspan x="10px" y="4078px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::IntoIter = _`</tspan> -</tspan> - <tspan x="10px" y="4096px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> -</tspan> - <tspan x="10px" y="4114px"><tspan> `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::Item = _`</tspan> -</tspan> - <tspan x="10px" y="4132px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> -</tspan> - <tspan x="10px" y="4150px"><tspan> `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>>: IntoIterator`</tspan> -</tspan> - <tspan x="10px" y="4168px"><tspan> which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> -</tspan> - <tspan x="10px" y="4186px"><tspan> `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> -</tspan> - <tspan x="10px" y="4204px"><tspan> which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator`</tspan> -</tspan> - <tspan x="10px" y="4222px"> -</tspan> - <tspan x="10px" y="4240px"><tspan class="fg-bright-red bold">error</tspan><tspan class="bold">: aborting due to 12 previous errors</tspan> -</tspan> - <tspan x="10px" y="4258px"> -</tspan> - <tspan x="10px" y="4276px"><tspan class="bold">Some errors have detailed explanations: E0277, E0599.</tspan> -</tspan> - <tspan x="10px" y="4294px"><tspan class="bold">For more information about an error, try `rustc --explain E0277`.</tspan> -</tspan> - <tspan x="10px" y="4312px"> + <tspan x="10px" y="3880px"> </tspan> </text>
diff --git a/tests/ui/expr/issue-22933-2.rs b/tests/ui/expr/issue-22933-2.rs index dfd84b9..3f593ca 100644 --- a/tests/ui/expr/issue-22933-2.rs +++ b/tests/ui/expr/issue-22933-2.rs
@@ -2,7 +2,7 @@ Pie = 0x1, Apple = 0x2, ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, - //~^ ERROR no variant or associated item named `PIE` found + //~^ ERROR no variant, associated function, or constant named `PIE` found } fn main() {}
diff --git a/tests/ui/expr/issue-22933-2.stderr b/tests/ui/expr/issue-22933-2.stderr index 07f095f6..0b7416b 100644 --- a/tests/ui/expr/issue-22933-2.stderr +++ b/tests/ui/expr/issue-22933-2.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no variant or associated item named `PIE` found for enum `Delicious` in the current scope +error[E0599]: no variant, associated function, or constant named `PIE` found for enum `Delicious` in the current scope --> $DIR/issue-22933-2.rs:4:55 | LL | enum Delicious { - | -------------- variant or associated item `PIE` not found for this enum + | -------------- variant, associated function, or constant `PIE` not found for this enum ... LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, - | ^^^ variant or associated item not found in `Delicious` + | ^^^ variant, associated function, or constant not found in `Delicious` | help: there is a variant with a similar name |
diff --git a/tests/ui/feature-gates/feature-gate-box_patterns.rs b/tests/ui/feature-gates/feature-gate-box_patterns.rs index 8bec16a..9ff6604 100644 --- a/tests/ui/feature-gates/feature-gate-box_patterns.rs +++ b/tests/ui/feature-gates/feature-gate-box_patterns.rs
@@ -1,4 +1,9 @@ fn main() { let box x = Box::new('c'); //~ ERROR box pattern syntax is experimental - println!("x: {}", x); + let _: char = x; + + struct Packet { x: Box<i32> } + + let Packet { box x } = Packet { x: Box::new(0) }; //~ ERROR box pattern syntax is experimental + let _: i32 = x; }
diff --git a/tests/ui/feature-gates/feature-gate-box_patterns.stderr b/tests/ui/feature-gates/feature-gate-box_patterns.stderr index fb61b2b..6f5ee20 100644 --- a/tests/ui/feature-gates/feature-gate-box_patterns.stderr +++ b/tests/ui/feature-gates/feature-gate-box_patterns.stderr
@@ -8,6 +8,16 @@ = help: add `#![feature(box_patterns)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0658]: box pattern syntax is experimental + --> $DIR/feature-gate-box_patterns.rs:7:18 + | +LL | let Packet { box x } = Packet { x: Box::new(0) }; + | ^^^^^ + | + = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr index 34a56fe..e699c5d 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr
@@ -1,5 +1,5 @@ error[E0658]: the `#[force_target_feature]` attribute is an experimental feature - --> $DIR/feature-gate-effective-target-features.rs:13:5 + --> $DIR/feature-gate-effective-target-features.rs:14:5 | LL | #[unsafe(force_target_feature(enable = "avx2"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `#[target_feature(..)]` cannot be applied to safe trait method - --> $DIR/feature-gate-effective-target-features.rs:21:5 + --> $DIR/feature-gate-effective-target-features.rs:22:5 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method @@ -18,13 +18,13 @@ | ------------- not an `unsafe` function error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/feature-gate-effective-target-features.rs:23:5 + --> $DIR/feature-gate-effective-target-features.rs:24:5 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait - --> $DIR/feature-gate-effective-target-features.rs:7:5 + --> $DIR/feature-gate-effective-target-features.rs:8:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr index d51956f..bf9f5d7 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr
@@ -1,14 +1,18 @@ warning: the feature `effective_target_features` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-effective-target-features.rs:3:30 + --> $DIR/feature-gate-effective-target-features.rs:4:30 | LL | #![cfg_attr(feature, feature(effective_target_features))] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #143352 <https://github.com/rust-lang/rust/issues/143352> for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/feature-gate-effective-target-features.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: `#[target_feature(..)]` cannot be applied to safe trait method - --> $DIR/feature-gate-effective-target-features.rs:21:5 + --> $DIR/feature-gate-effective-target-features.rs:22:5 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method @@ -17,13 +21,13 @@ | ------------- not an `unsafe` function error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/feature-gate-effective-target-features.rs:23:5 + --> $DIR/feature-gate-effective-target-features.rs:24:5 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait - --> $DIR/feature-gate-effective-target-features.rs:7:5 + --> $DIR/feature-gate-effective-target-features.rs:8:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.rs b/tests/ui/feature-gates/feature-gate-effective-target-features.rs index d383897..a8be611 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.rs +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.rs
@@ -1,5 +1,6 @@ //@ revisions: default feature //@ only-x86_64 +#![warn(incomplete_features)] #![cfg_attr(feature, feature(effective_target_features))] //[feature]~^ WARN the feature `effective_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
diff --git a/tests/ui/feature-gates/feature-gate-macro-guard-matcher.rs b/tests/ui/feature-gates/feature-gate-macro-guard-matcher.rs new file mode 100644 index 0000000..662161f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-guard-matcher.rs
@@ -0,0 +1,5 @@ +fn main() { + macro_rules! m { + ($x:guard) => {}; //~ ERROR `guard` fragments in macro are unstable + } +}
diff --git a/tests/ui/feature-gates/feature-gate-macro-guard-matcher.stderr b/tests/ui/feature-gates/feature-gate-macro-guard-matcher.stderr new file mode 100644 index 0000000..0977f94 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-guard-matcher.stderr
@@ -0,0 +1,13 @@ +error[E0658]: `guard` fragments in macro are unstable + --> $DIR/feature-gate-macro-guard-matcher.rs:3:10 + | +LL | ($x:guard) => {}; + | ^^^^^^^^ + | + = note: see issue #153104 <https://github.com/rust-lang/rust/issues/153104> for more information + = help: add `#![feature(macro_guard_matcher)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-new_range.rs b/tests/ui/feature-gates/feature-gate-new_range.rs index 32eeb04..6fd4f19 100644 --- a/tests/ui/feature-gates/feature-gate-new_range.rs +++ b/tests/ui/feature-gates/feature-gate-new_range.rs
@@ -1,5 +1,3 @@ -#![feature(new_range_api)] - fn main() { let a: core::range::RangeFrom<u8> = 1..; //~^ ERROR mismatched types
diff --git a/tests/ui/feature-gates/feature-gate-new_range.stderr b/tests/ui/feature-gates/feature-gate-new_range.stderr index b7f70d3..c7f2d21 100644 --- a/tests/ui/feature-gates/feature-gate-new_range.stderr +++ b/tests/ui/feature-gates/feature-gate-new_range.stderr
@@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:4:41 + --> $DIR/feature-gate-new_range.rs:2:41 | LL | let a: core::range::RangeFrom<u8> = 1..; | -------------------------- ^^^ expected `RangeFrom<u8>`, found `RangeFrom<{integer}>` @@ -14,7 +14,7 @@ | + ++++++++ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:6:37 + --> $DIR/feature-gate-new_range.rs:4:37 | LL | let b: core::range::Range<u8> = 2..3; | ---------------------- ^^^^ expected `Range<u8>`, found `Range<{integer}>` @@ -29,7 +29,7 @@ | + ++++++++ error[E0308]: mismatched types - --> $DIR/feature-gate-new_range.rs:8:46 + --> $DIR/feature-gate-new_range.rs:6:46 | LL | let c: core::range::RangeInclusive<u8> = 4..=5; | ------------------------------- ^^^^^ expected `RangeInclusive<u8>`, found `RangeInclusive<{integer}>`
diff --git a/tests/ui/feature-gates/feature-gate-try_blocks.stderr b/tests/ui/feature-gates/feature-gate-try_blocks.stderr index dbef7fb..0a7580d 100644 --- a/tests/ui/feature-gates/feature-gate-try_blocks.stderr +++ b/tests/ui/feature-gates/feature-gate-try_blocks.stderr
@@ -8,7 +8,7 @@ LL | | }; | |_____^ | - = note: see issue #31436 <https://github.com/rust-lang/rust/issues/31436> for more information + = note: see issue #154391 <https://github.com/rust-lang/rust/issues/154391> for more information = help: add `#![feature(try_blocks)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs index 2b0bbaa..27e8b51 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs
@@ -1,7 +1,7 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate //@ [with_gate] check-pass - +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING #[cfg(false)]
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr index a7deeb0..4220930 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr
@@ -5,7 +5,11 @@ | ^^^^^^^^^^^^^ | = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/feature-gate-unsafe_fields.rs:4:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr index 912c274..c51d615 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 1560f2b..66d36d9 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs
@@ -37,7 +37,7 @@ #[inline] //~^ ERROR attribute cannot be used on mod inline { - //~^ NOTE the inner attribute doesn't annotate this module + //~^ NOTE the inner attribute doesn't annotate this item mod inner { #![inline] } //~^ ERROR attribute cannot be used on
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 662776e..db56f22 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -24,6 +24,21 @@ | = help: `#[rustc_main]` can only be applied to functions +error: `repr` attribute cannot be used at crate level + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 + | +LL | #![repr()] + | ^^^^^^^^^^ +... +LL | mod inline { + | ------------ the inner attribute doesn't annotate this item + | +help: perhaps you meant to use an outer attribute + | +LL - #![repr()] +LL + #[repr()] + | + error: `#[path]` attribute cannot be used on crates --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:20:1 | @@ -243,21 +258,6 @@ LL - #![no_mangle] | -error: `repr` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 - | -LL | #![repr()] - | ^^^^^^^^^^ -... -LL | mod inline { - | ------ the inner attribute doesn't annotate this module - | -help: perhaps you meant to use an outer attribute - | -LL - #![repr()] -LL + #[repr()] - | - error[E0517]: attribute should be applied to a struct, enum, or union --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:25 |
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr index 6e706b1..8af140b 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | fn main() {} - | ---- the inner attribute doesn't annotate this function + | ------------ the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs b/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs new file mode 100644 index 0000000..0ccbaf1 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs
@@ -0,0 +1,12 @@ +// For historical reasons, auto traits don't have a proper pre-expansion feature gate. +// We're now at least issuing a *warning* for those that only exist before macro expansion. +// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one. +// As part of this, move these test cases into `feature-gate-auto-traits.rs`. +//@ check-pass + +#[cfg(false)] +auto trait Foo {} +//~^ WARN `auto` traits are unstable +//~| WARN unstable syntax can change at any point in the future + +fn main() {}
diff --git a/tests/ui/auto-traits/pre-cfg.stderr b/tests/ui/feature-gates/soft-feature-gate-auto_traits.stderr similarity index 91% rename from tests/ui/auto-traits/pre-cfg.stderr rename to tests/ui/feature-gates/soft-feature-gate-auto_traits.stderr index 648f946..20811aa 100644 --- a/tests/ui/auto-traits/pre-cfg.stderr +++ b/tests/ui/feature-gates/soft-feature-gate-auto_traits.stderr
@@ -1,5 +1,5 @@ warning: `auto` traits are unstable - --> $DIR/pre-cfg.rs:4:1 + --> $DIR/soft-feature-gate-auto_traits.rs:8:1 | LL | auto trait Foo {} | ^^^^
diff --git a/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs b/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs new file mode 100644 index 0000000..8ab0e80 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs
@@ -0,0 +1,17 @@ +// For historical reasons, box patterns don't have a proper pre-expansion feature gate. +// We're now at least issuing a *warning* for those that only exist before macro expansion. +// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one. +// As part of this, move these test cases into `feature-gate-box_patterns.rs`. +//@ check-pass + +fn main() { + #[cfg(false)] + let box x; + //~^ WARN box pattern syntax is experimental + //~| WARN unstable syntax can change at any point in the future + + #[cfg(false)] + let Packet { box x }; + //~^ WARN box pattern syntax is experimental + //~| WARN unstable syntax can change at any point in the future +}
diff --git a/tests/ui/feature-gates/soft-feature-gate-box_patterns.stderr b/tests/ui/feature-gates/soft-feature-gate-box_patterns.stderr new file mode 100644 index 0000000..a8399b5 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-box_patterns.stderr
@@ -0,0 +1,26 @@ +warning: box pattern syntax is experimental + --> $DIR/soft-feature-gate-box_patterns.rs:9:9 + | +LL | let box x; + | ^^^^^ + | + = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: box pattern syntax is experimental + --> $DIR/soft-feature-gate-box_patterns.rs:14:18 + | +LL | let Packet { box x }; + | ^^^ + | + = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: 2 warnings emitted +
diff --git a/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs b/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs new file mode 100644 index 0000000..7d2d485 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs
@@ -0,0 +1,17 @@ +// For historical reasons, decl macros 2.0 don't have a proper pre-expansion feature gate. +// We're now at least issuing a *warning* for those that only exist before macro expansion. +// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one. +// As part of this, move these test cases into `feature-gate-decl_macro.rs`. +//@ check-pass + +#[cfg(false)] +macro make() {} +//~^ WARN `macro` is experimental +//~| WARN unstable syntax can change at any point in the future + +#[cfg(false)] +macro create { () => {} } +//~^ WARN `macro` is experimental +//~| WARN unstable syntax can change at any point in the future + +fn main() {}
diff --git a/tests/ui/feature-gates/soft-feature-gate-decl_macro.stderr b/tests/ui/feature-gates/soft-feature-gate-decl_macro.stderr new file mode 100644 index 0000000..7152162 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-decl_macro.stderr
@@ -0,0 +1,26 @@ +warning: `macro` is experimental + --> $DIR/soft-feature-gate-decl_macro.rs:8:1 + | +LL | macro make() {} + | ^^^^^^^^^^^^^^^ + | + = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information + = help: add `#![feature(decl_macro)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: `macro` is experimental + --> $DIR/soft-feature-gate-decl_macro.rs:13:1 + | +LL | macro create { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information + = help: add `#![feature(decl_macro)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: 2 warnings emitted +
diff --git a/tests/ui/feature-gates/soft-feature-gate-trait_alias.rs b/tests/ui/feature-gates/soft-feature-gate-trait_alias.rs new file mode 100644 index 0000000..553e883 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-trait_alias.rs
@@ -0,0 +1,17 @@ +// For historical reasons, trait aliases don't have a proper pre-expansion feature gate. +// We're now at least issuing a *warning* for those that only exist before macro expansion. +// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one. +// As part of this, move these test cases into `feature-gate-trait-alias.rs`. +//@ check-pass + +#[cfg(false)] +trait Trait =; +//~^ WARN trait aliases are experimental +//~| WARN unstable syntax can change at any point in the future + +#[cfg(false)] +trait Trait<T> = Bound where T: Bound; +//~^ WARN trait aliases are experimental +//~| WARN unstable syntax can change at any point in the future + +fn main() {}
diff --git a/tests/ui/feature-gates/soft-feature-gate-trait_alias.stderr b/tests/ui/feature-gates/soft-feature-gate-trait_alias.stderr new file mode 100644 index 0000000..e50d4c3 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-trait_alias.stderr
@@ -0,0 +1,26 @@ +warning: trait aliases are experimental + --> $DIR/soft-feature-gate-trait_alias.rs:8:1 + | +LL | trait Trait =; + | ^^^^^^^^^^^^^^ + | + = note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information + = help: add `#![feature(trait_alias)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: trait aliases are experimental + --> $DIR/soft-feature-gate-trait_alias.rs:13:1 + | +LL | trait Trait<T> = Bound where T: Bound; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information + = help: add `#![feature(trait_alias)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: 2 warnings emitted +
diff --git a/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs b/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs new file mode 100644 index 0000000..aa51e60 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs
@@ -0,0 +1,13 @@ +// For historical reasons, try blocks don't have a proper pre-expansion feature gate. +// We're now at least issuing a *warning* for those that only exist before macro expansion. +// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one. +// As part of this, move these test cases into `feature-gate-try_blocks.rs`. +//@ edition: 2018 +//@ check-pass + +fn main() { + #[cfg(false)] + try {} + //~^ WARN `try` blocks are unstable + //~| WARN unstable syntax can change at any point +}
diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr b/tests/ui/feature-gates/soft-feature-gate-try_blocks.stderr similarity index 74% rename from tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr rename to tests/ui/feature-gates/soft-feature-gate-try_blocks.stderr index dc92d7e..2b20f40 100644 --- a/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr +++ b/tests/ui/feature-gates/soft-feature-gate-try_blocks.stderr
@@ -1,10 +1,10 @@ warning: `try` blocks are unstable - --> $DIR/try-block-homogeneous-pre-expansion.rs:9:5 + --> $DIR/soft-feature-gate-try_blocks.rs:10:5 | LL | try {} | ^^^^^^ | - = note: see issue #31436 <https://github.com/rust-lang/rust/issues/31436> for more information + = note: see issue #154391 <https://github.com/rust-lang/rust/issues/154391> for more information = help: add `#![feature(try_blocks)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = warning: unstable syntax can change at any point in the future, causing a hard error!
diff --git a/tests/ui/fn/issue-1900.rs b/tests/ui/fn/issue-1900.rs deleted file mode 100644 index 761bd31..0000000 --- a/tests/ui/fn/issue-1900.rs +++ /dev/null
@@ -1,2 +0,0 @@ -fn main<T>() { } -//~^ ERROR `main` function is not allowed to have generic parameters
diff --git a/tests/ui/fn/issue-1900.stderr b/tests/ui/fn/issue-1900.stderr deleted file mode 100644 index 31fd46c..0000000 --- a/tests/ui/fn/issue-1900.stderr +++ /dev/null
@@ -1,9 +0,0 @@ -error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-1900.rs:1:8 - | -LL | fn main<T>() { } - | ^^^ `main` cannot have generic parameters - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0131`.
diff --git a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs index d7dff32..ec6dfb8 100644 --- a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs +++ b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs
@@ -29,5 +29,5 @@ fn new() -> P::Pointer<Self> { fn main() { let mut list = RcNode::<i32>::new(); - //~^ ERROR the variant or associated item `new` exists for enum `Node<i32, RcFamily>`, but its trait bounds were not satisfied + //~^ ERROR the variant, associated function, or constant `new` exists for enum `Node<i32, RcFamily>`, but its trait bounds were not satisfied }
diff --git a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr index b31689d..674e288 100644 --- a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr +++ b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr
@@ -15,14 +15,14 @@ LL | type Pointer<T>: Deref<Target = T> + ?Sized; | ++++++++ -error[E0599]: the variant or associated item `new` exists for enum `Node<i32, RcFamily>`, but its trait bounds were not satisfied +error[E0599]: the variant, associated function, or constant `new` exists for enum `Node<i32, RcFamily>`, but its trait bounds were not satisfied --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:31:35 | LL | enum Node<T, P: PointerFamily> { - | ------------------------------ variant or associated item `new` not found for this enum + | ------------------------------ variant, associated function, or constant `new` not found for this enum ... LL | let mut list = RcNode::<i32>::new(); - | ^^^ variant or associated item cannot be called on `Node<i32, RcFamily>` due to unsatisfied trait bounds + | ^^^ variant, associated function, or constant cannot be called on `Node<i32, RcFamily>` due to unsatisfied trait bounds | note: trait bound `(dyn Deref<Target = Node<i32, RcFamily>> + 'static): Sized` was not satisfied --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:23:29
diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.rs b/tests/ui/generic-associated-types/issue-87429-specialization.rs index 87e9116..4a1e6aa 100644 --- a/tests/ui/generic-associated-types/issue-87429-specialization.rs +++ b/tests/ui/generic-associated-types/issue-87429-specialization.rs
@@ -1,7 +1,6 @@ //@ check-fail #![feature(specialization)] -//~^ WARN incomplete trait Family { type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.stderr b/tests/ui/generic-associated-types/issue-87429-specialization.stderr index 44f871e..dbe97bd 100644 --- a/tests/ui/generic-associated-types/issue-87429-specialization.stderr +++ b/tests/ui/generic-associated-types/issue-87429-specialization.stderr
@@ -1,22 +1,12 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-87429-specialization.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: can't compare `Foo` with `Foo` - --> $DIR/issue-87429-specialization.rs:20:31 + --> $DIR/issue-87429-specialization.rs:19:31 | LL | default type Member<'a> = Foo; | ^^^ no implementation for `Foo == Foo` | = help: the trait `PartialEq` is not implemented for `Foo` note: required by a bound in `Family::Member` - --> $DIR/issue-87429-specialization.rs:7:22 + --> $DIR/issue-87429-specialization.rs:6:22 | LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member` @@ -26,6 +16,6 @@ LL | struct Foo; | -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index b27a2dc..f8fcb73 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr
@@ -1,4 +1,4 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a))], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a))], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied --> $DIR/structually-relate-aliases.rs:13:36 |
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs index 821a04f..b0f623c 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
@@ -5,6 +5,6 @@ pub struct Bar where for<'a> &'a mut Self:; -//~^ ERROR overflow evaluating the requirement `for<'a> &'a mut Bar well-formed` +//~^ ERROR: overflow evaluating whether `&'a mut Bar` is well-formed fn main() {}
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.stderr b/tests/ui/higher-ranked/trait-bounds/issue-95230.stderr index 7070af7..9e85c68 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-95230.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.stderr
@@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-formed` +error[E0275]: overflow evaluating whether `&'a mut Bar` is well-formed --> $DIR/issue-95230.rs:7:13 | LL | for<'a> &'a mut Self:;
diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs index d6490d5..dc47eba 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs
@@ -1,5 +1,6 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(impl_restriction))] //[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes #![feature(auto_traits, const_trait_impl)]
diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr index ad183b2..834cc99 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr
@@ -1,5 +1,5 @@ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + --> $DIR/recover-incorrect-impl-restriction.rs:9:14 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^ @@ -15,7 +15,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + --> $DIR/recover-incorrect-impl-restriction.rs:11:21 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^ @@ -31,7 +31,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + --> $DIR/recover-incorrect-impl-restriction.rs:13:19 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^ @@ -47,7 +47,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + --> $DIR/recover-incorrect-impl-restriction.rs:15:20 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^ @@ -63,7 +63,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + --> $DIR/recover-incorrect-impl-restriction.rs:17:27 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^ @@ -79,7 +79,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + --> $DIR/recover-incorrect-impl-restriction.rs:19:26 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^ @@ -95,13 +95,17 @@ | ++ warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/recover-incorrect-impl-restriction.rs:3:32 + --> $DIR/recover-incorrect-impl-restriction.rs:4:32 | LL | #![cfg_attr(with_gate, feature(impl_restriction))] | ^^^^^^^^^^^^^^^^ | = note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/recover-incorrect-impl-restriction.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors; 1 warning emitted
diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr index d949172..223a7cd 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr
@@ -1,5 +1,5 @@ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + --> $DIR/recover-incorrect-impl-restriction.rs:9:14 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^ @@ -15,7 +15,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + --> $DIR/recover-incorrect-impl-restriction.rs:11:21 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^ @@ -31,7 +31,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + --> $DIR/recover-incorrect-impl-restriction.rs:13:19 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^ @@ -47,7 +47,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + --> $DIR/recover-incorrect-impl-restriction.rs:15:20 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^ @@ -63,7 +63,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + --> $DIR/recover-incorrect-impl-restriction.rs:17:27 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^ @@ -79,7 +79,7 @@ | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + --> $DIR/recover-incorrect-impl-restriction.rs:19:26 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^ @@ -95,7 +95,7 @@ | ++ error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:8:9 + --> $DIR/recover-incorrect-impl-restriction.rs:9:9 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:10:16 + --> $DIR/recover-incorrect-impl-restriction.rs:11:16 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^^^^^^^ @@ -115,7 +115,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:12:14 + --> $DIR/recover-incorrect-impl-restriction.rs:13:14 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:14:15 + --> $DIR/recover-incorrect-impl-restriction.rs:15:15 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:16:22 + --> $DIR/recover-incorrect-impl-restriction.rs:17:22 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:18:21 + --> $DIR/recover-incorrect-impl-restriction.rs:19:21 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs index 62622e1..ce36a49 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs
@@ -1,5 +1,6 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(impl_restriction))] //[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes #![feature(auto_traits, const_trait_impl, trait_alias)]
diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr index 70287ac..7be0300 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr
@@ -1,83 +1,87 @@ error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:32 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:4:32 | LL | #![cfg_attr(with_gate, feature(impl_restriction))] | ^^^^^^^^^^^^^^^^ | = note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors; 1 warning emitted
diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr index 7bff903..c99bfce 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr
@@ -1,77 +1,77 @@ error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^ @@ -81,7 +81,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:6 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:6 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:8 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:8 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^ @@ -101,7 +101,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:7 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:7 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:18 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:18 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:17 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:17 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/equality-rpass.rs b/tests/ui/impl-trait/equality-rpass.rs index da750f4..d5cac80 100644 --- a/tests/ui/impl-trait/equality-rpass.rs +++ b/tests/ui/impl-trait/equality-rpass.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: std::fmt::Debug + Eq {}
diff --git a/tests/ui/impl-trait/equality-rpass.stderr b/tests/ui/impl-trait/equality-rpass.stderr deleted file mode 100644 index bde8362..0000000 --- a/tests/ui/impl-trait/equality-rpass.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality-rpass.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 07fc4a5..4a31563 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs
@@ -1,6 +1,6 @@ //@ dont-require-annotations: NOTE -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: Copy + ToString {}
diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 7f965b9..3c765da 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/equality.rs:17:5 | @@ -48,7 +38,7 @@ = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/equality2.rs b/tests/ui/impl-trait/equality2.rs index 808c600..44d356e 100644 --- a/tests/ui/impl-trait/equality2.rs +++ b/tests/ui/impl-trait/equality2.rs
@@ -1,6 +1,6 @@ //@ dont-require-annotations: NOTE -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: Copy + ToString {}
diff --git a/tests/ui/impl-trait/equality2.stderr b/tests/ui/impl-trait/equality2.stderr index 2fa7eb2..ce0ccea 100644 --- a/tests/ui/impl-trait/equality2.stderr +++ b/tests/ui/impl-trait/equality2.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality2.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/equality2.rs:27:18 | @@ -72,6 +62,6 @@ found opaque type `impl Foo` (`u32`) = note: distinct uses of `impl Trait` result in different opaque types -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs index 351cdad..ba6dfd4 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
@@ -1,7 +1,6 @@ //@ compile-flags: -Znext-solver #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete trait Foo {}
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index a95670c..03c5d7a 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -1,53 +1,44 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/alias-bounds-when-not-wf.rs:3:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:15 + --> $DIR/alias-bounds-when-not-wf.rs:15:15 | LL | fn hello(_: W<A<usize>>) {} | ^^^^^^^^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ note: required by a bound in `A` - --> $DIR/alias-bounds-when-not-wf.rs:8:11 + --> $DIR/alias-bounds-when-not-wf.rs:7:11 | LL | type A<T: Foo> = T; | ^^^ required by this bound in `A` error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:10 + --> $DIR/alias-bounds-when-not-wf.rs:15:10 | LL | fn hello(_: W<A<usize>>) {} | ^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:1 + --> $DIR/alias-bounds-when-not-wf.rs:15:1 | LL | fn hello(_: W<A<usize>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/issues/issue-62742.rs b/tests/ui/impl-trait/issues/issue-62742.rs index c64278c2..0529170 100644 --- a/tests/ui/impl-trait/issues/issue-62742.rs +++ b/tests/ui/impl-trait/issues/issue-62742.rs
@@ -2,7 +2,7 @@ fn a() { WrongImpl::foo(0i32); - //~^ ERROR the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied + //~^ ERROR the associated function or constant `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied //~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied }
diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index a1fedb8..4899a96 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr
@@ -16,17 +16,17 @@ LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); | ^^^^^^ required by this bound in `SafeImpl` -error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied --> $DIR/issue-62742.rs:4:16 | LL | WrongImpl::foo(0i32); - | ^^^ function or associated item cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds ... LL | pub struct RawImpl<T>(PhantomData<T>); | --------------------- doesn't satisfy `RawImpl<_>: Raw<_>` ... LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); - | ----------------------------------------- function or associated item `foo` not found for this struct + | ----------------------------------------- associated function or constant `foo` not found for this struct | note: trait bound `RawImpl<_>: Raw<_>` was not satisfied --> $DIR/issue-62742.rs:35:20 @@ -60,17 +60,17 @@ LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); | ^^^^^^ required by this bound in `SafeImpl` -error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied --> $DIR/issue-62742.rs:10:22 | LL | WrongImpl::<()>::foo(0i32); - | ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds ... LL | pub struct RawImpl<T>(PhantomData<T>); | --------------------- doesn't satisfy `RawImpl<()>: Raw<()>` ... LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); - | ----------------------------------------- function or associated item `foo` not found for this struct + | ----------------------------------------- associated function or constant `foo` not found for this struct | note: trait bound `RawImpl<()>: Raw<()>` was not satisfied --> $DIR/issue-62742.rs:35:20
diff --git a/tests/ui/impl-trait/rpit/unit-impl-default-36379.rs b/tests/ui/impl-trait/rpit/unit-impl-default-36379.rs new file mode 100644 index 0000000..43c9306 --- /dev/null +++ b/tests/ui/impl-trait/rpit/unit-impl-default-36379.rs
@@ -0,0 +1,6 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/36379 +//@ check-pass + +fn _test() -> impl Default { } + +fn main() {}
diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr new file mode 100644 index 0000000..bea5ddb --- /dev/null +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr
@@ -0,0 +1,11 @@ +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/unsized_coercion.rs:14:17 + | +LL | let x = hello(); + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs index f77f219..2cbf0d2 100644 --- a/tests/ui/impl-trait/unsized_coercion.rs +++ b/tests/ui/impl-trait/unsized_coercion.rs
@@ -3,7 +3,7 @@ //@ revisions: next old //@[next] compile-flags: -Znext-solver -//@ check-pass +//@[old] check-pass trait Trait {} @@ -12,6 +12,7 @@ impl Trait for u32 {} fn hello() -> Box<impl Trait> { if true { let x = hello(); + //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time let y: Box<dyn Trait> = x; } Box::new(1u32)
diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index db75876..a480a69 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr
@@ -1,5 +1,5 @@ error[E0277]: the trait bound `dyn Send: Trait` is not satisfied - --> $DIR/unsized_coercion3.rs:14:17 + --> $DIR/unsized_coercion3.rs:13:17 | LL | let x = hello(); | ^^^^^^^ the trait `Trait` is not implemented for `dyn Send` @@ -9,37 +9,7 @@ | LL | impl Trait for u32 {} | ^^^^^^^^^^^^^^^^^^ -note: required by a bound in `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:19:5 - | -LL | fn hello() -> Box<impl Trait + ?Sized> { - | ------------------------ - | | | - | | the expected opaque type - | expected `Box<impl Trait + ?Sized>` because of return type -... -LL | Box::new(1u32) - | ^^^^^^^^^^^^^^ types differ - | - = note: expected struct `Box<impl Trait + ?Sized>` - found struct `Box<u32>` +error: aborting due to 1 previous error -error[E0277]: the trait bound `dyn Send: Trait` is not satisfied - --> $DIR/unsized_coercion3.rs:11:1 - | -LL | fn hello() -> Box<impl Trait + ?Sized> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send` - | -help: the trait `Trait` is implemented for `u32` - --> $DIR/unsized_coercion3.rs:9:1 - | -LL | impl Trait for u32 {} - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr index 3bb9f9c..52a72b8 100644 --- a/tests/ui/impl-trait/unsized_coercion3.old.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr
@@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:16:32 + --> $DIR/unsized_coercion3.rs:15:32 | LL | let y: Box<dyn Send> = x; | ^ doesn't have a size known at compile-time
diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs index c1dd535..ebfbb29 100644 --- a/tests/ui/impl-trait/unsized_coercion3.rs +++ b/tests/ui/impl-trait/unsized_coercion3.rs
@@ -9,7 +9,6 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box<impl Trait + ?Sized> { - //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied if true { let x = hello(); //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied @@ -17,7 +16,6 @@ fn hello() -> Box<impl Trait + ?Sized> { //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } Box::new(1u32) - //[next]~^ ERROR: mismatched types } fn main() {}
diff --git a/tests/ui/imports/inconsistent-resolution-153842.rs b/tests/ui/imports/inconsistent-resolution-153842.rs new file mode 100644 index 0000000..85fff36 --- /dev/null +++ b/tests/ui/imports/inconsistent-resolution-153842.rs
@@ -0,0 +1,17 @@ +mod a { + pub use crate::s::Trait as s; + //~^ ERROR cannot determine resolution for the import + //~| ERROR cannot determine resolution for the import + //~| ERROR unresolved imports `crate::s::Trait`, `a::s` +} + +mod b { + pub mod s { + pub trait Trait {} + } +} + +use a::s; +use b::*; + +fn main() {}
diff --git a/tests/ui/imports/inconsistent-resolution-153842.stderr b/tests/ui/imports/inconsistent-resolution-153842.stderr new file mode 100644 index 0000000..2b686ff --- /dev/null +++ b/tests/ui/imports/inconsistent-resolution-153842.stderr
@@ -0,0 +1,26 @@ +error: cannot determine resolution for the import + --> $DIR/inconsistent-resolution-153842.rs:2:13 + | +LL | pub use crate::s::Trait as s; + | ^^^^^^^^^^^^^^^^^^^^ + +error: cannot determine resolution for the import + --> $DIR/inconsistent-resolution-153842.rs:2:13 + | +LL | pub use crate::s::Trait as s; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0432]: unresolved imports `crate::s::Trait`, `a::s` + --> $DIR/inconsistent-resolution-153842.rs:2:13 + | +LL | pub use crate::s::Trait as s; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | use a::s; + | ^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/issue-114682-3.stderr b/tests/ui/imports/issue-114682-3.stderr index 6af7a4e..0b8c8d3 100644 --- a/tests/ui/imports/issue-114682-3.stderr +++ b/tests/ui/imports/issue-114682-3.stderr
@@ -5,13 +5,17 @@ | --- the method is available for `u8` here ... LL | a.ext(); - | ^^^ method not found in `u8` + | ^^^ | = help: items from traits can only be used if the trait is in scope help: trait `SettingsExt` which provides `ext` is implemented but not in scope; perhaps you want to import it | LL + use auto::SettingsExt; | +help: there is a method `extend` with a similar name + | +LL | a.extend(); + | +++ error: aborting due to 1 previous error
diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index 8fc91c1..65faaec 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr
@@ -5,13 +5,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `Vec<{integer}>` to implement `Index<i32>` error: aborting due to 1 previous error
diff --git a/tests/ui/indexing/indexing-integral-types.stderr b/tests/ui/indexing/indexing-integral-types.stderr index 3dfc5f5..6041613 100644 --- a/tests/ui/indexing/indexing-integral-types.stderr +++ b/tests/ui/indexing/indexing-integral-types.stderr
@@ -5,13 +5,13 @@ | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `Vec<isize>` to implement `Index<u8>` error[E0277]: the type `[isize]` cannot be indexed by `i8` @@ -21,13 +21,13 @@ | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `Vec<isize>` to implement `Index<i8>` error[E0277]: the type `[isize]` cannot be indexed by `u32` @@ -37,13 +37,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `Vec<isize>` to implement `Index<u32>` error[E0277]: the type `[isize]` cannot be indexed by `i32` @@ -53,13 +53,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `Vec<isize>` to implement `Index<i32>` error[E0277]: the type `[u8]` cannot be indexed by `u8` @@ -69,13 +69,13 @@ | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[u8]` to implement `Index<u8>` error[E0277]: the type `[u8]` cannot be indexed by `i8` @@ -85,13 +85,13 @@ | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[u8]` to implement `Index<i8>` error[E0277]: the type `[u8]` cannot be indexed by `u32` @@ -101,13 +101,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[u8]` to implement `Index<u32>` error[E0277]: the type `[u8]` cannot be indexed by `i32` @@ -117,13 +117,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[u8]` to implement `Index<i32>` error: aborting due to 8 previous errors
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index e5f9f78..17ef331 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -5,14 +5,16 @@ | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[{integer}]` to implement `Index<u8>` + = note: 1 redundant requirement hidden + = note: required for `[{integer}; 1]` to implement `Index<u8>` error[E0308]: mismatched types --> $DIR/indexing-requires-a-uint.rs:12:18
diff --git a/tests/ui/indexing/point-at-index-for-obligation-failure.rs b/tests/ui/indexing/point-at-index-for-obligation-failure.rs index 4ff9069..e9c429b 100644 --- a/tests/ui/indexing/point-at-index-for-obligation-failure.rs +++ b/tests/ui/indexing/point-at-index-for-obligation-failure.rs
@@ -1,7 +1,7 @@ fn main() { let a = std::collections::HashMap::<String,String>::new(); let s = "hello"; - let _b = a[ //~ ERROR E0277 - &s + let _b = a[ + &s //~ ERROR E0277 ]; }
diff --git a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr index 22f48d6..a221e43 100644 --- a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr +++ b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr
@@ -1,11 +1,8 @@ error[E0277]: the trait bound `String: Borrow<&str>` is not satisfied - --> $DIR/point-at-index-for-obligation-failure.rs:4:14 + --> $DIR/point-at-index-for-obligation-failure.rs:5:9 | -LL | let _b = a[ - | ______________^ -LL | | &s -LL | | ]; - | |_____^ the trait `Borrow<&str>` is not implemented for `String` +LL | &s + | ^^ the trait `Borrow<&str>` is not implemented for `String` | help: the trait `Borrow<&_>` is not implemented for `String` but trait `Borrow<_>` is implemented for it
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs new file mode 100644 index 0000000..6a32cd9 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs
@@ -0,0 +1,18 @@ +//@ check-fail + +#![feature(repr_simd, intrinsics, core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +// Bad monomorphizations could previously cause LLVM asserts even though the +// error was caught in the compiler. + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); + +pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { + intrinsics::fadd_fast(a, b) + //~^ ERROR the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied +}
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr new file mode 100644 index 0000000..db2a222 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr
@@ -0,0 +1,30 @@ +error[E0277]: the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied + --> $DIR/bad-intrinsic-monomorphization-bounds.rs:16:5 + | +LL | intrinsics::fadd_fast(a, b) + | ^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | +help: the nightly-only, unstable trait `intrinsics::bounds::FloatPrimitive` is not implemented for `Foo` + --> $DIR/bad-intrinsic-monomorphization-bounds.rs:13:1 + | +LL | pub struct Foo(i64); + | ^^^^^^^^^^^^^^ +help: the following other types implement trait `intrinsics::bounds::FloatPrimitive` + --> $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f16` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f32` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f64` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f128` +note: required by a bound in `fadd_fast` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs index d68cbf2..8849ed2 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
@@ -17,11 +17,6 @@ pub fn test_cttz(v: Foo) -> u32 { //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo` } -pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { - intrinsics::fadd_fast(a, b) - //~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo` -} - pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { intrinsics::simd::simd_add(a, b) //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo`
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr index 51ef71c..329bf21 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr
@@ -1,21 +1,15 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:26:5 + --> $DIR/bad-intrinsic-monomorphization.rs:21:5 | LL | intrinsics::simd::simd_add(a, b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:21:5 - | -LL | intrinsics::fadd_fast(a, b) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo` --> $DIR/bad-intrinsic-monomorphization.rs:16:5 | LL | intrinsics::cttz(v) | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs deleted file mode 100644 index d40b869..0000000 --- a/tests/ui/issues/issue-25901.rs +++ /dev/null
@@ -1,14 +0,0 @@ -struct A; -struct B; - -static S: &'static B = &A; -//~^ ERROR the trait bound `A: const Deref` is not satisfied - -use std::ops::Deref; - -impl Deref for A { - type Target = B; - fn deref(&self)->&B { static B_: B = B; &B_ } -} - -fn main(){}
diff --git a/tests/ui/issues/issue-28586.rs b/tests/ui/issues/issue-28586.rs index c543ef9..9520e0e 100644 --- a/tests/ui/issues/issue-28586.rs +++ b/tests/ui/issues/issue-28586.rs
@@ -2,6 +2,6 @@ pub trait Foo {} impl Foo for [u8; usize::BYTES] {} -//~^ ERROR no associated item named `BYTES` found +//~^ ERROR no associated function or constant named `BYTES` found fn main() { }
diff --git a/tests/ui/issues/issue-28586.stderr b/tests/ui/issues/issue-28586.stderr index 33f40a3..dda1479 100644 --- a/tests/ui/issues/issue-28586.stderr +++ b/tests/ui/issues/issue-28586.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `BYTES` found for type `usize` in the current scope +error[E0599]: no associated function or constant named `BYTES` found for type `usize` in the current scope --> $DIR/issue-28586.rs:4:26 | LL | impl Foo for [u8; usize::BYTES] {} - | ^^^^^ associated item not found in `usize` + | ^^^^^ associated function or constant not found in `usize` error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-28971.rs b/tests/ui/issues/issue-28971.rs index 8e7a2fe0..e6a504f 100644 --- a/tests/ui/issues/issue-28971.rs +++ b/tests/ui/issues/issue-28971.rs
@@ -5,7 +5,7 @@ fn main(){ foo(|| { match Foo::Bar(1) { Foo::Baz(..) => (), - //~^ ERROR no variant or associated item named `Baz` found + //~^ ERROR no variant, associated function, or constant named `Baz` found _ => (), } });
diff --git a/tests/ui/issues/issue-28971.stderr b/tests/ui/issues/issue-28971.stderr index fd689a2..de3fff0 100644 --- a/tests/ui/issues/issue-28971.stderr +++ b/tests/ui/issues/issue-28971.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no variant or associated item named `Baz` found for enum `Foo` in the current scope +error[E0599]: no variant, associated function, or constant named `Baz` found for enum `Foo` in the current scope --> $DIR/issue-28971.rs:7:18 | LL | enum Foo { - | -------- variant or associated item `Baz` not found for this enum + | -------- variant, associated function, or constant `Baz` not found for this enum ... LL | Foo::Baz(..) => (), - | ^^^ variant or associated item not found in `Foo` + | ^^^ variant, associated function, or constant not found in `Foo` | help: there is a variant with a similar name |
diff --git a/tests/ui/issues/issue-30123.rs b/tests/ui/issues/issue-30123.rs index f6511b5..88fab44 100644 --- a/tests/ui/issues/issue-30123.rs +++ b/tests/ui/issues/issue-30123.rs
@@ -5,5 +5,5 @@ fn main() { let ug = Graph::<i32, i32>::new_undirected(); - //~^ ERROR no function or associated item named `new_undirected` found + //~^ ERROR no associated function or constant named `new_undirected` found }
diff --git a/tests/ui/issues/issue-30123.stderr b/tests/ui/issues/issue-30123.stderr index db2e3dd7..1e27474 100644 --- a/tests/ui/issues/issue-30123.stderr +++ b/tests/ui/issues/issue-30123.stderr
@@ -1,15 +1,15 @@ -error[E0599]: no function or associated item named `new_undirected` found for struct `issue_30123_aux::Graph<i32, i32>` in the current scope +error[E0599]: no associated function or constant named `new_undirected` found for struct `issue_30123_aux::Graph<i32, i32>` in the current scope --> $DIR/issue-30123.rs:7:33 | LL | let ug = Graph::<i32, i32>::new_undirected(); - | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph<i32, i32>` + | ^^^^^^^^^^^^^^ associated function or constant not found in `issue_30123_aux::Graph<i32, i32>` | note: if you're trying to build a new `issue_30123_aux::Graph<i32, i32>`, consider using `issue_30123_aux::Graph::<N, E>::new` which returns `issue_30123_aux::Graph<_, _>` --> $DIR/auxiliary/issue-30123-aux.rs:14:5 | LL | pub fn new() -> Self { | ^^^^^^^^^^^^^^^^^^^^ - = note: the function or associated item was found for `issue_30123_aux::Graph<N, E, Undirected>` + = note: the associated function or constant was found for `issue_30123_aux::Graph<N, E, Undirected>` error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-36379.rs b/tests/ui/issues/issue-36379.rs deleted file mode 100644 index 6e275b0..0000000 --- a/tests/ui/issues/issue-36379.rs +++ /dev/null
@@ -1,5 +0,0 @@ -//@ check-pass - -fn _test() -> impl Default { } - -fn main() {}
diff --git a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs deleted file mode 100644 index 0e1f19a..0000000 --- a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs +++ /dev/null
@@ -1,14 +0,0 @@ -struct P { child: Option<Box<P>> } -trait PTrait { - fn getChildOption(&self) -> Option<Box<P>>; -} - -impl PTrait for P { - fn getChildOption(&self) -> Option<Box<P>> { - static childVal: Box<P> = self.child.get(); - //~^ ERROR attempt to use a non-constant value in a constant - panic!(); - } -} - -fn main() {}
diff --git a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr deleted file mode 100644 index 06e0192..0000000 --- a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr +++ /dev/null
@@ -1,15 +0,0 @@ -error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3668.rs:8:34 - | -LL | static childVal: Box<P> = self.child.get(); - | ^^^^ non-constant value - | -help: consider using `let` instead of `static` - | -LL - static childVal: Box<P> = self.child.get(); -LL + let childVal: Box<P> = self.child.get(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/issues/issue-39367.rs b/tests/ui/issues/issue-39367.rs deleted file mode 100644 index 68b4d28..0000000 --- a/tests/ui/issues/issue-39367.rs +++ /dev/null
@@ -1,41 +0,0 @@ -//@ run-pass - -use std::ops::Deref; - -struct ArenaSet<U: Deref, V=<U as Deref>::Target>(U, &'static V) - where V: 'static + ?Sized; - -static Z: [u8; 4] = [1,2,3,4]; - -fn arena() -> &'static ArenaSet<Vec<u8>> { - fn __static_ref_initialize() -> ArenaSet<Vec<u8>> { - ArenaSet(vec![], &Z) - } - unsafe { - use std::sync::Once; - fn require_sync<T: Sync>(_: &T) { } - unsafe fn __stability() -> &'static ArenaSet<Vec<u8>> { - use std::mem::transmute; - static mut DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut(); - - static mut ONCE: Once = Once::new(); - ONCE.call_once(|| { - //~^ WARN creating a shared reference to mutable static [static_mut_refs] - DATA = transmute - ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>> - (Box::new(__static_ref_initialize())); - }); - - &*DATA - } - let static_ref = __stability(); - require_sync(static_ref); - static_ref - } -} - -fn main() { - let &ArenaSet(ref u, v) = arena(); - assert!(u.is_empty()); - assert_eq!(v, Z); -}
diff --git a/tests/ui/issues/issue-42880.rs b/tests/ui/issues/issue-42880.rs index b61ba80..36d15fc 100644 --- a/tests/ui/issues/issue-42880.rs +++ b/tests/ui/issues/issue-42880.rs
@@ -1,7 +1,7 @@ type Value = String; fn main() { - let f = |&Value::String(_)| (); //~ ERROR no associated item named + let f = |&Value::String(_)| (); //~ ERROR no associated function or constant named let vec: Vec<Value> = Vec::new(); vec.last().map(f);
diff --git a/tests/ui/issues/issue-42880.stderr b/tests/ui/issues/issue-42880.stderr index f174f42..8743b1c 100644 --- a/tests/ui/issues/issue-42880.stderr +++ b/tests/ui/issues/issue-42880.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `String` found for struct `String` in the current scope +error[E0599]: no associated function or constant named `String` found for struct `String` in the current scope --> $DIR/issue-42880.rs:4:22 | LL | let f = |&Value::String(_)| (); - | ^^^^^^ associated item not found in `String` + | ^^^^^^ associated function or constant not found in `String` error: aborting due to 1 previous error
diff --git a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs new file mode 100644 index 0000000..e2aa817 --- /dev/null +++ b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs
@@ -0,0 +1,9 @@ +//@ compile-flags: -C overflow-checks=no + +#![crate_type = "lib"] + +use std::range::RangeFromIter; + +pub fn next(iter: &mut RangeFromIter<u8>) -> u8 { + iter.next().unwrap() +}
diff --git a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs new file mode 100644 index 0000000..b37f698 --- /dev/null +++ b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs
@@ -0,0 +1,9 @@ +//@ compile-flags: -C overflow-checks=yes + +#![crate_type = "lib"] + +use std::range::RangeFromIter; + +pub fn next(iter: &mut RangeFromIter<u8>) -> u8 { + iter.next().unwrap() +}
diff --git a/tests/ui/iterators/fromrangeiter.rs b/tests/ui/iterators/fromrangeiter.rs index 54d8f52..c672f13 100644 --- a/tests/ui/iterators/fromrangeiter.rs +++ b/tests/ui/iterators/fromrangeiter.rs
@@ -1,8 +1,6 @@ //@ run-pass //@ compile-flags: -C overflow-checks=yes -#![feature(new_range_api)] - use std::{iter, range}; fn main() {
diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index 99bff6b..f22fc21 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr
@@ -33,13 +33,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -74,13 +74,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -115,13 +115,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index c94b716..82269f6 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
@@ -7,13 +7,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<{integer}>` is not implemented for `f32` -help: the following other types implement trait `Sum<A>` +help: `f32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `f32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `f32` implements `Sum<&f32>` + = note: `Sum<&f32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation
diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 7f0c154..d58fe43 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr
@@ -33,13 +33,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -73,13 +73,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -120,13 +120,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<f64>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -158,13 +158,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -194,13 +194,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<&()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation
diff --git a/tests/ui/iterators/rangefrom-overflow-2crates.rs b/tests/ui/iterators/rangefrom-overflow-2crates.rs new file mode 100644 index 0000000..56b642b --- /dev/null +++ b/tests/ui/iterators/rangefrom-overflow-2crates.rs
@@ -0,0 +1,38 @@ +//@ run-pass +//@ needs-unwind +//@ aux-build:rangefrom-overflow-2crates-ocno.rs +//@ aux-build:rangefrom-overflow-2crates-ocyes.rs + +// For #154124 +// Test that two crates with different overflow-checks have the same results, +// even when the iterator is passed between them. + +extern crate rangefrom_overflow_2crates_ocno; +extern crate rangefrom_overflow_2crates_ocyes; + +use rangefrom_overflow_2crates_ocno::next as next_ocno; +use rangefrom_overflow_2crates_ocyes::next as next_ocyes; + +fn main() { + let mut iter_ocyes = std::range::RangeFrom::from(0_u8..).into_iter(); + let mut iter_ocno = iter_ocyes.clone(); + + for n in 0_u8..=255 { + assert_eq!(n, next_ocno(&mut iter_ocyes.clone())); + assert_eq!(n, next_ocyes(&mut iter_ocyes)); + assert_eq!(n, next_ocyes(&mut iter_ocno.clone())); + assert_eq!(n, next_ocno(&mut iter_ocno)); + } + + // `iter_ocno` should have wrapped + assert_eq!(0, next_ocyes(&mut iter_ocno.clone())); + assert_eq!(0, next_ocno(&mut iter_ocno)); + // `iter_ocyes` should be exhausted, + // which will wrap when called without overflow-checks + assert_eq!(0, next_ocno(&mut iter_ocyes.clone())); + // and panic when called with overflow-checks + let r = std::panic::catch_unwind(move || { + let _ = next_ocyes(&mut iter_ocyes); + }); + assert!(r.is_err()); +}
diff --git a/tests/ui/iterators/rangefrom-overflow-debug.rs b/tests/ui/iterators/rangefrom-overflow-debug.rs index 9a1bc69..7eafbad 100644 --- a/tests/ui/iterators/rangefrom-overflow-debug.rs +++ b/tests/ui/iterators/rangefrom-overflow-debug.rs
@@ -2,7 +2,7 @@ //@ needs-unwind //@ compile-flags: -O -C debug_assertions=yes -#![feature(new_range_api)] +#![feature(new_range_remainder)] use std::panic;
diff --git a/tests/ui/iterators/rangefrom-overflow-ndebug.rs b/tests/ui/iterators/rangefrom-overflow-ndebug.rs index 4ce9b06..f1a6301 100644 --- a/tests/ui/iterators/rangefrom-overflow-ndebug.rs +++ b/tests/ui/iterators/rangefrom-overflow-ndebug.rs
@@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -O -C debug_assertions=no -#![feature(new_range_api)] +#![feature(new_range_remainder)] fn main() { let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter();
diff --git a/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs b/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs index 7e3b0fc..af432af 100644 --- a/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs +++ b/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs
@@ -2,7 +2,7 @@ //@ needs-unwind //@ compile-flags: -O -C overflow-checks=yes -#![feature(new_range_api)] +#![feature(new_range_remainder)] use std::panic;
diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.rs b/tests/ui/layout/gce-rigid-const-in-array-len.rs index 8e57907..d8cc415 100644 --- a/tests/ui/layout/gce-rigid-const-in-array-len.rs +++ b/tests/ui/layout/gce-rigid-const-in-array-len.rs
@@ -12,7 +12,7 @@ //! constant. #![feature(rustc_attrs)] -#![feature(generic_const_exprs)] //~ WARNING: the feature `generic_const_exprs` is incomplete +#![feature(generic_const_exprs)] #![feature(trivial_bounds)] #![crate_type = "lib"]
diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.stderr b/tests/ui/layout/gce-rigid-const-in-array-len.stderr index 6149deb..9038563 100644 --- a/tests/ui/layout/gce-rigid-const-in-array-len.stderr +++ b/tests/ui/layout/gce-rigid-const-in-array-len.stderr
@@ -1,17 +1,8 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/gce-rigid-const-in-array-len.rs:15:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error: the type `[u8; <u8 as A>::B]` has an unknown layout --> $DIR/gce-rigid-const-in-array-len.rs:25:1 | LL | struct S([u8; <u8 as A>::B]) | ^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs index 6ded911..e9e7de8 100644 --- a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs
@@ -1,7 +1,6 @@ // regression test for #127351 #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete type ExplicitTypeOutlives<T> = T;
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr index 3a5ded6..7aa34a2 100644 --- a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr
@@ -1,20 +1,11 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-lazy-type-alias.rs:3:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0107]: missing generics for type alias `ExplicitTypeOutlives` - --> $DIR/bad-lazy-type-alias.rs:9:24 + --> $DIR/bad-lazy-type-alias.rs:8:24 | LL | _significant_drop: ExplicitTypeOutlives, | ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument | note: type alias defined here, with 1 generic parameter: `T` - --> $DIR/bad-lazy-type-alias.rs:6:6 + --> $DIR/bad-lazy-type-alias.rs:5:6 | LL | type ExplicitTypeOutlives<T> = T; | ^^^^^^^^^^^^^^^^^^^^ - @@ -23,6 +14,6 @@ LL | _significant_drop: ExplicitTypeOutlives<T>, | +++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr b/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr deleted file mode 100644 index 78dd05b..0000000 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-behind-lazy.rs:6:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr b/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr deleted file mode 100644 index 78dd05b..0000000 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-behind-lazy.rs:6:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs index 7873ff4..a69e39b 100644 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs +++ b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs
@@ -4,7 +4,6 @@ //@[next] compile-flags: -Znext-solver #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete use std::any::Any;
diff --git a/tests/ui/lazy-type-alias/enum-variant.rs b/tests/ui/lazy-type-alias/enum-variant.rs index d9b7dff..236e193 100644 --- a/tests/ui/lazy-type-alias/enum-variant.rs +++ b/tests/ui/lazy-type-alias/enum-variant.rs
@@ -2,7 +2,6 @@ //@ check-pass #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete and may not be safe to use enum Enum { Unit,
diff --git a/tests/ui/lazy-type-alias/enum-variant.stderr b/tests/ui/lazy-type-alias/enum-variant.stderr deleted file mode 100644 index 4360db9..0000000 --- a/tests/ui/lazy-type-alias/enum-variant.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/enum-variant.rs:4:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/lazy-type-alias/trailing-where-clause.stderr b/tests/ui/lazy-type-alias/trailing-where-clause.stderr index 93cd314..170bc3b 100644 --- a/tests/ui/lazy-type-alias/trailing-where-clause.stderr +++ b/tests/ui/lazy-type-alias/trailing-where-clause.stderr
@@ -4,13 +4,13 @@ LL | let _: Alias<()>; | ^^ the trait `From<()>` is not implemented for `String` | - = help: the following other types implement trait `From<T>`: - `String` implements `From<&String>` - `String` implements `From<&mut str>` - `String` implements `From<&str>` - `String` implements `From<Box<str>>` - `String` implements `From<Cow<'_, str>>` - `String` implements `From<char>` + = help: `String` implements trait `From<T>`: + From<&String> + From<&mut str> + From<&str> + From<Box<str>> + From<Cow<'_, str>> + From<char> note: required by a bound in `Alias` --> $DIR/trailing-where-clause.rs:8:13 |
diff --git a/tests/ui/let-else/let-else-no-double-error.rs b/tests/ui/let-else/let-else-no-double-error.rs index 91fcc5d..7b69559 100644 --- a/tests/ui/let-else/let-else-no-double-error.rs +++ b/tests/ui/let-else/let-else-no-double-error.rs
@@ -8,5 +8,5 @@ fn main() { let foo = 22; - let u32::XXX = foo else { return }; //~ ERROR: no associated item named `XXX` found for type `u32` in the current scope [E0599] + let u32::XXX = foo else { return }; //~ ERROR: no associated function or constant named `XXX` found for type `u32` in the current scope [E0599] }
diff --git a/tests/ui/let-else/let-else-no-double-error.stderr b/tests/ui/let-else/let-else-no-double-error.stderr index 05668a23..4fd6a14 100644 --- a/tests/ui/let-else/let-else-no-double-error.stderr +++ b/tests/ui/let-else/let-else-no-double-error.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `XXX` found for type `u32` in the current scope +error[E0599]: no associated function or constant named `XXX` found for type `u32` in the current scope --> $DIR/let-else-no-double-error.rs:11:14 | LL | let u32::XXX = foo else { return }; - | ^^^ associated item not found in `u32` + | ^^^ associated function or constant not found in `u32` error: aborting due to 1 previous error
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.fixed b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.fixed new file mode 100644 index 0000000..cd5cda6 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.fixed
@@ -0,0 +1,19 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/154493> +//@ run-rustfix +#![deny(mismatched_lifetime_syntaxes)] +#![allow(unused)] + +struct Pair<'a, 'b>(&'a u8, &'b u8); + +macro_rules! repeated { + ($($pair:ident),+ ; $middle:ty) => { + ($($pair<'a, 'a>),+, $middle, $($pair<'a, 'a>),+) + //~^ ERROR hiding or eliding a lifetime that's named elsewhere is confusing + }; +} + +fn repeated_macro<'a>(x: &'a u8) -> repeated!(Pair, Pair; &'a u8) { + (Pair(x, x), Pair(x, x), x, Pair(x, x), Pair(x, x)) +} + +fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.rs new file mode 100644 index 0000000..8e8b6d9 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.rs
@@ -0,0 +1,19 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/154493> +//@ run-rustfix +#![deny(mismatched_lifetime_syntaxes)] +#![allow(unused)] + +struct Pair<'a, 'b>(&'a u8, &'b u8); + +macro_rules! repeated { + ($($pair:ident),+ ; $middle:ty) => { + ($($pair),+, $middle, $($pair),+) + //~^ ERROR hiding or eliding a lifetime that's named elsewhere is confusing + }; +} + +fn repeated_macro<'a>(x: &'a u8) -> repeated!(Pair, Pair; &'_ u8) { + (Pair(x, x), Pair(x, x), x, Pair(x, x), Pair(x, x)) +} + +fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.stderr new file mode 100644 index 0000000..5412c94 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/macro.stderr
@@ -0,0 +1,33 @@ +error: hiding or eliding a lifetime that's named elsewhere is confusing + --> $DIR/macro.rs:10:12 + | +LL | ($($pair),+, $middle, $($pair),+) + | ^^^^^ ^^^^^ the same lifetimes are hidden here + | | + | the same lifetimes are hidden here +... +LL | fn repeated_macro<'a>(x: &'a u8) -> repeated!(Pair, Pair; &'_ u8) { + | -- -----------------------^^---- + | | | | + | | | the same lifetime is elided here + | | in this macro invocation + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +note: the lint level is defined here + --> $DIR/macro.rs:3:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `repeated` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consistently use `'a` + | +LL ~ ($($pair<'a, 'a>),+, $middle, $($pair<'a, 'a>),+) +LL | +... +LL | +LL ~ fn repeated_macro<'a>(x: &'a u8) -> repeated!(Pair, Pair; &'a u8) { + | + +error: aborting due to 1 previous error +
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/mismatched-lifetime-syntaxes.rs similarity index 100% rename from tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs rename to tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/mismatched-lifetime-syntaxes.rs
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/mismatched-lifetime-syntaxes.stderr similarity index 100% rename from tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr rename to tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/mismatched-lifetime-syntaxes.stderr
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.fixed b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.fixed new file mode 100644 index 0000000..5689eed --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.fixed
@@ -0,0 +1,69 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/154493> +//@ run-rustfix +#![deny(mismatched_lifetime_syntaxes)] +#![allow(unused)] + +struct Foo<'a, 'b> { + ptr1: &'a str, + ptr2: &'b str, +} + +// with generic +struct Bar<'a, 'b, T> { + ptr1: &'a T, + ptr2: &'b T, +} + +struct Wrapper<T>(T); + +fn missing(_: &str) -> Foo<'_, '_> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn missing_double(_: &str) -> (Foo<'_, '_>, Foo<'_, '_>) { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn empty(_: &str) -> Foo<'_, '_> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn wrapper_missing(_: &str) -> Wrapper<Foo<'_, '_>> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn missing_generic(_: &str) -> Bar<'_, '_, u8> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn named_missing<'a>(_: &'a u8) -> Foo<'a, 'a> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn named_empty<'a>(_: &'a u8) -> Foo<'a, 'a> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_missing(_: &'static u8) -> Foo<'static, 'static> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_empty(_: &'static u8) -> Foo<'static, 'static> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_missing_generic(_: &'static str) -> Bar<'static, 'static, u8> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.rs new file mode 100644 index 0000000..3c12600 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.rs
@@ -0,0 +1,69 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/154493> +//@ run-rustfix +#![deny(mismatched_lifetime_syntaxes)] +#![allow(unused)] + +struct Foo<'a, 'b> { + ptr1: &'a str, + ptr2: &'b str, +} + +// with generic +struct Bar<'a, 'b, T> { + ptr1: &'a T, + ptr2: &'b T, +} + +struct Wrapper<T>(T); + +fn missing(_: &str) -> Foo { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn missing_double(_: &str) -> (Foo, Foo) { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn empty(_: &str) -> Foo<> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn wrapper_missing(_: &str) -> Wrapper<Foo> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn missing_generic(_: &str) -> Bar<u8> { + //~^ ERROR: hiding a lifetime that's elided elsewhere is confusing + todo!() +} + +fn named_missing<'a>(_: &'a u8) -> Foo { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn named_empty<'a>(_: &'a u8) -> Foo<> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_missing(_: &'static u8) -> Foo { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_empty(_: &'static u8) -> Foo<> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn static_missing_generic(_: &'static str) -> Bar<u8> { + //~^ ERROR: hiding a lifetime that's named elsewhere is confusing + todo!() +} + +fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.stderr new file mode 100644 index 0000000..45e135b --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/path-count.stderr
@@ -0,0 +1,148 @@ +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/path-count.rs:19:15 + | +LL | fn missing(_: &str) -> Foo { + | ^^^^ ^^^ the same lifetimes are hidden here + | | + | the lifetime is elided here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +note: the lint level is defined here + --> $DIR/path-count.rs:3:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use `'_` for type paths + | +LL | fn missing(_: &str) -> Foo<'_, '_> { + | ++++++++ + +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/path-count.rs:24:22 + | +LL | fn missing_double(_: &str) -> (Foo, Foo) { + | ^^^^ ^^^ ^^^ the same lifetimes are hidden here + | | | + | | the same lifetimes are hidden here + | the lifetime is elided here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths + | +LL | fn missing_double(_: &str) -> (Foo<'_, '_>, Foo<'_, '_>) { + | ++++++++ ++++++++ + +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/path-count.rs:29:13 + | +LL | fn empty(_: &str) -> Foo<> { + | ^^^^ ^^^^^ the same lifetimes are hidden here + | | + | the lifetime is elided here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths + | +LL | fn empty(_: &str) -> Foo<'_, '_> { + | ++++++ + +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/path-count.rs:34:23 + | +LL | fn wrapper_missing(_: &str) -> Wrapper<Foo> { + | ^^^^ ^^^ the same lifetimes are hidden here + | | + | the lifetime is elided here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths + | +LL | fn wrapper_missing(_: &str) -> Wrapper<Foo<'_, '_>> { + | ++++++++ + +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/path-count.rs:39:23 + | +LL | fn missing_generic(_: &str) -> Bar<u8> { + | ^^^^ ^^^^^^^ the same lifetimes are hidden here + | | + | the lifetime is elided here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths + | +LL | fn missing_generic(_: &str) -> Bar<'_, '_, u8> { + | +++++++ + +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/path-count.rs:44:36 + | +LL | fn named_missing<'a>(_: &'a u8) -> Foo { + | -- ^^^ the same lifetimes are hidden here + | | + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` + | +LL | fn named_missing<'a>(_: &'a u8) -> Foo<'a, 'a> { + | ++++++++ + +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/path-count.rs:49:34 + | +LL | fn named_empty<'a>(_: &'a u8) -> Foo<> { + | -- ^^^^^ the same lifetimes are hidden here + | | + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` + | +LL | fn named_empty<'a>(_: &'a u8) -> Foo<'a, 'a> { + | ++++++ + +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/path-count.rs:54:38 + | +LL | fn static_missing(_: &'static u8) -> Foo { + | ------- ^^^ the same lifetimes are hidden here + | | + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` + | +LL | fn static_missing(_: &'static u8) -> Foo<'static, 'static> { + | ++++++++++++++++++ + +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/path-count.rs:59:36 + | +LL | fn static_empty(_: &'static u8) -> Foo<> { + | ------- ^^^^^ the same lifetimes are hidden here + | | + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` + | +LL | fn static_empty(_: &'static u8) -> Foo<'static, 'static> { + | ++++++++++++++++ + +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/path-count.rs:64:47 + | +LL | fn static_missing_generic(_: &'static str) -> Bar<u8> { + | ------- ^^^^^^^ the same lifetimes are hidden here + | | + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` + | +LL | fn static_missing_generic(_: &'static str) -> Bar<'static, 'static, u8> { + | +++++++++++++++++ + +error: aborting due to 10 previous errors +
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs index f5fb164..d9251f6 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs
@@ -1,11 +1,11 @@ //@ only-windows #[link(name = "foo", kind = "raw-dylib")] extern "C" { - #[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes - #[link_ordinal(2)] + #[link_ordinal(1)] + #[link_ordinal(2)] //~ ERROR multiple `link_ordinal` attributes fn foo(); - #[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes - #[link_ordinal(2)] + #[link_ordinal(1)] + #[link_ordinal(2)] //~ ERROR multiple `link_ordinal` attributes static mut imported_variable: i32; }
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr index 2e6cf37..26d7351 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr
@@ -1,25 +1,25 @@ error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:4:5 - | -LL | #[link_ordinal(1)] - | ^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here --> $DIR/link-ordinal-multiple.rs:5:5 | LL | #[link_ordinal(2)] - | ^^^^^^^^^^^^^^^^^^ - -error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:7:5 - | -LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here + --> $DIR/link-ordinal-multiple.rs:4:5 + | +LL | #[link_ordinal(1)] + | ^^^^^^^^^^^^^^^^^^ + +error: multiple `link_ordinal` attributes --> $DIR/link-ordinal-multiple.rs:8:5 | LL | #[link_ordinal(2)] + | ^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/link-ordinal-multiple.rs:7:5 + | +LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors
diff --git a/tests/ui/lint/dead-code/const-underscore-issue-101532.rs b/tests/ui/lint/dead-code/const-underscore-issue-101532.rs new file mode 100644 index 0000000..4dc25fb --- /dev/null +++ b/tests/ui/lint/dead-code/const-underscore-issue-101532.rs
@@ -0,0 +1,14 @@ +//@ check-pass +// Test for issue #101532 - dead code warnings should work inside const _ + +#![warn(dead_code)] + +const _: () = { + let a: (); + struct B {} //~ WARN struct `B` is never constructed + enum C {} //~ WARN enum `C` is never used + fn d() {} //~ WARN function `d` is never used + const E: () = {}; //~ WARN constant `E` is never used +}; + +fn main() {}
diff --git a/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr b/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr new file mode 100644 index 0000000..d330b9e --- /dev/null +++ b/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr
@@ -0,0 +1,32 @@ +warning: struct `B` is never constructed + --> $DIR/const-underscore-issue-101532.rs:8:12 + | +LL | struct B {} + | ^ + | +note: the lint level is defined here + --> $DIR/const-underscore-issue-101532.rs:4:9 + | +LL | #![warn(dead_code)] + | ^^^^^^^^^ + +warning: enum `C` is never used + --> $DIR/const-underscore-issue-101532.rs:9:10 + | +LL | enum C {} + | ^ + +warning: function `d` is never used + --> $DIR/const-underscore-issue-101532.rs:10:8 + | +LL | fn d() {} + | ^ + +warning: constant `E` is never used + --> $DIR/const-underscore-issue-101532.rs:11:11 + | +LL | const E: () = {}; + | ^ + +warning: 4 warnings emitted +
diff --git a/tests/ui/lint/inline-trait-and-foreign-items.stderr b/tests/ui/lint/inline-trait-and-foreign-items.stderr index 4bde4bc..b12fa4d 100644 --- a/tests/ui/lint/inline-trait-and-foreign-items.stderr +++ b/tests/ui/lint/inline-trait-and-foreign-items.stderr
@@ -38,14 +38,6 @@ | = help: `#[inline]` can only be applied to functions -error: unconstrained opaque type - --> $DIR/inline-trait-and-foreign-items.rs:26:14 - | -LL | type U = impl Trait; - | ^^^^^^^^^^ - | - = note: `U` must be used in combination with a concrete type within the same impl - warning: `#[inline]` attribute cannot be used on associated consts --> $DIR/inline-trait-and-foreign-items.rs:7:5 | @@ -69,5 +61,13 @@ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[inline]` can only be applied to functions +error: unconstrained opaque type + --> $DIR/inline-trait-and-foreign-items.rs:26:14 + | +LL | type U = impl Trait; + | ^^^^^^^^^^ + | + = note: `U` must be used in combination with a concrete type within the same impl + error: aborting due to 6 previous errors; 2 warnings emitted
diff --git a/tests/ui/lint/unused/unused-assign-148960.stderr b/tests/ui/lint/unused/unused-assign-148960.stderr index 0e23fab..aa5326c 100644 --- a/tests/ui/lint/unused/unused-assign-148960.stderr +++ b/tests/ui/lint/unused/unused-assign-148960.stderr
@@ -2,9 +2,10 @@ --> $DIR/unused-assign-148960.rs:6:21 | LL | let mut value = b"0".to_vec(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ this value is reassigned later and never used +LL | value = b"1".to_vec(); + | ----- `value` is overwritten here before the previous value is read | - = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/unused-assign-148960.rs:2:9 | @@ -16,25 +17,25 @@ --> $DIR/unused-assign-148960.rs:12:17 | LL | let mut x = 1; - | ^ - | - = help: maybe it is overwritten before being read? + | ^ this value is reassigned later and never used +LL | x = 2; + | ----- `x` is overwritten here before the previous value is read error: value assigned to `x` is never read --> $DIR/unused-assign-148960.rs:13:5 | LL | x = 2; - | ^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^ this value is reassigned later and never used +LL | x = 3; + | ----- `x` is overwritten here before the previous value is read error: value assigned to `p` is never read --> $DIR/unused-assign-148960.rs:24:17 | LL | let mut p = Point { x: 1, y: 1 }; - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | p = Point { x: 2, y: 2 }; + | ------------------------ `p` is overwritten here before the previous value is read error: variable `foo` is assigned to, but never used --> $DIR/unused-assign-148960.rs:38:9
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs index a334c49..2b29fde 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.rs +++ b/tests/ui/lint/unused/unused-attr-duplicate.rs
@@ -61,7 +61,7 @@ macro_rules! foo { fn t1() {} #[must_use] -#[must_use = "some message"] //~ ERROR unused attribute +#[must_use = "some message"] //~ ERROR unused attribute //~^ WARN this was previously accepted // No warnings for #[repr], would require more logic. #[repr(C)] @@ -89,15 +89,15 @@ pub fn xyz() {} #[link(name = "rust_test_helpers", kind = "static")] #[link(name = "rust_test_helpers", kind = "static")] extern "C" { - #[link_name = "this_does_not_exist"] //~ ERROR unused attribute + #[link_name = "this_does_not_exist"] + #[link_name = "rust_dbg_extern_identity_u32"] //~ ERROR unused attribute //~^ WARN this was previously accepted - #[link_name = "rust_dbg_extern_identity_u32"] pub fn name_in_rust(v: u32) -> u32; } -#[export_name = "exported_symbol_name"] //~ ERROR unused attribute +#[export_name = "exported_symbol_name"] +#[export_name = "exported_symbol_name2"] //~ ERROR unused attribute //~^ WARN this was previously accepted -#[export_name = "exported_symbol_name2"] pub fn export_test() {} #[no_mangle] @@ -109,9 +109,9 @@ pub fn no_mangle_test() {} static FOO: u32 = 0; #[link_section = ".text"] +#[link_section = ".bss"] //~^ ERROR unused attribute //~| WARN this was previously accepted -#[link_section = ".bss"] pub extern "C" fn example() {} fn main() {}
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 351645f..1942249 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr
@@ -165,29 +165,29 @@ | ^^^^^^^^^^^^^^^ error: unused attribute + --> $DIR/unused-attr-duplicate.rs:93:5 + | +LL | #[link_name = "rust_dbg_extern_identity_u32"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here --> $DIR/unused-attr-duplicate.rs:92:5 | LL | #[link_name = "this_does_not_exist"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:94:5 - | -LL | #[link_name = "rust_dbg_extern_identity_u32"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute + --> $DIR/unused-attr-duplicate.rs:99:1 + | +LL | #[export_name = "exported_symbol_name2"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here --> $DIR/unused-attr-duplicate.rs:98:1 | LL | #[export_name = "exported_symbol_name"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:100:1 - | -LL | #[export_name = "exported_symbol_name2"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute @@ -215,16 +215,16 @@ | ^^^^^^^ error: unused attribute + --> $DIR/unused-attr-duplicate.rs:112:1 + | +LL | #[link_section = ".bss"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here --> $DIR/unused-attr-duplicate.rs:111:1 | LL | #[link_section = ".text"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:114:1 - | -LL | #[link_section = ".bss"] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute
diff --git a/tests/ui/liveness/liveness-consts.stderr b/tests/ui/liveness/liveness-consts.stderr index 2d2750f..6b4acf1 100644 --- a/tests/ui/liveness/liveness-consts.stderr +++ b/tests/ui/liveness/liveness-consts.stderr
@@ -44,17 +44,17 @@ --> $DIR/liveness-consts.rs:18:17 | LL | let mut b = 1; - | ^ - | - = help: maybe it is overwritten before being read? + | ^ this value is reassigned later and never used +LL | b += 1; + | ------ `b` is overwritten here before the previous value is read warning: value assigned to `b` is never read --> $DIR/liveness-consts.rs:19:5 | LL | b += 1; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | b = 42; + | ------ `b` is overwritten here before the previous value is read warning: unused variable: `z` --> $DIR/liveness-consts.rs:62:13
diff --git a/tests/ui/liveness/liveness-dead.stderr b/tests/ui/liveness/liveness-dead.stderr index 4f7dda4..ade0e04 100644 --- a/tests/ui/liveness/liveness-dead.stderr +++ b/tests/ui/liveness/liveness-dead.stderr
@@ -2,9 +2,10 @@ --> $DIR/liveness-dead.rs:9:24 | LL | let mut x: isize = 3; - | ^ + | ^ this value is reassigned later and never used +LL | x = 4; + | ----- `x` is overwritten here before the previous value is read | - = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness-dead.rs:2:9 |
diff --git a/tests/ui/liveness/liveness-unused.stderr b/tests/ui/liveness/liveness-unused.stderr index f56ca78..9f84c1c 100644 --- a/tests/ui/liveness/liveness-unused.stderr +++ b/tests/ui/liveness/liveness-unused.stderr
@@ -167,49 +167,55 @@ --> $DIR/liveness-unused.rs:183:5 | LL | a += b; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a -= c; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:185:5 | LL | a -= c; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a *= d; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:187:5 | LL | a *= d; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a /= e; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:189:5 | LL | a /= e; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a |= f; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:191:5 | LL | a |= f; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a &= g; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:193:5 | LL | a &= g; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a %= h; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:195:5 @@ -231,33 +237,37 @@ --> $DIR/liveness-unused.rs:229:5 | LL | a += b; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a -= c; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:231:5 | LL | a -= c; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a *= d; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:233:5 | LL | a *= d; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a /= e; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:235:5 | LL | a /= e; - | ^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^ this value is reassigned later and never used +LL | +LL | a %= f; + | ------ `a` is overwritten here before the previous value is read error: value assigned to `a` is never read --> $DIR/liveness-unused.rs:237:5
diff --git a/tests/ui/liveness/liveness-upvars.rs b/tests/ui/liveness/liveness-upvars.rs index be58b48..0e198f1 100644 --- a/tests/ui/liveness/liveness-upvars.rs +++ b/tests/ui/liveness/liveness-upvars.rs
@@ -98,7 +98,7 @@ pub fn g<T: Default>(mut v: T) { } pub fn h<T: Copy + Default + std::fmt::Debug>() { - let mut z = T::default(); + let mut z = T::default(); //~ WARN unused variable: `z` let _ = move |b| { loop { if b {
diff --git a/tests/ui/liveness/liveness-upvars.stderr b/tests/ui/liveness/liveness-upvars.stderr index cfed283..9f5a3de 100644 --- a/tests/ui/liveness/liveness-upvars.stderr +++ b/tests/ui/liveness/liveness-upvars.stderr
@@ -112,9 +112,10 @@ --> $DIR/liveness-upvars.rs:82:13 | LL | e = Some("e1"); - | ^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | +LL | e = Some("e2"); + | -------------- `e` is overwritten here before the previous value is read warning: value assigned to `e` is never read --> $DIR/liveness-upvars.rs:84:13 @@ -128,9 +129,9 @@ --> $DIR/liveness-upvars.rs:78:13 | LL | d = Some("d1"); - | ^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^^^ this value is reassigned later and never used +LL | d = Some("d2"); + | -------------- `d` is overwritten here before the previous value is read warning: value assigned to `v` is never read --> $DIR/liveness-upvars.rs:92:13 @@ -156,6 +157,14 @@ | = help: maybe it is overwritten before being read? +warning: unused variable: `z` + --> $DIR/liveness-upvars.rs:101:9 + | +LL | let mut z = T::default(); + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_z` + | + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + warning: value captured by `state` is never read --> $DIR/liveness-upvars.rs:131:9 | @@ -168,9 +177,10 @@ --> $DIR/liveness-upvars.rs:131:9 | LL | state = 4; - | ^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^ this value is reassigned later and never used +... +LL | state = 5; + | --------- `state` is overwritten here before the previous value is read warning: value assigned to `state` is never read --> $DIR/liveness-upvars.rs:134:9 @@ -184,17 +194,17 @@ --> $DIR/liveness-upvars.rs:143:9 | LL | s = 1; - | ^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^ this value is reassigned later and never used +LL | yield (s = 2); + | ------- `s` is overwritten here before the previous value is read warning: value assigned to `s` is never read --> $DIR/liveness-upvars.rs:145:9 | LL | s = yield (); - | ^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? + | ^^^^^^^^^^^^ this value is reassigned later and never used +LL | s = 3; + | ----- `s` is overwritten here before the previous value is read -warning: 24 warnings emitted +warning: 25 warnings emitted
diff --git a/tests/ui/lowering/issue-121108.stderr b/tests/ui/lowering/issue-121108.stderr index f68655a..e1aa153 100644 --- a/tests/ui/lowering/issue-121108.stderr +++ b/tests/ui/lowering/issue-121108.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | use std::ptr::addr_of; - | ------- the inner attribute doesn't annotate this import + | ---------------------- the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/issues/issue-44056.rs b/tests/ui/lto/lto-avx-target-feature.rs similarity index 72% rename from tests/ui/issues/issue-44056.rs rename to tests/ui/lto/lto-avx-target-feature.rs index 37d7b00..37a8ce6 100644 --- a/tests/ui/issues/issue-44056.rs +++ b/tests/ui/lto/lto-avx-target-feature.rs
@@ -1,3 +1,4 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/44056> //@ build-pass (FIXME(55996): should be run on targets supporting avx) //@ only-x86_64 //@ no-prefer-dynamic
diff --git a/tests/ui/issues/issue-51947.rs b/tests/ui/lto/lto-weak-merge-functions.rs similarity index 82% rename from tests/ui/issues/issue-51947.rs rename to tests/ui/lto/lto-weak-merge-functions.rs index eda48aa..bf16fbc 100644 --- a/tests/ui/issues/issue-51947.rs +++ b/tests/ui/lto/lto-weak-merge-functions.rs
@@ -1,3 +1,4 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/51947> //@ build-pass #![crate_type = "lib"]
diff --git a/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.rs b/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.rs new file mode 100644 index 0000000..5a6ef04 --- /dev/null +++ b/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.rs
@@ -0,0 +1,23 @@ +macro_rules! local_assert_ne { + ($left:expr, $right:expr $(,)?) => { + match (&$left, &$right) { + (left_val, right_val) => { + if *left_val == *right_val { + //~^ ERROR can't compare `[u8; 4]` with `&[u8; 4]` + panic!(); + } + } + } + }; +} + +fn main() { + let buf = [0_u8; 4]; + assert_ne!(buf, b"----"); + //~^ ERROR can't compare `[u8; 4]` with `&[u8; 4]` + + assert_eq!(buf, b"----"); + //~^ ERROR can't compare `[u8; 4]` with `&[u8; 4]` + + local_assert_ne!(buf, b"----"); +}
diff --git a/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.stderr b/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.stderr new file mode 100644 index 0000000..359deee --- /dev/null +++ b/tests/ui/macros/assert-ne-no-invalid-help-issue-146204.stderr
@@ -0,0 +1,55 @@ +error[E0277]: can't compare `[u8; 4]` with `&[u8; 4]` + --> $DIR/assert-ne-no-invalid-help-issue-146204.rs:16:5 + | +LL | assert_ne!(buf, b"----"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `[u8; 4] == &[u8; 4]` + | + = help: the trait `PartialEq<&[u8; 4]>` is not implemented for `[u8; 4]` + = help: the following other types implement trait `PartialEq<Rhs>`: + `&[T]` implements `PartialEq<Vec<U, A>>` + `&[T]` implements `PartialEq<[U; N]>` + `&[u8; N]` implements `PartialEq<ByteStr>` + `&[u8; N]` implements `PartialEq<ByteString>` + `&[u8]` implements `PartialEq<ByteStr>` + `&[u8]` implements `PartialEq<ByteString>` + `&mut [T]` implements `PartialEq<Vec<U, A>>` + `&mut [T]` implements `PartialEq<[U; N]>` + and 11 others + +error[E0277]: can't compare `[u8; 4]` with `&[u8; 4]` + --> $DIR/assert-ne-no-invalid-help-issue-146204.rs:19:5 + | +LL | assert_eq!(buf, b"----"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `[u8; 4] == &[u8; 4]` + | + = help: the trait `PartialEq<&[u8; 4]>` is not implemented for `[u8; 4]` + = help: the following other types implement trait `PartialEq<Rhs>`: + `&[T]` implements `PartialEq<Vec<U, A>>` + `&[T]` implements `PartialEq<[U; N]>` + `&[u8; N]` implements `PartialEq<ByteStr>` + `&[u8; N]` implements `PartialEq<ByteString>` + `&[u8]` implements `PartialEq<ByteStr>` + `&[u8]` implements `PartialEq<ByteString>` + `&mut [T]` implements `PartialEq<Vec<U, A>>` + `&mut [T]` implements `PartialEq<[U; N]>` + and 11 others + +error[E0277]: can't compare `[u8; 4]` with `&[u8; 4]` + --> $DIR/assert-ne-no-invalid-help-issue-146204.rs:5:30 + | +LL | if *left_val == *right_val { + | ^^ no implementation for `[u8; 4] == &[u8; 4]` +... +LL | local_assert_ne!(buf, b"----"); + | ------------------------------ in this macro invocation + | + = help: the trait `PartialEq<&[u8; 4]>` is not implemented for `[u8; 4]` + = note: this error originates in the macro `local_assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider dereferencing here + | +LL | if *left_val == **right_val { + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/macros/die-macro-2.rs b/tests/ui/macros/die-macro-2.rs deleted file mode 100644 index d802f18..0000000 --- a/tests/ui/macros/die-macro-2.rs +++ /dev/null
@@ -1,7 +0,0 @@ -//@ run-fail -//@ error-pattern:test -//@ needs-subprocess - -fn main() { - panic!("test"); -}
diff --git a/tests/ui/macros/die-macro-expr.rs b/tests/ui/macros/die-macro-expr.rs deleted file mode 100644 index f4fefb0..0000000 --- a/tests/ui/macros/die-macro-expr.rs +++ /dev/null
@@ -1,7 +0,0 @@ -//@ run-fail -//@ error-pattern:test -//@ needs-subprocess - -fn main() { - let __isize: isize = panic!("test"); -}
diff --git a/tests/ui/macros/die-macro-pure.rs b/tests/ui/macros/die-macro-pure.rs deleted file mode 100644 index d847877..0000000 --- a/tests/ui/macros/die-macro-pure.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-fail -//@ error-pattern:test -//@ needs-subprocess - -fn f() { - panic!("test"); -} - -fn main() { - f(); -}
diff --git a/tests/ui/macros/die-macro.rs b/tests/ui/macros/die-macro.rs deleted file mode 100644 index b717eed..0000000 --- a/tests/ui/macros/die-macro.rs +++ /dev/null
@@ -1,16 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -// Just testing that panic!() type checks in statement or expr - - -#![allow(unreachable_code)] - -fn f() { - panic!(); - - let _x: isize = panic!(); -} - -pub fn main() { - -}
diff --git a/tests/ui/macros/issue-2804.rs b/tests/ui/macros/issue-2804.rs index 0b6f948..9f45df4 100644 --- a/tests/ui/macros/issue-2804.rs +++ b/tests/ui/macros/issue-2804.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(non_camel_case_types)] #![allow(dead_code)]
diff --git a/tests/ui/macros/issue-33185.rs b/tests/ui/macros/issue-33185.rs index 8d7e305..5771b40 100644 --- a/tests/ui/macros/issue-33185.rs +++ b/tests/ui/macros/issue-33185.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #[macro_export]
diff --git a/tests/ui/macros/issue-40469.rs b/tests/ui/macros/issue-40469.rs index faa4c65..4529e44 100644 --- a/tests/ui/macros/issue-40469.rs +++ b/tests/ui/macros/issue-40469.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)]
diff --git a/tests/ui/macros/issue-40770.rs b/tests/ui/macros/issue-40770.rs index d90294a..028bd48 100644 --- a/tests/ui/macros/issue-40770.rs +++ b/tests/ui/macros/issue-40770.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(unused_macros)] macro_rules! m { ($e:expr) => {
diff --git a/tests/ui/macros/issue-6596-1.stderr b/tests/ui/macros/issue-6596-1.stderr index f20d673..cb66dcc 100644 --- a/tests/ui/macros/issue-6596-1.stderr +++ b/tests/ui/macros/issue-6596-1.stderr
@@ -2,11 +2,15 @@ --> $DIR/issue-6596-1.rs:3:9 | LL | $nonexistent - | ^^^^^^^^^^^^ expected expression + | ^----------- + | || + | |macro metavariable not found + | expected expression ... LL | e!(foo); | ------- in this macro invocation | + = note: available metavariable names are: $inp = note: this error originates in the macro `e` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error
diff --git a/tests/ui/macros/macro-attribute-expansion.rs b/tests/ui/macros/macro-attribute-expansion.rs index be682b3..255400e 100644 --- a/tests/ui/macros/macro-attribute-expansion.rs +++ b/tests/ui/macros/macro-attribute-expansion.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! descriptions { ($name:ident is $desc:expr) => { // Check that we will correctly expand attributes
diff --git a/tests/ui/macros/macro-attributes.rs b/tests/ui/macros/macro-attributes.rs index 976d2cb..a25ed2b 100644 --- a/tests/ui/macros/macro-attributes.rs +++ b/tests/ui/macros/macro-attributes.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! compiles_fine { (#[$at:meta]) => {
diff --git a/tests/ui/macros/macro-delimiter-significance.rs b/tests/ui/macros/macro-delimiter-significance.rs index 8b532e1..1947ecf 100644 --- a/tests/ui/macros/macro-delimiter-significance.rs +++ b/tests/ui/macros/macro-delimiter-significance.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass fn main() { vec![1_usize, 2, 3].len(); }
diff --git a/tests/ui/macros/macro-doc-comments.rs b/tests/ui/macros/macro-doc-comments.rs index 47740e2..4622c37 100644 --- a/tests/ui/macros/macro-doc-comments.rs +++ b/tests/ui/macros/macro-doc-comments.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(non_snake_case)] macro_rules! doc {
diff --git a/tests/ui/macros/macro-doc-escapes.rs b/tests/ui/macros/macro-doc-escapes.rs index 81c8d33..77d9a5c 100644 --- a/tests/ui/macros/macro-doc-escapes.rs +++ b/tests/ui/macros/macro-doc-escapes.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass // When expanding a macro, documentation attributes (including documentation comments) must be // passed "as is" without being parsed. Otherwise, some text will be incorrectly interpreted as // escape sequences, leading to an ICE.
diff --git a/tests/ui/macros/macro-follow-rpass.rs b/tests/ui/macros/macro-follow-rpass.rs index 8551b18..3103e86 100644 --- a/tests/ui/macros/macro-follow-rpass.rs +++ b/tests/ui/macros/macro-follow-rpass.rs
@@ -1,15 +1,16 @@ //@ edition:2015..2021 -//@ run-pass +//@ check-pass #![allow(unused_macros)] // Check the macro follow sets (see corresponding cfail test). -// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)} +// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), MetaVarDecl(Guard), Ident(in)} macro_rules! follow_pat { ($p:pat =>) => {}; ($p:pat ,) => {}; ($p:pat =) => {}; ($p:pat |) => {}; ($p:pat if) => {}; + ($p:pat if let) => {}; ($p:pat in) => {}; } // FOLLOW(expr) = {FatArrow, Comma, Semicolon}
diff --git a/tests/ui/macros/macro-follow.rs b/tests/ui/macros/macro-follow.rs index 923c9bd..874bad6 100644 --- a/tests/ui/macros/macro-follow.rs +++ b/tests/ui/macros/macro-follow.rs
@@ -2,9 +2,10 @@ // // Check the macro follow sets (see corresponding rpass test). +#![feature(macro_guard_matcher)] #![allow(unused_macros)] -// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)} +// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), MetaVarDecl(Guard), Ident(in)} macro_rules! follow_pat { ($p:pat ()) => {}; //~ERROR `$p:pat` is followed by `(` ($p:pat []) => {}; //~ERROR `$p:pat` is followed by `[` @@ -47,6 +48,7 @@ macro_rules! follow_expr { ($e:expr $t:tt) => {}; //~ERROR `$e:expr` is followed by `$t:tt` ($e:expr $i:item) => {}; //~ERROR `$e:expr` is followed by `$i:item` ($e:expr $m:meta) => {}; //~ERROR `$e:expr` is followed by `$m:meta` + ($e:expr $g:guard) => {}; //~ERROR `$e:expr` is followed by `$g:guard` } // FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or, // Ident(as), Ident(where), OpenDelim(Bracket), Nonterminal(Block)} @@ -66,6 +68,7 @@ macro_rules! follow_ty { ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt` ($t:ty $i:item) => {}; //~ERROR `$t:ty` is followed by `$i:item` ($t:ty $m:meta) => {}; //~ERROR `$t:ty` is followed by `$m:meta` + ($t:ty $g:guard) => {}; //~ERROR `$t:ty` is followed by `$g:guard` } // FOLLOW(stmt) = FOLLOW(expr) macro_rules! follow_stmt { @@ -90,6 +93,7 @@ macro_rules! follow_stmt { ($s:stmt $t:tt) => {}; //~ERROR `$s:stmt` is followed by `$t:tt` ($s:stmt $i:item) => {}; //~ERROR `$s:stmt` is followed by `$i:item` ($s:stmt $m:meta) => {}; //~ERROR `$s:stmt` is followed by `$m:meta` + ($s:stmt $g:guard) => {}; //~ERROR `$s:stmt` is followed by `$g:guard` } // FOLLOW(path) = FOLLOW(ty) macro_rules! follow_path { @@ -108,6 +112,7 @@ macro_rules! follow_path { ($p:path $t:tt) => {}; //~ERROR `$p:path` is followed by `$t:tt` ($p:path $i:item) => {}; //~ERROR `$p:path` is followed by `$i:item` ($p:path $m:meta) => {}; //~ERROR `$p:path` is followed by `$m:meta` + ($p:path $g:guard) => {}; //~ERROR `$p:path` is followed by `$g:guard` } // FOLLOW(block) = any token // FOLLOW(ident) = any token
diff --git a/tests/ui/macros/macro-follow.stderr b/tests/ui/macros/macro-follow.stderr index 92491dc..78d167a 100644 --- a/tests/ui/macros/macro-follow.stderr +++ b/tests/ui/macros/macro-follow.stderr
@@ -1,141 +1,141 @@ error: `$p:pat` is followed by `(`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:9:13 + --> $DIR/macro-follow.rs:10:13 | LL | ($p:pat ()) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `[`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:10:13 + --> $DIR/macro-follow.rs:11:13 | LL | ($p:pat []) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `{`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:11:13 + --> $DIR/macro-follow.rs:12:13 | LL | ($p:pat {}) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `:`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:12:13 + --> $DIR/macro-follow.rs:13:13 | LL | ($p:pat :) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `>`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:13:13 + --> $DIR/macro-follow.rs:14:13 | LL | ($p:pat >) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `+`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:14:13 + --> $DIR/macro-follow.rs:15:13 | LL | ($p:pat +) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `ident`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:15:13 + --> $DIR/macro-follow.rs:16:13 | LL | ($p:pat ident) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:16:13 + --> $DIR/macro-follow.rs:17:13 | LL | ($p:pat $q:pat) => {}; | ^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$e:expr`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:17:13 + --> $DIR/macro-follow.rs:18:13 | LL | ($p:pat $e:expr) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$t:ty`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:18:13 + --> $DIR/macro-follow.rs:19:13 | LL | ($p:pat $t:ty) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$s:stmt`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:19:13 + --> $DIR/macro-follow.rs:20:13 | LL | ($p:pat $s:stmt) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:20:13 + --> $DIR/macro-follow.rs:21:13 | LL | ($p:pat $q:path) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$b:block`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:21:13 + --> $DIR/macro-follow.rs:22:13 | LL | ($p:pat $b:block) => {}; | ^^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$i:ident`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:22:13 + --> $DIR/macro-follow.rs:23:13 | LL | ($p:pat $i:ident) => {}; | ^^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$t:tt`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:23:13 + --> $DIR/macro-follow.rs:24:13 | LL | ($p:pat $t:tt) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$i:item`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:24:13 + --> $DIR/macro-follow.rs:25:13 | LL | ($p:pat $i:item) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$p:pat` is followed by `$m:meta`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:25:13 + --> $DIR/macro-follow.rs:26:13 | LL | ($p:pat $m:meta) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$e:expr` is followed by `(`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:29:14 + --> $DIR/macro-follow.rs:30:14 | LL | ($e:expr ()) => {}; | ^ not allowed after `expr` fragments @@ -143,7 +143,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `[`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:30:14 + --> $DIR/macro-follow.rs:31:14 | LL | ($e:expr []) => {}; | ^ not allowed after `expr` fragments @@ -151,7 +151,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `{`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:31:14 + --> $DIR/macro-follow.rs:32:14 | LL | ($e:expr {}) => {}; | ^ not allowed after `expr` fragments @@ -159,7 +159,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `=`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:32:14 + --> $DIR/macro-follow.rs:33:14 | LL | ($e:expr =) => {}; | ^ not allowed after `expr` fragments @@ -167,7 +167,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `|`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:33:14 + --> $DIR/macro-follow.rs:34:14 | LL | ($e:expr |) => {}; | ^ not allowed after `expr` fragments @@ -175,7 +175,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `:`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:34:14 + --> $DIR/macro-follow.rs:35:14 | LL | ($e:expr :) => {}; | ^ not allowed after `expr` fragments @@ -183,7 +183,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `>`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:35:14 + --> $DIR/macro-follow.rs:36:14 | LL | ($e:expr >) => {}; | ^ not allowed after `expr` fragments @@ -191,7 +191,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:36:14 + --> $DIR/macro-follow.rs:37:14 | LL | ($e:expr +) => {}; | ^ not allowed after `expr` fragments @@ -199,7 +199,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `ident`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:37:14 + --> $DIR/macro-follow.rs:38:14 | LL | ($e:expr ident) => {}; | ^^^^^ not allowed after `expr` fragments @@ -207,7 +207,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `if`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:38:14 + --> $DIR/macro-follow.rs:39:14 | LL | ($e:expr if) => {}; | ^^ not allowed after `expr` fragments @@ -215,7 +215,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `in`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:39:14 + --> $DIR/macro-follow.rs:40:14 | LL | ($e:expr in) => {}; | ^^ not allowed after `expr` fragments @@ -223,7 +223,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$p:pat`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:40:14 + --> $DIR/macro-follow.rs:41:14 | LL | ($e:expr $p:pat) => {}; | ^^^^^^ not allowed after `expr` fragments @@ -231,7 +231,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:41:14 + --> $DIR/macro-follow.rs:42:14 | LL | ($e:expr $f:expr) => {}; | ^^^^^^^ not allowed after `expr` fragments @@ -239,7 +239,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$t:ty`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:42:14 + --> $DIR/macro-follow.rs:43:14 | LL | ($e:expr $t:ty) => {}; | ^^^^^ not allowed after `expr` fragments @@ -247,7 +247,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$s:stmt`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:43:14 + --> $DIR/macro-follow.rs:44:14 | LL | ($e:expr $s:stmt) => {}; | ^^^^^^^ not allowed after `expr` fragments @@ -255,7 +255,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$p:path`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:44:14 + --> $DIR/macro-follow.rs:45:14 | LL | ($e:expr $p:path) => {}; | ^^^^^^^ not allowed after `expr` fragments @@ -263,7 +263,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$b:block`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:45:14 + --> $DIR/macro-follow.rs:46:14 | LL | ($e:expr $b:block) => {}; | ^^^^^^^^ not allowed after `expr` fragments @@ -271,7 +271,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$i:ident`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:46:14 + --> $DIR/macro-follow.rs:47:14 | LL | ($e:expr $i:ident) => {}; | ^^^^^^^^ not allowed after `expr` fragments @@ -279,7 +279,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$t:tt`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:47:14 + --> $DIR/macro-follow.rs:48:14 | LL | ($e:expr $t:tt) => {}; | ^^^^^ not allowed after `expr` fragments @@ -287,7 +287,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$i:item`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:48:14 + --> $DIR/macro-follow.rs:49:14 | LL | ($e:expr $i:item) => {}; | ^^^^^^^ not allowed after `expr` fragments @@ -295,15 +295,23 @@ = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `$m:meta`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:49:14 + --> $DIR/macro-follow.rs:50:14 | LL | ($e:expr $m:meta) => {}; | ^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` +error: `$e:expr` is followed by `$g:guard`, which is not allowed for `expr` fragments + --> $DIR/macro-follow.rs:51:14 + | +LL | ($e:expr $g:guard) => {}; + | ^^^^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + error: `$t:ty` is followed by `(`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:54:12 + --> $DIR/macro-follow.rs:56:12 | LL | ($t:ty ()) => {}; | ^ not allowed after `ty` fragments @@ -311,7 +319,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `+`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:56:12 + --> $DIR/macro-follow.rs:58:12 | LL | ($t:ty +) => {}; | ^ not allowed after `ty` fragments @@ -319,7 +327,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `ident`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:57:12 + --> $DIR/macro-follow.rs:59:12 | LL | ($t:ty ident) => {}; | ^^^^^ not allowed after `ty` fragments @@ -327,7 +335,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `if`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:58:12 + --> $DIR/macro-follow.rs:60:12 | LL | ($t:ty if) => {}; | ^^ not allowed after `ty` fragments @@ -335,7 +343,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$p:pat`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:59:12 + --> $DIR/macro-follow.rs:61:12 | LL | ($t:ty $p:pat) => {}; | ^^^^^^ not allowed after `ty` fragments @@ -343,7 +351,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$e:expr`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:60:12 + --> $DIR/macro-follow.rs:62:12 | LL | ($t:ty $e:expr) => {}; | ^^^^^^^ not allowed after `ty` fragments @@ -351,7 +359,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:61:12 + --> $DIR/macro-follow.rs:63:12 | LL | ($t:ty $r:ty) => {}; | ^^^^^ not allowed after `ty` fragments @@ -359,7 +367,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$s:stmt`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:62:12 + --> $DIR/macro-follow.rs:64:12 | LL | ($t:ty $s:stmt) => {}; | ^^^^^^^ not allowed after `ty` fragments @@ -367,7 +375,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$p:path`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:63:12 + --> $DIR/macro-follow.rs:65:12 | LL | ($t:ty $p:path) => {}; | ^^^^^^^ not allowed after `ty` fragments @@ -375,7 +383,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$i:ident`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:65:12 + --> $DIR/macro-follow.rs:67:12 | LL | ($t:ty $i:ident) => {}; | ^^^^^^^^ not allowed after `ty` fragments @@ -383,7 +391,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:66:12 + --> $DIR/macro-follow.rs:68:12 | LL | ($t:ty $r:tt) => {}; | ^^^^^ not allowed after `ty` fragments @@ -391,7 +399,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$i:item`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:67:12 + --> $DIR/macro-follow.rs:69:12 | LL | ($t:ty $i:item) => {}; | ^^^^^^^ not allowed after `ty` fragments @@ -399,15 +407,23 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$t:ty` is followed by `$m:meta`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:68:12 + --> $DIR/macro-follow.rs:70:12 | LL | ($t:ty $m:meta) => {}; | ^^^^^^^ not allowed after `ty` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` +error: `$t:ty` is followed by `$g:guard`, which is not allowed for `ty` fragments + --> $DIR/macro-follow.rs:71:12 + | +LL | ($t:ty $g:guard) => {}; + | ^^^^^^^^ not allowed after `ty` fragments + | + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + error: `$s:stmt` is followed by `(`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:72:14 + --> $DIR/macro-follow.rs:75:14 | LL | ($s:stmt ()) => {}; | ^ not allowed after `stmt` fragments @@ -415,7 +431,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `[`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:73:14 + --> $DIR/macro-follow.rs:76:14 | LL | ($s:stmt []) => {}; | ^ not allowed after `stmt` fragments @@ -423,7 +439,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `{`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:74:14 + --> $DIR/macro-follow.rs:77:14 | LL | ($s:stmt {}) => {}; | ^ not allowed after `stmt` fragments @@ -431,7 +447,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `=`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:75:14 + --> $DIR/macro-follow.rs:78:14 | LL | ($s:stmt =) => {}; | ^ not allowed after `stmt` fragments @@ -439,7 +455,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `|`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:76:14 + --> $DIR/macro-follow.rs:79:14 | LL | ($s:stmt |) => {}; | ^ not allowed after `stmt` fragments @@ -447,7 +463,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `:`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:77:14 + --> $DIR/macro-follow.rs:80:14 | LL | ($s:stmt :) => {}; | ^ not allowed after `stmt` fragments @@ -455,7 +471,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `>`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:78:14 + --> $DIR/macro-follow.rs:81:14 | LL | ($s:stmt >) => {}; | ^ not allowed after `stmt` fragments @@ -463,7 +479,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `+`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:79:14 + --> $DIR/macro-follow.rs:82:14 | LL | ($s:stmt +) => {}; | ^ not allowed after `stmt` fragments @@ -471,7 +487,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `ident`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:80:14 + --> $DIR/macro-follow.rs:83:14 | LL | ($s:stmt ident) => {}; | ^^^^^ not allowed after `stmt` fragments @@ -479,7 +495,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `if`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:81:14 + --> $DIR/macro-follow.rs:84:14 | LL | ($s:stmt if) => {}; | ^^ not allowed after `stmt` fragments @@ -487,7 +503,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `in`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:82:14 + --> $DIR/macro-follow.rs:85:14 | LL | ($s:stmt in) => {}; | ^^ not allowed after `stmt` fragments @@ -495,7 +511,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$p:pat`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:83:14 + --> $DIR/macro-follow.rs:86:14 | LL | ($s:stmt $p:pat) => {}; | ^^^^^^ not allowed after `stmt` fragments @@ -503,7 +519,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$e:expr`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:84:14 + --> $DIR/macro-follow.rs:87:14 | LL | ($s:stmt $e:expr) => {}; | ^^^^^^^ not allowed after `stmt` fragments @@ -511,7 +527,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$t:ty`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:85:14 + --> $DIR/macro-follow.rs:88:14 | LL | ($s:stmt $t:ty) => {}; | ^^^^^ not allowed after `stmt` fragments @@ -519,7 +535,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:86:14 + --> $DIR/macro-follow.rs:89:14 | LL | ($s:stmt $t:stmt) => {}; | ^^^^^^^ not allowed after `stmt` fragments @@ -527,7 +543,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$p:path`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:87:14 + --> $DIR/macro-follow.rs:90:14 | LL | ($s:stmt $p:path) => {}; | ^^^^^^^ not allowed after `stmt` fragments @@ -535,7 +551,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$b:block`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:88:14 + --> $DIR/macro-follow.rs:91:14 | LL | ($s:stmt $b:block) => {}; | ^^^^^^^^ not allowed after `stmt` fragments @@ -543,7 +559,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$i:ident`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:89:14 + --> $DIR/macro-follow.rs:92:14 | LL | ($s:stmt $i:ident) => {}; | ^^^^^^^^ not allowed after `stmt` fragments @@ -551,7 +567,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$t:tt`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:90:14 + --> $DIR/macro-follow.rs:93:14 | LL | ($s:stmt $t:tt) => {}; | ^^^^^ not allowed after `stmt` fragments @@ -559,7 +575,7 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$i:item`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:91:14 + --> $DIR/macro-follow.rs:94:14 | LL | ($s:stmt $i:item) => {}; | ^^^^^^^ not allowed after `stmt` fragments @@ -567,23 +583,31 @@ = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `$m:meta`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:92:14 + --> $DIR/macro-follow.rs:95:14 | LL | ($s:stmt $m:meta) => {}; | ^^^^^^^ not allowed after `stmt` fragments | = note: allowed there are: `=>`, `,` or `;` -error: `$p:path` is followed by `(`, which is not allowed for `path` fragments +error: `$s:stmt` is followed by `$g:guard`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:96:14 | +LL | ($s:stmt $g:guard) => {}; + | ^^^^^^^^ not allowed after `stmt` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$p:path` is followed by `(`, which is not allowed for `path` fragments + --> $DIR/macro-follow.rs:100:14 + | LL | ($p:path ()) => {}; | ^ not allowed after `path` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `+`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:98:14 + --> $DIR/macro-follow.rs:102:14 | LL | ($p:path +) => {}; | ^ not allowed after `path` fragments @@ -591,7 +615,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `ident`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:99:14 + --> $DIR/macro-follow.rs:103:14 | LL | ($p:path ident) => {}; | ^^^^^ not allowed after `path` fragments @@ -599,7 +623,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `if`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:100:14 + --> $DIR/macro-follow.rs:104:14 | LL | ($p:path if) => {}; | ^^ not allowed after `path` fragments @@ -607,7 +631,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:101:14 + --> $DIR/macro-follow.rs:105:14 | LL | ($p:path $q:pat) => {}; | ^^^^^^ not allowed after `path` fragments @@ -615,7 +639,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$e:expr`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:102:14 + --> $DIR/macro-follow.rs:106:14 | LL | ($p:path $e:expr) => {}; | ^^^^^^^ not allowed after `path` fragments @@ -623,7 +647,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$t:ty`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:103:14 + --> $DIR/macro-follow.rs:107:14 | LL | ($p:path $t:ty) => {}; | ^^^^^ not allowed after `path` fragments @@ -631,7 +655,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$s:stmt`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:104:14 + --> $DIR/macro-follow.rs:108:14 | LL | ($p:path $s:stmt) => {}; | ^^^^^^^ not allowed after `path` fragments @@ -639,7 +663,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:105:14 + --> $DIR/macro-follow.rs:109:14 | LL | ($p:path $q:path) => {}; | ^^^^^^^ not allowed after `path` fragments @@ -647,7 +671,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$i:ident`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:107:14 + --> $DIR/macro-follow.rs:111:14 | LL | ($p:path $i:ident) => {}; | ^^^^^^^^ not allowed after `path` fragments @@ -655,7 +679,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$t:tt`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:108:14 + --> $DIR/macro-follow.rs:112:14 | LL | ($p:path $t:tt) => {}; | ^^^^^ not allowed after `path` fragments @@ -663,7 +687,7 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$i:item`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:109:14 + --> $DIR/macro-follow.rs:113:14 | LL | ($p:path $i:item) => {}; | ^^^^^^^ not allowed after `path` fragments @@ -671,12 +695,20 @@ = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$p:path` is followed by `$m:meta`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:110:14 + --> $DIR/macro-follow.rs:114:14 | LL | ($p:path $m:meta) => {}; | ^^^^^^^ not allowed after `path` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` -error: aborting due to 85 previous errors +error: `$p:path` is followed by `$g:guard`, which is not allowed for `path` fragments + --> $DIR/macro-follow.rs:115:14 + | +LL | ($p:path $g:guard) => {}; + | ^^^^^^^^ not allowed after `path` fragments + | + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + +error: aborting due to 89 previous errors
diff --git a/tests/ui/macros/macro-followed-by-seq.rs b/tests/ui/macros/macro-followed-by-seq.rs index f4756d4..3643836 100644 --- a/tests/ui/macros/macro-followed-by-seq.rs +++ b/tests/ui/macros/macro-followed-by-seq.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(unused_macros)] // Regression test for issue #25436: check that things which can be // followed by any token also permit X* to come afterwards.
diff --git a/tests/ui/macros/macro-guard-matcher.rs b/tests/ui/macros/macro-guard-matcher.rs new file mode 100644 index 0000000..81a4412 --- /dev/null +++ b/tests/ui/macros/macro-guard-matcher.rs
@@ -0,0 +1,17 @@ +#![feature(macro_guard_matcher)] + +fn main() { + macro_rules! m { + ($x:guard) => {}; + } + + // Accepts + m!(if true); + m!(if let Some(x) = Some(1)); + m!(if let Some(x) = Some(1) && x == 1); + m!(if let Some(x) = Some(Some(1)) && let Some(1) = x); + m!(if let Some(x) = Some(Some(1)) && let Some(y) = x && y == 1); + + // Rejects + m!(let Some(x) = Some(1)); //~ERROR no rules expected keyword `let` +}
diff --git a/tests/ui/macros/macro-guard-matcher.stderr b/tests/ui/macros/macro-guard-matcher.stderr new file mode 100644 index 0000000..eddb0de --- /dev/null +++ b/tests/ui/macros/macro-guard-matcher.stderr
@@ -0,0 +1,17 @@ +error: no rules expected keyword `let` + --> $DIR/macro-guard-matcher.rs:16:8 + | +LL | macro_rules! m { + | -------------- when calling this macro +... +LL | m!(let Some(x) = Some(1)); + | ^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$x:guard` + --> $DIR/macro-guard-matcher.rs:5:10 + | +LL | ($x:guard) => {}; + | ^^^^^^^^ + +error: aborting due to 1 previous error +
diff --git a/tests/ui/macros/macro-in-fn.rs b/tests/ui/macros/macro-in-fn.rs index 2ffa6b2..48085b8 100644 --- a/tests/ui/macros/macro-in-fn.rs +++ b/tests/ui/macros/macro-in-fn.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![feature(decl_macro)] pub fn moo() {
diff --git a/tests/ui/macros/macro-input-future-proofing.stderr b/tests/ui/macros/macro-input-future-proofing.stderr index 11960db..a12cc9f 100644 --- a/tests/ui/macros/macro-input-future-proofing.stderr +++ b/tests/ui/macros/macro-input-future-proofing.stderr
@@ -20,7 +20,7 @@ LL | ($pa:pat >) => (); | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$pa:pat` is followed by `$pb:pat`, which is not allowed for `pat` fragments --> $DIR/macro-input-future-proofing.rs:14:14 @@ -28,7 +28,7 @@ LL | ($pa:pat $pb:pat $ty:ty ,) => (); | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$pb:pat` is followed by `$ty:ty`, which is not allowed for `pat` fragments --> $DIR/macro-input-future-proofing.rs:14:22 @@ -36,7 +36,7 @@ LL | ($pa:pat $pb:pat $ty:ty ,) => (); | ^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, `if let` or `in` error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments --> $DIR/macro-input-future-proofing.rs:17:17
diff --git a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs index e80c712..ed8974c 100644 --- a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs +++ b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! four { () => (4)
diff --git a/tests/ui/macros/macro-multiple-items.rs b/tests/ui/macros/macro-multiple-items.rs index c746d1b..46b561af 100644 --- a/tests/ui/macros/macro-multiple-items.rs +++ b/tests/ui/macros/macro-multiple-items.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! make_foo { () => ( struct Foo;
diff --git a/tests/ui/macros/macro-named-default.rs b/tests/ui/macros/macro-named-default.rs index bca0e00..c7eac83 100644 --- a/tests/ui/macros/macro-named-default.rs +++ b/tests/ui/macros/macro-named-default.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! default { ($($x:tt)*) => { $($x)* } }
diff --git a/tests/ui/macros/macro-nt-list.rs b/tests/ui/macros/macro-nt-list.rs index b7b260c..56ea917 100644 --- a/tests/ui/macros/macro-nt-list.rs +++ b/tests/ui/macros/macro-nt-list.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! list { ( ($($id:ident),*) ) => (());
diff --git a/tests/ui/macros/macro-pat-follow-2018.rs b/tests/ui/macros/macro-pat-follow-2018.rs index 6dcb841..b2a556f 100644 --- a/tests/ui/macros/macro-pat-follow-2018.rs +++ b/tests/ui/macros/macro-pat-follow-2018.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ edition:2018 macro_rules! pat_bar {
diff --git a/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr b/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr index a06487b..9179fbc 100644 --- a/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr +++ b/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr
@@ -6,7 +6,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:4:32 @@ -16,7 +16,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:7:36 @@ -26,7 +26,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$pat:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: aborting due to 3 previous errors
diff --git a/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr b/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr index c3754dd..af76e3f 100644 --- a/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr +++ b/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr
@@ -6,7 +6,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat2021-pattern-followed-by-or.rs:7:28 @@ -16,7 +16,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat2021-pattern-followed-by-or.rs:9:35 @@ -26,7 +26,7 @@ | | | help: try a `pat_param` fragment specifier instead: `$pat:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, `if let` or `in` error: aborting due to 3 previous errors
diff --git a/tests/ui/macros/macro-pub-matcher.rs b/tests/ui/macros/macro-pub-matcher.rs index e0b03db..20cacab 100644 --- a/tests/ui/macros/macro-pub-matcher.rs +++ b/tests/ui/macros/macro-pub-matcher.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code, unused_imports, unused_macro_rules)] /**
diff --git a/tests/ui/macros/macro-seq-followed-by-seq.rs b/tests/ui/macros/macro-seq-followed-by-seq.rs index 3661744..cf5a1c1 100644 --- a/tests/ui/macros/macro-seq-followed-by-seq.rs +++ b/tests/ui/macros/macro-seq-followed-by-seq.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass // Test of allowing two sequences repetitions in a row, // functionality added as byproduct of RFC amendment #1384 // https://github.com/rust-lang/rfcs/pull/1384
diff --git a/tests/ui/macros/macro-use-all-and-none.rs b/tests/ui/macros/macro-use-all-and-none.rs index f1acff4..53d450e 100644 --- a/tests/ui/macros/macro-use-all-and-none.rs +++ b/tests/ui/macros/macro-use-all-and-none.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ aux-build:two_macros-rpass.rs #![warn(unused_attributes)]
diff --git a/tests/ui/macros/macro-use-all.rs b/tests/ui/macros/macro-use-all.rs index a7fd3df..06b96da 100644 --- a/tests/ui/macros/macro-use-all.rs +++ b/tests/ui/macros/macro-use-all.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ aux-build:two_macros.rs #[macro_use]
diff --git a/tests/ui/macros/macro-use-both.rs b/tests/ui/macros/macro-use-both.rs index e49f346..c417975 100644 --- a/tests/ui/macros/macro-use-both.rs +++ b/tests/ui/macros/macro-use-both.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ aux-build:two_macros.rs #[macro_use(macro_one, macro_two)]
diff --git a/tests/ui/macros/macro-use-one.rs b/tests/ui/macros/macro-use-one.rs index 2b04865..93f7c21 100644 --- a/tests/ui/macros/macro-use-one.rs +++ b/tests/ui/macros/macro-use-one.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ aux-build:two_macros.rs #[macro_use(macro_two)]
diff --git a/tests/ui/macros/panic-macro-basic.rs b/tests/ui/macros/panic-macro-basic.rs new file mode 100644 index 0000000..96ed426 --- /dev/null +++ b/tests/ui/macros/panic-macro-basic.rs
@@ -0,0 +1,14 @@ +//@ run-fail +//@ error-pattern:test +//@ needs-subprocess +// Just testing that panic!() type checks in statement or expr + +fn f() { + let __isize: isize = panic!("test"); + + panic!(); +} + +fn main() { + f(); +}
diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs index 2c384bd..bbb01fa 100644 --- a/tests/ui/macros/parse-complex-macro-invoc-op.rs +++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_assignments)]
diff --git a/tests/ui/macros/pub-item-inside-macro.rs b/tests/ui/macros/pub-item-inside-macro.rs index c37945a..679987a 100644 --- a/tests/ui/macros/pub-item-inside-macro.rs +++ b/tests/ui/macros/pub-item-inside-macro.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass // Issue #14660
diff --git a/tests/ui/macros/pub-method-inside-macro.rs b/tests/ui/macros/pub-method-inside-macro.rs index dd4e6fd..23d8c45 100644 --- a/tests/ui/macros/pub-method-inside-macro.rs +++ b/tests/ui/macros/pub-method-inside-macro.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass // Issue #17436
diff --git a/tests/ui/macros/semi-after-macro-ty.rs b/tests/ui/macros/semi-after-macro-ty.rs index 60afc3b..ff026c5 100644 --- a/tests/ui/macros/semi-after-macro-ty.rs +++ b/tests/ui/macros/semi-after-macro-ty.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass macro_rules! foo { ($t:ty; $p:path;) => {} }
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 3f331b0..af2ba7a 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs
@@ -14,6 +14,7 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![feature(macro_guard_matcher)] #![deny(unused_macros)] // These macros force the use of AST pretty-printing by converting the input to @@ -27,6 +28,7 @@ macro_rules! stmt { ($stmt:stmt) => { stringify!($stmt) }; } macro_rules! ty { ($ty:ty) => { stringify!($ty) }; } macro_rules! vis { ($vis:vis) => { stringify!($vis) }; } +macro_rules! guard { ($guard:guard) => { stringify!($guard) }; } macro_rules! c1 { ($frag:ident, [$($tt:tt)*], $s:literal) => { @@ -792,6 +794,21 @@ fn test_vis() { // Attributes are not allowed on visibilities. } +#[test] +fn test_guard() { + c1!(guard, [ if true ], "if true"); + c1!(guard, [ if let Some(x) = Some(1) ], "if let Some(x) = Some(1)"); + c1!(guard, [ if let Some(x) = Some(1) && x == 1 ], "if let Some(x) = Some(1) && x == 1"); + c1!(guard, + [ if let Some(x) = Some(Some(1)) && let Some(1) = x ], + "if let Some(x) = Some(Some(1)) && let Some(1) = x" + ); + c1!(guard, + [ if let Some(x) = Some(Some(1)) && let Some(y) = x && y == 1 ], + "if let Some(x) = Some(Some(1)) && let Some(y) = x && y == 1" + ); +} + macro_rules! p { ([$($tt:tt)*], $s:literal) => { assert_eq!(stringify!($($tt)*), $s);
diff --git a/tests/ui/macros/two-macro-use.rs b/tests/ui/macros/two-macro-use.rs index 8bb3c9d..733853f 100644 --- a/tests/ui/macros/two-macro-use.rs +++ b/tests/ui/macros/two-macro-use.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass //@ aux-build:two_macros.rs #[macro_use(macro_one)]
diff --git a/tests/ui/macros/type-macros-simple.rs b/tests/ui/macros/type-macros-simple.rs index d189b88..800a796 100644 --- a/tests/ui/macros/type-macros-simple.rs +++ b/tests/ui/macros/type-macros-simple.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(unused_variables)] #![allow(non_local_definitions)]
diff --git a/tests/ui/macros/typo-in-norepeat-expr-2.rs b/tests/ui/macros/typo-in-norepeat-expr-2.rs new file mode 100644 index 0000000..48b64c2 --- /dev/null +++ b/tests/ui/macros/typo-in-norepeat-expr-2.rs
@@ -0,0 +1,42 @@ +macro_rules! err { + (begin $follow:ident end $arg:expr) => { + [$arg] + }; + (begin1 $arg1:ident end $agr2:expr) => { + [$follow] //~ ERROR: expected expression, found `$` + //~^ NOTE: there is an macro metavariable with this name in another macro matcher + //~| NOTE: expected expression + }; +} + +macro_rules! err1 { + (begin $follow:ident end $arg:expr) => { + [$arg] + }; + (begin1 $arg1:ident end) => { + [$follo] //~ ERROR: expected expression, found `$` + //~| NOTE: expected expression + //~| HELP: there is a macro metavariable with a similar name in another macro matcher + }; +} + +macro_rules! err2 { + (begin $follow:ident end $arg:expr) => { + [$arg] + }; + (begin1 $arg1:ident end) => { + [$xyz] //~ ERROR: expected expression, found `$` + //~^ NOTE: expected expression + //~| NOTE available metavariable names are: $arg1 + //~| NOTE: macro metavariable not found + }; +} + +fn main () { + let _ = err![begin1 x end ig]; //~ NOTE: in this expansion of err! + let _ = err1![begin1 x end]; //~ NOTE: in this expansion of err1! + //~| NOTE: in this expansion of err1! + + let _ = err2![begin1 x end]; //~ NOTE: in this expansion of err2! + //~| NOTE in this expansion of err2! +}
diff --git a/tests/ui/macros/typo-in-norepeat-expr-2.stderr b/tests/ui/macros/typo-in-norepeat-expr-2.stderr new file mode 100644 index 0000000..20390cc --- /dev/null +++ b/tests/ui/macros/typo-in-norepeat-expr-2.stderr
@@ -0,0 +1,46 @@ +error: expected expression, found `$` + --> $DIR/typo-in-norepeat-expr-2.rs:6:10 + | +LL | [$follow] + | ^------ + | || + | |there is an macro metavariable with this name in another macro matcher + | expected expression +... +LL | let _ = err![begin1 x end ig]; + | ---------------------- in this macro invocation + | + = note: this error originates in the macro `err` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected expression, found `$` + --> $DIR/typo-in-norepeat-expr-2.rs:17:10 + | +LL | [$follo] + | ^^^^^^ expected expression +... +LL | let _ = err1![begin1 x end]; + | -------------------- in this macro invocation + | + = note: this error originates in the macro `err1` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a macro metavariable with a similar name in another macro matcher + | +LL | [$follow] + | + + +error: expected expression, found `$` + --> $DIR/typo-in-norepeat-expr-2.rs:28:10 + | +LL | [$xyz] + | ^--- + | || + | |macro metavariable not found + | expected expression +... +LL | let _ = err2![begin1 x end]; + | -------------------- in this macro invocation + | + = note: available metavariable names are: $arg1 + = note: this error originates in the macro `err2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors +
diff --git a/tests/ui/macros/typo-in-norepeat-expr.fixed b/tests/ui/macros/typo-in-norepeat-expr.fixed new file mode 100644 index 0000000..a59f461 --- /dev/null +++ b/tests/ui/macros/typo-in-norepeat-expr.fixed
@@ -0,0 +1,12 @@ +//@ run-rustfix +macro_rules! m { + (begin $ard:ident end) => { + [$ard] //~ ERROR: expected expression, found `$` + //~^ HELP: there is a macro metavariable with similar name + }; +} + +fn main() { + let x = 1; + let _ = m![begin x end]; +}
diff --git a/tests/ui/macros/typo-in-norepeat-expr.rs b/tests/ui/macros/typo-in-norepeat-expr.rs new file mode 100644 index 0000000..fe554f0 --- /dev/null +++ b/tests/ui/macros/typo-in-norepeat-expr.rs
@@ -0,0 +1,12 @@ +//@ run-rustfix +macro_rules! m { + (begin $ard:ident end) => { + [$arg] //~ ERROR: expected expression, found `$` + //~^ HELP: there is a macro metavariable with similar name + }; +} + +fn main() { + let x = 1; + let _ = m![begin x end]; +}
diff --git a/tests/ui/macros/typo-in-norepeat-expr.stderr b/tests/ui/macros/typo-in-norepeat-expr.stderr new file mode 100644 index 0000000..8f37957 --- /dev/null +++ b/tests/ui/macros/typo-in-norepeat-expr.stderr
@@ -0,0 +1,18 @@ +error: expected expression, found `$` + --> $DIR/typo-in-norepeat-expr.rs:4:10 + | +LL | [$arg] + | ^^^^ expected expression +... +LL | let _ = m![begin x end]; + | --------------- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a macro metavariable with similar name + | +LL - [$arg] +LL + [$ard] + | + +error: aborting due to 1 previous error +
diff --git a/tests/ui/macros/use-macro-self.rs b/tests/ui/macros/use-macro-self.rs index 1d15b83..cf5a410 100644 --- a/tests/ui/macros/use-macro-self.rs +++ b/tests/ui/macros/use-macro-self.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(unused_imports)] //@ aux-build:use-macro-self.rs
diff --git a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs index a9f0cda..cd2eaa5 100644 --- a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs +++ b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs
@@ -1,7 +1,7 @@ //@ run-pass #![feature(marker_trait_attr)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #[marker] trait MyMarker {}
diff --git a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr deleted file mode 100644 index 649e589..0000000 --- a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-doesnt-conflict-with-specialization.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/methods/ident-from-macro-expansion.rs b/tests/ui/methods/ident-from-macro-expansion.rs index 38d2fee..2bdf5fc 100644 --- a/tests/ui/methods/ident-from-macro-expansion.rs +++ b/tests/ui/methods/ident-from-macro-expansion.rs
@@ -14,5 +14,5 @@ fn main() { dot!(hello); //~^ ERROR no method named `hello` found for unit type `()` in the current scope dispatch!(hello); - //~^ ERROR no function or associated item named `hello` found for unit type `()` in the current scope + //~^ ERROR no associated function or constant named `hello` found for unit type `()` in the current scope }
diff --git a/tests/ui/methods/ident-from-macro-expansion.stderr b/tests/ui/methods/ident-from-macro-expansion.stderr index b596ce2..5fc8be8 100644 --- a/tests/ui/methods/ident-from-macro-expansion.stderr +++ b/tests/ui/methods/ident-from-macro-expansion.stderr
@@ -7,14 +7,14 @@ LL | dot!(hello); | ^^^^^ method not found in `()` -error[E0599]: no function or associated item named `hello` found for unit type `()` in the current scope +error[E0599]: no associated function or constant named `hello` found for unit type `()` in the current scope --> $DIR/ident-from-macro-expansion.rs:16:15 | LL | <()>::$id(); | --- due to this macro variable ... LL | dispatch!(hello); - | ^^^^^ function or associated item not found in `()` + | ^^^^^ associated function or constant not found in `()` error: aborting due to 2 previous errors
diff --git a/tests/ui/methods/issue-7950.rs b/tests/ui/methods/issue-7950.rs index d3dcb33..d87618a 100644 --- a/tests/ui/methods/issue-7950.rs +++ b/tests/ui/methods/issue-7950.rs
@@ -4,5 +4,5 @@ fn main() { Foo::bar(); - //~^ ERROR no function or associated item named `bar` found for struct `Foo` + //~^ ERROR no associated function or constant named `bar` found for struct `Foo` }
diff --git a/tests/ui/methods/issue-7950.stderr b/tests/ui/methods/issue-7950.stderr index 80504c0..84e6dfee 100644 --- a/tests/ui/methods/issue-7950.stderr +++ b/tests/ui/methods/issue-7950.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no function or associated item named `bar` found for struct `Foo` in the current scope +error[E0599]: no associated function or constant named `bar` found for struct `Foo` in the current scope --> $DIR/issue-7950.rs:6:10 | LL | struct Foo; - | ---------- function or associated item `bar` not found for this struct + | ---------- associated function or constant `bar` not found for this struct ... LL | Foo::bar(); - | ^^^ function or associated item not found in `Foo` + | ^^^ associated function or constant not found in `Foo` error: aborting due to 1 previous error
diff --git a/tests/ui/methods/missing-method-on-type-parameter.stderr b/tests/ui/methods/missing-method-on-type-parameter.stderr index 0b58fbf..0289904 100644 --- a/tests/ui/methods/missing-method-on-type-parameter.stderr +++ b/tests/ui/methods/missing-method-on-type-parameter.stderr
@@ -1,10 +1,10 @@ -error[E0599]: no function or associated item named `try_from` found for type parameter `T` in the current scope +error[E0599]: no associated function or constant named `try_from` found for type parameter `T` in the current scope --> $DIR/missing-method-on-type-parameter.rs:4:8 | LL | fn x<T: Copy>() { - | - function or associated item `try_from` not found for this type parameter + | - associated function or constant `try_from` not found for this type parameter LL | T::try_from(); - | ^^^^^^^^ function or associated item not found in `T` + | ^^^^^^^^ associated function or constant not found in `T` | = help: items from traits can only be used if the trait is in scope help: there is an associated function `from` with a similar name
diff --git a/tests/ui/methods/receiver-equality.rs b/tests/ui/methods/receiver-equality.rs index 891435a..d409edc 100644 --- a/tests/ui/methods/receiver-equality.rs +++ b/tests/ui/methods/receiver-equality.rs
@@ -10,7 +10,7 @@ fn method(self) { fn foo(y: B<fn(&'static ())>) { B::<for<'a> fn(&'a ())>::method(y); - //~^ ERROR no function or associated item named `method` found + //~^ ERROR no associated function or constant named `method` found } fn main() {}
diff --git a/tests/ui/methods/receiver-equality.stderr b/tests/ui/methods/receiver-equality.stderr index bf149cc..9dd4d71 100644 --- a/tests/ui/methods/receiver-equality.stderr +++ b/tests/ui/methods/receiver-equality.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no function or associated item named `method` found for struct `B<for<'a> fn(&'a ())>` in the current scope +error[E0599]: no associated function or constant named `method` found for struct `B<for<'a> fn(&'a ())>` in the current scope --> $DIR/receiver-equality.rs:12:30 | LL | struct B<T>(T); - | ----------- function or associated item `method` not found for this struct + | ----------- associated function or constant `method` not found for this struct ... LL | B::<for<'a> fn(&'a ())>::method(y); - | ^^^^^^ function or associated item not found in `B<for<'a> fn(&'a ())>` + | ^^^^^^ associated function or constant not found in `B<for<'a> fn(&'a ())>` error: aborting due to 1 previous error
diff --git a/tests/ui/methods/rigid-alias-bound-is-not-inherent.next.stderr b/tests/ui/methods/rigid-alias-bound-is-not-inherent.next.stderr index 4652bf5..afacb3a 100644 --- a/tests/ui/methods/rigid-alias-bound-is-not-inherent.next.stderr +++ b/tests/ui/methods/rigid-alias-bound-is-not-inherent.next.stderr
@@ -9,7 +9,7 @@ | LL | fn method(&self) { | ^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Trait2` for the type `T` +note: candidate #2 is defined in the trait `Trait2` --> $DIR/rigid-alias-bound-is-not-inherent.rs:27:5 | LL | fn method(&self) {
diff --git a/tests/ui/issues/issue-50411.rs b/tests/ui/mir/inliner-double-elaborate.rs similarity index 72% rename from tests/ui/issues/issue-50411.rs rename to tests/ui/mir/inliner-double-elaborate.rs index 7fbbada..c6af573 100644 --- a/tests/ui/issues/issue-50411.rs +++ b/tests/ui/mir/inliner-double-elaborate.rs
@@ -1,4 +1,4 @@ -// Regression test for #50411: the MIR inliner was causing problems +// Regression test for https://github.com/rust-lang/rust/issues/50411: the MIR inliner was causing problems // here because it would inline promoted code (which had already had // elaborate-drops invoked on it) and then try to elaboate drops a // second time. Uncool.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed index 1c45a2c..ba46a44 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
@@ -8,5 +8,6 @@ //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //[current]~^ ERROR type mismatch in closure arguments - //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found + //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}` + //[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found }
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr index 36e49c2..7912ed4 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
@@ -12,6 +12,12 @@ note: required by a bound in `find` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +error[E0271]: expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}` + --> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:24 + | +LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); + | ^^^^ expected `&&i32`, found integer + error[E0277]: expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}` --> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:29 | @@ -26,6 +32,7 @@ note: required by a bound in `find` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs index 20d6fed..0fd5670 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
@@ -8,5 +8,6 @@ fn main() { //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); //[current]~^ ERROR type mismatch in closure arguments - //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found + //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}` + //[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found }
diff --git a/tests/ui/missing/undeclared-generic-parameter.rs b/tests/ui/missing/undeclared-generic-parameter.rs new file mode 100644 index 0000000..eebae21 --- /dev/null +++ b/tests/ui/missing/undeclared-generic-parameter.rs
@@ -0,0 +1,5 @@ +struct A; +impl A<B> {} +//~^ ERROR cannot find type `B` in this scope +//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied +fn main() {}
diff --git a/tests/ui/missing/undeclared-generic-parameter.stderr b/tests/ui/missing/undeclared-generic-parameter.stderr new file mode 100644 index 0000000..101a579 --- /dev/null +++ b/tests/ui/missing/undeclared-generic-parameter.stderr
@@ -0,0 +1,36 @@ +error[E0425]: cannot find type `B` in this scope + --> $DIR/undeclared-generic-parameter.rs:2:8 + | +LL | struct A; + | --------- similarly named struct `A` defined here +LL | impl A<B> {} + | ^ + | +help: a struct with a similar name exists + | +LL - impl A<B> {} +LL + impl A<A> {} + | +help: you might be missing a type parameter + | +LL | impl<B> A<B> {} + | +++ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/undeclared-generic-parameter.rs:2:6 + | +LL | impl A<B> {} + | ^--- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/undeclared-generic-parameter.rs:1:8 + | +LL | struct A; + | ^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0107, E0425. +For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs index ab6fbd3..528c464 100644 --- a/tests/ui/new-range/disabled.rs +++ b/tests/ui/new-range/disabled.rs
@@ -1,6 +1,6 @@ //@ check-pass -#![feature(new_range_api)] +#![feature(new_range_api_legacy)] fn main() { // Unchanged
diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs index b49681e..6d9a125 100644 --- a/tests/ui/new-range/enabled.rs +++ b/tests/ui/new-range/enabled.rs
@@ -1,6 +1,5 @@ //@ check-pass -#![feature(new_range_api)] #![feature(new_range)] fn main() {
diff --git a/tests/ui/nll/issue-57362-2.rs b/tests/ui/nll/issue-57362-2.rs index 664cdf8..1f723be 100644 --- a/tests/ui/nll/issue-57362-2.rs +++ b/tests/ui/nll/issue-57362-2.rs
@@ -21,7 +21,7 @@ fn make_g() -> Self::G { // FIXME(@compiler-errors): This error message is less than helpful. fn g() { let x = <fn (&())>::make_g(); - //~^ ERROR no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope + //~^ ERROR no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope } fn main() {}
diff --git a/tests/ui/nll/issue-57362-2.stderr b/tests/ui/nll/issue-57362-2.stderr index 8a1a4d6..1b962b1 100644 --- a/tests/ui/nll/issue-57362-2.stderr +++ b/tests/ui/nll/issue-57362-2.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope +error[E0599]: no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope --> $DIR/issue-57362-2.rs:23:25 | LL | let x = <fn (&())>::make_g(); - | ^^^^^^ function or associated item not found in `for<'a> fn(&'a ())` + | ^^^^^^ associated function or constant not found in `for<'a> fn(&'a ())` | = help: items from traits can only be used if the trait is implemented and in scope note: `X` defines an item `make_g`, perhaps you need to implement it
diff --git a/tests/ui/nll/issue-57642-higher-ranked-subtype.rs b/tests/ui/nll/issue-57642-higher-ranked-subtype.rs index 69187ca..059a2be 100644 --- a/tests/ui/nll/issue-57642-higher-ranked-subtype.rs +++ b/tests/ui/nll/issue-57642-higher-ranked-subtype.rs
@@ -29,11 +29,12 @@ fn make_f() -> Self::F { fn higher_ranked_region_has_lost_its_binder() { let x = <fn (&())>::make_g(); - //~^ ERROR no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope + //~^ ERROR no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope } fn magical() { - let x = <fn (&())>::make_f(); //~ ERROR no function + let x = <fn (&())>::make_f(); + //~^ ERROR no associated function or constant named `make_f` found for fn pointer `for<'a> fn(&'a ())` in the current scope } fn main() {}
diff --git a/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr b/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr index 27a887e..0a56d1b 100644 --- a/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr +++ b/tests/ui/nll/issue-57642-higher-ranked-subtype.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope +error[E0599]: no associated function or constant named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope --> $DIR/issue-57642-higher-ranked-subtype.rs:31:25 | LL | let x = <fn (&())>::make_g(); - | ^^^^^^ function or associated item not found in `for<'a> fn(&'a ())` + | ^^^^^^ associated function or constant not found in `for<'a> fn(&'a ())` | = help: items from traits can only be used if the trait is implemented and in scope note: `X` defines an item `make_g`, perhaps you need to implement it @@ -11,11 +11,11 @@ LL | trait X { | ^^^^^^^ -error[E0599]: no function or associated item named `make_f` found for fn pointer `for<'a> fn(&'a ())` in the current scope +error[E0599]: no associated function or constant named `make_f` found for fn pointer `for<'a> fn(&'a ())` in the current scope --> $DIR/issue-57642-higher-ranked-subtype.rs:36:25 | LL | let x = <fn (&())>::make_f(); - | ^^^^^^ function or associated item not found in `for<'a> fn(&'a ())` + | ^^^^^^ associated function or constant not found in `for<'a> fn(&'a ())` | = help: items from traits can only be used if the trait is implemented and in scope note: `Y` defines an item `make_f`, perhaps you need to implement it
diff --git a/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.rs b/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.rs new file mode 100644 index 0000000..b28e093 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.rs
@@ -0,0 +1,20 @@ +//@ edition:2021 +// Regression test for #125805. +// ICE when using `offset_of!` on a field whose type is a bare trait object +// with a missing lifetime parameter. + +trait X<'a> {} + +use std::mem::offset_of; + +struct T { + y: X, + //~^ ERROR missing lifetime specifier [E0106] + //~| ERROR expected a type, found a trait [E0782] +} + +fn other() { + offset_of!(T, y); +} + +fn main() {}
diff --git a/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.stderr b/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.stderr new file mode 100644 index 0000000..7f4a370 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unsized-trait-object-missing-lifetime.stderr
@@ -0,0 +1,27 @@ +error[E0106]: missing lifetime specifier + --> $DIR/offset-of-unsized-trait-object-missing-lifetime.rs:11:8 + | +LL | y: X, + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ struct T<'a> { +LL ~ y: X<'a>, + | + +error[E0782]: expected a type, found a trait + --> $DIR/offset-of-unsized-trait-object-missing-lifetime.rs:11:8 + | +LL | y: X, + | ^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | y: dyn X, + | +++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0782. +For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index 67b72bd..61d4866 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr
@@ -5,13 +5,13 @@ | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[i32]` to implement `Index<i32>` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>` @@ -21,19 +21,19 @@ | ^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>` -help: the following other types implement trait `SliceIndex<T>` +help: `RangeTo<usize>` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `RangeTo<usize>` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `RangeTo<usize>` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` ::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL | = note: in this macro invocation --> $SRC_DIR/core/src/str/traits.rs:LL:COL | - = note: `RangeTo<usize>` implements `SliceIndex<str>` + = note: `SliceIndex<str>` = note: required for `[i32]` to implement `Index<RangeTo<i32>>` = note: this error originates in the macro `impl_slice_index` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs index aaaf4d3..2c89863 100644 --- a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.rs
@@ -5,7 +5,7 @@ fn from(_: (u8,)) -> Self { todo!() } } -impl From<(u8, u8)> for Tuple { //~ HELP the following other types implement trait `From<T>` +impl From<(u8, u8)> for Tuple { //~ HELP `Tuple` implements trait `From<T>` fn from(_: (u8, u8)) -> Self { todo!() }
diff --git a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr index cf15ac1..f07db05 100644 --- a/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr +++ b/tests/ui/on-unimplemented/suggest_tuple_wrap_root_obligation.stderr
@@ -11,17 +11,17 @@ | LL | struct Tuple; | ^^^^^^^^^^^^ -help: the following other types implement trait `From<T>` +help: `Tuple` implements trait `From<T>` --> $DIR/suggest_tuple_wrap_root_obligation.rs:3:1 | LL | impl From<(u8,)> for Tuple { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `Tuple` implements `From<(u8,)>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<(u8,)>` ... LL | impl From<(u8, u8)> for Tuple { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Tuple` implements `From<(u8, u8)>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<(u8, u8)>` ... LL | impl From<(u8, u8, u8)> for Tuple { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Tuple` implements `From<(u8, u8, u8)>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<(u8, u8, u8)>` = note: required for `u8` to implement `Into<Tuple>` note: required by a bound in `convert_into_tuple` --> $DIR/suggest_tuple_wrap_root_obligation.rs:19:32
diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index 5e82948..56257079 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr
@@ -7,13 +7,13 @@ | required by a bound introduced by this call | = help: the trait `Sum<&()>` is not implemented for `i32` -help: the following other types implement trait `Sum<A>` +help: `i32` implements trait `Sum<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: `Sum` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum<&i32>` + = note: `Sum<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation @@ -37,13 +37,13 @@ | required by a bound introduced by this call | = help: the trait `Product<&()>` is not implemented for `i32` -help: the following other types implement trait `Product<A>` +help: `i32` implements trait `Product<A>` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Product` + = note: `Product` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Product<&i32>` + = note: `Product<&i32>` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation
diff --git a/tests/ui/parallel-rustc/assert-found_cycle-issue-115223.rs b/tests/ui/parallel-rustc/assert-found_cycle-issue-115223.rs new file mode 100644 index 0000000..96a1172 --- /dev/null +++ b/tests/ui/parallel-rustc/assert-found_cycle-issue-115223.rs
@@ -0,0 +1,31 @@ +// Test for #115223, which causes a deadlock bug without finding the cycle +//@ build-pass +#![crate_name = "foo"] + +use std::ops; + +pub struct Foo; + +impl Foo { + pub fn foo(&mut self) {} +} + +pub struct Bar { + foo: Foo, +} + +impl ops::Deref for Bar { + type Target = Foo; + + fn deref(&self) -> &Foo { + &self.foo + } +} + +impl ops::DerefMut for Bar { + fn deref_mut(&mut self) -> &mut Foo { + &mut self.foo + } +} + +fn main() {}
diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.rs b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.rs new file mode 100644 index 0000000..8bc11ce --- /dev/null +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.rs
@@ -0,0 +1,12 @@ +// Test for #151358, assertion failed: !worker_thread.is_null() +//~^ ERROR cycle detected when looking up span for `Default` +// +//@ compile-flags: -Z threads=2 +//@ compare-output-by-lines + +trait Default {} +use std::num::NonZero; +fn main() { + NonZero(); + todo!(); +}
diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr new file mode 100644 index 0000000..9c1d7b1 --- /dev/null +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr
@@ -0,0 +1,9 @@ +error[E0391]: cycle detected when looking up span for `Default` + | + = note: ...which immediately requires looking up span for `Default` again + = note: cycle used when perform lints prior to AST lowering + = 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 1 previous error + +For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.rs b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.rs new file mode 100644 index 0000000..ef484c3 --- /dev/null +++ b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.rs
@@ -0,0 +1,127 @@ +// Test for #120757, deadlock due to query cycle + +#![feature(generic_const_exprs)] + +trait TensorDimension { + const DIM: usize; + const ISSCALAR: bool = Self::DIM == 0; + fn is_scalar(&self) -> bool { + Self::ISSCALAR + } +} + +trait TensorSize: TensorDimension { + fn size(&self) -> [usize; Self::DIM]; + fn inbounds(&self, index: [usize; Self::DIM]) -> bool { + index.iter().zip(self.size().iter()).all(|(i, s)| i < s) + } +} + +trait Broadcastable: TensorSize + Sized { + type Element; + fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>; + fn lazy_updim<const NEWDIM: usize>( + &self, + size: [usize; NEWDIM], + ) -> LazyUpdim<Self, { Self::DIM }, NEWDIM> { + assert!( + NEWDIM >= Self::DIM, + "Updimmed tensor cannot have fewer indices than the initial one." + ); + LazyUpdim { size, reference: &self } + } + fn bmap<T, F: Fn(Self::Element) -> T>(&self, foo: F) -> BMap<T, Self, F, { Self::DIM }> { + BMap { reference: self, closure: foo } + } +} + +struct LazyUpdim<'a, T: Broadcastable, const OLDDIM: usize, const DIM: usize> { + size: [usize; DIM], + reference: &'a T, +} + +impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T, { T::DIM }, DIM> { + const DIM: usize = DIM; +} +impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> { + fn size(&self) -> [usize; DIM] { + //~^ ERROR method not compatible with trait + self.size + } +} +impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> { + type Element = T::Element; + fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { + //~^ ERROR method not compatible with trait + assert!(DIM >= T::DIM); + if !self.inbounds(index) { + //~^ ERROR unconstrained generic constant + //~| ERROR mismatched types + return None; + } + let size = self.size(); + //~^ ERROR unconstrained generic constant + + let newindex: [usize; T::DIM] = Default::default(); + //~^ ERROR the trait bound `[usize; T::DIM]: Default` is not satisfied + self.reference.bget(newindex) + } +} + +struct BMap<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> { + reference: &'a T, + closure: F, +} + +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorDimension + for BMap<'a, R, T, F, DIM> +{ + const DIM: usize = DIM; +} +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSize + for BMap<'a, R, T, F, DIM> +{ + fn size(&self) -> [usize; DIM] { + //~^ ERROR method not compatible with trait + self.reference.size() + //~^ ERROR unconstrained generic constant + //~| ERROR mismatched types + } +} +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcastable + for BMap<'a, R, T, F, DIM> +{ + type Element = R; + fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { + //~^ ERROR method not compatible with trait + self.reference.bget(index).map(ns_window) + //~^ ERROR unconstrained generic constant + //~| ERROR mismatched types + //~| ERROR cannot find value `ns_window` in this scope + } +} + +impl<T> TensorDimension for Vec<T> { + const DIM: usize = 1; +} +impl<T> TensorSize for Vec<T> { + fn size(&self) -> [usize; 1] { + //~^ ERROR method not compatible with trait + [self.len()] + } +} +impl<T: Clone> Broadcastable for Vec<T> { + type Element = T; + fn bget(&self, index: [usize; 1]) -> Option<T> { + //~^ ERROR method not compatible with trait + self.get(index[0]).cloned() + } +} + +fn main() { + let v = vec![1, 2, 3]; + let bv = v.lazy_updim([3, 4]); + let bbv = bv.bmap(|x| x * x); + + println!("The size of v is {:?}", bbv.bget([0, 2]).expect("Out of bounds.")); +}
diff --git a/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.stderr b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.stderr new file mode 100644 index 0000000..4e8cbdb --- /dev/null +++ b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-120757.stderr
@@ -0,0 +1,166 @@ +error[E0425]: cannot find value `ns_window` in this scope + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:97:40 + | +LL | self.reference.bget(index).map(ns_window) + | ^^^^^^^^^ not found in this scope + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:47:5 + | +LL | fn size(&self) -> [usize; DIM] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:54:5 + | +LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:84:5 + | +LL | fn size(&self) -> [usize; DIM] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:95:5 + | +LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:108:5 + | +LL | fn size(&self) -> [usize; 1] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `1` + | + = note: expected constant `Self::DIM` + found constant `1` + +error[E0308]: method not compatible with trait + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:115:5 + | +LL | fn bget(&self, index: [usize; 1]) -> Option<T> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `1` + | + = note: expected constant `Self::DIM` + found constant `1` + +error: unconstrained generic constant + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:57:13 + | +LL | if !self.inbounds(index) { + | ^^^^ + | +note: required by a bound in `TensorSize::inbounds` + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:15:39 + | +LL | fn inbounds(&self, index: [usize; Self::DIM]) -> bool { + | ^^^^^^^^^ required by this bound in `TensorSize::inbounds` +help: try adding a `where` bound + | +LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: { + | ++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:57:27 + | +LL | if !self.inbounds(index) { + | ^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error: unconstrained generic constant + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:62:25 + | +LL | let size = self.size(); + | ^^^^ + | +note: required by a bound in `TensorSize::size` + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:14:31 + | +LL | fn size(&self) -> [usize; Self::DIM]; + | ^^^^^^^^^ required by this bound in `TensorSize::size` +help: try adding a `where` bound + | +LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: { + | ++++++++++++++++++++++ + +error[E0277]: the trait bound `[usize; T::DIM]: Default` is not satisfied + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:65:41 + | +LL | let newindex: [usize; T::DIM] = Default::default(); + | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[usize; T::DIM]` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> where [usize; T::DIM]: Default { + | ++++++++++++++++++++++++++++++ + +error: unconstrained generic constant + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:86:24 + | +LL | self.reference.size() + | ^^^^ + | +note: required by a bound in `TensorSize::size` + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:14:31 + | +LL | fn size(&self) -> [usize; Self::DIM]; + | ^^^^^^^^^ required by this bound in `TensorSize::size` +help: try adding a `where` bound + | +LL | fn size(&self) -> [usize; DIM] where [(); Self::DIM]: { + | ++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:86:9 + | +LL | self.reference.size() + | ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM` + | + = note: expected constant `DIM` + found constant `Self::DIM` + +error: unconstrained generic constant + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:97:9 + | +LL | self.reference.bget(index).map(ns_window) + | ^^^^^^^^^^^^^^ + | +note: required by a bound in `Broadcastable::bget` + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:22:35 + | +LL | fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>; + | ^^^^^^^^^ required by this bound in `Broadcastable::bget` +help: try adding a `where` bound + | +LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> where [(); Self::DIM]: { + | ++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/generic-const-exprs-deadlock-issue-120757.rs:97:29 + | +LL | self.reference.bget(index).map(ns_window) + | ^^^^^ expected `Self::DIM`, found `DIM` + | + = note: expected constant `Self::DIM` + found constant `DIM` + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0277, E0308, E0425. +For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.rs b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.rs new file mode 100644 index 0000000..ccc03a4 --- /dev/null +++ b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.rs
@@ -0,0 +1,20 @@ +// Test for #134978, deadlock detected as we're unable to find a query cycle to break + +#![feature(generic_const_exprs)] + +pub struct Struct<const N: usize>; + +impl<const N: usize> Struct<N> { + pub const OK: usize = 0; +} + +fn main() { + function::<0>(); +} + +fn function<const NUM_CARDS: usize>() +where + [(); Struct::<{ NUM_CARDS + 0 }>::OK]:, + //~^ ERROR cycle detected when building an abstract representation +{ +}
diff --git a/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.stderr b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.stderr new file mode 100644 index 0000000..a27c107 --- /dev/null +++ b/tests/ui/parallel-rustc/generic-const-exprs-deadlock-issue-134978.stderr
@@ -0,0 +1,29 @@ +error[E0391]: cycle detected when building an abstract representation for `function::{constant#0}` + --> $DIR/generic-const-exprs-deadlock-issue-134978.rs:17:10 + | +LL | [(); Struct::<{ NUM_CARDS + 0 }>::OK]:, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires building THIR for `function::{constant#0}`... + --> $DIR/generic-const-exprs-deadlock-issue-134978.rs:17:10 + | +LL | [(); Struct::<{ NUM_CARDS + 0 }>::OK]:, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires type-checking `function::{constant#0}`... + --> $DIR/generic-const-exprs-deadlock-issue-134978.rs:17:10 + | +LL | [(); Struct::<{ NUM_CARDS + 0 }>::OK]:, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires building an abstract representation for `function::{constant#0}`, completing the cycle +note: cycle used when checking that `function` is well-formed + --> $DIR/generic-const-exprs-deadlock-issue-134978.rs:15:1 + | +LL | / fn function<const NUM_CARDS: usize>() +LL | | where +LL | | [(); Struct::<{ NUM_CARDS + 0 }>::OK]:, + | |___________________________________________^ + = 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 1 previous error + +For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs new file mode 100644 index 0000000..f617e20 --- /dev/null +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs
@@ -0,0 +1,82 @@ +// Test for #120786, which causes an ice bug: infer: `None` + +fn no_err() { + |x: u32, y| x; + //~^ ERROR type annotations needed + let _ = String::from("x"); +} + +fn err() { + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} + +fn arg_pat_closure_err() { + |x| String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} + +fn local_pat_closure_err() { + let _ = "x".as_ref(); + //~^ ERROR type annotations needed +} + +fn err_first_arg_pat() { + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed + |x: String| x; +} + +fn err_second_arg_pat() { + |x: String| x; + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} + +fn err_mid_arg_pat() { + |x: String| x; + |x: String| x; + |x: String| x; + |x: String| x; + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed + |x: String| x; + |x: String| x; + |x: String| x; + |x: String| x; +} + +fn err_first_local_pat() { + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed + let _ = String::from("x"); +} + +fn err_second_local_pat() { + let _ = String::from("x"); + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} + +fn err_mid_local_pat() { + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + String::from("x".as_ref()); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); +} + +fn main() {}
diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr new file mode 100644 index 0000000..3be18fc --- /dev/null +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr
@@ -0,0 +1,256 @@ +error[E0282]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:4:14 + | +LL | |x: u32, y| x; + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | |x: u32, y: /* Type */| x; + | ++++++++++++ + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:10:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:10:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:16:9 + | +LL | |x| String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:16:26 + | +LL | |x| String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed for `&_` + --> $DIR/infer-unwrap-none-issue-120786.rs:22:9 + | +LL | let _ = "x".as_ref(); + | ^ ------ type must be known at this point + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: consider giving this pattern a type, where the type for type parameter `T` is specified + | +LL | let _: &T = "x".as_ref(); + | ++++ + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:27:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:27:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:35:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:35:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:45:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:45:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:55:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:55:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:63:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:63:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:73:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl From<&String> for String; + - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:73:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef<ByteStr> for str; + - impl AsRef<OsStr> for str; + - impl AsRef<Path> for str; + - impl AsRef<[u8]> for str; + - impl AsRef<str> for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(<str as AsRef<T>>::as_ref("x")); + | + +error: aborting due to 18 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.rs b/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.rs new file mode 100644 index 0000000..1fd058d --- /dev/null +++ b/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.rs
@@ -0,0 +1,89 @@ +// Test for #129911, deadlock detected as we're unable to find a query cycle to break + +fn main() { + type KooArc = Frc< + //~^ ERROR cannot find type `Frc` in this scope + { + { + { + {}; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + } + type Frc = Frc< + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + { + { + { + {}; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + } + type Frc = Frc< + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + { + { + { + {}; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + } + type Frc = Frc< + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + { + { + { + {}; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + } + type Frc = Frc< + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + { + { + { + { + {}; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + }; + } + type Frc = Frc< + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + { + { + { + {}; + }; + } + type Frc = Frc<{}>::Arc;; + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR cycle detected when expanding type alias + }, + >::Arc;; + }, + >::Arc;; + }, + >::Arc;; + }, + >::Arc;; + }, + >::Arc;; + }, + >::Arc; +}
diff --git a/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.stderr b/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.stderr new file mode 100644 index 0000000..b1ece17 --- /dev/null +++ b/tests/ui/parallel-rustc/nested-type-alias-cycle-issue-129911.stderr
@@ -0,0 +1,391 @@ +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:11:28 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:11:22 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:11:28 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:11:17 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:15:24 + | +LL | type Frc = Frc< + | ________________________^^^- + | | | + | | expected 0 generic arguments +... | +LL | | }, +LL | | >::Arc;; + | |_____________- help: remove the unnecessary generics + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:15:18 + | +LL | type Frc = Frc< + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:15:24 + | +LL | type Frc = Frc< + | ________________________^ +... | +LL | | }, +LL | | >::Arc;; + | |_____________^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:15:13 + | +LL | type Frc = Frc< + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:23:36 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:23:30 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:23:36 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:23:25 + | +LL | type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:27:32 + | +LL | type Frc = Frc< + | ________________________________^^^- + | | | + | | expected 0 generic arguments +... | +LL | | }, +LL | | >::Arc;; + | |_____________________- help: remove the unnecessary generics + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:27:26 + | +LL | type Frc = Frc< + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:27:32 + | +LL | type Frc = Frc< + | ________________________________^ +... | +LL | | }, +LL | | >::Arc;; + | |_____________________^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:27:21 + | +LL | type Frc = Frc< + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:35:44 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:35:38 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:35:44 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:35:33 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:39:40 + | +LL | ... type Frc = Frc< + | __________________________________^^^- + | | | + | | expected 0 generic arguments +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________- help: remove the unnecessary generics + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:39:34 + | +LL | ... type Frc = Frc< + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:39:40 + | +LL | ... type Frc = Frc< + | __________________________________^ +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:39:29 + | +LL | ... type Frc = Frc< + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:47:52 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:47:46 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:47:52 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:47:41 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:51:48 + | +LL | ... type Frc = Frc< + | __________________________________^^^- + | | | + | | expected 0 generic arguments +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________- help: remove the unnecessary generics + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:51:42 + | +LL | ... type Frc = Frc< + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:51:48 + | +LL | ... type Frc = Frc< + | __________________________________^ +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:51:37 + | +LL | ... type Frc = Frc< + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:60:64 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:60:58 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:60:64 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:60:53 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:65:56 + | +LL | ... type Frc = Frc< + | __________________________________^^^- + | | | + | | expected 0 generic arguments +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________- help: remove the unnecessary generics + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:65:50 + | +LL | ... type Frc = Frc< + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:65:56 + | +LL | ... type Frc = Frc< + | __________________________________^ +... | +LL | | ... }, +LL | | ... >::Arc;; + | |_______________________^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:65:45 + | +LL | ... type Frc = Frc< + | ^^^^^^^^ + = 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[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/nested-type-alias-cycle-issue-129911.rs:74:64 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/nested-type-alias-cycle-issue-129911.rs:74:58 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^ + +error[E0391]: cycle detected when expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` + --> $DIR/nested-type-alias-cycle-issue-129911.rs:74:64 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^ + | + = note: ...which immediately requires expanding type alias `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `main::KooArc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc::{constant#0}::Frc` is well-formed + --> $DIR/nested-type-alias-cycle-issue-129911.rs:74:53 + | +LL | ... type Frc = Frc<{}>::Arc;; + | ^^^^^^^^ + = 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[E0433]: cannot find type `Frc` in this scope + --> $DIR/nested-type-alias-cycle-issue-129911.rs:4:19 + | +LL | type KooArc = Frc< + | ^^^ use of undeclared type `Frc` + +error: aborting due to 23 previous errors + +Some errors have detailed explanations: E0107, E0391, E0433. +For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.rs b/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.rs new file mode 100644 index 0000000..5b0bd19 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.rs
@@ -0,0 +1,97 @@ +// Test for #129912, which causes a deadlock bug without finding a cycle + +#![feature(generators)] +//~^ ERROR feature has been removed +#![allow(unconditional_recursion)] + +fn option(i: i32) -> impl Sync { + if generator_sig() < 0 { None } else { Sized((option(i - Sized), i)) } + //~^ ERROR expected value, found trait `Sized` + //~| ERROR expected function, tuple struct or tuple variant, found trait `Sized` +} + +fn tuple() -> impl Sized { + (tuple(),) +} + +fn array() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + [array()] +} + +fn ptr() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &ptr() as *const impl Sized + //~^ ERROR `impl Trait` is not allowed in cast expression types +} + +fn fn_ptr() -> impl Sized { + fn_ptr as fn() -> _ +} + +fn closure_capture() -> impl Sized { + let x = closure_capture(); + move || { + x; + } +} + +fn closure_ref_capture() -> impl Sized { + let x = closure_ref_capture(); + move || { + &x; + } +} + +fn closure_sig() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + || closure_sig() +} + +fn generator_sig() -> impl Sized { + || i + //~^ ERROR cannot find value `i` in this scope +} + +fn generator_capture() -> impl i32 { + //~^ ERROR expected trait, found builtin type `i32` + let x = 1(); + move || { + yield; + //~^ ERROR yield syntax is experimental + //~| ERROR yield syntax is experimental + //~| ERROR `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + x; + } +} + +fn substs_change<T: 'static>() -> impl Sized { + (substs_change::<&T>(),) +} + +fn generator_hold() -> impl generator_capture { + //~^ ERROR expected trait, found function `generator_capture` + move || { + let x = (); + yield; + //~^ ERROR yield syntax is experimental + //~| ERROR yield syntax is experimental + //~| ERROR `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + x virtual ; + //~^ ERROR expected one of + } +} + +fn use_fn_ptr() -> impl Sized { + fn_ptr() +} + +fn mutual_recursion() -> impl Sync { + mutual_recursion_b() +} + +fn mutual_recursion_b() -> impl Sized { + mutual_recursion() +} + +fn main() {}
diff --git a/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.stderr b/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.stderr new file mode 100644 index 0000000..420fb36 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-impl-trait-deadlock-issue-129912.stderr
@@ -0,0 +1,137 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found reserved keyword `virtual` + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:80:11 + | +LL | x virtual ; + | ^^^^^^^ expected one of 8 possible tokens + +error[E0557]: feature has been removed + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:3:12 + | +LL | #![feature(generators)] + | ^^^^^^^^^^ feature has been removed + | + = note: removed in 1.75.0; see <https://github.com/rust-lang/rust/pull/116958> for more information + = note: renamed to `coroutines` + +error[E0423]: expected value, found trait `Sized` + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:8:62 + | +LL | if generator_sig() < 0 { None } else { Sized((option(i - Sized), i)) } + | ^^^^^ not a value + +error[E0425]: cannot find value `i` in this scope + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:52:8 + | +LL | || i + | ^ not found in this scope + +error[E0404]: expected trait, found builtin type `i32` + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:56:32 + | +LL | fn generator_capture() -> impl i32 { + | ^^^ not a trait + +error[E0404]: expected trait, found function `generator_capture` + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:72:29 + | +LL | fn generator_hold() -> impl generator_capture { + | ^^^^^^^^^^^^^^^^^ not a trait + +error[E0658]: yield syntax is experimental + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:60:9 + | +LL | yield; + | ^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + = help: add `#![feature(yield_expr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: yield syntax is experimental + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:76:9 + | +LL | yield; + | ^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + = help: add `#![feature(yield_expr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0562]: `impl Trait` is not allowed in cast expression types + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:24:22 + | +LL | &ptr() as *const impl Sized + | ^^^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0658]: yield syntax is experimental + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:60:9 + | +LL | yield; + | ^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + = help: add `#![feature(yield_expr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:60:9 + | +LL | yield; + | ^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] move || { + | ++++++++++++ + +error[E0658]: yield syntax is experimental + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:76:9 + | +LL | yield; + | ^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + = help: add `#![feature(yield_expr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:76:9 + | +LL | yield; + | ^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] move || { + | ++++++++++++ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:17:15 + | +LL | fn array() -> _ { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:22:13 + | +LL | fn ptr() -> _ { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:46:21 + | +LL | fn closure_sig() -> _ { + | ^ not allowed in type signatures + +error[E0423]: expected function, tuple struct or tuple variant, found trait `Sized` + --> $DIR/recursive-impl-trait-deadlock-issue-129912.rs:8:44 + | +LL | if generator_sig() < 0 { None } else { Sized((option(i - Sized), i)) } + | ^^^^^ not a function, tuple struct or tuple variant + +error: aborting due to 17 previous errors + +Some errors have detailed explanations: E0121, E0404, E0423, E0425, E0557, E0562, E0658. +For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.rs b/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.rs new file mode 100644 index 0000000..69cbd57 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.rs
@@ -0,0 +1,9 @@ +// Test for #151226, Unable to verify registry association +// +//@ compile-flags: -Z threads=2 +//@ compare-output-by-lines + +struct A<T>(std::sync::OnceLock<Self>); +//~^ ERROR recursive type `A` has infinite size +static B: A<()> = todo!(); +fn main() {}
diff --git a/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.stderr b/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.stderr new file mode 100644 index 0000000..2a51ee9 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-struct-oncelock-issue-151226.stderr
@@ -0,0 +1,14 @@ +error[E0072]: recursive type `A` has infinite size + --> $DIR/recursive-struct-oncelock-issue-151226.rs:6:1 + | +LL | struct A<T>(std::sync::OnceLock<Self>); + | ^^^^^^^^^^^ ------------------------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct A<T>(Box<std::sync::OnceLock<Self>>); + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0072`.
diff --git a/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.rs b/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.rs new file mode 100644 index 0000000..5ae2f93 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.rs
@@ -0,0 +1,18 @@ +// Test for #142064, internal error: entered unreachable code +// +//@ compile-flags: -Zthreads=2 +//@ compare-output-by-lines + +#![crate_type = "rlib"] +trait A { fn foo() -> A; } +//~^ WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| ERROR the trait `A` is not dyn compatible +trait B { fn foo() -> A; } +//~^ WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| ERROR the trait `A` is not dyn compatible
diff --git a/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.stderr b/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.stderr new file mode 100644 index 0000000..540f70e --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-trait-fn-sig-issue-142064.stderr
@@ -0,0 +1,114 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:7:23 + | +LL | trait A { fn foo() -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait A { fn foo() -> dyn A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:13:23 + | +LL | trait B { fn foo() -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait B { fn foo() -> dyn A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:7:23 + | +LL | trait A { fn foo() -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait A { fn foo() -> dyn A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:13:23 + | +LL | trait B { fn foo() -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is a dyn-compatible trait, use `dyn` + | +LL | trait B { fn foo() -> dyn A; } + | +++ + +error[E0038]: the trait `A` is not dyn compatible + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:7:23 + | +LL | trait A { fn foo() -> A; } + | ^ `A` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:7:14 + | +LL | trait A { fn foo() -> A; } + | - ^^^ ...because associated function `foo` has no `self` parameter + | | + | this trait is not dyn compatible... +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | trait A { fn foo(&self) -> A; } + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | trait A { fn foo() -> A where Self: Sized; } + | +++++++++++++++++ +help: you might have meant to use `Self` to refer to the implementing type + | +LL - trait A { fn foo() -> A; } +LL + trait A { fn foo() -> Self; } + | + +error[E0038]: the trait `A` is not dyn compatible + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:13:23 + | +LL | trait B { fn foo() -> A; } + | ^ `A` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/recursive-trait-fn-sig-issue-142064.rs:7:14 + | +LL | trait A { fn foo() -> A; } + | - ^^^ ...because associated function `foo` has no `self` parameter + | | + | this trait is not dyn compatible... +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | trait A { fn foo(&self) -> A; } + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | trait A { fn foo() -> A where Self: Sized; } + | +++++++++++++++++ +help: you might have meant to use `Self` to refer to the implementing type + | +LL - trait B { fn foo() -> A; } +LL + trait B { fn foo() -> Self; } + | + +error: aborting due to 2 previous errors; 4 warnings emitted + +For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.rs b/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.rs new file mode 100644 index 0000000..cee6698 --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.rs
@@ -0,0 +1,26 @@ +// Test for #120759, deadlock detected without any query + +#![crate_type = "lib"] +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + //~^ ERROR unresolved import `std::mem::BikeshedIntrinsicFrom` + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>(&self, cpu: &mut CPU) + //~^ ERROR `self` parameter is only allowed in associated functions + //~| ERROR cannot find type `CPU` in this scope + where + Dst: BikeshedIntrinsicFrom<Src, Context>, + { + } +} + +fn should_pad_explicitly_packed_field() { + #[repr(C)] + struct ExplicitlyPadded(ExplicitlyPadded); + //~^ ERROR recursive type `ExplicitlyPadded` has infinite size + + assert::is_maybe_transmutable::<ExplicitlyPadded, ()>(); +}
diff --git a/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.stderr b/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.stderr new file mode 100644 index 0000000..c21418c --- /dev/null +++ b/tests/ui/parallel-rustc/recursive-type-with-transmutability-issue-120759.stderr
@@ -0,0 +1,35 @@ +error: `self` parameter is only allowed in associated functions + --> $DIR/recursive-type-with-transmutability-issue-120759.rs:11:44 + | +LL | pub fn is_maybe_transmutable<Src, Dst>(&self, cpu: &mut CPU) + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error[E0432]: unresolved import `std::mem::BikeshedIntrinsicFrom` + --> $DIR/recursive-type-with-transmutability-issue-120759.rs:7:28 + | +LL | use std::mem::{Assume, BikeshedIntrinsicFrom}; + | ^^^^^^^^^^^^^^^^^^^^^ no `BikeshedIntrinsicFrom` in `mem` + +error[E0425]: cannot find type `CPU` in this scope + --> $DIR/recursive-type-with-transmutability-issue-120759.rs:11:61 + | +LL | pub fn is_maybe_transmutable<Src, Dst>(&self, cpu: &mut CPU) + | ^^^ not found in this scope + +error[E0072]: recursive type `ExplicitlyPadded` has infinite size + --> $DIR/recursive-type-with-transmutability-issue-120759.rs:22:5 + | +LL | struct ExplicitlyPadded(ExplicitlyPadded); + | ^^^^^^^^^^^^^^^^^^^^^^^ ---------------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct ExplicitlyPadded(Box<ExplicitlyPadded>); + | ++++ + + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0072, E0425, E0432. +For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/parallel-rustc/ty-variance-issue-124423.rs b/tests/ui/parallel-rustc/ty-variance-issue-124423.rs index 8d7f29f..501b0fc 100644 --- a/tests/ui/parallel-rustc/ty-variance-issue-124423.rs +++ b/tests/ui/parallel-rustc/ty-variance-issue-124423.rs
@@ -43,7 +43,7 @@ fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) } //~| ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` //~| ERROR at least one trait is required for an object type -//~| ERROR no function or associated item named `u32` found for struct `Box<_, _>` in the current scope +//~| ERROR no associated function or constant named `u32` found for struct `Box<_, _>` in the current scope fn elided4(_: &impl Copy + 'a) -> new { x(x) } //~^ ERROR ambiguous `+` in a type
diff --git a/tests/ui/parallel-rustc/ty-variance-issue-124423.stderr b/tests/ui/parallel-rustc/ty-variance-issue-124423.stderr index 631f43e..2246a22 100644 --- a/tests/ui/parallel-rustc/ty-variance-issue-124423.stderr +++ b/tests/ui/parallel-rustc/ty-variance-issue-124423.stderr
@@ -244,18 +244,18 @@ | ^^^ not found in this scope error[E0224]: at least one trait is required for an object type - --> $DIR/ty-variance-issue-124423.rs:55:40 - | -LL | impl<'a> LifetimeTrait<'a> for &'a Box<dyn 'a> {} - | ^^^^^^ - -error[E0224]: at least one trait is required for an object type --> $DIR/ty-variance-issue-124423.rs:41:40 | LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) } | ^^^^^^ error[E0224]: at least one trait is required for an object type + --> $DIR/ty-variance-issue-124423.rs:55:40 + | +LL | impl<'a> LifetimeTrait<'a> for &'a Box<dyn 'a> {} + | ^^^^^^ + +error[E0224]: at least one trait is required for an object type --> $DIR/ty-variance-issue-124423.rs:35:39 | LL | fn elided3(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) } @@ -267,11 +267,11 @@ LL | fn elided(_: &impl Copy + 'a) -> _ { x } | ^ not allowed in type signatures -error[E0599]: no function or associated item named `u32` found for struct `Box<_, _>` in the current scope +error[E0599]: no associated function or constant named `u32` found for struct `Box<_, _>` in the current scope --> $DIR/ty-variance-issue-124423.rs:41:55 | LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) } - | ^^^ function or associated item not found in `Box<_, _>` + | ^^^ associated function or constant not found in `Box<_, _>` | note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions: Box::<T>::new
diff --git a/tests/ui/parallel-rustc/ty-variance-issue-127971.rs b/tests/ui/parallel-rustc/ty-variance-issue-127971.rs index a179168..db2dc8e 100644 --- a/tests/ui/parallel-rustc/ty-variance-issue-127971.rs +++ b/tests/ui/parallel-rustc/ty-variance-issue-127971.rs
@@ -20,6 +20,6 @@ fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) } //~| ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` //~| ERROR at least one trait is required for an object type -//~| ERROR no function or associated item named `u32` found for struct `Box<_, _>` in the current scope +//~| ERROR no associated function or constant named `u32` found for struct `Box<_, _>` in the current scope fn main() {}
diff --git a/tests/ui/parallel-rustc/ty-variance-issue-127971.stderr b/tests/ui/parallel-rustc/ty-variance-issue-127971.stderr index dce4acf..47286d9 100644 --- a/tests/ui/parallel-rustc/ty-variance-issue-127971.stderr +++ b/tests/ui/parallel-rustc/ty-variance-issue-127971.stderr
@@ -93,11 +93,11 @@ LL | fn elided(_: &impl Copy + 'a) -> _ { x } | ^ not allowed in type signatures -error[E0599]: no function or associated item named `u32` found for struct `Box<_, _>` in the current scope +error[E0599]: no associated function or constant named `u32` found for struct `Box<_, _>` in the current scope --> $DIR/ty-variance-issue-127971.rs:18:55 | LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) } - | ^^^ function or associated item not found in `Box<_, _>` + | ^^^ associated function or constant not found in `Box<_, _>` | note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions: Box::<T>::new
diff --git a/tests/ui/parser/assoc/assoc-static-semantic-fail.rs b/tests/ui/parser/assoc/assoc-static-semantic-fail.rs index 403160f..de0cee6 100644 --- a/tests/ui/parser/assoc/assoc-static-semantic-fail.rs +++ b/tests/ui/parser/assoc/assoc-static-semantic-fail.rs
@@ -1,7 +1,6 @@ // Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete fn main() {}
diff --git a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr index cc21df7..4ac3528 100644 --- a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr +++ b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr
@@ -1,17 +1,17 @@ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:10:5 + --> $DIR/assoc-static-semantic-fail.rs:9:5 | LL | static IA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:12:5 + --> $DIR/assoc-static-semantic-fail.rs:11:5 | LL | static IB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:15:5 + --> $DIR/assoc-static-semantic-fail.rs:14:5 | LL | default static IC: u8 = 0; | ^^^^^^^ `default` because of this @@ -19,13 +19,13 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:15:5 + --> $DIR/assoc-static-semantic-fail.rs:14:5 | LL | default static IC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:18:16 + --> $DIR/assoc-static-semantic-fail.rs:17:16 | LL | pub(crate) default static ID: u8; | ^^^^^^^ `default` because of this @@ -33,25 +33,25 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:18:5 + --> $DIR/assoc-static-semantic-fail.rs:17:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:25:5 + --> $DIR/assoc-static-semantic-fail.rs:24:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:27:5 + --> $DIR/assoc-static-semantic-fail.rs:26:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:29:5 + --> $DIR/assoc-static-semantic-fail.rs:28:5 | LL | default static TC: u8 = 0; | ^^^^^^^ `default` because of this @@ -59,13 +59,13 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:29:5 + --> $DIR/assoc-static-semantic-fail.rs:28:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:32:16 + --> $DIR/assoc-static-semantic-fail.rs:31:16 | LL | pub(crate) default static TD: u8; | ^^^^^^^ `default` because of this @@ -73,25 +73,25 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:32:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:39:5 + --> $DIR/assoc-static-semantic-fail.rs:38:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:41:5 + --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:44:5 + --> $DIR/assoc-static-semantic-fail.rs:43:5 | LL | default static TC: u8 = 0; | ^^^^^^^ `default` because of this @@ -99,13 +99,13 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:44:5 + --> $DIR/assoc-static-semantic-fail.rs:43:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:47:9 + --> $DIR/assoc-static-semantic-fail.rs:46:9 | LL | pub default static TD: u8; | ^^^^^^^ `default` because of this @@ -113,13 +113,13 @@ = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:12:5 + --> $DIR/assoc-static-semantic-fail.rs:11:5 | LL | static IB: u8; | ^^^^^^^^^^^^^- @@ -127,7 +127,7 @@ | help: provide a definition for the constant: `= <expr>;` error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:18:5 + --> $DIR/assoc-static-semantic-fail.rs:17:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -135,7 +135,7 @@ | help: provide a definition for the constant: `= <expr>;` error[E0449]: visibility qualifiers are not permitted here - --> $DIR/assoc-static-semantic-fail.rs:32:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^ help: remove the qualifier @@ -143,7 +143,7 @@ = note: trait items always share the visibility of their trait error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:41:5 + --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | static TB: u8; | ^^^^^^^^^^^^^- @@ -151,7 +151,7 @@ | help: provide a definition for the constant: `= <expr>;` error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -159,23 +159,13 @@ | help: provide a definition for the constant: `= <expr>;` error[E0449]: visibility qualifiers are not permitted here - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-static-semantic-fail.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 24 previous errors; 1 warning emitted +error: aborting due to 24 previous errors For more information about this error, try `rustc --explain E0449`.
diff --git a/tests/ui/parser/default.rs b/tests/ui/parser/default.rs index d1058ce..81821ce 100644 --- a/tests/ui/parser/default.rs +++ b/tests/ui/parser/default.rs
@@ -1,7 +1,6 @@ // Test successful and unsuccessful parsing of the `default` contextual keyword #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Foo { fn foo<T: Default>() -> T;
diff --git a/tests/ui/parser/default.stderr b/tests/ui/parser/default.stderr index c420e5a..1f2312d 100644 --- a/tests/ui/parser/default.stderr +++ b/tests/ui/parser/default.stderr
@@ -1,5 +1,5 @@ error: `default` is not followed by an item - --> $DIR/default.rs:23:5 + --> $DIR/default.rs:22:5 | LL | default pub fn foo<T: Default>() -> T { T::default() } | ^^^^^^^ the `default` qualifier @@ -7,7 +7,7 @@ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` error: non-item in item list - --> $DIR/default.rs:23:13 + --> $DIR/default.rs:22:13 | LL | impl Foo for u32 { | - item list starts here @@ -18,25 +18,15 @@ | - item list ends here error[E0449]: visibility qualifiers are not permitted here - --> $DIR/default.rs:17:5 + --> $DIR/default.rs:16:5 | LL | pub default fn foo<T: Default>() -> T { | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/default.rs:22:1 + --> $DIR/default.rs:21:1 | LL | fn foo<T: Default>() -> T; | -------------------------- `foo` from trait @@ -44,7 +34,7 @@ LL | impl Foo for u32 { | ^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0449. For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs index bff53f6..f274040 100644 --- a/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] fn main() {}
diff --git a/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr index 41fad3a..4adb0ab 100644 --- a/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr
@@ -70,15 +70,5 @@ | | | `default` because of this -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/defaultness-invalid-places-fail-semantic.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 9 previous errors
diff --git a/tests/ui/parser/emoji-identifiers.rs b/tests/ui/parser/emoji-identifiers.rs index b50c046..cbd2e54 100644 --- a/tests/ui/parser/emoji-identifiers.rs +++ b/tests/ui/parser/emoji-identifiers.rs
@@ -6,7 +6,7 @@ fn full_of_✨() -> 👀 { //~ ERROR identifiers cannot contain emoji } } fn i_like_to_😅_a_lot() -> 👀 { //~ ERROR identifiers cannot contain emoji - 👀::full_of✨() //~ ERROR no function or associated item named `full_of✨` found for struct `👀` + 👀::full_of✨() //~ ERROR no associated function or constant named `full_of✨` found for struct `👀` //~^ ERROR identifiers cannot contain emoji } fn main() {
diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index 016ed04..a6532f9 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr
@@ -65,14 +65,14 @@ LL | dbg!(🦀); | ^^ -error[E0599]: no function or associated item named `full_of✨` found for struct `👀` in the current scope +error[E0599]: no associated function or constant named `full_of✨` found for struct `👀` in the current scope --> $DIR/emoji-identifiers.rs:9:8 | LL | struct 👀; - | --------- function or associated item `full_of✨` not found for this struct + | --------- associated function or constant `full_of✨` not found for this struct ... LL | 👀::full_of✨() - | ^^^^^^^^^ function or associated item not found in `👀` + | ^^^^^^^^^ associated function or constant not found in `👀` | note: if you're trying to build a new `👀`, consider using `👀::full_of_✨` which returns `👀` --> $DIR/emoji-identifiers.rs:4:5
diff --git a/tests/ui/parser/issue-12187-1.stderr b/tests/ui/parser/issue-12187-1.stderr index ee5d1c0..704854f 100644 --- a/tests/ui/parser/issue-12187-1.stderr +++ b/tests/ui/parser/issue-12187-1.stderr
@@ -6,7 +6,7 @@ | help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let &v: &_ = new(); +LL | let &v: &T = new(); | ++++ error: aborting due to 1 previous error
diff --git a/tests/ui/parser/issue-12187-2.stderr b/tests/ui/parser/issue-12187-2.stderr index 67d18cf..eeef63a 100644 --- a/tests/ui/parser/issue-12187-2.stderr +++ b/tests/ui/parser/issue-12187-2.stderr
@@ -6,7 +6,7 @@ | help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let &v: &_ = new(); +LL | let &v: &T = new(); | ++++ error: aborting due to 1 previous error
diff --git a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr index 22fb1b9..b1d9c9d 100644 --- a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr +++ b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr
@@ -6,7 +6,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' = note: `#[deny(text_direction_codepoint_in_literal)]` on by default error: unicode codepoint changing visible direction of text present in doc comment @@ -19,7 +19,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:33:9 @@ -31,7 +31,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:41:9 @@ -41,7 +41,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:46:9 @@ -51,7 +51,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: aborting due to 5 previous errors
diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.rs b/tests/ui/parser/recover/recover-enum-with-bad-where.rs similarity index 100% rename from tests/ui/structs-enums/recover-enum-with-bad-where.rs rename to tests/ui/parser/recover/recover-enum-with-bad-where.rs
diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.stderr b/tests/ui/parser/recover/recover-enum-with-bad-where.stderr similarity index 100% rename from tests/ui/structs-enums/recover-enum-with-bad-where.stderr rename to tests/ui/parser/recover/recover-enum-with-bad-where.stderr
diff --git a/tests/ui/parser/shebang/multiline-attrib.rs b/tests/ui/parser/shebang/multiline-attrib.rs index 2d2e029..d67ba5f 100644 --- a/tests/ui/parser/shebang/multiline-attrib.rs +++ b/tests/ui/parser/shebang/multiline-attrib.rs
@@ -1,7 +1,7 @@ #! [allow(unused_variables)] //@ check-pass -//@ reference: input.shebang.inner-attribute +//@ reference: shebang.syntax-description fn main() { let x = 5;
diff --git a/tests/ui/parser/shebang/regular-attrib.rs b/tests/ui/parser/shebang/regular-attrib.rs index c2ac256..f711b81 100644 --- a/tests/ui/parser/shebang/regular-attrib.rs +++ b/tests/ui/parser/shebang/regular-attrib.rs
@@ -1,6 +1,6 @@ #![allow(unused_variables)] //@ check-pass -//@ reference: input.shebang.inner-attribute +//@ reference: shebang.syntax-description fn main() { let x = 5; }
diff --git a/tests/ui/parser/shebang/shebang-and-attrib.rs b/tests/ui/parser/shebang/shebang-and-attrib.rs index d73db6b..e3e52b5 100644 --- a/tests/ui/parser/shebang/shebang-and-attrib.rs +++ b/tests/ui/parser/shebang/shebang-and-attrib.rs
@@ -1,7 +1,7 @@ #!/usr/bin/env run-cargo-script //@ check-pass -//@ reference: input.shebang.inner-attribute +//@ reference: shebang.syntax-description #![allow(unused_variables)]
diff --git a/tests/ui/parser/shebang/shebang-doc-comment.rs b/tests/ui/parser/shebang/shebang-doc-comment.rs index 4992c75..976a2b3 100644 --- a/tests/ui/parser/shebang/shebang-doc-comment.rs +++ b/tests/ui/parser/shebang/shebang-doc-comment.rs
@@ -2,4 +2,4 @@ [allow(unused_variables)] //~^ ERROR expected item, found `[` -//@ reference: input.shebang.inner-attribute +//@ reference: shebang.syntax-description
diff --git a/tests/ui/parser/shebang/sneaky-attrib.rs b/tests/ui/parser/shebang/sneaky-attrib.rs index e22c45c..b9c4adb 100644 --- a/tests/ui/parser/shebang/sneaky-attrib.rs +++ b/tests/ui/parser/shebang/sneaky-attrib.rs
@@ -11,7 +11,7 @@ [allow(unused_variables)] //@ check-pass -//@ reference: input.shebang.inner-attribute +//@ reference: shebang.syntax-description fn main() { let x = 5; }
diff --git a/tests/ui/parser/unicode-control-codepoints.stderr b/tests/ui/parser/unicode-control-codepoints.stderr index 7978c14..3b273f8 100644 --- a/tests/ui/parser/unicode-control-codepoints.stderr +++ b/tests/ui/parser/unicode-control-codepoints.stderr
@@ -232,7 +232,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints.rs:46:1 @@ -244,7 +244,7 @@ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}' error: aborting due to 20 previous errors
diff --git a/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs b/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs new file mode 100644 index 0000000..a7998da --- /dev/null +++ b/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs
@@ -0,0 +1,8 @@ +//@ edition: 2024 + +#[allow(unused)] +/// א, ב, ג, ד, ה +//~^ ERROR unicode codepoint changing visible direction of text present in doc comment +fn foo() {} + +fn main() {}
diff --git a/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr b/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr new file mode 100644 index 0000000..668a784 --- /dev/null +++ b/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr
@@ -0,0 +1,13 @@ +error: unicode codepoint changing visible direction of text present in doc comment + --> $DIR/unicode-control-doc-comment-issue-153096.rs:4:1 + | +LL | /// �א�, �ב�, �ג�, �ד�, �ה� + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: if their presence wasn't intentional, you can remove them + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}' + = note: `#[deny(text_direction_codepoint_in_literal)]` on by default + +error: aborting due to 1 previous error +
diff --git a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr index a75542f..7c17616 100644 --- a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr +++ b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr
@@ -9,9 +9,14 @@ | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | - = note: `Vec<()>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + = note: `Vec<()>` is not usable in patterns | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: add a condition to the match arm checking for equality + | +LL - EMPTY => {} +LL + binding if binding == EMPTY => {} + | error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr index ed465ea..f776623 100644 --- a/tests/ui/pattern/issue-115599.stderr +++ b/tests/ui/pattern/issue-115599.stderr
@@ -9,9 +9,14 @@ | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | - = note: `Vec<u8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns + = note: `Vec<u8>` is not usable in patterns | = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +help: check for equality instead of pattern matching + | +LL - if let CONST_STRING = empty_str {} +LL + if CONST_STRING == empty_str {} + | error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/pattern-match-invalid-variant.stderr b/tests/ui/pattern/pattern-match-invalid-variant.stderr index 08a99f6..94373af 100644 --- a/tests/ui/pattern/pattern-match-invalid-variant.stderr +++ b/tests/ui/pattern/pattern-match-invalid-variant.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no variant or associated item named `Hsl` found for enum `Color` in the current scope +error[E0599]: no variant, associated function, or constant named `Hsl` found for enum `Color` in the current scope --> $DIR/pattern-match-invalid-variant.rs:14:16 | LL | enum Color { - | ---------- variant or associated item `Hsl` not found for this enum + | ---------- variant, associated function, or constant `Hsl` not found for this enum ... LL | Color::Hsl(h, s, l) => { - | ^^^ variant or associated item not found in `Color` + | ^^^ variant, associated function, or constant not found in `Color` error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index f9da043..66aa551 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq<usize> for MyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: check for equality instead of pattern matching + | +LL - if let CONSTANT = &&MyType { +LL + if CONSTANT == &&MyType { + | error: aborting due to 1 previous error
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index d26ba93..75a633c 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -9,13 +9,13 @@ | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -26,7 +26,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -41,7 +41,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:69:9 + --> $DIR/empty-types.rs:68:9 | LL | (_, _) => {} | ^^^^^^------ @@ -52,7 +52,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:75:9 + --> $DIR/empty-types.rs:74:9 | LL | _ => {} | ^------ @@ -63,7 +63,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:78:9 + --> $DIR/empty-types.rs:77:9 | LL | (_, _) => {} | ^^^^^^------ @@ -74,7 +74,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -85,7 +85,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -104,7 +104,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:93:9 + --> $DIR/empty-types.rs:92:9 | LL | Err(_) => {} | ^^^^^^------ @@ -115,7 +115,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:98:9 + --> $DIR/empty-types.rs:97:9 | LL | Err(_) => {} | ^^^^^^------ @@ -126,7 +126,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -144,7 +144,7 @@ | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -158,7 +158,7 @@ | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:111:9 + --> $DIR/empty-types.rs:110:9 | LL | _ => {} | ^------ @@ -169,7 +169,18 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:114:9 + --> $DIR/empty-types.rs:113:9 + | +LL | Ok(_) => {} + | ^^^^^------ + | | + | matches no values because `Result<!, !>` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/empty-types.rs:116:9 | LL | Ok(_) => {} | ^^^^^------ @@ -182,17 +193,6 @@ error: unreachable pattern --> $DIR/empty-types.rs:117:9 | -LL | Ok(_) => {} - | ^^^^^------ - | | - | matches no values because `Result<!, !>` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/empty-types.rs:118:9 - | LL | _ => {} | ^------ | | @@ -202,7 +202,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:121:9 + --> $DIR/empty-types.rs:120:9 | LL | Ok(_) => {} | ^^^^^------ @@ -213,7 +213,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:122:9 + --> $DIR/empty-types.rs:121:9 | LL | Err(_) => {} | ^^^^^^------ @@ -224,7 +224,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -235,7 +235,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -246,7 +246,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:142:13 + --> $DIR/empty-types.rs:141:13 | LL | Some(_) => {} | ^^^^^^^------ @@ -257,7 +257,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:146:13 + --> $DIR/empty-types.rs:145:13 | LL | None => {} | ---- matches all the relevant values @@ -265,7 +265,7 @@ | ^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -276,7 +276,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -287,7 +287,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -298,7 +298,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -309,7 +309,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -320,7 +320,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -331,7 +331,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:283:9 + --> $DIR/empty-types.rs:282:9 | LL | (_, _) => {} | ^^^^^^------ @@ -342,7 +342,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:286:9 + --> $DIR/empty-types.rs:285:9 | LL | Ok(_) => {} | ^^^^^------ @@ -353,7 +353,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:287:9 + --> $DIR/empty-types.rs:286:9 | LL | Err(_) => {} | ^^^^^^------ @@ -364,7 +364,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -378,7 +378,7 @@ | error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[]` not covered @@ -391,7 +391,7 @@ | error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[]` not covered @@ -405,7 +405,7 @@ | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -419,7 +419,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:367:9 + --> $DIR/empty-types.rs:366:9 | LL | _ => {} | ^------ @@ -430,7 +430,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:370:9 + --> $DIR/empty-types.rs:369:9 | LL | [_, _, _] => {} | ^^^^^^^^^------ @@ -441,7 +441,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:373:9 + --> $DIR/empty-types.rs:372:9 | LL | [_, ..] => {} | ^^^^^^^------ @@ -452,7 +452,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -466,7 +466,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -474,7 +474,7 @@ | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -488,7 +488,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:415:9 + --> $DIR/empty-types.rs:414:9 | LL | Some(_) => {} | ^^^^^^^------ @@ -499,7 +499,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:420:9 + --> $DIR/empty-types.rs:419:9 | LL | Some(_a) => {} | ^^^^^^^^------ @@ -510,7 +510,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:425:9 + --> $DIR/empty-types.rs:424:9 | LL | None => {} | ---- matches all the relevant values @@ -519,7 +519,7 @@ | ^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:430:9 + --> $DIR/empty-types.rs:429:9 | LL | None => {} | ---- matches all the relevant values @@ -528,7 +528,7 @@ | ^^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -539,7 +539,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -550,7 +550,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -561,7 +561,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^---------------
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 55d6eb8..046c0d5 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -1,14 +1,5 @@ -warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-types.rs:11:33 - | -LL | #![cfg_attr(never_pats, feature(never_patterns))] - | ^^^^^^^^^^^^^^ - | - = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information - = note: `#[warn(incomplete_features)]` on by default - error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -18,13 +9,13 @@ | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -35,7 +26,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -50,7 +41,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -61,7 +52,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -80,7 +71,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -98,7 +89,7 @@ | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -112,7 +103,7 @@ | ++++++++++++++++ error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:105:9 + --> $DIR/empty-types.rs:104:9 | LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(!)` not covered @@ -126,7 +117,7 @@ | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -137,7 +128,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -148,7 +139,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:155:15 + --> $DIR/empty-types.rs:154:15 | LL | match *ref_opt_void { | ^^^^^^^^^^^^^ pattern `Some(!)` not covered @@ -167,7 +158,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -178,7 +169,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -189,7 +180,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -200,7 +191,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -211,7 +202,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -222,7 +213,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -233,7 +224,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:296:13 + --> $DIR/empty-types.rs:295:13 | LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(!)` not covered @@ -247,7 +238,7 @@ | ++ +++++++++++ error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:315:11 + --> $DIR/empty-types.rs:314:11 | LL | match *x {} | ^^ @@ -261,7 +252,7 @@ | error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty - --> $DIR/empty-types.rs:317:11 + --> $DIR/empty-types.rs:316:11 | LL | match *x {} | ^^ @@ -275,7 +266,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(!)` and `Err(!)` not covered - --> $DIR/empty-types.rs:319:11 + --> $DIR/empty-types.rs:318:11 | LL | match *x {} | ^^ patterns `Ok(!)` and `Err(!)` not covered @@ -297,7 +288,7 @@ | error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty - --> $DIR/empty-types.rs:321:11 + --> $DIR/empty-types.rs:320:11 | LL | match *x {} | ^^ @@ -311,7 +302,7 @@ | error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -325,7 +316,7 @@ | error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered - --> $DIR/empty-types.rs:328:11 + --> $DIR/empty-types.rs:327:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[!, ..]` not covered @@ -339,7 +330,7 @@ | error[E0004]: non-exhaustive patterns: `&[]`, `&[!]` and `&[!, !]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]`, `&[!]` and `&[!, !]` not covered @@ -352,7 +343,7 @@ | error[E0004]: non-exhaustive patterns: `&[]` and `&[!, ..]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]` and `&[!, ..]` not covered @@ -366,7 +357,7 @@ | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -380,7 +371,7 @@ | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -394,7 +385,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -402,7 +393,7 @@ | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -416,7 +407,7 @@ | error[E0004]: non-exhaustive patterns: `&Some(!)` not covered - --> $DIR/empty-types.rs:450:11 + --> $DIR/empty-types.rs:449:11 | LL | match ref_opt_never { | ^^^^^^^^^^^^^ pattern `&Some(!)` not covered @@ -435,7 +426,7 @@ | error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:491:11 + --> $DIR/empty-types.rs:490:11 | LL | match *ref_opt_never { | ^^^^^^^^^^^^^^ pattern `Some(!)` not covered @@ -454,7 +445,7 @@ | error[E0004]: non-exhaustive patterns: `Err(!)` not covered - --> $DIR/empty-types.rs:539:11 + --> $DIR/empty-types.rs:538:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(!)` not covered @@ -473,7 +464,7 @@ | error[E0004]: non-exhaustive patterns: `Err(!)` not covered - --> $DIR/empty-types.rs:550:11 + --> $DIR/empty-types.rs:549:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(!)` not covered @@ -492,7 +483,7 @@ | error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:569:11 + --> $DIR/empty-types.rs:568:11 | LL | match *ref_tuple_half_never {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -506,7 +497,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -517,7 +508,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -528,7 +519,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -539,7 +530,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^--------------- @@ -550,7 +541,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `&!` not covered - --> $DIR/empty-types.rs:636:11 + --> $DIR/empty-types.rs:635:11 | LL | match ref_never { | ^^^^^^^^^ pattern `&!` not covered @@ -566,7 +557,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(!)` not covered - --> $DIR/empty-types.rs:652:11 + --> $DIR/empty-types.rs:651:11 | LL | match *ref_result_never { | ^^^^^^^^^^^^^^^^^ pattern `Ok(!)` not covered @@ -585,7 +576,7 @@ | error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:672:11 + --> $DIR/empty-types.rs:671:11 | LL | match *x { | ^^ pattern `Some(!)` not covered @@ -603,7 +594,7 @@ LL + Some(!) | -error: aborting due to 42 previous errors; 1 warning emitted +error: aborting due to 42 previous errors Some errors have detailed explanations: E0004, E0005. For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index 0ed8c21..ba158c1 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -9,13 +9,13 @@ | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -26,7 +26,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -41,7 +41,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -52,7 +52,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -71,7 +71,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -89,7 +89,7 @@ | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -103,7 +103,7 @@ | ++++++++++++++++ error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:105:9 + --> $DIR/empty-types.rs:104:9 | LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(_)` not covered @@ -117,7 +117,7 @@ | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -128,7 +128,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -139,7 +139,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:155:15 + --> $DIR/empty-types.rs:154:15 | LL | match *ref_opt_void { | ^^^^^^^^^^^^^ pattern `Some(_)` not covered @@ -158,7 +158,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -169,7 +169,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -180,7 +180,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -191,7 +191,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -202,7 +202,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -213,7 +213,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -224,7 +224,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:296:13 + --> $DIR/empty-types.rs:295:13 | LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(_)` not covered @@ -238,7 +238,7 @@ | ++ +++++++++++ error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:315:11 + --> $DIR/empty-types.rs:314:11 | LL | match *x {} | ^^ @@ -252,7 +252,7 @@ | error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty - --> $DIR/empty-types.rs:317:11 + --> $DIR/empty-types.rs:316:11 | LL | match *x {} | ^^ @@ -266,7 +266,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered - --> $DIR/empty-types.rs:319:11 + --> $DIR/empty-types.rs:318:11 | LL | match *x {} | ^^ patterns `Ok(_)` and `Err(_)` not covered @@ -288,7 +288,7 @@ | error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty - --> $DIR/empty-types.rs:321:11 + --> $DIR/empty-types.rs:320:11 | LL | match *x {} | ^^ @@ -302,7 +302,7 @@ | error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -316,7 +316,7 @@ | error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/empty-types.rs:328:11 + --> $DIR/empty-types.rs:327:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[_, ..]` not covered @@ -330,7 +330,7 @@ | error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered @@ -343,7 +343,7 @@ | error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered @@ -357,7 +357,7 @@ | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -371,7 +371,7 @@ | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -393,7 +393,7 @@ | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -407,7 +407,7 @@ | error[E0004]: non-exhaustive patterns: `&Some(_)` not covered - --> $DIR/empty-types.rs:450:11 + --> $DIR/empty-types.rs:449:11 | LL | match ref_opt_never { | ^^^^^^^^^^^^^ pattern `&Some(_)` not covered @@ -426,7 +426,7 @@ | error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:491:11 + --> $DIR/empty-types.rs:490:11 | LL | match *ref_opt_never { | ^^^^^^^^^^^^^^ pattern `Some(_)` not covered @@ -445,7 +445,7 @@ | error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:539:11 + --> $DIR/empty-types.rs:538:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered @@ -464,7 +464,7 @@ | error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:550:11 + --> $DIR/empty-types.rs:549:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered @@ -483,7 +483,7 @@ | error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:569:11 + --> $DIR/empty-types.rs:568:11 | LL | match *ref_tuple_half_never {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -497,7 +497,7 @@ | error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -508,7 +508,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -519,7 +519,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -530,7 +530,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^--------------- @@ -541,7 +541,7 @@ = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `&_` not covered - --> $DIR/empty-types.rs:636:11 + --> $DIR/empty-types.rs:635:11 | LL | match ref_never { | ^^^^^^^^^ pattern `&_` not covered @@ -557,7 +557,7 @@ | error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:652:11 + --> $DIR/empty-types.rs:651:11 | LL | match *ref_result_never { | ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -576,7 +576,7 @@ | error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:672:11 + --> $DIR/empty-types.rs:671:11 | LL | match *x { | ^^ pattern `Some(_)` not covered
diff --git a/tests/ui/pattern/usefulness/empty-types.rs b/tests/ui/pattern/usefulness/empty-types.rs index a503295..d4fdb7c 100644 --- a/tests/ui/pattern/usefulness/empty-types.rs +++ b/tests/ui/pattern/usefulness/empty-types.rs
@@ -9,7 +9,6 @@ #![feature(never_type)] #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![cfg_attr(never_pats, feature(never_patterns))] -//[never_pats]~^ WARN the feature `never_patterns` is incomplete #![allow(dead_code, unreachable_code)] #![deny(unreachable_patterns)]
diff --git a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs index a95665f..b5a0c6e 100644 --- a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs +++ b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(pin_ergonomics)] -//~^ WARN the feature `pin_ergonomics` is incomplete use std::pin::Pin;
diff --git a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr deleted file mode 100644 index 2deb5b0..0000000 --- a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `pin_ergonomics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-non-pointer-pin.rs:3:12 - | -LL | #![feature(pin_ergonomics)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/precondition-checks/alignment.rs b/tests/ui/precondition-checks/alignment.rs index 038a625..3f0eae4 100644 --- a/tests/ui/precondition-checks/alignment.rs +++ b/tests/ui/precondition-checks/alignment.rs
@@ -6,6 +6,6 @@ fn main() { unsafe { - std::ptr::Alignment::new_unchecked(0); + std::mem::Alignment::new_unchecked(0); } }
diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index 6a0ac2b..299fe9a 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs
@@ -49,10 +49,10 @@ pub trait Tr3 { fn f<T: PrivTr>(arg: T) {} //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f` fn g() -> impl PrivTr; - //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` + //~^ ERROR private trait `traits::PrivTr` in public interface //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` fn h() -> impl PrivTr {} - //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` + //~^ ERROR private trait `traits::PrivTr` in public interface //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` } impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>` @@ -93,13 +93,13 @@ pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more priva pub trait Tr5 { fn required() -> impl PrivTr<Priv<()>>; - //~^ ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}` - //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` + //~^ ERROR private trait `generics::PrivTr<generics::Priv<()>>` in public interface + //~| ERROR private type `generics::Priv<()>` in public interface //~| ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}` //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` fn provided() -> impl PrivTr<Priv<()>> {} - //~^ ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}` - //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` + //~^ ERROR private trait `generics::PrivTr<generics::Priv<()>>` in public interface + //~| ERROR private type `generics::Priv<()>` in public interface //~| ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}` //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` }
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index 1fd648f..649b117 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -194,17 +194,14 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ -error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` +error[E0446]: private trait `traits::PrivTr` in public interface --> $DIR/private-in-public-warn.rs:51:19 | -LL | fn g() -> impl PrivTr; - | ^^^^^^^^^^^ opaque type `traits::Tr3::g::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:37:5 - | LL | trait PrivTr {} - | ^^^^^^^^^^^^ + | ------------ `traits::PrivTr` declared as private +... +LL | fn g() -> impl PrivTr; + | ^^^^^^^^^^^ can't leak private trait error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` --> $DIR/private-in-public-warn.rs:51:19 @@ -218,17 +215,14 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ -error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` +error[E0446]: private trait `traits::PrivTr` in public interface --> $DIR/private-in-public-warn.rs:54:19 | -LL | fn h() -> impl PrivTr {} - | ^^^^^^^^^^^ opaque type `traits::Tr3::h::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:37:5 - | LL | trait PrivTr {} - | ^^^^^^^^^^^^ + | ------------ `traits::PrivTr` declared as private +... +LL | fn h() -> impl PrivTr {} + | ^^^^^^^^^^^ can't leak private trait error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` --> $DIR/private-in-public-warn.rs:54:19 @@ -350,29 +344,23 @@ LL | struct Priv<T = u8>(T); | ^^^^^^^^^^^^^^^^^^^ -error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}` +error[E0446]: private trait `generics::PrivTr<generics::Priv<()>>` in public interface --> $DIR/private-in-public-warn.rs:95:26 | -LL | fn required() -> impl PrivTr<Priv<()>>; - | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but trait `generics::PrivTr<generics::Priv<()>>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:84:5 - | LL | trait PrivTr<T> {} - | ^^^^^^^^^^^^^^^ + | --------------- `generics::PrivTr<generics::Priv<()>>` declared as private +... +LL | fn required() -> impl PrivTr<Priv<()>>; + | ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error: type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` +error[E0446]: private type `generics::Priv<()>` in public interface --> $DIR/private-in-public-warn.rs:95:26 | -LL | fn required() -> impl PrivTr<Priv<()>>; - | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:82:5 - | LL | struct Priv<T = u8>(T); - | ^^^^^^^^^^^^^^^^^^^ + | ------------------- `generics::Priv<()>` declared as private +... +LL | fn required() -> impl PrivTr<Priv<()>>; + | ^^^^^^^^^^^^^^^^^^^^^ can't leak private type error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}` --> $DIR/private-in-public-warn.rs:95:26 @@ -398,29 +386,23 @@ LL | struct Priv<T = u8>(T); | ^^^^^^^^^^^^^^^^^^^ -error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}` +error[E0446]: private trait `generics::PrivTr<generics::Priv<()>>` in public interface --> $DIR/private-in-public-warn.rs:100:26 | -LL | fn provided() -> impl PrivTr<Priv<()>> {} - | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but trait `generics::PrivTr<generics::Priv<()>>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:84:5 - | LL | trait PrivTr<T> {} - | ^^^^^^^^^^^^^^^ + | --------------- `generics::PrivTr<generics::Priv<()>>` declared as private +... +LL | fn provided() -> impl PrivTr<Priv<()>> {} + | ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error: type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` +error[E0446]: private type `generics::Priv<()>` in public interface --> $DIR/private-in-public-warn.rs:100:26 | -LL | fn provided() -> impl PrivTr<Priv<()>> {} - | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` - | -note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:82:5 - | LL | struct Priv<T = u8>(T); - | ^^^^^^^^^^^^^^^^^^^ + | ------------------- `generics::Priv<()>` declared as private +... +LL | fn provided() -> impl PrivTr<Priv<()>> {} + | ^^^^^^^^^^^^^^^^^^^^^ can't leak private type error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}` --> $DIR/private-in-public-warn.rs:100:26
diff --git a/tests/ui/privacy/ufc-method-call.different_name.stderr b/tests/ui/privacy/ufc-method-call.different_name.stderr index c65fe51..5d722c6 100644 --- a/tests/ui/privacy/ufc-method-call.different_name.stderr +++ b/tests/ui/privacy/ufc-method-call.different_name.stderr
@@ -1,13 +1,13 @@ -error[E0599]: no function or associated item named `foo` found for struct `Foo<B>` in the current scope +error[E0599]: no associated function or constant named `foo` found for struct `Foo<B>` in the current scope --> $DIR/ufc-method-call.rs:27:27 | LL | pub struct Foo<T>(T); - | ----------------- function or associated item `foo` not found for this struct + | ----------------- associated function or constant `foo` not found for this struct ... LL | test::Foo::<test::B>::foo(); - | ^^^ function or associated item not found in `Foo<B>` + | ^^^ associated function or constant not found in `Foo<B>` | - = note: the function or associated item was found for `Foo<A>` + = note: the associated function or constant was found for `Foo<A>` error: aborting due to 1 previous error
diff --git a/tests/ui/privacy/ufc-method-call.rs b/tests/ui/privacy/ufc-method-call.rs index 525d9a9..87efbc7 100644 --- a/tests/ui/privacy/ufc-method-call.rs +++ b/tests/ui/privacy/ufc-method-call.rs
@@ -26,5 +26,5 @@ fn bar() {} fn main() { test::Foo::<test::B>::foo(); //[same_name]~^ ERROR associated function `foo` is private - //[different_name]~^^ ERROR no function or associated item named `foo` found for struct `Foo<B>` + //[different_name]~^^ ERROR no associated function or constant named `foo` found for struct `Foo<B>` }
diff --git a/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr index 0990816..1d7b5ab 100644 --- a/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr +++ b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^^ LL | #[allow(dead_code)] LL | struct Test {} - | ---- the inner attribute doesn't annotate this struct + | -------------- the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/range/new_range_stability.rs b/tests/ui/range/new_range_stability.rs index 2d129fb..965be17 100644 --- a/tests/ui/range/new_range_stability.rs +++ b/tests/ui/range/new_range_stability.rs
@@ -1,6 +1,13 @@ // Stable -use std::range::{RangeInclusive, RangeInclusiveIter, RangeToInclusive}; +use std::range::{ + RangeInclusive, + RangeInclusiveIter, + RangeToInclusive, + RangeFrom, + RangeFromIter, + Range, +}; fn range_inclusive(mut r: RangeInclusive<usize>) { &[1, 2, 3][r]; // Indexing @@ -13,7 +20,7 @@ fn range_inclusive(mut r: RangeInclusive<usize>) { let mut i = r.into_iter(); i.next(); - i.remainder(); + i.remainder(); //~ ERROR unstable } fn range_to_inclusive(mut r: RangeToInclusive<usize>) { @@ -23,15 +30,38 @@ fn range_to_inclusive(mut r: RangeToInclusive<usize>) { r.contains(&5); } +fn range_from(mut r: RangeFrom<usize>) { + &[1, 2, 3][r]; // Indexing + + r.start; + r.contains(&5); + r.iter(); + + let mut i = r.into_iter(); + i.next(); + + // Left unstable + i.remainder(); //~ ERROR unstable +} + +fn range(mut r: Range<usize>) { + &[1, 2, 3][r]; + + r.start; + r.end; + r.contains(&5); + r.is_empty(); + r.iter(); + + let mut i = r.into_iter(); + i.next(); + + // Left unstable + i.remainder(); //~ ERROR unstable +} + // Unstable module use std::range::legacy; //~ ERROR unstable -// Unstable types - -use std::range::RangeFrom; //~ ERROR unstable -use std::range::Range; //~ ERROR unstable -use std::range::RangeFromIter; //~ ERROR unstable -use std::range::RangeIter; //~ ERROR unstable - fn main() {}
diff --git a/tests/ui/range/new_range_stability.stderr b/tests/ui/range/new_range_stability.stderr index b5a7e06..ac269a2 100644 --- a/tests/ui/range/new_range_stability.stderr +++ b/tests/ui/range/new_range_stability.stderr
@@ -1,53 +1,43 @@ -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:28:5 +error[E0658]: use of unstable library feature `new_range_api_legacy` + --> $DIR/new_range_stability.rs:65:5 | LL | use std::range::legacy; | ^^^^^^^^^^^^^^^^^^ | = note: see issue #125687 <https://github.com/rust-lang/rust/issues/125687> for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = help: add `#![feature(new_range_api_legacy)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:32:5 +error[E0658]: use of unstable library feature `new_range_remainder` + --> $DIR/new_range_stability.rs:23:7 | -LL | use std::range::RangeFrom; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | i.remainder(); + | ^^^^^^^^^ | - = note: see issue #125687 <https://github.com/rust-lang/rust/issues/125687> for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = note: see issue #154458 <https://github.com/rust-lang/rust/issues/154458> for more information + = help: add `#![feature(new_range_remainder)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:33:5 +error[E0658]: use of unstable library feature `new_range_remainder` + --> $DIR/new_range_stability.rs:44:7 | -LL | use std::range::Range; - | ^^^^^^^^^^^^^^^^^ +LL | i.remainder(); + | ^^^^^^^^^ | - = note: see issue #125687 <https://github.com/rust-lang/rust/issues/125687> for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = note: see issue #154458 <https://github.com/rust-lang/rust/issues/154458> for more information + = help: add `#![feature(new_range_remainder)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:34:5 +error[E0658]: use of unstable library feature `new_range_remainder` + --> $DIR/new_range_stability.rs:60:7 | -LL | use std::range::RangeFromIter; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | i.remainder(); + | ^^^^^^^^^ | - = note: see issue #125687 <https://github.com/rust-lang/rust/issues/125687> for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable + = note: see issue #154458 <https://github.com/rust-lang/rust/issues/154458> for more information + = help: add `#![feature(new_range_remainder)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:35:5 - | -LL | use std::range::RangeIter; - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #125687 <https://github.com/rust-lang/rust/issues/125687> for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/reachable/never-pattern-closure-param-array.rs b/tests/ui/reachable/never-pattern-closure-param-array.rs new file mode 100644 index 0000000..83bbc4b --- /dev/null +++ b/tests/ui/reachable/never-pattern-closure-param-array.rs
@@ -0,0 +1,13 @@ +//@ check-pass +//@ edition: 2024 + +#![feature(never_patterns)] +#![allow(incomplete_features)] +#![allow(unreachable_code)] + +fn main() { + let _ = Some({ + return; + }) + .map(|!| [1]); +}
diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr index ba44beb..c98b9bb 100644 --- a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr
@@ -7,7 +7,7 @@ LL | extract(x).max(2); | ---------- type must be known at this point | -help: consider giving `x` an explicit type, where the type for type parameter `T` is specified +help: consider giving `x` an explicit type, where the placeholders `_` are specified | LL | let x: [Foo<T>; 2] = [Foo(PhantomData); 2]; | +++++++++++++
diff --git a/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs b/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs new file mode 100644 index 0000000..dc8b572 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs
@@ -0,0 +1,9 @@ +pub mod utils { + pub fn root_helper() { + println!("root_helper"); + } +} + +pub fn root_function() -> String { + "my_api root!".to_string() +}
diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api.rs b/tests/ui/resolve/auxiliary/open-ns-my_api.rs new file mode 100644 index 0000000..be4bf31 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api.rs
@@ -0,0 +1,3 @@ +pub fn root_function() -> String { + "my_api root!".to_string() +}
diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs b/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs new file mode 100644 index 0000000..41418f1 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs
@@ -0,0 +1,15 @@ +// #![crate_name = "my_api::core"] + +pub mod util { + pub fn core_mod_fn() -> String { + format!("core_fn from my_api::core::util",) + } +} + +pub fn core_fn() -> String { + format!("core_fn from my_api::core!",) +} + +pub fn core_fn2() -> String { + format!("core_fn2 from my_api::core!",) +}
diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs b/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs new file mode 100644 index 0000000..d2af207 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs
@@ -0,0 +1,13 @@ +pub mod util { + pub fn util_mod_helper() -> String { + format!("Helper from my_api::utils::util",) + } +} + +pub fn utils_helper() -> String { + format!("Helper from my_api::utils!",) +} + +pub fn get_u32() -> u32 { + 1 +}
diff --git a/tests/ui/resolve/empty-struct-braces-expr.rs b/tests/ui/resolve/empty-struct-braces-expr.rs index c10f76b..f6a1742 100644 --- a/tests/ui/resolve/empty-struct-braces-expr.rs +++ b/tests/ui/resolve/empty-struct-braces-expr.rs
@@ -22,8 +22,8 @@ fn main() { let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` let xe1 = XEmpty1(); //~^ ERROR expected function, tuple struct or tuple variant, found struct `XEmpty1` - let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for enum - let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for enum + let xe3 = XE::Empty3; //~ ERROR no variant, associated function, or constant named `Empty3` found for enum + let xe3 = XE::Empty3(); //~ ERROR no variant, associated function, or constant named `Empty3` found for enum XE::Empty1 {}; //~ ERROR no variant named `Empty1` found for enum `empty_struct::XE` }
diff --git a/tests/ui/resolve/empty-struct-braces-expr.stderr b/tests/ui/resolve/empty-struct-braces-expr.stderr index a176107..f496708 100644 --- a/tests/ui/resolve/empty-struct-braces-expr.stderr +++ b/tests/ui/resolve/empty-struct-braces-expr.stderr
@@ -117,22 +117,22 @@ LL + let xe1 = XEmpty2(); | -error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope +error[E0599]: no variant, associated function, or constant named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:25:19 | LL | let xe3 = XE::Empty3; - | ^^^^^^ variant or associated item not found in `empty_struct::XE` + | ^^^^^^ variant, associated function, or constant not found in `empty_struct::XE` | help: there is a variant with a similar name | LL | let xe3 = XE::XEmpty3; | + -error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope +error[E0599]: no variant, associated function, or constant named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:26:19 | LL | let xe3 = XE::Empty3(); - | ^^^^^^ variant or associated item not found in `empty_struct::XE` + | ^^^^^^ variant, associated function, or constant not found in `empty_struct::XE` | help: there is a variant with a similar name |
diff --git a/tests/ui/resolve/filter-intrinsics.rs b/tests/ui/resolve/filter-intrinsics.rs index 8d6d228..9998bec 100644 --- a/tests/ui/resolve/filter-intrinsics.rs +++ b/tests/ui/resolve/filter-intrinsics.rs
@@ -3,8 +3,8 @@ let _ = transmute::<usize>(); //~^ ERROR cannot find - // Should suggest `std::intrinsics::fabsf64`, + // Should suggest `std::intrinsics::fabs`, // since there is no non-intrinsic to suggest. - let _ = fabsf64(1.0); + let _ = fabs(1.0); //~^ ERROR cannot find }
diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 9c9e92f..3870cfc 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr
@@ -9,15 +9,15 @@ LL + use std::mem::transmute; | -error[E0425]: cannot find function `fabsf64` in this scope +error[E0425]: cannot find function `fabs` in this scope --> $DIR/filter-intrinsics.rs:8:13 | -LL | let _ = fabsf64(1.0); - | ^^^^^^^ not found in this scope +LL | let _ = fabs(1.0); + | ^^^^ not found in this scope | help: consider importing this function | -LL + use std::intrinsics::fabsf64; +LL + use std::intrinsics::fabs; | error: aborting due to 2 previous errors
diff --git a/tests/ui/resolve/issue-82865.rs b/tests/ui/resolve/issue-82865.rs index 545ca63..2307251 100644 --- a/tests/ui/resolve/issue-82865.rs +++ b/tests/ui/resolve/issue-82865.rs
@@ -6,7 +6,7 @@ use x::y::z; //~ ERROR: cannot find module or crate `x` macro mac () { - Box::z //~ ERROR: no function or associated item + Box::z //~ ERROR: no associated function or constant } fn main() {
diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr index 90059ad..198f7f8 100644 --- a/tests/ui/resolve/issue-82865.stderr +++ b/tests/ui/resolve/issue-82865.stderr
@@ -9,11 +9,11 @@ LL + extern crate x; | -error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope +error[E0599]: no associated function or constant named `z` found for struct `Box<_, _>` in the current scope --> $DIR/issue-82865.rs:9:10 | LL | Box::z - | ^ function or associated item not found in `Box<_, _>` + | ^ associated function or constant not found in `Box<_, _>` ... LL | mac!(); | ------ in this macro invocation
diff --git a/tests/ui/resolve/missing-associated-items.rs b/tests/ui/resolve/missing-associated-items.rs index 72d6cbb..1308ce5 100644 --- a/tests/ui/resolve/missing-associated-items.rs +++ b/tests/ui/resolve/missing-associated-items.rs
@@ -14,8 +14,8 @@ fn use_token(token: &Token) { } fn main() { - use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura` - Struct::method(); //~ ERROR no function or associated item named `method` found - Struct::method; //~ ERROR no function or associated item named `method` found - Struct::Assoc; //~ ERROR no associated item named `Assoc` found + use_token(&Token::Homura); //~ ERROR no variant, associated function, or constant named `Homura` + Struct::method(); //~ ERROR no associated function or constant named `method` found + Struct::method; //~ ERROR no associated function or constant named `method` found + Struct::Assoc; //~ ERROR no associated function or constant named `Assoc` found }
diff --git a/tests/ui/resolve/missing-associated-items.stderr b/tests/ui/resolve/missing-associated-items.stderr index d27a3a6..3bc63de 100644 --- a/tests/ui/resolve/missing-associated-items.stderr +++ b/tests/ui/resolve/missing-associated-items.stderr
@@ -1,38 +1,38 @@ -error[E0599]: no variant or associated item named `Homura` found for enum `Token` in the current scope +error[E0599]: no variant, associated function, or constant named `Homura` found for enum `Token` in the current scope --> $DIR/missing-associated-items.rs:17:23 | LL | enum Token { - | ---------- variant or associated item `Homura` not found for this enum + | ---------- variant, associated function, or constant `Homura` not found for this enum ... LL | use_token(&Token::Homura); - | ^^^^^^ variant or associated item not found in `Token` + | ^^^^^^ variant, associated function, or constant not found in `Token` -error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope +error[E0599]: no associated function or constant named `method` found for struct `Struct` in the current scope --> $DIR/missing-associated-items.rs:18:13 | LL | struct Struct { - | ------------- function or associated item `method` not found for this struct + | ------------- associated function or constant `method` not found for this struct ... LL | Struct::method(); - | ^^^^^^ function or associated item not found in `Struct` + | ^^^^^^ associated function or constant not found in `Struct` -error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope +error[E0599]: no associated function or constant named `method` found for struct `Struct` in the current scope --> $DIR/missing-associated-items.rs:19:13 | LL | struct Struct { - | ------------- function or associated item `method` not found for this struct + | ------------- associated function or constant `method` not found for this struct ... LL | Struct::method; - | ^^^^^^ function or associated item not found in `Struct` + | ^^^^^^ associated function or constant not found in `Struct` -error[E0599]: no associated item named `Assoc` found for struct `Struct` in the current scope +error[E0599]: no associated function or constant named `Assoc` found for struct `Struct` in the current scope --> $DIR/missing-associated-items.rs:20:13 | LL | struct Struct { - | ------------- associated item `Assoc` not found for this struct + | ------------- associated function or constant `Assoc` not found for this struct ... LL | Struct::Assoc; - | ^^^^^ associated item not found in `Struct` + | ^^^^^ associated function or constant not found in `Struct` error: aborting due to 4 previous errors
diff --git a/tests/ui/resolve/open-ns-1.rs b/tests/ui/resolve/open-ns-1.rs new file mode 100644 index 0000000..e77ddbe --- /dev/null +++ b/tests/ui/resolve/open-ns-1.rs
@@ -0,0 +1,19 @@ +//@ aux-crate:my_api=open-ns-my_api.rs +//@ aux-crate:my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate:my_api::core=open-ns-my_api_core.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::root_function; +use my_api::utils::util; +//~^ ERROR unresolved import `my_api::utils` + +fn main() { + let _ = root_function(); + let _ = my_api::root_function(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] + let _ = util::util_mod_helper(); + let _ = my_api::core::core_fn(); + //~^ ERROR cannot find `core` in `my_api` [E0433] +}
diff --git a/tests/ui/resolve/open-ns-1.stderr b/tests/ui/resolve/open-ns-1.stderr new file mode 100644 index 0000000..65b9c6a --- /dev/null +++ b/tests/ui/resolve/open-ns-1.stderr
@@ -0,0 +1,22 @@ +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-1.rs:8:13 + | +LL | use my_api::utils::util; + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-1.rs:14:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `core` in `my_api` + --> $DIR/open-ns-1.rs:17:21 + | +LL | let _ = my_api::core::core_fn(); + | ^^^^ could not find `core` in `my_api` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0432, E0433. +For more information about an error, try `rustc --explain E0432`.
diff --git a/tests/ui/resolve/open-ns-10.rs b/tests/ui/resolve/open-ns-10.rs new file mode 100644 index 0000000..b05a0ab --- /dev/null +++ b/tests/ui/resolve/open-ns-10.rs
@@ -0,0 +1,8 @@ +// Tests that namespaced crate names are limited to two segments + +//@ aux-crate: nscrate::three::segments=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//~? ERROR crate name `nscrate::three::segments` passed to `--extern` can have at most two segments. + +fn main() {}
diff --git a/tests/ui/resolve/open-ns-10.stderr b/tests/ui/resolve/open-ns-10.stderr new file mode 100644 index 0000000..fdef748 --- /dev/null +++ b/tests/ui/resolve/open-ns-10.stderr
@@ -0,0 +1,2 @@ +error: crate name `nscrate::three::segments` passed to `--extern` can have at most two segments. +
diff --git a/tests/ui/resolve/open-ns-11.rs b/tests/ui/resolve/open-ns-11.rs new file mode 100644 index 0000000..90e85a9 --- /dev/null +++ b/tests/ui/resolve/open-ns-11.rs
@@ -0,0 +1,12 @@ +// Tests that std has higher precedence than an open module with the same name. + +//@ aux-crate: std::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use std::utils::get_u32; +//~^ ERROR unresolved import `std::utils` + +fn main() { + let _ = get_u32(); +}
diff --git a/tests/ui/resolve/open-ns-11.stderr b/tests/ui/resolve/open-ns-11.stderr new file mode 100644 index 0000000..cb073bc --- /dev/null +++ b/tests/ui/resolve/open-ns-11.stderr
@@ -0,0 +1,9 @@ +error[E0432]: unresolved import `std::utils` + --> $DIR/open-ns-11.rs:7:10 + | +LL | use std::utils::get_u32; + | ^^^^^ could not find `utils` in `std` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/resolve/open-ns-2.rs b/tests/ui/resolve/open-ns-2.rs new file mode 100644 index 0000000..6165a41 --- /dev/null +++ b/tests/ui/resolve/open-ns-2.rs
@@ -0,0 +1,18 @@ +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate: my_api::core=open-ns-my_api_core.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::core::{core_fn, core_fn2}; +//~^ ERROR unresolved import `my_api::core` [E0432] +use my_api::utils::*; +//~^ ERROR unresolved import `my_api::utils` [E0432] +use my_api::*; + +fn main() { + let _ = root_function(); + let _ = utils_helper(); + let _ = core_fn(); + let _ = core_fn2(); +}
diff --git a/tests/ui/resolve/open-ns-2.stderr b/tests/ui/resolve/open-ns-2.stderr new file mode 100644 index 0000000..0e22123 --- /dev/null +++ b/tests/ui/resolve/open-ns-2.stderr
@@ -0,0 +1,15 @@ +error[E0432]: unresolved import `my_api::core` + --> $DIR/open-ns-2.rs:7:13 + | +LL | use my_api::core::{core_fn, core_fn2}; + | ^^^^ could not find `core` in `my_api` + +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-2.rs:9:13 + | +LL | use my_api::utils::*; + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/resolve/open-ns-3.rs b/tests/ui/resolve/open-ns-3.rs new file mode 100644 index 0000000..9c78999 --- /dev/null +++ b/tests/ui/resolve/open-ns-3.rs
@@ -0,0 +1,14 @@ +// This test should fail with `utils_helper` being unresolvable in `my_api::utils`. +// If a crate contains a module that overlaps with a namespaced crate name, then +// the namespaced crate will not be used in name resolution. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate: my_api=open-ns-mod-my_api.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +fn main() { + let _ = my_api::utils::root_helper(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find function `utils_helper` in module `my_api::utils` [E0425] +}
diff --git a/tests/ui/resolve/open-ns-3.stderr b/tests/ui/resolve/open-ns-3.stderr new file mode 100644 index 0000000..8ae261a --- /dev/null +++ b/tests/ui/resolve/open-ns-3.stderr
@@ -0,0 +1,19 @@ +error[E0425]: cannot find function `utils_helper` in module `my_api::utils` + --> $DIR/open-ns-3.rs:12:28 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^^^^^^^^ not found in `my_api::utils` + | +help: consider importing this function + | +LL + use my_api::utils::utils_helper; + | +help: if you import `utils_helper`, refer to it directly + | +LL - let _ = my_api::utils::utils_helper(); +LL + let _ = utils_helper(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/resolve/open-ns-4.rs b/tests/ui/resolve/open-ns-4.rs new file mode 100644 index 0000000..4db3ad4 --- /dev/null +++ b/tests/ui/resolve/open-ns-4.rs
@@ -0,0 +1,12 @@ +// This tests that namespaced crates are shadowed. + +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +fn main() { + let _ = my_api::root_function(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] +}
diff --git a/tests/ui/resolve/open-ns-4.stderr b/tests/ui/resolve/open-ns-4.stderr new file mode 100644 index 0000000..2e6872c --- /dev/null +++ b/tests/ui/resolve/open-ns-4.stderr
@@ -0,0 +1,9 @@ +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-4.rs:10:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/resolve/open-ns-5.rs b/tests/ui/resolve/open-ns-5.rs new file mode 100644 index 0000000..8776da3 --- /dev/null +++ b/tests/ui/resolve/open-ns-5.rs
@@ -0,0 +1,18 @@ +// Tests that namespaced crate names work inside macros. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +macro_rules! import_and_call { + ($import_path:path, $fn_name:ident) => {{ + use $import_path; + $fn_name(); + }}; +} + +fn main() { + import_and_call!(my_api::utils::utils_helper, utils_helper); + let _x = 4 + 5; +}
diff --git a/tests/ui/resolve/open-ns-6.rs b/tests/ui/resolve/open-ns-6.rs new file mode 100644 index 0000000..856858a --- /dev/null +++ b/tests/ui/resolve/open-ns-6.rs
@@ -0,0 +1,13 @@ +// Tests that open modules are resolvable. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +use my_api; +use my_api::utils::utils_helper; + +fn main() { + let _ = utils_helper(); +}
diff --git a/tests/ui/resolve/open-ns-7.rs b/tests/ui/resolve/open-ns-7.rs new file mode 100644 index 0000000..cf16c59 --- /dev/null +++ b/tests/ui/resolve/open-ns-7.rs
@@ -0,0 +1,14 @@ +// Tests that namespaced crates cannot be resolved if shadowed. + +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::utils::utils_helper; +//~^ ERROR unresolved import `my_api::utils` [E0432] + +fn main() { + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] +}
diff --git a/tests/ui/resolve/open-ns-7.stderr b/tests/ui/resolve/open-ns-7.stderr new file mode 100644 index 0000000..b008547 --- /dev/null +++ b/tests/ui/resolve/open-ns-7.stderr
@@ -0,0 +1,16 @@ +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-7.rs:8:13 + | +LL | use my_api::utils::utils_helper; + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-7.rs:12:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0432, E0433. +For more information about an error, try `rustc --explain E0432`.
diff --git a/tests/ui/resolve/open-ns-8.rs b/tests/ui/resolve/open-ns-8.rs new file mode 100644 index 0000000..46aafb6 --- /dev/null +++ b/tests/ui/resolve/open-ns-8.rs
@@ -0,0 +1,23 @@ +// Tests that a macro-generated item has higher precendence than a namespaced crate +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +macro_rules! define { + () => { + pub mod my_api { + pub mod utils { + pub fn get_u32() -> u32 { + 2 + } + } + } + }; +} + +fn main() { + define!(); + let res = my_api::utils::get_u32(); + assert_eq!(res, 2); +}
diff --git a/tests/ui/resolve/open-ns-9.rs b/tests/ui/resolve/open-ns-9.rs new file mode 100644 index 0000000..7ded0b3 --- /dev/null +++ b/tests/ui/resolve/open-ns-9.rs
@@ -0,0 +1,25 @@ +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::utils::get_u32; +//~^ ERROR `my_api` is ambiguous [E0659] + +macro_rules! define { + () => { + pub mod my_api { + pub mod utils { + pub fn get_u32() -> u32 { + 2 + } + } + } + }; +} + +define!(); + +fn main() { + let val = get_u32(); + assert_eq!(val, 2); +}
diff --git a/tests/ui/resolve/open-ns-9.stderr b/tests/ui/resolve/open-ns-9.stderr new file mode 100644 index 0000000..675f487 --- /dev/null +++ b/tests/ui/resolve/open-ns-9.stderr
@@ -0,0 +1,27 @@ +error[E0659]: `my_api` is ambiguous + --> $DIR/open-ns-9.rs:5:5 + | +LL | use my_api::utils::get_u32; + | ^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution + = note: `my_api` could refer to a namespaced crate passed with `--extern` +note: `my_api` could also refer to the module defined here + --> $DIR/open-ns-9.rs:10:9 + | +LL | / pub mod my_api { +LL | | pub mod utils { +LL | | pub fn get_u32() -> u32 { +LL | | 2 +... | +LL | | } + | |_________^ +... +LL | define!(); + | --------- in this macro invocation + = help: use `crate::my_api` to refer to this module unambiguously + = note: this error originates in the macro `define` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/resolve/suggestions/suggest-builder-fn.rs b/tests/ui/resolve/suggestions/suggest-builder-fn.rs index 959675e..4552ed5 100644 --- a/tests/ui/resolve/suggestions/suggest-builder-fn.rs +++ b/tests/ui/resolve/suggestions/suggest-builder-fn.rs
@@ -50,15 +50,15 @@ fn build_private() -> Self { fn main() { // `new` not found on `TcpStream` and `connect` should be suggested let _stream = TcpStream::new(); - //~^ ERROR no function or associated item named `new` found + //~^ ERROR no associated function or constant named `new` found // Although `new` is found on `<impl Foo<T>>` it should not be // suggested because `u8` does not meet the `T: SomeTrait` constraint let _foo = Foo::<u8>::new(); - //~^ ERROR the function or associated item `new` exists for struct `Foo<u8>`, but its trait bounds were not satisfied + //~^ ERROR the associated function or constant `new` exists for struct `Foo<u8>`, but its trait bounds were not satisfied // Should suggest only `<impl Bar>::build()` and `SomeMod::<impl Bar>::build_public()`. // Other methods should not suggested because they are private or are not a builder let _bar = Bar::new(); - //~^ ERROR no function or associated item named `new` found + //~^ ERROR no associated function or constant named `new` found }
diff --git a/tests/ui/resolve/suggestions/suggest-builder-fn.stderr b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr index 9c5eed3..1eabb8e 100644 --- a/tests/ui/resolve/suggestions/suggest-builder-fn.stderr +++ b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr
@@ -1,22 +1,22 @@ -error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `TcpStream` in the current scope --> $DIR/suggest-builder-fn.rs:52:29 | LL | let _stream = TcpStream::new(); - | ^^^ function or associated item not found in `TcpStream` + | ^^^ associated function or constant not found in `TcpStream` | note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: TcpStream::connect TcpStream::connect_timeout --> $SRC_DIR/std/src/net/tcp.rs:LL:COL -error[E0599]: the function or associated item `new` exists for struct `Foo<u8>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `new` exists for struct `Foo<u8>`, but its trait bounds were not satisfied --> $DIR/suggest-builder-fn.rs:57:27 | LL | struct Foo<T> { - | ------------- function or associated item `new` not found for this struct + | ------------- associated function or constant `new` not found for this struct ... LL | let _foo = Foo::<u8>::new(); - | ^^^ function or associated item cannot be called on `Foo<u8>` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `Foo<u8>` due to unsatisfied trait bounds | note: trait bound `u8: SomeTrait` was not satisfied --> $DIR/suggest-builder-fn.rs:12:9 @@ -26,14 +26,14 @@ | | | unsatisfied trait bound introduced here -error[E0599]: no function or associated item named `new` found for struct `Bar` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `Bar` in the current scope --> $DIR/suggest-builder-fn.rs:62:21 | LL | struct Bar; - | ---------- function or associated item `new` not found for this struct + | ---------- associated function or constant `new` not found for this struct ... LL | let _bar = Bar::new(); - | ^^^ function or associated item not found in `Bar` + | ^^^ associated function or constant not found in `Bar` | note: if you're trying to build a new `Bar` consider using one of the following associated functions: Bar::build
diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs index 706564d..dfbb8f1 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs
@@ -1,5 +1,5 @@ struct Struct; -//~^ NOTE function or associated item `fob` not found for this struct +//~^ NOTE associated function or constant `fob` not found for this struct impl Struct { fn foo() { } @@ -21,8 +21,8 @@ trait Trait { fn main() { Struct::fob(); - //~^ ERROR no function or associated item named `fob` found for struct `Struct` in the current scope - //~| NOTE function or associated item not found in `Struct` + //~^ ERROR no associated function or constant named `fob` found for struct `Struct` in the current scope + //~| NOTE associated function or constant not found in `Struct` Struc::foo(); //~^ ERROR cannot find type `Struc`
diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr index b1afa70..9841255 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr
@@ -9,14 +9,14 @@ LL | module::Struct::foo(); | + -error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope +error[E0599]: no associated function or constant named `fob` found for struct `Struct` in the current scope --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 | LL | struct Struct; - | ------------- function or associated item `fob` not found for this struct + | ------------- associated function or constant `fob` not found for this struct ... LL | Struct::fob(); - | ^^^ function or associated item not found in `Struct` + | ^^^ associated function or constant not found in `Struct` | help: there is an associated function `foo` with a similar name |
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs index a66c446..8dff48d 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs +++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs
@@ -1,7 +1,6 @@ // Make sure we consider `!` to be a union read. #![feature(never_type, never_patterns)] -//~^ WARN the feature `never_patterns` is incomplete union U { a: !,
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr index d7dc7a4..c415e26 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr +++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr
@@ -1,20 +1,11 @@ -warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/never-pattern-is-a-read.rs:3:24 - | -LL | #![feature(never_type, never_patterns)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/never-pattern-is-a-read.rs:12:16 + --> $DIR/never-pattern-is-a-read.rs:11:16 | LL | let U { a: ! } = u; | ^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr index 8787d14..ebba825 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } +LL + binding if binding == WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index ec836db..849b5cc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } +LL + binding if binding == WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index fdc16fe..cb19c41 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } +LL + binding if binding == WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index b46fc04..8dffde7 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } +LL + binding if binding == WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index 70f39aa..7b47540 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } +LL + binding if binding == WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index fceb3ac..958b731 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } +LL + binding if binding == WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index 34fffd9..295b2a7 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
@@ -15,6 +15,11 @@ | LL | impl PartialEq for B { | ^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } +LL + binding if binding == RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } + | error: constant of non-structural type `B` in a pattern --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:42:9 @@ -33,6 +38,11 @@ | LL | impl PartialEq for B { | ^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } +LL + binding if binding == RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } + | error: aborting due to 2 previous errors
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs index 74394698..cb6ab97 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
@@ -16,8 +16,8 @@ fn eq(&self, _: &Foo) -> bool { fn main() { let y = Foo { x: 1 }; match y { - FOO => { } + FOO => {} //~^ ERROR constant of non-structural type `Foo` in a pattern - _ => { } + _ => {} } }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr index bbcab3b..1d216a6 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr
@@ -7,7 +7,7 @@ LL | const FOO: Foo = Foo { x: 0 }; | -------------- constant defined here ... -LL | FOO => { } +LL | FOO => {} | ^^^ constant of non-structural type | note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details @@ -15,6 +15,11 @@ | LL | impl PartialEq for Foo { | ^^^^^^^^^^^^^^^^^^^^^^ +help: add a condition to the match arm checking for equality + | +LL - FOO => {} +LL + binding if binding == FOO => {} + | error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr index a953e85..c888ec2 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr
@@ -2,9 +2,11 @@ --> $DIR/general.rs:60:25 | LL | (Some(a), &Some(mut b)) => { - | ^^^^^ + | ^^^^^ this value is reassigned later and never used +... +LL | b = 7; + | ----- `b` is overwritten here before the previous value is read | - = help: maybe it is overwritten before being read? = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default warning: 1 warning emitted
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.rs index 46fdfd6..c54f08e 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.rs +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.rs
@@ -5,7 +5,7 @@ fn main() { let foo = 22; match foo { - u32::XXX => { } //~ ERROR no associated item named + u32::XXX => { } //~ ERROR no associated function or constant named _ => { } } }
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.stderr index 6000507..51b08cd 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.stderr +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/no-double-error.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no associated item named `XXX` found for type `u32` in the current scope +error[E0599]: no associated function or constant named `XXX` found for type `u32` in the current scope --> $DIR/no-double-error.rs:8:14 | LL | u32::XXX => { } - | ^^^ associated item not found in `u32` + | ^^^ associated function or constant not found in `u32` error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr index f8ef315..7ce5ebf 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
@@ -1,13 +1,21 @@ error[E0382]: use of moved value: `a` - --> $DIR/dbg-macro-move-semantics.rs:9:13 + --> $DIR/dbg-macro-move-semantics.rs:9:18 | LL | let a = NoCopy(0); | - move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait LL | let _ = dbg!(a); - | ------- value moved here + | - value moved here LL | let _ = dbg!(a); - | ^^^^^^^ value used here after move + | ^ value used here after move | +note: if `NoCopy` implemented `Clone`, you could clone the value + --> $DIR/dbg-macro-move-semantics.rs:4:1 + | +LL | struct NoCopy(usize); + | ^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _ = dbg!(a); + | - you could clone this value help: consider borrowing instead of transferring ownership | LL | let _ = dbg!(&a);
diff --git a/tests/ui/rust-2018/trait-import-suggestions.rs b/tests/ui/rust-2018/trait-import-suggestions.rs index 5a5eeac..dce01de 100644 --- a/tests/ui/rust-2018/trait-import-suggestions.rs +++ b/tests/ui/rust-2018/trait-import-suggestions.rs
@@ -27,5 +27,5 @@ fn main() { let x: u32 = 22; x.bar(); //~ ERROR no method named `bar` x.baz(); //~ ERROR no method named `baz` - let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str` + let y = u32::from_str("33"); //~ ERROR no associated function or constant named `from_str` }
diff --git a/tests/ui/rust-2018/trait-import-suggestions.stderr b/tests/ui/rust-2018/trait-import-suggestions.stderr index 488044e..721ba0c 100644 --- a/tests/ui/rust-2018/trait-import-suggestions.stderr +++ b/tests/ui/rust-2018/trait-import-suggestions.stderr
@@ -49,11 +49,11 @@ LL + x.bar(); | -error[E0599]: no function or associated item named `from_str` found for type `u32` in the current scope +error[E0599]: no associated function or constant named `from_str` found for type `u32` in the current scope --> $DIR/trait-import-suggestions.rs:30:18 | LL | let y = u32::from_str("33"); - | ^^^^^^^^ function or associated item not found in `u32` + | ^^^^^^^^ associated function or constant not found in `u32` | = help: items from traits can only be used if the trait is in scope help: trait `FromStr` which provides `from_str` is implemented but not in scope; perhaps you want to import it
diff --git a/tests/ui/rust-2018/uniform-paths/issue-87932.rs b/tests/ui/rust-2018/uniform-paths/issue-87932.rs index d24d4b8b..cde7fe7 100644 --- a/tests/ui/rust-2018/uniform-paths/issue-87932.rs +++ b/tests/ui/rust-2018/uniform-paths/issue-87932.rs
@@ -11,5 +11,5 @@ fn deserialize() { fn main() { A::deserialize(); - //~^ ERROR no function or associated item named `deserialize` found for struct `A` + //~^ ERROR no associated function or constant named `deserialize` found for struct `A` }
diff --git a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr index 3e6fc3f..c408b74 100644 --- a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr +++ b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no function or associated item named `deserialize` found for struct `A` in the current scope +error[E0599]: no associated function or constant named `deserialize` found for struct `A` in the current scope --> $DIR/issue-87932.rs:13:8 | LL | pub struct A {} - | ------------ function or associated item `deserialize` not found for this struct + | ------------ associated function or constant `deserialize` not found for this struct ... LL | A::deserialize(); - | ^^^^^^^^^^^ function or associated item not found in `A` + | ^^^^^^^^^^^ associated function or constant not found in `A` | = help: items from traits can only be used if the trait is in scope help: trait `Deserialize` which provides `deserialize` is implemented but not in scope; perhaps you want to import it
diff --git a/tests/ui/sanitize-attr/invalid-sanitize.rs b/tests/ui/sanitize-attr/invalid-sanitize.rs index 6846b6f..5574661 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.rs +++ b/tests/ui/sanitize-attr/invalid-sanitize.rs
@@ -4,12 +4,12 @@ #[sanitize(brontosaurus = "off")] //~ ERROR malformed `sanitize` attribute input fn main() {} -#[sanitize(address = "off")] //~ ERROR multiple `sanitize` attributes #[sanitize(address = "off")] +#[sanitize(address = "off")] //~ ERROR multiple `sanitize` attributes fn multiple_consistent() {} -#[sanitize(address = "on")] //~ ERROR multiple `sanitize` attributes -#[sanitize(address = "off")] +#[sanitize(address = "on")] +#[sanitize(address = "off")] //~ ERROR multiple `sanitize` attributes fn multiple_inconsistent() {} #[sanitize(address = "bogus")] //~ ERROR malformed `sanitize` attribute input
diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index 00bb774..699902f 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr
@@ -4,31 +4,31 @@ LL | #[sanitize(brontosaurus = "off")] | ^^^^^^^^^^^------------^^^^^^^^^^ | | - | valid arguments are "address", "kernel_address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime" + | valid arguments are "address", "kernel_address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress", "kernel_hwaddress" or "realtime" error: multiple `sanitize` attributes - --> $DIR/invalid-sanitize.rs:7:1 + --> $DIR/invalid-sanitize.rs:8:1 | LL | #[sanitize(address = "off")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-sanitize.rs:8:1 + --> $DIR/invalid-sanitize.rs:7:1 | LL | #[sanitize(address = "off")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: multiple `sanitize` attributes - --> $DIR/invalid-sanitize.rs:11:1 - | -LL | #[sanitize(address = "on")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here --> $DIR/invalid-sanitize.rs:12:1 | LL | #[sanitize(address = "off")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/invalid-sanitize.rs:11:1 + | +LL | #[sanitize(address = "on")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:15:1
diff --git a/tests/ui/sanitizer/cfg-khwasan.rs b/tests/ui/sanitizer/cfg-khwasan.rs new file mode 100644 index 0000000..27a2f60 --- /dev/null +++ b/tests/ui/sanitizer/cfg-khwasan.rs
@@ -0,0 +1,20 @@ +// Verifies that when compiling with -Zsanitizer=kernel-hwaddress, +// the `#[cfg(sanitize = "hwaddress")]` attribute is configured. + +//@ add-minicore +//@ check-pass +//@ compile-flags: -Zsanitizer=kernel-hwaddress --target aarch64-unknown-none +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc + +#![crate_type = "rlib"] +#![feature(cfg_sanitize, no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; + +const _: fn() -> () = main; + +#[cfg(sanitize = "hwaddress")] +fn main() {}
diff --git a/tests/ui/sanitizer/incompatible-khwasan.rs b/tests/ui/sanitizer/incompatible-khwasan.rs new file mode 100644 index 0000000..eb6a5d3 --- /dev/null +++ b/tests/ui/sanitizer/incompatible-khwasan.rs
@@ -0,0 +1,9 @@ +//@ compile-flags: -Z sanitizer=kernel-hwaddress -Z sanitizer=kernel-address --target aarch64-unknown-none +//@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc + +#![feature(no_core)] +#![no_core] +#![no_main] + +//~? ERROR `-Zsanitizer=kernel-address` is incompatible with `-Zsanitizer=kernel-hwaddress`
diff --git a/tests/ui/sanitizer/incompatible-khwasan.stderr b/tests/ui/sanitizer/incompatible-khwasan.stderr new file mode 100644 index 0000000..35246fb --- /dev/null +++ b/tests/ui/sanitizer/incompatible-khwasan.stderr
@@ -0,0 +1,4 @@ +error: `-Zsanitizer=kernel-address` is incompatible with `-Zsanitizer=kernel-hwaddress` + +error: aborting due to 1 previous error +
diff --git a/tests/ui/sanitizer/unsupported-target-khwasan.rs b/tests/ui/sanitizer/unsupported-target-khwasan.rs new file mode 100644 index 0000000..bef6d95 --- /dev/null +++ b/tests/ui/sanitizer/unsupported-target-khwasan.rs
@@ -0,0 +1,9 @@ +//@ compile-flags: -Z sanitizer=kernel-hwaddress --target x86_64-unknown-none +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc + +#![feature(no_core)] +#![no_core] +#![no_main] + +//~? ERROR kernel-hwaddress sanitizer is not supported for this target
diff --git a/tests/ui/sanitizer/unsupported-target-khwasan.stderr b/tests/ui/sanitizer/unsupported-target-khwasan.stderr new file mode 100644 index 0000000..8b122a6 --- /dev/null +++ b/tests/ui/sanitizer/unsupported-target-khwasan.stderr
@@ -0,0 +1,4 @@ +error: kernel-hwaddress sanitizer is not supported for this target + +error: aborting due to 1 previous error +
diff --git a/tests/ui/shadowed/shadowing-generic-item.rs b/tests/ui/shadowed/shadowing-generic-item.rs index c3a0ced..8a81530 100644 --- a/tests/ui/shadowed/shadowing-generic-item.rs +++ b/tests/ui/shadowed/shadowing-generic-item.rs
@@ -9,7 +9,7 @@ mod Foo { pub fn f() {} } fn g<Foo>() { - Foo::f(); //~ ERROR no function or associated item named `f` + Foo::f(); //~ ERROR no associated function or constant named `f` } fn main() {}
diff --git a/tests/ui/shadowed/shadowing-generic-item.stderr b/tests/ui/shadowed/shadowing-generic-item.stderr index 55a0bb3..eb517b1 100644 --- a/tests/ui/shadowed/shadowing-generic-item.stderr +++ b/tests/ui/shadowed/shadowing-generic-item.stderr
@@ -8,13 +8,13 @@ LL | let t = T { i: 0 }; | ^ not a struct, variant or union type -error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope +error[E0599]: no associated function or constant named `f` found for type parameter `Foo` in the current scope --> $DIR/shadowing-generic-item.rs:12:10 | LL | fn g<Foo>() { - | --- function or associated item `f` not found for this type parameter + | --- associated function or constant `f` not found for this type parameter LL | Foo::f(); - | ^ function or associated item not found in `Foo` + | ^ associated function or constant not found in `Foo` error: aborting due to 2 previous errors
diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs index d9dc291..8ef5d85 100644 --- a/tests/ui/simd/intrinsic/float-minmax-pass.rs +++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs
@@ -1,8 +1,8 @@ //@ run-pass //@ ignore-emscripten -//@ compile-flags: --cfg minisimd_const +//@ compile-flags: --cfg minisimd_const -O -// Test that the simd_f{min,max} intrinsics produce the correct results. +// Test that the simd_{min,max}imum_number_nsz intrinsics produce the correct results. #![feature(repr_simd, core_intrinsics, const_trait_impl, const_cmp, const_index)] #![allow(non_camel_case_types)] @@ -12,41 +12,38 @@ use minisimd::*; use std::intrinsics::simd::*; +use std::hint::black_box; const fn minmax() { let x = f32x4::from_array([1.0, 2.0, 3.0, 4.0]); let y = f32x4::from_array([2.0, 1.0, 4.0, 3.0]); - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] let nan = f32::NAN; - // MIPS hardware except MIPS R6 treats f32::NAN as SNAN. Clear the signaling bit. - // See https://github.com/rust-lang/rust/issues/52746. // The "-1" works because we rely on `NAN` to have an all-0 payload, so the signaling // bit is the least significant non-zero bit. - #[cfg(any(target_arch = "mips", target_arch = "mips64"))] - let nan = f32::from_bits(f32::NAN.to_bits() - 1); + let snan = f32::from_bits(f32::NAN.to_bits() - 1); - let n = f32x4::from_array([nan, nan, nan, nan]); + let n = f32x4::from_array([nan, nan, snan, snan]); unsafe { - let min0 = simd_fmin(x, y); - let min1 = simd_fmin(y, x); + let min0 = simd_minimum_number_nsz(x, y); + let min1 = simd_minimum_number_nsz(y, black_box(x)); assert_eq!(min0, min1); let e = f32x4::from_array([1.0, 1.0, 3.0, 3.0]); assert_eq!(min0, e); - let minn = simd_fmin(x, n); + let minn = simd_minimum_number_nsz(x, n); assert_eq!(minn, x); - let minn = simd_fmin(y, n); + let minn = simd_minimum_number_nsz(black_box(y), n); assert_eq!(minn, y); - let max0 = simd_fmax(x, y); - let max1 = simd_fmax(y, x); + let max0 = simd_maximum_number_nsz(x, y); + let max1 = simd_maximum_number_nsz(y, black_box(x)); assert_eq!(max0, max1); let e = f32x4::from_array([2.0, 2.0, 4.0, 4.0]); assert_eq!(max0, e); - let maxn = simd_fmax(x, n); + let maxn = simd_maximum_number_nsz(x, n); assert_eq!(maxn, x); - let maxn = simd_fmax(y, n); + let maxn = simd_maximum_number_nsz(n, black_box(y)); assert_eq!(maxn, y); } }
diff --git a/tests/ui/span/issue-43927-non-ADT-derive.stderr b/tests/ui/span/issue-43927-non-ADT-derive.stderr index 27ed561..8742f34 100644 --- a/tests/ui/span/issue-43927-non-ADT-derive.stderr +++ b/tests/ui/span/issue-43927-non-ADT-derive.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | struct DerivedOn; - | --------- the inner attribute doesn't annotate this struct + | ----------------- the inner attribute doesn't annotate this item | help: perhaps you meant to use an outer attribute |
diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr index e013b3c..ea7aff3 100644 --- a/tests/ui/span/multiline-span-simple.stderr +++ b/tests/ui/span/multiline-span-simple.stderr
@@ -1,8 +1,13 @@ error[E0277]: cannot add `()` to `u32` --> $DIR/multiline-span-simple.rs:13:18 | -LL | foo(1 as u32 + - | ^ no implementation for `u32 + ()` +LL | foo(1 as u32 + + | -------- ^ no implementation for `u32 + ()` +LL | +LL | / bar(x, +LL | | +LL | | y), + | |______________- | = help: the trait `Add<()>` is not implemented for `u32` help: the following other types implement trait `Add<Rhs>`
diff --git a/tests/ui/specialization/assoc-ty-graph-cycle.rs b/tests/ui/specialization/assoc-ty-graph-cycle.rs index 083b030..16be58e 100644 --- a/tests/ui/specialization/assoc-ty-graph-cycle.rs +++ b/tests/ui/specialization/assoc-ty-graph-cycle.rs
@@ -2,7 +2,7 @@ // Make sure we don't crash with a cycle error during coherence. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Trait<T> { type Assoc;
diff --git a/tests/ui/specialization/assoc-ty-graph-cycle.stderr b/tests/ui/specialization/assoc-ty-graph-cycle.stderr deleted file mode 100644 index f5529c2..0000000 --- a/tests/ui/specialization/assoc-ty-graph-cycle.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-ty-graph-cycle.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs index 1691530..a0073d5 100644 --- a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs +++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs
@@ -1,5 +1,5 @@ // regression test for #118987 -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Assoc { type Output;
diff --git a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr index e950268..8ccf0c2 100644 --- a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr +++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-impl-normalization-ambig-2.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `u16: Assoc` is not satisfied --> $DIR/default-impl-normalization-ambig-2.rs:17:14 | @@ -20,6 +10,6 @@ LL | impl Assoc for u8 {} | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs index af7cf33..24142a4 100644 --- a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs +++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs
@@ -1,5 +1,5 @@ // regression test for #73299. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait X { type U;
diff --git a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr index a15151c..f45c4e5 100644 --- a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr +++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-item-normalization-ambig-1.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `Y` for type `<() as X>::U` --> $DIR/default-item-normalization-ambig-1.rs:20:1 | @@ -16,6 +6,6 @@ LL | impl Y for <i32 as X>::U {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<() as X>::U` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/cross-crate-defaults.rs b/tests/ui/specialization/cross-crate-defaults.rs index c920446..0a2d6e9 100644 --- a/tests/ui/specialization/cross-crate-defaults.rs +++ b/tests/ui/specialization/cross-crate-defaults.rs
@@ -2,7 +2,7 @@ //@ aux-build:cross_crates_defaults.rs -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] extern crate cross_crates_defaults;
diff --git a/tests/ui/specialization/cross-crate-defaults.stderr b/tests/ui/specialization/cross-crate-defaults.stderr deleted file mode 100644 index ee5c77a..0000000 --- a/tests/ui/specialization/cross-crate-defaults.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate-defaults.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/ctfe/default-assoc-const.rs b/tests/ui/specialization/ctfe/default-assoc-const.rs index 083aede..644e56f 100644 --- a/tests/ui/specialization/ctfe/default-assoc-const.rs +++ b/tests/ui/specialization/ctfe/default-assoc-const.rs
@@ -1,7 +1,6 @@ //! Regression test for revealing associated types through specialization during const eval. //@ check-pass #![feature(specialization)] -//~^ WARNING the feature `specialization` is incomplete and may not be safe to use trait Foo { const ASSOC: usize;
diff --git a/tests/ui/specialization/ctfe/default-assoc-const.stderr b/tests/ui/specialization/ctfe/default-assoc-const.stderr deleted file mode 100644 index 933b6dc..0000000 --- a/tests/ui/specialization/ctfe/default-assoc-const.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-assoc-const.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/ctfe/default-assoc-type.rs b/tests/ui/specialization/ctfe/default-assoc-type.rs index 0ceba2d..0415cd3 100644 --- a/tests/ui/specialization/ctfe/default-assoc-type.rs +++ b/tests/ui/specialization/ctfe/default-assoc-type.rs
@@ -2,7 +2,6 @@ //! even if they rely on specialization. //@ check-pass #![feature(specialization)] -//~^ WARNING the feature `specialization` is incomplete and may not be safe to use trait Foo { type Assoc: Trait;
diff --git a/tests/ui/specialization/ctfe/default-assoc-type.stderr b/tests/ui/specialization/ctfe/default-assoc-type.stderr deleted file mode 100644 index 23fa213..0000000 --- a/tests/ui/specialization/ctfe/default-assoc-type.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-assoc-type.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/default-associated-type-bound-1.rs b/tests/ui/specialization/default-associated-type-bound-1.rs index c043114..8e889a6 100644 --- a/tests/ui/specialization/default-associated-type-bound-1.rs +++ b/tests/ui/specialization/default-associated-type-bound-1.rs
@@ -2,7 +2,6 @@ // bounds on them. #![feature(specialization)] -//~^ WARNING `specialization` is incomplete trait X { type U: Clone;
diff --git a/tests/ui/specialization/default-associated-type-bound-1.stderr b/tests/ui/specialization/default-associated-type-bound-1.stderr index aa6f695..7040814 100644 --- a/tests/ui/specialization/default-associated-type-bound-1.stderr +++ b/tests/ui/specialization/default-associated-type-bound-1.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-associated-type-bound-1.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/default-associated-type-bound-1.rs:18:22 + --> $DIR/default-associated-type-bound-1.rs:17:22 | LL | default type U = str; | ^^^ the trait `Clone` is not implemented for `str` @@ -17,11 +7,11 @@ help: the trait `Clone` is implemented for `String` --> $SRC_DIR/alloc/src/string.rs:LL:COL note: required by a bound in `X::U` - --> $DIR/default-associated-type-bound-1.rs:8:13 + --> $DIR/default-associated-type-bound-1.rs:7:13 | LL | type U: Clone; | ^^^^^ required by this bound in `X::U` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/default-associated-type-bound-2.rs b/tests/ui/specialization/default-associated-type-bound-2.rs index 0a21b1f..9ea31f3 100644 --- a/tests/ui/specialization/default-associated-type-bound-2.rs +++ b/tests/ui/specialization/default-associated-type-bound-2.rs
@@ -1,6 +1,5 @@ // Check that generic predicates are also checked for default associated types. #![feature(specialization)] -//~^ WARNING `specialization` is incomplete trait X<T> { type U: PartialEq<T>;
diff --git a/tests/ui/specialization/default-associated-type-bound-2.stderr b/tests/ui/specialization/default-associated-type-bound-2.stderr index e02a945..3d3fdba 100644 --- a/tests/ui/specialization/default-associated-type-bound-2.stderr +++ b/tests/ui/specialization/default-associated-type-bound-2.stderr
@@ -1,22 +1,12 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-associated-type-bound-2.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: can't compare `&'static B` with `B` - --> $DIR/default-associated-type-bound-2.rs:16:22 + --> $DIR/default-associated-type-bound-2.rs:15:22 | LL | default type U = &'static B; | ^^^^^^^^^^ no implementation for `&'static B == B` | = help: the trait `PartialEq<B>` is not implemented for `&'static B` note: required by a bound in `X::U` - --> $DIR/default-associated-type-bound-2.rs:6:13 + --> $DIR/default-associated-type-bound-2.rs:5:13 | LL | type U: PartialEq<T>; | ^^^^^^^^^^^^ required by this bound in `X::U` @@ -25,6 +15,6 @@ LL | impl<B: 'static, T> X<B> for T where &'static B: PartialEq<B> { | ++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/default-generic-associated-type-bound.rs b/tests/ui/specialization/default-generic-associated-type-bound.rs index 31a0685..7cdb6c2 100644 --- a/tests/ui/specialization/default-generic-associated-type-bound.rs +++ b/tests/ui/specialization/default-generic-associated-type-bound.rs
@@ -1,7 +1,6 @@ // Check that default generics associated types are validated. #![feature(specialization)] -//~^ WARNING `specialization` is incomplete trait X { type U<'a>: PartialEq<&'a Self> where Self: 'a;
diff --git a/tests/ui/specialization/default-generic-associated-type-bound.stderr b/tests/ui/specialization/default-generic-associated-type-bound.stderr index 57d67ac..7c2bde8 100644 --- a/tests/ui/specialization/default-generic-associated-type-bound.stderr +++ b/tests/ui/specialization/default-generic-associated-type-bound.stderr
@@ -1,22 +1,12 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-generic-associated-type-bound.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: can't compare `T` with `T` - --> $DIR/default-generic-associated-type-bound.rs:17:26 + --> $DIR/default-generic-associated-type-bound.rs:16:26 | LL | default type U<'a> = &'a T; | ^^^^^ no implementation for `T == T` | = note: required for `&'a T` to implement `PartialEq` note: required by a bound in `X::U` - --> $DIR/default-generic-associated-type-bound.rs:7:17 + --> $DIR/default-generic-associated-type-bound.rs:6:17 | LL | type U<'a>: PartialEq<&'a Self> where Self: 'a; | ^^^^^^^^^^^^^^^^^^^ required by this bound in `X::U` @@ -25,6 +15,6 @@ LL | impl<T: 'static + std::cmp::PartialEq> X for T { | +++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs b/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs index 697a62c..1a6c383 100644 --- a/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs +++ b/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs
@@ -5,7 +5,7 @@ //@ aux-build:go_trait.rs -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] extern crate go_trait;
diff --git a/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr b/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr deleted file mode 100644 index 02f13d4..0000000 --- a/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/allowed-cross-crate.rs:8:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/defaultimpl/out-of-order.rs b/tests/ui/specialization/defaultimpl/out-of-order.rs index 2274946..bd3bfe2 100644 --- a/tests/ui/specialization/defaultimpl/out-of-order.rs +++ b/tests/ui/specialization/defaultimpl/out-of-order.rs
@@ -2,7 +2,7 @@ // Test that you can list the more specific impl before the more general one. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { type Out;
diff --git a/tests/ui/specialization/defaultimpl/out-of-order.stderr b/tests/ui/specialization/defaultimpl/out-of-order.stderr deleted file mode 100644 index 2cf1ac9..0000000 --- a/tests/ui/specialization/defaultimpl/out-of-order.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/out-of-order.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/defaultimpl/overlap-projection.rs b/tests/ui/specialization/defaultimpl/overlap-projection.rs index da466e6..1af1040 100644 --- a/tests/ui/specialization/defaultimpl/overlap-projection.rs +++ b/tests/ui/specialization/defaultimpl/overlap-projection.rs
@@ -4,7 +4,7 @@ // projections involve specialization, so long as the associated type is // provided by the most specialized impl. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Assoc { type Output;
diff --git a/tests/ui/specialization/defaultimpl/overlap-projection.stderr b/tests/ui/specialization/defaultimpl/overlap-projection.stderr deleted file mode 100644 index 75fdfaf..0000000 --- a/tests/ui/specialization/defaultimpl/overlap-projection.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-projection.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/defaultimpl/projection.rs b/tests/ui/specialization/defaultimpl/projection.rs index 7a77c76..9a2fc8d 100644 --- a/tests/ui/specialization/defaultimpl/projection.rs +++ b/tests/ui/specialization/defaultimpl/projection.rs
@@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Make sure we *can* project non-defaulted associated types // cf ui/specialization/specialization-default-projection.rs
diff --git a/tests/ui/specialization/defaultimpl/projection.stderr b/tests/ui/specialization/defaultimpl/projection.stderr deleted file mode 100644 index cc3fe82..0000000 --- a/tests/ui/specialization/defaultimpl/projection.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs deleted file mode 100644 index 89158b6..0000000 --- a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs +++ /dev/null
@@ -1,11 +0,0 @@ -// Check that specialization must be ungated to use the `default` keyword - -trait Foo { - fn foo(&self); -} - -default impl<T> Foo for T { //~ ERROR specialization is unstable - fn foo(&self) {} -} - -fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr deleted file mode 100644 index e28d9c9..0000000 --- a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr +++ /dev/null
@@ -1,15 +0,0 @@ -error[E0658]: specialization is unstable - --> $DIR/specialization-feature-gate-default.rs:7:1 - | -LL | / default impl<T> Foo for T { -LL | | fn foo(&self) {} -LL | | } - | |_^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: add `#![feature(specialization)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.rs b/tests/ui/specialization/defaultimpl/specialization-no-default.rs index ddc3233..a3b1d09 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.rs +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Check a number of scenarios in which one impl tries to override another, // without correctly using `default`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr index f9e62a9..60c489d 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-no-default.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 | @@ -63,6 +53,6 @@ | = note: to specialize, `redundant` in the parent `impl` must be marked `default` -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs index eb4ecf2..b88bf52 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs +++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs
@@ -3,7 +3,7 @@ // Tests that we can combine a default impl that supplies one method with a // full impl that supplies the other, and they can invoke one another. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn foo_one(&self) -> &'static str;
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr deleted file mode 100644 index 407c1ab..0000000 --- a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-trait-item-not-implemented-rpass.rs:6:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs index 3c54144..2a121e6 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs +++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs
@@ -1,6 +1,6 @@ // Tests that default impls do not have to supply all items but regular impls do. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn foo_one(&self) -> &'static str;
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr index d3441b0..ae336da 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-trait-item-not-implemented.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `foo_two` --> $DIR/specialization-trait-item-not-implemented.rs:18:1 | @@ -17,6 +7,6 @@ LL | impl Foo for MyStruct {} | ^^^^^^^^^^^^^^^^^^^^^ missing `foo_two` in implementation -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs index 344dd7b..2867a00 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs +++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
@@ -2,7 +2,7 @@ // - default impls do not have to supply all items and // - a default impl does not count as an impl (in this case, an incomplete default impl). -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn foo_one(&self) -> &'static str;
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index 74f81bb..7cec84b 100644 --- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-trait-not-implemented.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope --> $DIR/specialization-trait-not-implemented.rs:22:29 | @@ -24,6 +14,6 @@ LL | trait Foo { | ^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs b/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs index eb18d6e..51b63f0 100644 --- a/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs +++ b/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs
@@ -1,6 +1,6 @@ // Tests that a default impl still has to have a WF trait ref. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo<'a, T: Eq + 'a> { }
diff --git a/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr index 4a51a7d..aaf0204 100644 --- a/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-wfcheck.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `U: Eq` is not satisfied --> $DIR/specialization-wfcheck.rs:7:17 | @@ -24,6 +14,6 @@ LL | default impl<U: std::cmp::Eq> Foo<'static, U> for () {} | ++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs index 78f6099..3504d3e 100644 --- a/tests/ui/specialization/defaultimpl/validation.rs +++ b/tests/ui/specialization/defaultimpl/validation.rs
@@ -1,5 +1,5 @@ #![feature(negative_impls)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] struct S; struct Z;
diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr index a8dfef2..99ae6de 100644 --- a/tests/ui/specialization/defaultimpl/validation.stderr +++ b/tests/ui/specialization/defaultimpl/validation.stderr
@@ -8,16 +8,6 @@ | = note: only trait implementations may be annotated with `default` -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/validation.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0367]: `!Send` impl requires `Z: Send` but the struct it is implemented for does not --> $DIR/validation.rs:12:1 | @@ -58,7 +48,7 @@ LL | default impl !Tr for S {} | ^^^^^^^ ^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 6 previous errors Some errors have detailed explanations: E0367, E0750. For more information about an error, try `rustc --explain E0367`.
diff --git a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs index 559c234..f0a40ef 100644 --- a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs +++ b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.rs
@@ -1,7 +1,7 @@ // This test previously tried to use a tainted `EvalCtxt` when emitting // an error during coherence. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete + trait Iterate<'a> { type Ty: Valid; }
diff --git a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr index 611fef1..5db98e7 100644 --- a/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr +++ b/tests/ui/specialization/fuzzed/fuzzing-ice-134905.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/fuzzing-ice-134905.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `(): Valid` is not satisfied --> $DIR/fuzzing-ice-134905.rs:12:23 | @@ -34,7 +24,7 @@ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0210, E0277. For more information about an error, try `rustc --explain E0210`.
diff --git a/tests/ui/specialization/issue-35376.rs b/tests/ui/specialization/issue-35376.rs index 786f229..df4361b 100644 --- a/tests/ui/specialization/issue-35376.rs +++ b/tests/ui/specialization/issue-35376.rs
@@ -1,6 +1,5 @@ //@ check-pass #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete fn main() {}
diff --git a/tests/ui/specialization/issue-35376.stderr b/tests/ui/specialization/issue-35376.stderr deleted file mode 100644 index 6c4167f..0000000 --- a/tests/ui/specialization/issue-35376.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-35376.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/issue-36804.rs b/tests/ui/specialization/issue-36804.rs index 5ed0c1a..c0c188f 100644 --- a/tests/ui/specialization/issue-36804.rs +++ b/tests/ui/specialization/issue-36804.rs
@@ -1,5 +1,5 @@ //@ check-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] pub struct Cloned<I>(I);
diff --git a/tests/ui/specialization/issue-36804.stderr b/tests/ui/specialization/issue-36804.stderr deleted file mode 100644 index c2113b2..0000000 --- a/tests/ui/specialization/issue-36804.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-36804.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/issue-38091-2.rs b/tests/ui/specialization/issue-38091-2.rs index da27603..bd62a08 100644 --- a/tests/ui/specialization/issue-38091-2.rs +++ b/tests/ui/specialization/issue-38091-2.rs
@@ -2,7 +2,6 @@ //~^ ERROR overflow evaluating the requirement `i32: Check` #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Iterate<'a> { type Ty: Valid;
diff --git a/tests/ui/specialization/issue-38091-2.stderr b/tests/ui/specialization/issue-38091-2.stderr index 828a8e93..d0a15e6 100644 --- a/tests/ui/specialization/issue-38091-2.stderr +++ b/tests/ui/specialization/issue-38091-2.stderr
@@ -1,17 +1,7 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-38091-2.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0275]: overflow evaluating the requirement `i32: Check` | note: required for `i32` to implement `Iterate<'_>` - --> $DIR/issue-38091-2.rs:11:13 + --> $DIR/issue-38091-2.rs:10:13 | LL | impl<'a, T> Iterate<'a> for T | ^^^^^^^^^^^ ^ @@ -19,6 +9,6 @@ LL | T: Check, | ----- unsatisfied trait bound introduced here -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/specialization/issue-38091.rs b/tests/ui/specialization/issue-38091.rs index 5b39836..06236aa 100644 --- a/tests/ui/specialization/issue-38091.rs +++ b/tests/ui/specialization/issue-38091.rs
@@ -1,5 +1,4 @@ #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Iterate<'a> { type Ty: Valid;
diff --git a/tests/ui/specialization/issue-38091.stderr b/tests/ui/specialization/issue-38091.stderr index eb64383..91ea3db 100644 --- a/tests/ui/specialization/issue-38091.stderr +++ b/tests/ui/specialization/issue-38091.stderr
@@ -1,30 +1,20 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-38091.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `(): Valid` is not satisfied - --> $DIR/issue-38091.rs:12:23 + --> $DIR/issue-38091.rs:11:23 | LL | default type Ty = (); | ^^ the trait `Valid` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/issue-38091.rs:20:1 + --> $DIR/issue-38091.rs:19:1 | LL | trait Valid {} | ^^^^^^^^^^^ note: required by a bound in `Iterate::Ty` - --> $DIR/issue-38091.rs:5:14 + --> $DIR/issue-38091.rs:4:14 | LL | type Ty: Valid; | ^^^^^ required by this bound in `Iterate::Ty` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/issue-39448.rs b/tests/ui/specialization/issue-39448.rs index 1c8843d..4d07b11 100644 --- a/tests/ui/specialization/issue-39448.rs +++ b/tests/ui/specialization/issue-39448.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Regression test for a specialization-related ICE (#39448).
diff --git a/tests/ui/specialization/issue-39448.stderr b/tests/ui/specialization/issue-39448.stderr index e2c5f8c..09f2ced 100644 --- a/tests/ui/specialization/issue-39448.stderr +++ b/tests/ui/specialization/issue-39448.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-39448.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0391]: cycle detected when computing whether impls specialize one another --> $DIR/issue-39448.rs:24:1 | @@ -23,6 +13,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 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/specialization/issue-39618.rs b/tests/ui/specialization/issue-39618.rs index 14a6fcf..d6346a9 100644 --- a/tests/ui/specialization/issue-39618.rs +++ b/tests/ui/specialization/issue-39618.rs
@@ -2,7 +2,7 @@ // FIXME(JohnTitor): Centril pointed out this looks suspicions, we should revisit here. // More context: https://github.com/rust-lang/rust/pull/69192#discussion_r379846796 -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn foo(&self);
diff --git a/tests/ui/specialization/issue-39618.stderr b/tests/ui/specialization/issue-39618.stderr index 756162c..ca3c250 100644 --- a/tests/ui/specialization/issue-39618.stderr +++ b/tests/ui/specialization/issue-39618.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-39618.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0391]: cycle detected when computing whether impls specialize one another --> $DIR/issue-39618.rs:19:1 | @@ -23,6 +13,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 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/specialization/issue-50452-fail.rs b/tests/ui/specialization/issue-50452-fail.rs index fe21e9b..3096ac3 100644 --- a/tests/ui/specialization/issue-50452-fail.rs +++ b/tests/ui/specialization/issue-50452-fail.rs
@@ -1,5 +1,4 @@ #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete pub trait Foo { fn foo();
diff --git a/tests/ui/specialization/issue-50452-fail.stderr b/tests/ui/specialization/issue-50452-fail.stderr index 7ac4b39..5bca4cc 100644 --- a/tests/ui/specialization/issue-50452-fail.stderr +++ b/tests/ui/specialization/issue-50452-fail.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-50452-fail.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/issue-50452-fail.rs:10:5 + --> $DIR/issue-50452-fail.rs:9:5 | LL | fn foo() {} | ^^^^^^^^ cannot specialize default item `foo` @@ -19,6 +9,6 @@ | = note: to specialize, `foo` in the parent `impl` must be marked `default` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/issue-50452.rs b/tests/ui/specialization/issue-50452.rs index c379825..629ae80 100644 --- a/tests/ui/specialization/issue-50452.rs +++ b/tests/ui/specialization/issue-50452.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] pub trait Foo { fn foo();
diff --git a/tests/ui/specialization/issue-50452.stderr b/tests/ui/specialization/issue-50452.stderr deleted file mode 100644 index 48cab9d..0000000 --- a/tests/ui/specialization/issue-50452.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-50452.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/issue-52050.rs b/tests/ui/specialization/issue-52050.rs index 8046587..1e1bfe9 100644 --- a/tests/ui/specialization/issue-52050.rs +++ b/tests/ui/specialization/issue-52050.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Regression test for #52050: when inserting the blanket impl `I` // into the tree, we had to replace the child node for `Foo`, which
diff --git a/tests/ui/specialization/issue-52050.stderr b/tests/ui/specialization/issue-52050.stderr index 3b0cac5..b8368c6 100644 --- a/tests/ui/specialization/issue-52050.stderr +++ b/tests/ui/specialization/issue-52050.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-52050.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `IntoPyDictPointer` for type `()` --> $DIR/issue-52050.rs:28:1 | @@ -21,6 +11,6 @@ | = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/issue-63716-parse-async.rs b/tests/ui/specialization/issue-63716-parse-async.rs index 00c0b29..26fd84b 100644 --- a/tests/ui/specialization/issue-63716-parse-async.rs +++ b/tests/ui/specialization/issue-63716-parse-async.rs
@@ -4,7 +4,7 @@ //@ check-pass //@ edition:2018 -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] fn main() {}
diff --git a/tests/ui/specialization/issue-63716-parse-async.stderr b/tests/ui/specialization/issue-63716-parse-async.stderr deleted file mode 100644 index a00572d..0000000 --- a/tests/ui/specialization/issue-63716-parse-async.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-63716-parse-async.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/issue-70442.rs b/tests/ui/specialization/issue-70442.rs index fb82b0d..c2168b3 100644 --- a/tests/ui/specialization/issue-70442.rs +++ b/tests/ui/specialization/issue-70442.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] //@ check-pass
diff --git a/tests/ui/specialization/issue-70442.stderr b/tests/ui/specialization/issue-70442.stderr deleted file mode 100644 index aa72c32..0000000 --- a/tests/ui/specialization/issue-70442.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-70442.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/non-defaulted-item-fail.rs b/tests/ui/specialization/non-defaulted-item-fail.rs index b7d6ac8..403f718 100644 --- a/tests/ui/specialization/non-defaulted-item-fail.rs +++ b/tests/ui/specialization/non-defaulted-item-fail.rs
@@ -1,5 +1,4 @@ #![feature(specialization, associated_type_defaults)] -//~^ WARN the feature `specialization` is incomplete // Test that attempting to override a non-default method or one not in the // parent impl causes an error.
diff --git a/tests/ui/specialization/non-defaulted-item-fail.stderr b/tests/ui/specialization/non-defaulted-item-fail.stderr index 9d62a35..739f171 100644 --- a/tests/ui/specialization/non-defaulted-item-fail.stderr +++ b/tests/ui/specialization/non-defaulted-item-fail.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non-defaulted-item-fail.rs:1:12 - | -LL | #![feature(specialization, associated_type_defaults)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:30:5 + --> $DIR/non-defaulted-item-fail.rs:29:5 | LL | impl<T> Foo for Box<T> { | ---------------------- parent `impl` is here @@ -20,7 +10,7 @@ = note: to specialize, `Ty` in the parent `impl` must be marked `default` error[E0520]: `CONST` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:32:5 + --> $DIR/non-defaulted-item-fail.rs:31:5 | LL | impl<T> Foo for Box<T> { | ---------------------- parent `impl` is here @@ -31,7 +21,7 @@ = note: to specialize, `CONST` in the parent `impl` must be marked `default` error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:34:5 + --> $DIR/non-defaulted-item-fail.rs:33:5 | LL | impl<T> Foo for Box<T> { | ---------------------- parent `impl` is here @@ -42,7 +32,7 @@ = note: to specialize, `foo` in the parent `impl` must be marked `default` error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:46:5 + --> $DIR/non-defaulted-item-fail.rs:45:5 | LL | impl<T> Foo for Vec<T> {} | ---------------------- parent `impl` is here @@ -53,7 +43,7 @@ = note: to specialize, `Ty` in the parent `impl` must be marked `default` error[E0520]: `CONST` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:48:5 + --> $DIR/non-defaulted-item-fail.rs:47:5 | LL | impl<T> Foo for Vec<T> {} | ---------------------- parent `impl` is here @@ -64,7 +54,7 @@ = note: to specialize, `CONST` in the parent `impl` must be marked `default` error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/non-defaulted-item-fail.rs:50:5 + --> $DIR/non-defaulted-item-fail.rs:49:5 | LL | impl<T> Foo for Vec<T> {} | ---------------------- parent `impl` is here @@ -74,6 +64,6 @@ | = note: to specialize, `foo` in the parent `impl` must be marked `default` -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs index 578a46c..0cf6092 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs
@@ -1,8 +1,6 @@ // Regression test for #140571. The compiler used to ICE #![feature(min_generic_const_args, specialization)] -//~^ WARN the feature `specialization` is incomplete -//~| WARN the feature `min_generic_const_args` is incomplete pub trait IsVoid {
diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr index 9361f7d..3ec3e83 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr
@@ -1,29 +1,11 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:12 - | -LL | #![feature(min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:36 - | -LL | #![feature(min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()` - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:20:1 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:18:1 | LL | impl<T> Maybe<T> for T {} | ---------------------- first implementation here LL | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` -error: aborting due to 1 previous error; 2 warnings emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/prefer-specializing-impl-over-default.current.stderr b/tests/ui/specialization/prefer-specializing-impl-over-default.current.stderr deleted file mode 100644 index 7e3df0c..0000000 --- a/tests/ui/specialization/prefer-specializing-impl-over-default.current.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/prefer-specializing-impl-over-default.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/prefer-specializing-impl-over-default.next.stderr b/tests/ui/specialization/prefer-specializing-impl-over-default.next.stderr deleted file mode 100644 index 7e3df0c..0000000 --- a/tests/ui/specialization/prefer-specializing-impl-over-default.next.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/prefer-specializing-impl-over-default.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/prefer-specializing-impl-over-default.rs b/tests/ui/specialization/prefer-specializing-impl-over-default.rs index af6837b..4fa5b3e 100644 --- a/tests/ui/specialization/prefer-specializing-impl-over-default.rs +++ b/tests/ui/specialization/prefer-specializing-impl-over-default.rs
@@ -3,7 +3,6 @@ //@[next] compile-flags: -Znext-solver //@ check-pass #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait WithAssoc: 'static { type Assoc;
diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr deleted file mode 100644 index 17918a7..0000000 --- a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/source-impl-requires-constraining-predicates-ambig.rs:14:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs index 2296cd8..ff56965 100644 --- a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs
@@ -12,7 +12,6 @@ // is ambiguous. #![feature(specialization)] -//[next]~^ WARN the feature `specialization` is incomplete trait Spec { type Assoc;
diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr deleted file mode 100644 index 3442e5b..0000000 --- a/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/source-impl-requires-constraining-predicates.rs:9:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr deleted file mode 100644 index 3442e5b..0000000 --- a/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/source-impl-requires-constraining-predicates.rs:9:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.rs b/tests/ui/specialization/source-impl-requires-constraining-predicates.rs index 532fc36..690649d 100644 --- a/tests/ui/specialization/source-impl-requires-constraining-predicates.rs +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates.rs
@@ -7,7 +7,6 @@ // `[u32; 0]: IntoIterator<Item = ?U>` predicate to constrain the `?U` impl arg. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Spec { type Assoc;
diff --git a/tests/ui/specialization/specialization-allowed-cross-crate.rs b/tests/ui/specialization/specialization-allowed-cross-crate.rs index 697a62c..1a6c383 100644 --- a/tests/ui/specialization/specialization-allowed-cross-crate.rs +++ b/tests/ui/specialization/specialization-allowed-cross-crate.rs
@@ -5,7 +5,7 @@ //@ aux-build:go_trait.rs -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] extern crate go_trait;
diff --git a/tests/ui/specialization/specialization-allowed-cross-crate.stderr b/tests/ui/specialization/specialization-allowed-cross-crate.stderr deleted file mode 100644 index 3eea4a5..0000000 --- a/tests/ui/specialization/specialization-allowed-cross-crate.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-allowed-cross-crate.rs:8:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-assoc-fns.rs b/tests/ui/specialization/specialization-assoc-fns.rs index 75f0b0d..596b1c9 100644 --- a/tests/ui/specialization/specialization-assoc-fns.rs +++ b/tests/ui/specialization/specialization-assoc-fns.rs
@@ -2,7 +2,7 @@ // Test that non-method associated functions can be specialized -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn mk() -> Self;
diff --git a/tests/ui/specialization/specialization-assoc-fns.stderr b/tests/ui/specialization/specialization-assoc-fns.stderr deleted file mode 100644 index 69f7cec..0000000 --- a/tests/ui/specialization/specialization-assoc-fns.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-assoc-fns.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-basics.rs b/tests/ui/specialization/specialization-basics.rs index dc320b2..76cba35 100644 --- a/tests/ui/specialization/specialization-basics.rs +++ b/tests/ui/specialization/specialization-basics.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Tests a variety of basic specialization scenarios and method // dispatch for them.
diff --git a/tests/ui/specialization/specialization-basics.stderr b/tests/ui/specialization/specialization-basics.stderr deleted file mode 100644 index 7714d4a..0000000 --- a/tests/ui/specialization/specialization-basics.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-basics.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-cross-crate.rs b/tests/ui/specialization/specialization-cross-crate.rs index 6daf48b..3900181 100644 --- a/tests/ui/specialization/specialization-cross-crate.rs +++ b/tests/ui/specialization/specialization-cross-crate.rs
@@ -2,7 +2,7 @@ //@ aux-build:specialization_cross_crate.rs -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] extern crate specialization_cross_crate;
diff --git a/tests/ui/specialization/specialization-cross-crate.stderr b/tests/ui/specialization/specialization-cross-crate.stderr deleted file mode 100644 index 06818bb..0000000 --- a/tests/ui/specialization/specialization-cross-crate.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-cross-crate.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-default-methods.rs b/tests/ui/specialization/specialization-default-methods.rs index 7058c03..1699fad 100644 --- a/tests/ui/specialization/specialization-default-methods.rs +++ b/tests/ui/specialization/specialization-default-methods.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Test that default methods are cascaded correctly
diff --git a/tests/ui/specialization/specialization-default-methods.stderr b/tests/ui/specialization/specialization-default-methods.stderr deleted file mode 100644 index d78d30b..0000000 --- a/tests/ui/specialization/specialization-default-methods.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-default-methods.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-default-projection.current.stderr b/tests/ui/specialization/specialization-default-projection.current.stderr index b88c1a9..859f83e 100644 --- a/tests/ui/specialization/specialization-default-projection.current.stderr +++ b/tests/ui/specialization/specialization-default-projection.current.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-default-projection.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:25:5 | @@ -42,6 +32,6 @@ = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-default-projection.next.stderr b/tests/ui/specialization/specialization-default-projection.next.stderr index a385b16..1a5869f 100644 --- a/tests/ui/specialization/specialization-default-projection.next.stderr +++ b/tests/ui/specialization/specialization-default-projection.next.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-default-projection.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:25:5 | @@ -42,6 +32,6 @@ = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-default-projection.rs b/tests/ui/specialization/specialization-default-projection.rs index 4f69ccb..36f20b6 100644 --- a/tests/ui/specialization/specialization-default-projection.rs +++ b/tests/ui/specialization/specialization-default-projection.rs
@@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Make sure we can't project defaulted associated types
diff --git a/tests/ui/specialization/specialization-default-types.current.stderr b/tests/ui/specialization/specialization-default-types.current.stderr index 8df170c..2447669 100644 --- a/tests/ui/specialization/specialization-default-types.current.stderr +++ b/tests/ui/specialization/specialization-default-types.current.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-default-types.rs:9:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:19:9 | @@ -38,6 +28,6 @@ = note: the associated type `<T as Example>::Output` is defined as `Box<T>` in the implementation, but the where-bound `T` shadows this definition see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-default-types.next.stderr b/tests/ui/specialization/specialization-default-types.next.stderr index 4ea9b99..b6f61b4 100644 --- a/tests/ui/specialization/specialization-default-types.next.stderr +++ b/tests/ui/specialization/specialization-default-types.next.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-default-types.rs:9:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:19:9 | @@ -38,6 +28,6 @@ = note: the associated type `<T as Example>::Output` is defined as `Box<T>` in the implementation, but the where-bound `T` shadows this definition see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-default-types.rs b/tests/ui/specialization/specialization-default-types.rs index 77817ab..ffbe856 100644 --- a/tests/ui/specialization/specialization-default-types.rs +++ b/tests/ui/specialization/specialization-default-types.rs
@@ -6,7 +6,7 @@ // associated type in the impl defining it -- otherwise, what happens // if it's overridden? -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Example { type Output;
diff --git a/tests/ui/specialization/specialization-no-default.rs b/tests/ui/specialization/specialization-no-default.rs index ae739b2..57346b2 100644 --- a/tests/ui/specialization/specialization-no-default.rs +++ b/tests/ui/specialization/specialization-no-default.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Check a number of scenarios in which one impl tries to override another, // without correctly using `default`.
diff --git a/tests/ui/specialization/specialization-no-default.stderr b/tests/ui/specialization/specialization-no-default.stderr index 695a3f6..07c3529 100644 --- a/tests/ui/specialization/specialization-no-default.stderr +++ b/tests/ui/specialization/specialization-no-default.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-no-default.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 | @@ -63,6 +53,6 @@ | = note: to specialize, `redundant` in the parent `impl` must be marked `default` -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/specialization-on-projection.rs b/tests/ui/specialization/specialization-on-projection.rs index 876439c..f5fc131 100644 --- a/tests/ui/specialization/specialization-on-projection.rs +++ b/tests/ui/specialization/specialization-on-projection.rs
@@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Ensure that specialization works for impls defined directly on a projection
diff --git a/tests/ui/specialization/specialization-on-projection.stderr b/tests/ui/specialization/specialization-on-projection.stderr deleted file mode 100644 index 00fc7ff..0000000 --- a/tests/ui/specialization/specialization-on-projection.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-on-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-out-of-order.rs b/tests/ui/specialization/specialization-out-of-order.rs index 4f4d40f..72b2856 100644 --- a/tests/ui/specialization/specialization-out-of-order.rs +++ b/tests/ui/specialization/specialization-out-of-order.rs
@@ -2,7 +2,7 @@ // Test that you can list the more specific impl before the more general one. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { type Out;
diff --git a/tests/ui/specialization/specialization-out-of-order.stderr b/tests/ui/specialization/specialization-out-of-order.stderr deleted file mode 100644 index b524e00..0000000 --- a/tests/ui/specialization/specialization-out-of-order.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-out-of-order.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-overlap-negative.rs b/tests/ui/specialization/specialization-overlap-negative.rs index 244f21c..d5cf51e 100644 --- a/tests/ui/specialization/specialization-overlap-negative.rs +++ b/tests/ui/specialization/specialization-overlap-negative.rs
@@ -1,5 +1,5 @@ #![feature(negative_impls)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait MyTrait {}
diff --git a/tests/ui/specialization/specialization-overlap-negative.stderr b/tests/ui/specialization/specialization-overlap-negative.stderr index 4874e89..3e1cf40 100644 --- a/tests/ui/specialization/specialization-overlap-negative.stderr +++ b/tests/ui/specialization/specialization-overlap-negative.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-negative.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`: --> $DIR/specialization-overlap-negative.rs:9:1 | @@ -28,7 +18,7 @@ LL | struct TestType<T>(::std::marker::PhantomData<T>); | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0367, E0751. For more information about an error, try `rustc --explain E0367`.
diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs index f7a2a79..504e5d1 100644 --- a/tests/ui/specialization/specialization-overlap-projection.rs +++ b/tests/ui/specialization/specialization-overlap-projection.rs
@@ -2,7 +2,6 @@ // projections involve specialization, so long as the associated type is // provided by the most specialized impl. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes trait Assoc { type Output;
diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.stderr index 5f3cd9c..270a498 100644 --- a/tests/ui/specialization/specialization-overlap-projection.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:20:1 + --> $DIR/specialization-overlap-projection.rs:19:1 | LL | impl Foo for u32 {} | ---------------- first implementation here @@ -17,7 +7,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:22:1 + --> $DIR/specialization-overlap-projection.rs:21:1 | LL | impl Foo for u32 {} | ---------------- first implementation here @@ -25,6 +15,6 @@ LL | impl Foo for <u16 as Assoc>::Output {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-overlap.rs b/tests/ui/specialization/specialization-overlap.rs index 6bee22c..c8ef8d6 100644 --- a/tests/ui/specialization/specialization-overlap.rs +++ b/tests/ui/specialization/specialization-overlap.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo { fn foo() {} } impl<T: Clone> Foo for T {}
diff --git a/tests/ui/specialization/specialization-overlap.stderr b/tests/ui/specialization/specialization-overlap.stderr index 098bf4a..ca32c17 100644 --- a/tests/ui/specialization/specialization-overlap.stderr +++ b/tests/ui/specialization/specialization-overlap.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `Foo` for type `Vec<_>` --> $DIR/specialization-overlap.rs:5:1 | @@ -40,6 +30,6 @@ LL | impl<T: Eq> Qux for T {} | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-polarity.rs b/tests/ui/specialization/specialization-polarity.rs index b3cd825..7427246 100644 --- a/tests/ui/specialization/specialization-polarity.rs +++ b/tests/ui/specialization/specialization-polarity.rs
@@ -2,7 +2,7 @@ #![feature(auto_traits)] #![feature(negative_impls)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] auto trait Foo {}
diff --git a/tests/ui/specialization/specialization-polarity.stderr b/tests/ui/specialization/specialization-polarity.stderr index f287018..44e60ca 100644 --- a/tests/ui/specialization/specialization-polarity.stderr +++ b/tests/ui/specialization/specialization-polarity.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-polarity.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`: --> $DIR/specialization-polarity.rs:10:1 | @@ -24,6 +14,6 @@ LL | impl Bar for u8 {} | ^^^^^^^^^^^^^^^ positive implementation here -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/specialization/specialization-projection-alias.rs b/tests/ui/specialization/specialization-projection-alias.rs index 73d6115..92368b1 100644 --- a/tests/ui/specialization/specialization-projection-alias.rs +++ b/tests/ui/specialization/specialization-projection-alias.rs
@@ -2,7 +2,7 @@ #![allow(dead_code)] #![allow(unused_variables)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Regression test for ICE when combining specialized associated types and type // aliases
diff --git a/tests/ui/specialization/specialization-projection-alias.stderr b/tests/ui/specialization/specialization-projection-alias.stderr deleted file mode 100644 index c94d9ed..0000000 --- a/tests/ui/specialization/specialization-projection-alias.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-projection-alias.rs:5:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-projection.rs b/tests/ui/specialization/specialization-projection.rs index b3efa6f..20105fb 100644 --- a/tests/ui/specialization/specialization-projection.rs +++ b/tests/ui/specialization/specialization-projection.rs
@@ -1,7 +1,7 @@ //@ run-pass #![allow(dead_code)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Make sure we *can* project non-defaulted associated types // cf ui/specialization/specialization-default-projection.rs
diff --git a/tests/ui/specialization/specialization-projection.stderr b/tests/ui/specialization/specialization-projection.stderr deleted file mode 100644 index bfc4e0a..0000000 --- a/tests/ui/specialization/specialization-projection.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-supertraits.rs b/tests/ui/specialization/specialization-supertraits.rs index cb4cfef..ffb20fe 100644 --- a/tests/ui/specialization/specialization-supertraits.rs +++ b/tests/ui/specialization/specialization-supertraits.rs
@@ -1,6 +1,6 @@ //@ check-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] // Test that you can specialize via an explicit trait hierarchy
diff --git a/tests/ui/specialization/specialization-supertraits.stderr b/tests/ui/specialization/specialization-supertraits.stderr deleted file mode 100644 index e716bc2..0000000 --- a/tests/ui/specialization/specialization-supertraits.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-supertraits.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs index 75d9a0d..06f7cdd 100644 --- a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs +++ b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Iterator { fn next(&self);
diff --git a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr deleted file mode 100644 index c7aad3c..0000000 --- a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-translate-projections-with-lifetimes.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-translate-projections-with-params.rs b/tests/ui/specialization/specialization-translate-projections-with-params.rs index 330f518..3b2f2c6 100644 --- a/tests/ui/specialization/specialization-translate-projections-with-params.rs +++ b/tests/ui/specialization/specialization-translate-projections-with-params.rs
@@ -4,7 +4,7 @@ // type parameters *and* rely on projections, and the type parameters are input // types on the trait. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Trait<T> { fn convert(&self) -> T;
diff --git a/tests/ui/specialization/specialization-translate-projections-with-params.stderr b/tests/ui/specialization/specialization-translate-projections-with-params.stderr deleted file mode 100644 index 1c4fd93..0000000 --- a/tests/ui/specialization/specialization-translate-projections-with-params.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-translate-projections-with-params.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/specialization-translate-projections.rs b/tests/ui/specialization/specialization-translate-projections.rs index 01c7619..c718f93 100644 --- a/tests/ui/specialization/specialization-translate-projections.rs +++ b/tests/ui/specialization/specialization-translate-projections.rs
@@ -3,8 +3,7 @@ // Ensure that provided items are inherited properly even when impls vary in // type parameters *and* rely on projections. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete - +#![feature(specialization)] trait Trait { fn to_u8(&self) -> u8;
diff --git a/tests/ui/specialization/specialization-translate-projections.stderr b/tests/ui/specialization/specialization-translate-projections.stderr deleted file mode 100644 index 22bbb12..0000000 --- a/tests/ui/specialization/specialization-translate-projections.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-translate-projections.rs:6:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/trait-specialization-default-methods-55380.rs b/tests/ui/specialization/trait-specialization-default-methods-55380.rs index b3d79fb..eeafcc1 100644 --- a/tests/ui/specialization/trait-specialization-default-methods-55380.rs +++ b/tests/ui/specialization/trait-specialization-default-methods-55380.rs
@@ -1,7 +1,6 @@ // https://github.com/rust-lang/rust/issues/55380 //@ run-pass #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete pub trait Foo { fn abc() -> u32;
diff --git a/tests/ui/specialization/trait-specialization-default-methods-55380.stderr b/tests/ui/specialization/trait-specialization-default-methods-55380.stderr deleted file mode 100644 index f7c1903..0000000 --- a/tests/ui/specialization/trait-specialization-default-methods-55380.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-specialization-default-methods-55380.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/specialization/transmute-specialization.rs b/tests/ui/specialization/transmute-specialization.rs index a896c14..da0f12c 100644 --- a/tests/ui/specialization/transmute-specialization.rs +++ b/tests/ui/specialization/transmute-specialization.rs
@@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Specializable { type Output; }
diff --git a/tests/ui/specialization/transmute-specialization.stderr b/tests/ui/specialization/transmute-specialization.stderr deleted file mode 100644 index b1c26d7..0000000 --- a/tests/ui/specialization/transmute-specialization.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/transmute-specialization.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/statics/mutable_memory_validation.rs b/tests/ui/statics/mutable_memory_validation.rs index 033c2bc..bdef949 100644 --- a/tests/ui/statics/mutable_memory_validation.rs +++ b/tests/ui/statics/mutable_memory_validation.rs
@@ -11,7 +11,7 @@ struct Meh { } const MUH: Meh = Meh { x: unsafe { &mut *(&READONLY as *const _ as *mut _) } }; -//~^ ERROR: invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory +//~^ ERROR: at .x.<deref>, encountered `UnsafeCell` in read-only memory static READONLY: i32 = 0;
diff --git a/tests/ui/statics/mutable_memory_validation.stderr b/tests/ui/statics/mutable_memory_validation.stderr index 1d6ba19..297a965 100644 --- a/tests/ui/statics/mutable_memory_validation.stderr +++ b/tests/ui/statics/mutable_memory_validation.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory +error[E0080]: constructing invalid value of type Meh: at .x.<deref>, encountered `UnsafeCell` in read-only memory --> $DIR/mutable_memory_validation.rs:13:1 | LL | const MUH: Meh = Meh { x: unsafe { &mut *(&READONLY as *const _ as *mut _) } };
diff --git a/tests/ui/issues/issue-3521-2.fixed b/tests/ui/statics/static-cannot-use-local-variable.fixed similarity index 68% rename from tests/ui/issues/issue-3521-2.fixed rename to tests/ui/statics/static-cannot-use-local-variable.fixed index 2a6e082..df9dfb7 100644 --- a/tests/ui/issues/issue-3521-2.fixed +++ b/tests/ui/statics/static-cannot-use-local-variable.fixed
@@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3521 +//! //@ run-rustfix fn main() { let foo = 100;
diff --git a/tests/ui/issues/issue-3521-2.rs b/tests/ui/statics/static-cannot-use-local-variable.rs similarity index 69% rename from tests/ui/issues/issue-3521-2.rs rename to tests/ui/statics/static-cannot-use-local-variable.rs index bd82202..0269f9e 100644 --- a/tests/ui/issues/issue-3521-2.rs +++ b/tests/ui/statics/static-cannot-use-local-variable.rs
@@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3521 +//! //@ run-rustfix fn main() { let foo = 100;
diff --git a/tests/ui/issues/issue-3521-2.stderr b/tests/ui/statics/static-cannot-use-local-variable.stderr similarity index 87% rename from tests/ui/issues/issue-3521-2.stderr rename to tests/ui/statics/static-cannot-use-local-variable.stderr index ecf1ad0..350c384 100644 --- a/tests/ui/issues/issue-3521-2.stderr +++ b/tests/ui/statics/static-cannot-use-local-variable.stderr
@@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3521-2.rs:5:23 + --> $DIR/static-cannot-use-local-variable.rs:7:23 | LL | static y: isize = foo + 1; | ^^^ non-constant value
diff --git a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed b/tests/ui/statics/static-in-fn-cannot-use-param.fixed similarity index 64% rename from tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed rename to tests/ui/statics/static-in-fn-cannot-use-param.fixed index bf10075..bf6df45 100644 --- a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed +++ b/tests/ui/statics/static-in-fn-cannot-use-param.fixed
@@ -1,6 +1,8 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3668 +//! //@ run-rustfix #![allow(unused_variables, dead_code)] -fn f(x:isize) { +fn f(x: isize) { let child: isize = x + 1; //~^ ERROR attempt to use a non-constant value in a constant }
diff --git a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs b/tests/ui/statics/static-in-fn-cannot-use-param.rs similarity index 64% rename from tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs rename to tests/ui/statics/static-in-fn-cannot-use-param.rs index 3751781..bd121a7 100644 --- a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs +++ b/tests/ui/statics/static-in-fn-cannot-use-param.rs
@@ -1,6 +1,8 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3668 +//! //@ run-rustfix #![allow(unused_variables, dead_code)] -fn f(x:isize) { +fn f(x: isize) { static child: isize = x + 1; //~^ ERROR attempt to use a non-constant value in a constant }
diff --git a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr b/tests/ui/statics/static-in-fn-cannot-use-param.stderr similarity index 88% rename from tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr rename to tests/ui/statics/static-in-fn-cannot-use-param.stderr index f87514b..67890de 100644 --- a/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr +++ b/tests/ui/statics/static-in-fn-cannot-use-param.stderr
@@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3668-2.rs:4:27 + --> $DIR/static-in-fn-cannot-use-param.rs:6:27 | LL | static child: isize = x + 1; | ^ non-constant value
diff --git a/tests/ui/statics/static-in-method-cannot-use-self.rs b/tests/ui/statics/static-in-method-cannot-use-self.rs new file mode 100644 index 0000000..a5d6fea --- /dev/null +++ b/tests/ui/statics/static-in-method-cannot-use-self.rs
@@ -0,0 +1,18 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3668 +//! +struct P { + child: Option<Box<P>>, +} +trait PTrait { + fn getChildOption(&self) -> Option<Box<P>>; +} + +impl PTrait for P { + fn getChildOption(&self) -> Option<Box<P>> { + static childVal: Box<P> = self.child.get(); + //~^ ERROR attempt to use a non-constant value in a constant + panic!(); + } +} + +fn main() {}
diff --git a/tests/ui/statics/static-in-method-cannot-use-self.stderr b/tests/ui/statics/static-in-method-cannot-use-self.stderr new file mode 100644 index 0000000..d5db956 --- /dev/null +++ b/tests/ui/statics/static-in-method-cannot-use-self.stderr
@@ -0,0 +1,15 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/static-in-method-cannot-use-self.rs:12:35 + | +LL | static childVal: Box<P> = self.child.get(); + | ^^^^ non-constant value + | +help: consider using `let` instead of `static` + | +LL - static childVal: Box<P> = self.child.get(); +LL + let childVal: Box<P> = self.child.get(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.rs b/tests/ui/statics/static-lazy-init-with-arena-set.rs new file mode 100644 index 0000000..009d1d9 --- /dev/null +++ b/tests/ui/statics/static-lazy-init-with-arena-set.rs
@@ -0,0 +1,46 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/39367 +//! +//! Tests that lazy static initialization using `Once` and `transmute` +//! works correctly with a struct that has a default type parameter. +//@ run-pass + +use std::ops::Deref; + +struct ArenaSet<U: Deref, V = <U as Deref>::Target>(U, &'static V) +where + V: 'static + ?Sized; + +static Z: [u8; 4] = [1, 2, 3, 4]; + +fn arena() -> &'static ArenaSet<Vec<u8>> { + fn __static_ref_initialize() -> ArenaSet<Vec<u8>> { + ArenaSet(vec![], &Z) + } + unsafe { + use std::sync::Once; + fn require_sync<T: Sync>(_: &T) {} + unsafe fn __stability() -> &'static ArenaSet<Vec<u8>> { + use std::mem::transmute; + static mut DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut(); + + static mut ONCE: Once = Once::new(); + ONCE.call_once(|| { + //~^ WARN creating a shared reference to mutable static [static_mut_refs] + DATA = transmute::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>(Box::new( + __static_ref_initialize(), + )); + }); + + &*DATA + } + let static_ref = __stability(); + require_sync(static_ref); + static_ref + } +} + +fn main() { + let &ArenaSet(ref u, v) = arena(); + assert!(u.is_empty()); + assert_eq!(v, Z); +}
diff --git a/tests/ui/issues/issue-39367.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr similarity index 72% rename from tests/ui/issues/issue-39367.stderr rename to tests/ui/statics/static-lazy-init-with-arena-set.stderr index e94c961..134129f 100644 --- a/tests/ui/issues/issue-39367.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr
@@ -1,11 +1,11 @@ warning: creating a shared reference to mutable static - --> $DIR/issue-39367.rs:22:13 + --> $DIR/static-lazy-init-with-arena-set.rs:27:13 | LL | / ONCE.call_once(|| { LL | | -LL | | DATA = transmute -LL | | ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>> -LL | | (Box::new(__static_ref_initialize())); +LL | | DATA = transmute::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>(Box::new( +LL | | __static_ref_initialize(), +LL | | )); LL | | }); | |______________^ shared reference to mutable static |
diff --git a/tests/ui/issues/issue-46604.rs b/tests/ui/statics/static-mut-borrow-of-temporary.rs similarity index 74% rename from tests/ui/issues/issue-46604.rs rename to tests/ui/statics/static-mut-borrow-of-temporary.rs index e15f0b5..8f679d2 100644 --- a/tests/ui/issues/issue-46604.rs +++ b/tests/ui/statics/static-mut-borrow-of-temporary.rs
@@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/46604 +//! static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR mutable borrows of temporaries fn write<T: AsRef<[u8]>>(buffer: T) { }
diff --git a/tests/ui/issues/issue-46604.stderr b/tests/ui/statics/static-mut-borrow-of-temporary.stderr similarity index 90% rename from tests/ui/issues/issue-46604.stderr rename to tests/ui/statics/static-mut-borrow-of-temporary.stderr index 21abc49..a3d0601 100644 --- a/tests/ui/issues/issue-46604.stderr +++ b/tests/ui/statics/static-mut-borrow-of-temporary.stderr
@@ -1,5 +1,5 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed - --> $DIR/issue-46604.rs:1:25 + --> $DIR/static-mut-borrow-of-temporary.rs:3:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; | ^^^^^^^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary @@ -9,7 +9,7 @@ = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item - --> $DIR/issue-46604.rs:6:5 + --> $DIR/static-mut-borrow-of-temporary.rs:8:5 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; | --------------------- this `static` cannot be written to
diff --git a/tests/ui/issues/issue-29821.rs b/tests/ui/statics/static-mut-with-assoc-type-field.rs similarity index 67% rename from tests/ui/issues/issue-29821.rs rename to tests/ui/statics/static-mut-with-assoc-type-field.rs index 5080093..347c50e 100644 --- a/tests/ui/issues/issue-29821.rs +++ b/tests/ui/statics/static-mut-with-assoc-type-field.rs
@@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/29821 +//! //@ build-pass pub trait Foo { @@ -5,7 +7,7 @@ pub trait Foo { } pub struct Bar<F: Foo> { - id: F::FooAssoc + id: F::FooAssoc, } pub struct Baz;
diff --git a/tests/ui/statics/static-ref-deref-non-const-trait.rs b/tests/ui/statics/static-ref-deref-non-const-trait.rs new file mode 100644 index 0000000..6d7b375 --- /dev/null +++ b/tests/ui/statics/static-ref-deref-non-const-trait.rs
@@ -0,0 +1,19 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/25901 +//! +struct A; +struct B; + +static S: &'static B = &A; +//~^ ERROR the trait bound `A: const Deref` is not satisfied + +use std::ops::Deref; + +impl Deref for A { + type Target = B; + fn deref(&self) -> &B { + static B_: B = B; + &B_ + } +} + +fn main() {}
diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/statics/static-ref-deref-non-const-trait.stderr similarity index 86% rename from tests/ui/issues/issue-25901.stderr rename to tests/ui/statics/static-ref-deref-non-const-trait.stderr index 9b65366..88ddffe 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/statics/static-ref-deref-non-const-trait.stderr
@@ -1,5 +1,5 @@ error[E0277]: the trait bound `A: const Deref` is not satisfied - --> $DIR/issue-25901.rs:4:24 + --> $DIR/static-ref-deref-non-const-trait.rs:6:24 | LL | static S: &'static B = &A; | ^^
diff --git a/tests/ui/statics/uninhabited-static.stderr b/tests/ui/statics/uninhabited-static.stderr index 47627845..8087108 100644 --- a/tests/ui/statics/uninhabited-static.stderr +++ b/tests/ui/statics/uninhabited-static.stderr
@@ -43,13 +43,13 @@ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840> -error[E0080]: constructing invalid value: encountered a value of uninhabited type `Void` +error[E0080]: constructing invalid value of type Void: encountered a value of uninhabited type `Void` --> $DIR/uninhabited-static.rs:12:31 | LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `VOID2` failed here -error[E0080]: constructing invalid value: encountered a value of uninhabited type `Void` +error[E0080]: constructing invalid value of type Void: encountered a value of uninhabited type `Void` --> $DIR/uninhabited-static.rs:15:32 | LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr index 4b1cd8a..4df97a6 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr
@@ -1,15 +1,15 @@ -error[E0599]: no function or associated item named `from_mut` found for struct `Atomic<u64>` in the current scope +error[E0599]: no associated function or constant named `from_mut` found for struct `Atomic<u64>` in the current scope --> $DIR/atomic-from-mut-not-available.rs:24:36 | LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); - | ^^^^^^^^ function or associated item not found in `Atomic<u64>` + | ^^^^^^^^ associated function or constant not found in `Atomic<u64>` | note: if you're trying to build a new `Atomic<u64>`, consider using `Atomic::<u64>::new` which returns `Atomic<u64>` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL ::: $SRC_DIR/core/src/sync/atomic.rs:LL:COL | = note: in this macro invocation - = note: the function or associated item was found for + = note: the associated function or constant was found for - `Atomic<*mut T>` - `Atomic<bool>` - `Atomic<i16>`
diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs index 519b697..b7c7f0e 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs
@@ -22,6 +22,6 @@ fn main() { core::sync::atomic::AtomicU64::from_mut(&mut 0u64); - //[alignment_mismatch]~^ ERROR no function or associated item named `from_mut` found for struct `Atomic<u64>` + //[alignment_mismatch]~^ ERROR no associated function or constant named `from_mut` found for struct `Atomic<u64>` //[alignment_matches]~^^ ERROR use of unstable library feature `atomic_from_mut` }
diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index 97a083b..84f698a6 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr
@@ -7,13 +7,13 @@ = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `str` to implement `Index<{integer}>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -27,13 +27,13 @@ = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` note: required by a bound in `core::str::<impl str>::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -48,13 +48,13 @@ = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` note: required by a bound in `core::str::<impl str>::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL
diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index c9bd66d..87b7891 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr
@@ -31,13 +31,13 @@ | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex<str>` is not implemented for `usize` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `str` to implement `Index<usize>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -51,13 +51,13 @@ = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` note: required by a bound in `core::str::<impl str>::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -72,13 +72,13 @@ = help: the trait `SliceIndex<str>` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` note: required by a bound in `core::str::<impl str>::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL
diff --git a/tests/ui/structs-enums/auxiliary/cci_class.rs b/tests/ui/structs-enums/auxiliary/cci_class.rs deleted file mode 100644 index de2945d..0000000 --- a/tests/ui/structs-enums/auxiliary/cci_class.rs +++ /dev/null
@@ -1,14 +0,0 @@ -pub mod kitties { - pub struct cat { - meows : usize, - - pub how_hungry : isize, - } - - pub fn cat(in_x : usize, in_y : isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } - } -}
diff --git a/tests/ui/structs-enums/auxiliary/cci_class_2.rs b/tests/ui/structs-enums/auxiliary/cci_class_2.rs deleted file mode 100644 index c3de315..0000000 --- a/tests/ui/structs-enums/auxiliary/cci_class_2.rs +++ /dev/null
@@ -1,19 +0,0 @@ -pub mod kitties { - pub struct cat { - meows : usize, - - pub how_hungry : isize, - - } - - impl cat { - pub fn speak(&self) {} - } - - pub fn cat(in_x : usize, in_y : isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } - } -}
diff --git a/tests/ui/structs-enums/auxiliary/cci_class_3.rs b/tests/ui/structs-enums/auxiliary/cci_class_3.rs deleted file mode 100644 index fb7fad0..0000000 --- a/tests/ui/structs-enums/auxiliary/cci_class_3.rs +++ /dev/null
@@ -1,19 +0,0 @@ -pub mod kitties { - pub struct cat { - meows : usize, - - pub how_hungry : isize, - } - - impl cat { - pub fn speak(&mut self) { self.meows += 1; } - pub fn meow_count(&mut self) -> usize { self.meows } - } - - pub fn cat(in_x : usize, in_y : isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } - } -}
diff --git a/tests/ui/structs-enums/auxiliary/cci_class_4.rs b/tests/ui/structs-enums/auxiliary/cci_class_4.rs index 85aa3bc..fff7b78 100644 --- a/tests/ui/structs-enums/auxiliary/cci_class_4.rs +++ b/tests/ui/structs-enums/auxiliary/cci_class_4.rs
@@ -1,41 +1,54 @@ -pub mod kitties { - pub struct cat { - meows : usize, +use std::fmt; - pub how_hungry : isize, - pub name : String, +#[derive(Clone)] +pub struct Cat { + meows: usize, + + pub how_hungry: isize, + pub name: String, +} + +impl Cat { + pub fn speak(&mut self) { + self.meow(); } - impl cat { - pub fn speak(&mut self) { self.meow(); } - - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } else { - println!("Not hungry!"); - return false; - } + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } else { + println!("Not hungry!"); + return false; } } - impl cat { - pub fn meow(&mut self) { - println!("Meow"); - self.meows += 1; - if self.meows % 5 == 0 { - self.how_hungry += 1; - } + pub fn noop(&self) {} +} + +impl Cat { + pub fn meow(&mut self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; } } + pub fn meow_count(&self) -> usize { + self.meows + } +} - pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } +pub fn cat(in_x: usize, in_y: isize, in_name: String) -> Cat { + Cat { meows: in_x, how_hungry: in_y, name: in_name } +} +pub fn cat_unnamed(in_x: usize, in_y: isize) -> Cat { + Cat { meows: in_x, how_hungry: in_y, name: String::new() } +} + +impl fmt::Display for Cat { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) } }
diff --git a/tests/ui/structs-enums/auxiliary/cci_class_cast.rs b/tests/ui/structs-enums/auxiliary/cci_class_cast.rs deleted file mode 100644 index dfc3c56..0000000 --- a/tests/ui/structs-enums/auxiliary/cci_class_cast.rs +++ /dev/null
@@ -1,50 +0,0 @@ -pub mod kitty { - use std::fmt; - - pub struct cat { - meows : usize, - pub how_hungry : isize, - pub name : String, - } - - impl fmt::Display for cat { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) - } - } - - impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1; - if self.meows % 5 == 0 { - self.how_hungry += 1; - } - } - - } - - impl cat { - pub fn speak(&mut self) { self.meow(); } - - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } - else { - println!("Not hungry!"); - return false; - } - } - } - - pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } - } -}
diff --git a/tests/ui/structs-enums/auxiliary/cci_class_trait.rs b/tests/ui/structs-enums/auxiliary/cci_class_trait.rs deleted file mode 100644 index 2d02b59..0000000 --- a/tests/ui/structs-enums/auxiliary/cci_class_trait.rs +++ /dev/null
@@ -1,5 +0,0 @@ -pub mod animals { - pub trait noisy { - fn speak(&mut self); - } -}
diff --git a/tests/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs b/tests/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs deleted file mode 100644 index d4caa19..0000000 --- a/tests/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs +++ /dev/null
@@ -1,17 +0,0 @@ -//@ run-pass -//@ aux-build:cci_class_cast.rs - -extern crate cci_class_cast; - -use cci_class_cast::kitty::cat; - -fn print_out(thing: Box<dyn ToString>, expected: String) { - let actual = (*thing).to_string(); - println!("{}", actual); - assert_eq!(actual.to_string(), expected); -} - -pub fn main() { - let nyan: Box<dyn ToString> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn ToString>; - print_out(nyan, "nyan".to_string()); -}
diff --git a/tests/ui/structs-enums/class-cast-to-trait-multiple-types.rs b/tests/ui/structs-enums/class-cast-to-trait-multiple-types.rs deleted file mode 100644 index 658e9d2..0000000 --- a/tests/ui/structs-enums/class-cast-to-trait-multiple-types.rs +++ /dev/null
@@ -1,94 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] -#![allow(dead_code)] - -trait noisy { - fn speak(&mut self) -> isize; -} - -struct dog { - barks: usize, - - volume: isize, -} - -impl dog { - fn bark(&mut self) -> isize { - println!("Woof {} {}", self.barks, self.volume); - self.barks += 1_usize; - if self.barks % 3_usize == 0_usize { - self.volume += 1; - } - if self.barks % 10_usize == 0_usize { - self.volume -= 2; - } - println!("Grrr {} {}", self.barks, self.volume); - self.volume - } -} - -impl noisy for dog { - fn speak(&mut self) -> isize { - self.bark() - } -} - -fn dog() -> dog { - dog { - volume: 0, - barks: 0_usize - } -} - -#[derive(Clone)] -struct cat { - meows: usize, - - how_hungry: isize, - name: String, -} - -impl noisy for cat { - fn speak(&mut self) -> isize { - self.meow() as isize - } -} - -impl cat { - pub fn meow_count(&self) -> usize { - self.meows - } -} - -impl cat { - fn meow(&mut self) -> usize { - println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { - self.how_hungry += 1; - } - self.meows - } -} - -fn cat(in_x: usize, in_y: isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } -} - - -fn annoy_neighbors(critter: &mut dyn noisy) { - for _i in 0_usize..10 { critter.speak(); } -} - -pub fn main() { - let mut nyan: cat = cat(0_usize, 2, "nyan".to_string()); - let mut whitefang: dog = dog(); - annoy_neighbors(&mut nyan); - annoy_neighbors(&mut whitefang); - assert_eq!(nyan.meow_count(), 10_usize); - assert_eq!(whitefang.volume, 1); -}
diff --git a/tests/ui/structs-enums/class-cast-to-trait.rs b/tests/ui/structs-enums/class-cast-to-trait.rs deleted file mode 100644 index bbbde34..0000000 --- a/tests/ui/structs-enums/class-cast-to-trait.rs +++ /dev/null
@@ -1,60 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(unused_mut)] -#![allow(non_camel_case_types)] - -//@ ignore-freebsd FIXME fails on BSD - - -trait noisy { - fn speak(&mut self); -} - -struct cat { - meows: usize, - how_hungry: isize, - name: String, -} - -impl noisy for cat { - fn speak(&mut self) { self.meow(); } -} - -impl cat { - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } - else { - println!("Not hungry!"); - return false; - } - } -} - -impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1; - if self.meows % 5 == 0 { - self.how_hungry += 1; - } - } -} - -fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } -} - - -pub fn main() { - let mut nyan = cat(0, 2, "nyan".to_string()); - let mut nyan: &mut dyn noisy = &mut nyan; - nyan.speak(); -}
diff --git a/tests/ui/structs-enums/class-dtor.rs b/tests/ui/structs-enums/class-dtor.rs index a08f0f0..b791182 100644 --- a/tests/ui/structs-enums/class-dtor.rs +++ b/tests/ui/structs-enums/class-dtor.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)]
diff --git a/tests/ui/structs-enums/class-exports.rs b/tests/ui/structs-enums/class-exports.rs deleted file mode 100644 index 53d0e3d..0000000 --- a/tests/ui/structs-enums/class-exports.rs +++ /dev/null
@@ -1,31 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -/* Test that exporting a class also exports its - public fields and methods */ - -use kitty::cat; - -mod kitty { - pub struct cat { - meows: usize, - name: String, - } - - impl cat { - pub fn get_name(&self) -> String { self.name.clone() } - } - - pub fn cat(in_name: String) -> cat { - cat { - name: in_name, - meows: 0 - } - } -} - -pub fn main() { - assert_eq!(cat("Spreckles".to_string()).get_name(), - "Spreckles".to_string()); -}
diff --git a/tests/ui/structs-enums/class-implement-trait-cross-crate.rs b/tests/ui/structs-enums/class-implement-trait-cross-crate.rs deleted file mode 100644 index 781ac6ad..0000000 --- a/tests/ui/structs-enums/class-implement-trait-cross-crate.rs +++ /dev/null
@@ -1,59 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -//@ aux-build:cci_class_trait.rs -extern crate cci_class_trait; -use cci_class_trait::animals::noisy; - -struct cat { - meows: usize, - - how_hungry : isize, - name : String, -} - -impl cat { - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } - else { - println!("Not hungry!"); - return false; - } - } -} - -impl noisy for cat { - fn speak(&mut self) { self.meow(); } -} - -impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { - self.how_hungry += 1; - } - } -} - -fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } -} - - -pub fn main() { - let mut nyan = cat(0_usize, 2, "nyan".to_string()); - nyan.eat(); - assert!(!nyan.eat()); - for _ in 1_usize..10_usize { nyan.speak(); }; - assert!(nyan.eat()); -}
diff --git a/tests/ui/structs-enums/class-implement-traits.rs b/tests/ui/structs-enums/class-implement-traits.rs deleted file mode 100644 index 3a514ff..0000000 --- a/tests/ui/structs-enums/class-implement-traits.rs +++ /dev/null
@@ -1,64 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] -#![allow(dead_code)] - -trait noisy { - fn speak(&mut self); -} - -#[derive(Clone)] -struct cat { - meows : usize, - - how_hungry : isize, - name : String, -} - -impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { - self.how_hungry += 1; - } - } -} - -impl cat { - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } else { - println!("Not hungry!"); - return false; - } - } -} - -impl noisy for cat { - fn speak(&mut self) { self.meow(); } -} - -fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name.clone() - } -} - - -fn make_speak<C:noisy>(mut c: C) { - c.speak(); -} - -pub fn main() { - let mut nyan = cat(0_usize, 2, "nyan".to_string()); - nyan.eat(); - assert!(!nyan.eat()); - for _ in 1_usize..10_usize { - make_speak(nyan.clone()); - } -}
diff --git a/tests/ui/structs-enums/class-method-cross-crate.rs b/tests/ui/structs-enums/class-method-cross-crate.rs deleted file mode 100644 index f73999a..0000000 --- a/tests/ui/structs-enums/class-method-cross-crate.rs +++ /dev/null
@@ -1,13 +0,0 @@ -//@ run-pass -//@ aux-build:cci_class_2.rs - -extern crate cci_class_2; -use cci_class_2::kitties::cat; - -pub fn main() { - let nyan : cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); - nyan.speak(); -}
diff --git a/tests/ui/structs-enums/class-methods-cross-crate.rs b/tests/ui/structs-enums/class-methods-cross-crate.rs deleted file mode 100644 index b2c4824..0000000 --- a/tests/ui/structs-enums/class-methods-cross-crate.rs +++ /dev/null
@@ -1,14 +0,0 @@ -//@ run-pass -//@ aux-build:cci_class_3.rs - -extern crate cci_class_3; -use cci_class_3::kitties::cat; - -pub fn main() { - let mut nyan : cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); - nyan.speak(); - assert_eq!(nyan.meow_count(), 53); -}
diff --git a/tests/ui/structs-enums/class-methods.rs b/tests/ui/structs-enums/class-methods.rs deleted file mode 100644 index b0dbbbe..0000000 --- a/tests/ui/structs-enums/class-methods.rs +++ /dev/null
@@ -1,30 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] - - -struct cat { - meows : usize, - - how_hungry : isize, -} - -impl cat { - pub fn speak(&mut self) { self.meows += 1; } - pub fn meow_count(&mut self) -> usize { self.meows } -} - -fn cat(in_x: usize, in_y: isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } -} - -pub fn main() { - let mut nyan: cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); - nyan.speak(); - assert_eq!(nyan.meow_count(), 53); -}
diff --git a/tests/ui/structs-enums/class-separate-impl.rs b/tests/ui/structs-enums/class-separate-impl.rs deleted file mode 100644 index 2768e28..0000000 --- a/tests/ui/structs-enums/class-separate-impl.rs +++ /dev/null
@@ -1,63 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -use std::fmt; - -struct cat { - meows : usize, - - how_hungry : isize, - name : String, -} - -impl cat { - pub fn speak(&mut self) { self.meow(); } - - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } - else { - println!("Not hungry!"); - return false; - } - } -} - -impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1; - if self.meows % 5 == 0 { - self.how_hungry += 1; - } - } -} - -fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } -} - -impl fmt::Display for cat { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) - } -} - -fn print_out(thing: Box<dyn ToString>, expected: String) { - let actual = (*thing).to_string(); - println!("{}", actual); - assert_eq!(actual.to_string(), expected); -} - -pub fn main() { - let nyan: Box<dyn ToString> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn ToString>; - print_out(nyan, "nyan".to_string()); -}
diff --git a/tests/ui/structs-enums/class-str-field.rs b/tests/ui/structs-enums/class-str-field.rs deleted file mode 100644 index 24f648a..0000000 --- a/tests/ui/structs-enums/class-str-field.rs +++ /dev/null
@@ -1,20 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -struct cat { - - name : String, - -} - -fn cat(in_name: String) -> cat { - cat { - name: in_name - } -} - -pub fn main() { - let _nyan = cat("nyan".to_string()); -}
diff --git a/tests/ui/structs-enums/classes-cross-crate.rs b/tests/ui/structs-enums/classes-cross-crate.rs index 6fb5f2e..85454bb 100644 --- a/tests/ui/structs-enums/classes-cross-crate.rs +++ b/tests/ui/structs-enums/classes-cross-crate.rs
@@ -2,12 +2,118 @@ //@ aux-build:cci_class_4.rs extern crate cci_class_4; -use cci_class_4::kitties::cat; +use cci_class_4::*; -pub fn main() { +fn simple_cross_crate() { + let nyan: Cat = cat_unnamed(52, 99); + let kitty = cat_unnamed(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.noop(); +} + +fn cross_crate() { let mut nyan = cat(0_usize, 2, "nyan".to_string()); nyan.eat(); assert!(!nyan.eat()); - for _ in 1_usize..10_usize { nyan.speak(); }; + for _ in 1_usize..10_usize { + nyan.speak(); + } assert!(nyan.eat()); } + +fn print_out(thing: Box<dyn ToString>, expected: String) { + let actual = (*thing).to_string(); + println!("{}", actual); + assert_eq!(actual.to_string(), expected); +} + +fn separate_impl() { + let nyan: Box<dyn ToString> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn ToString>; + print_out(nyan, "nyan".to_string()); +} + +trait Noisy { + fn speak(&mut self) -> isize; +} + +impl Noisy for Cat { + fn speak(&mut self) -> isize { + self.meow(); + 0 + } +} + +fn make_speak<C: Noisy>(mut c: C) { + c.speak(); +} + +fn implement_traits() { + let mut nyan = cat(0_usize, 2, "nyan".to_string()); + nyan.eat(); + assert!(!nyan.eat()); + for _ in 1_usize..10_usize { + make_speak(nyan.clone()); + } +} + +struct Dog { + barks: usize, + + volume: isize, +} + +impl Dog { + fn bark(&mut self) -> isize { + println!("Woof {} {}", self.barks, self.volume); + self.barks += 1_usize; + if self.barks % 3_usize == 0_usize { + self.volume += 1; + } + if self.barks % 10_usize == 0_usize { + self.volume -= 2; + } + println!("Grrr {} {}", self.barks, self.volume); + self.volume + } +} + +impl Noisy for Dog { + fn speak(&mut self) -> isize { + self.bark() + } +} + +fn dog() -> Dog { + Dog { volume: 0, barks: 0_usize } +} + +fn annoy_neighbors(critter: &mut dyn Noisy) { + for _i in 0_usize..10 { + critter.speak(); + } +} + +fn multiple_types() { + let mut nyan: Cat = cat(0_usize, 2, "nyan".to_string()); + let mut whitefang: Dog = dog(); + annoy_neighbors(&mut nyan); + annoy_neighbors(&mut whitefang); + assert_eq!(nyan.meow_count(), 10_usize); + assert_eq!(whitefang.volume, 1); +} + +fn cast_to_trait() { + let mut nyan = cat(0, 2, "nyan".to_string()); + let nyan: &mut dyn Noisy = &mut nyan; + nyan.speak(); +} + +fn main() { + simple_cross_crate(); + cross_crate(); + separate_impl(); + implement_traits(); + multiple_types(); + cast_to_trait(); +}
diff --git a/tests/ui/structs-enums/classes-self-referential.rs b/tests/ui/structs-enums/classes-self-referential.rs index f819e55..40c51a1 100644 --- a/tests/ui/structs-enums/classes-self-referential.rs +++ b/tests/ui/structs-enums/classes-self-referential.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)]
diff --git a/tests/ui/structs-enums/classes-simple-cross-crate.rs b/tests/ui/structs-enums/classes-simple-cross-crate.rs deleted file mode 100644 index 1548f76..0000000 --- a/tests/ui/structs-enums/classes-simple-cross-crate.rs +++ /dev/null
@@ -1,12 +0,0 @@ -//@ run-pass -//@ aux-build:cci_class.rs - -extern crate cci_class; -use cci_class::kitties::cat; - -pub fn main() { - let nyan : cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); -}
diff --git a/tests/ui/structs-enums/classes-simple-method.rs b/tests/ui/structs-enums/classes-simple-method.rs deleted file mode 100644 index 562fd59..0000000 --- a/tests/ui/structs-enums/classes-simple-method.rs +++ /dev/null
@@ -1,28 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -struct cat { - meows : usize, - - how_hungry : isize, -} - -impl cat { - pub fn speak(&mut self) {} -} - -fn cat(in_x : usize, in_y : isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } -} - -pub fn main() { - let mut nyan : cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); - nyan.speak(); -}
diff --git a/tests/ui/structs-enums/classes-simple.rs b/tests/ui/structs-enums/classes-simple.rs deleted file mode 100644 index d870a31..0000000 --- a/tests/ui/structs-enums/classes-simple.rs +++ /dev/null
@@ -1,23 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -struct cat { - meows : usize, - - how_hungry : isize, -} - -fn cat(in_x : usize, in_y : isize) -> cat { - cat { - meows: in_x, - how_hungry: in_y - } -} - -pub fn main() { - let nyan : cat = cat(52, 99); - let kitty = cat(1000, 2); - assert_eq!(nyan.how_hungry, 99); - assert_eq!(kitty.how_hungry, 2); -}
diff --git a/tests/ui/structs-enums/classes.rs b/tests/ui/structs-enums/classes.rs deleted file mode 100644 index 05976f6..0000000 --- a/tests/ui/structs-enums/classes.rs +++ /dev/null
@@ -1,51 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -struct cat { - meows : usize, - - how_hungry : isize, - name : String, -} - -impl cat { - pub fn speak(&mut self) { self.meow(); } - - pub fn eat(&mut self) -> bool { - if self.how_hungry > 0 { - println!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } else { - println!("Not hungry!"); - return false; - } - } -} - -impl cat { - fn meow(&mut self) { - println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { - self.how_hungry += 1; - } - } -} - -fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { - cat { - meows: in_x, - how_hungry: in_y, - name: in_name - } -} - -pub fn main() { - let mut nyan = cat(0_usize, 2, "nyan".to_string()); - nyan.eat(); - assert!(!nyan.eat()); - for _ in 1_usize..10_usize { nyan.speak(); }; - assert!(nyan.eat()); -}
diff --git a/tests/ui/structs-enums/export-abstract-tag.rs b/tests/ui/structs-enums/export-abstract-tag.rs deleted file mode 100644 index e6d3598..0000000 --- a/tests/ui/structs-enums/export-abstract-tag.rs +++ /dev/null
@@ -1,14 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] - -// We can export tags without exporting the variants to create a simple -// sort of ADT. - - -mod foo { - pub enum t { t1, } - - pub fn f() -> t { return t::t1; } -} - -pub fn main() { let _v: foo::t = foo::f(); }
diff --git a/tests/ui/structs-enums/export-tag-variant.rs b/tests/ui/structs-enums/export-tag-variant.rs deleted file mode 100644 index c6216d1..0000000 --- a/tests/ui/structs-enums/export-tag-variant.rs +++ /dev/null
@@ -1,8 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] - -mod foo { - pub enum t { t1, } -} - -pub fn main() { let _v = foo::t::t1; }
diff --git a/tests/ui/structs-enums/foreign-struct.rs b/tests/ui/structs-enums/foreign-struct.rs index f339c19..b710d83 100644 --- a/tests/ui/structs-enums/foreign-struct.rs +++ b/tests/ui/structs-enums/foreign-struct.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)]
diff --git a/tests/ui/structs-enums/nested-enum-same-names.rs b/tests/ui/structs-enums/nested-enum-same-names.rs index 5ff730a..1d3fab4 100644 --- a/tests/ui/structs-enums/nested-enum-same-names.rs +++ b/tests/ui/structs-enums/nested-enum-same-names.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] /*
diff --git a/tests/ui/structs-enums/rec-auto.rs b/tests/ui/structs-enums/rec-auto.rs deleted file mode 100644 index bf2e37a..0000000 --- a/tests/ui/structs-enums/rec-auto.rs +++ /dev/null
@@ -1,14 +0,0 @@ -//@ run-pass - - - - -// Issue #50. - -struct X { foo: String, bar: String } - -pub fn main() { - let x = X {foo: "hello".to_string(), bar: "world".to_string()}; - println!("{}", x.foo.clone()); - println!("{}", x.bar.clone()); -}
diff --git a/tests/ui/structs-enums/simple-generic-tag.rs b/tests/ui/structs-enums/simple-generic-tag.rs index b78505e..dbb5d70 100644 --- a/tests/ui/structs-enums/simple-generic-tag.rs +++ b/tests/ui/structs-enums/simple-generic-tag.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)]
diff --git a/tests/ui/structs-enums/tag-in-block.rs b/tests/ui/structs-enums/tag-in-block.rs index 27b48aa..75691f0 100644 --- a/tests/ui/structs-enums/tag-in-block.rs +++ b/tests/ui/structs-enums/tag-in-block.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)]
diff --git a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs b/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs deleted file mode 100644 index f4c202d..0000000 --- a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -enum color { - red = 1, - blue = 2, -} - -pub fn main() {}
diff --git a/tests/ui/structs-enums/tuple-struct-construct.rs b/tests/ui/structs-enums/tuple-struct-construct.rs deleted file mode 100644 index 4243bcc..0000000 --- a/tests/ui/structs-enums/tuple-struct-construct.rs +++ /dev/null
@@ -1,9 +0,0 @@ -//@ run-pass -#[allow(dead_code)] -#[derive(Debug)] -struct Foo(isize, isize); - -pub fn main() { - let x = Foo(1, 2); - println!("{:?}", x); -}
diff --git a/tests/ui/structs-enums/tuple-struct-destructuring.rs b/tests/ui/structs-enums/tuple-struct-destructuring.rs index 5213052..36a3660 100644 --- a/tests/ui/structs-enums/tuple-struct-destructuring.rs +++ b/tests/ui/structs-enums/tuple-struct-destructuring.rs
@@ -1,4 +1,5 @@ //@ run-pass +#[derive(Debug)] struct Foo(isize, isize); pub fn main() { @@ -7,4 +8,16 @@ pub fn main() { println!("{} {}", y, z); assert_eq!(y, 1); assert_eq!(z, 2); + + let x = Foo(1, 2); + match x { + Foo(a, b) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + println!("{} {}", a, b); + } + } + + let x = Foo(1, 2); + assert_eq!(format!("{x:?}"), "Foo(1, 2)"); }
diff --git a/tests/ui/structs-enums/tuple-struct-matching.rs b/tests/ui/structs-enums/tuple-struct-matching.rs deleted file mode 100644 index a543662..0000000 --- a/tests/ui/structs-enums/tuple-struct-matching.rs +++ /dev/null
@@ -1,13 +0,0 @@ -//@ run-pass -struct Foo(isize, isize); - -pub fn main() { - let x = Foo(1, 2); - match x { - Foo(a, b) => { - assert_eq!(a, 1); - assert_eq!(b, 2); - println!("{} {}", a, b); - } - } -}
diff --git a/tests/ui/structs-enums/tuple-struct-trivial.rs b/tests/ui/structs-enums/tuple-struct-trivial.rs deleted file mode 100644 index e239503..0000000 --- a/tests/ui/structs-enums/tuple-struct-trivial.rs +++ /dev/null
@@ -1,7 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -struct Foo(isize, isize, isize); - -pub fn main() { -}
diff --git a/tests/ui/structs-enums/auxiliary/newtype_struct_xc.rs b/tests/ui/structs/auxiliary/newtype_struct_xc.rs similarity index 100% rename from tests/ui/structs-enums/auxiliary/newtype_struct_xc.rs rename to tests/ui/structs/auxiliary/newtype_struct_xc.rs
diff --git a/tests/ui/structs-enums/cross-crate-newtype-struct-pat.rs b/tests/ui/structs/cross-crate-newtype-struct-pat.rs similarity index 100% rename from tests/ui/structs-enums/cross-crate-newtype-struct-pat.rs rename to tests/ui/structs/cross-crate-newtype-struct-pat.rs
diff --git a/tests/ui/structs-enums/field-destruction-order.rs b/tests/ui/structs/field-destruction-order.rs similarity index 100% rename from tests/ui/structs-enums/field-destruction-order.rs rename to tests/ui/structs/field-destruction-order.rs
diff --git a/tests/ui/structs-enums/module-qualified-struct-destructure.rs b/tests/ui/structs/module-qualified-struct-destructure.rs similarity index 100% rename from tests/ui/structs-enums/module-qualified-struct-destructure.rs rename to tests/ui/structs/module-qualified-struct-destructure.rs
diff --git a/tests/ui/structs-enums/newtype-struct-drop-run.rs b/tests/ui/structs/newtype-struct-drop-run.rs similarity index 100% rename from tests/ui/structs-enums/newtype-struct-drop-run.rs rename to tests/ui/structs/newtype-struct-drop-run.rs
diff --git a/tests/ui/structs-enums/newtype-struct-with-dtor.rs b/tests/ui/structs/newtype-struct-with-dtor.rs similarity index 93% rename from tests/ui/structs-enums/newtype-struct-with-dtor.rs rename to tests/ui/structs/newtype-struct-with-dtor.rs index 35476c5..c0d0493 100644 --- a/tests/ui/structs-enums/newtype-struct-with-dtor.rs +++ b/tests/ui/structs/newtype-struct-with-dtor.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(unused_unsafe)] #![allow(unused_variables)]
diff --git a/tests/ui/structs-enums/newtype-struct-xc-2.rs b/tests/ui/structs/newtype-struct-xc-2.rs similarity index 100% rename from tests/ui/structs-enums/newtype-struct-xc-2.rs rename to tests/ui/structs/newtype-struct-xc-2.rs
diff --git a/tests/ui/structs-enums/newtype-struct-xc.rs b/tests/ui/structs/newtype-struct-xc.rs similarity index 100% rename from tests/ui/structs-enums/newtype-struct-xc.rs rename to tests/ui/structs/newtype-struct-xc.rs
diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs/rec-align-u32.rs similarity index 100% rename from tests/ui/structs-enums/rec-align-u32.rs rename to tests/ui/structs/rec-align-u32.rs
diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs/rec-align-u64.rs similarity index 100% rename from tests/ui/structs-enums/rec-align-u64.rs rename to tests/ui/structs/rec-align-u64.rs
diff --git a/tests/ui/structs-enums/struct-lit-functional-no-fields.rs b/tests/ui/structs/struct-lit-functional-no-fields.rs similarity index 100% rename from tests/ui/structs-enums/struct-lit-functional-no-fields.rs rename to tests/ui/structs/struct-lit-functional-no-fields.rs
diff --git a/tests/ui/structs-enums/struct-literal-dtor.rs b/tests/ui/structs/struct-literal-dtor.rs similarity index 100% rename from tests/ui/structs-enums/struct-literal-dtor.rs rename to tests/ui/structs/struct-literal-dtor.rs
diff --git a/tests/ui/structs-enums/struct-new-as-field-name.rs b/tests/ui/structs/struct-new-as-field-name.rs similarity index 100% rename from tests/ui/structs-enums/struct-new-as-field-name.rs rename to tests/ui/structs/struct-new-as-field-name.rs
diff --git a/tests/ui/structs-enums/struct-order-of-eval-1.rs b/tests/ui/structs/struct-order-of-eval-1.rs similarity index 100% rename from tests/ui/structs-enums/struct-order-of-eval-1.rs rename to tests/ui/structs/struct-order-of-eval-1.rs
diff --git a/tests/ui/structs-enums/struct-order-of-eval-2.rs b/tests/ui/structs/struct-order-of-eval-2.rs similarity index 100% rename from tests/ui/structs-enums/struct-order-of-eval-2.rs rename to tests/ui/structs/struct-order-of-eval-2.rs
diff --git a/tests/ui/structs-enums/struct-order-of-eval-3.rs b/tests/ui/structs/struct-order-of-eval-3.rs similarity index 100% rename from tests/ui/structs-enums/struct-order-of-eval-3.rs rename to tests/ui/structs/struct-order-of-eval-3.rs
diff --git a/tests/ui/structs-enums/struct-order-of-eval-4.rs b/tests/ui/structs/struct-order-of-eval-4.rs similarity index 100% rename from tests/ui/structs-enums/struct-order-of-eval-4.rs rename to tests/ui/structs/struct-order-of-eval-4.rs
diff --git a/tests/ui/structs-enums/struct-partial-move-1.rs b/tests/ui/structs/struct-partial-move-1.rs similarity index 100% rename from tests/ui/structs-enums/struct-partial-move-1.rs rename to tests/ui/structs/struct-partial-move-1.rs
diff --git a/tests/ui/structs-enums/struct-partial-move-2.rs b/tests/ui/structs/struct-partial-move-2.rs similarity index 100% rename from tests/ui/structs-enums/struct-partial-move-2.rs rename to tests/ui/structs/struct-partial-move-2.rs
diff --git a/tests/ui/structs-enums/struct-path-associated-type.rs b/tests/ui/structs/struct-path-associated-type-2.rs similarity index 100% rename from tests/ui/structs-enums/struct-path-associated-type.rs rename to tests/ui/structs/struct-path-associated-type-2.rs
diff --git a/tests/ui/structs-enums/struct-path-self.rs b/tests/ui/structs/struct-path-self-2.rs similarity index 100% rename from tests/ui/structs-enums/struct-path-self.rs rename to tests/ui/structs/struct-path-self-2.rs
diff --git a/tests/ui/structs-enums/struct-pattern-matching.rs b/tests/ui/structs/struct-pattern-matching.rs similarity index 100% rename from tests/ui/structs-enums/struct-pattern-matching.rs rename to tests/ui/structs/struct-pattern-matching.rs
diff --git a/tests/ui/structs-enums/struct-variant-field-visibility.rs b/tests/ui/structs/struct-variant-field-visibility.rs similarity index 92% rename from tests/ui/structs-enums/struct-variant-field-visibility.rs rename to tests/ui/structs/struct-variant-field-visibility.rs index a6528f9..40acea9 100644 --- a/tests/ui/structs-enums/struct-variant-field-visibility.rs +++ b/tests/ui/structs/struct-variant-field-visibility.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] mod foo {
diff --git a/tests/ui/structs-enums/uninstantiable-struct.rs b/tests/ui/structs/uninstantiable-struct.rs similarity index 80% rename from tests/ui/structs-enums/uninstantiable-struct.rs rename to tests/ui/structs/uninstantiable-struct.rs index 97bc7d84..def0fa0 100644 --- a/tests/ui/structs-enums/uninstantiable-struct.rs +++ b/tests/ui/structs/uninstantiable-struct.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass pub struct Z(#[allow(dead_code)] &'static Z); pub fn main() {}
diff --git a/tests/ui/structs-enums/unit-like-struct-drop-run.rs b/tests/ui/structs/unit-like-struct-drop-run.rs similarity index 100% rename from tests/ui/structs-enums/unit-like-struct-drop-run.rs rename to tests/ui/structs/unit-like-struct-drop-run.rs
diff --git a/tests/ui/structs-enums/unit-like-struct.rs b/tests/ui/structs/unit-like-struct.rs similarity index 100% rename from tests/ui/structs-enums/unit-like-struct.rs rename to tests/ui/structs/unit-like-struct.rs
diff --git a/tests/ui/structs-enums/variant-structs-trivial.rs b/tests/ui/structs/variant-structs-trivial.rs similarity index 86% rename from tests/ui/structs-enums/variant-structs-trivial.rs rename to tests/ui/structs/variant-structs-trivial.rs index a7b0575..c1403b7 100644 --- a/tests/ui/structs-enums/variant-structs-trivial.rs +++ b/tests/ui/structs/variant-structs-trivial.rs
@@ -1,4 +1,4 @@ -//@ run-pass +//@ check-pass #![allow(dead_code)] enum Foo {
diff --git a/tests/ui/suggestions/deref-path-method.rs b/tests/ui/suggestions/deref-path-method.rs index 0281cdb..d44b3bd 100644 --- a/tests/ui/suggestions/deref-path-method.rs +++ b/tests/ui/suggestions/deref-path-method.rs
@@ -1,6 +1,6 @@ fn main() { let vec = Vec::new(); Vec::contains(&vec, &0); - //~^ ERROR no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope + //~^ ERROR no associated function or constant named `contains` found for struct `Vec<_, _>` in the current scope //~| HELP the function `contains` is implemented on `[_]` }
diff --git a/tests/ui/suggestions/deref-path-method.stderr b/tests/ui/suggestions/deref-path-method.stderr index 0dec424..8cf8ec9 100644 --- a/tests/ui/suggestions/deref-path-method.stderr +++ b/tests/ui/suggestions/deref-path-method.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope +error[E0599]: no associated function or constant named `contains` found for struct `Vec<_, _>` in the current scope --> $DIR/deref-path-method.rs:3:10 | LL | Vec::contains(&vec, &0); - | ^^^^^^^^ function or associated item not found in `Vec<_, _>` + | ^^^^^^^^ associated function or constant not found in `Vec<_, _>` | note: if you're trying to build a new `Vec<_, _>` consider using one of the following associated functions: Vec::<T>::new
diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr index 5eb64c4..836d31f 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr
@@ -4,13 +4,13 @@ LL | let _ = &str::from("value"); | ^^^ the trait `From<_>` is not implemented for `str` | - = help: the following other types implement trait `From<T>`: - `String` implements `From<&String>` - `String` implements `From<&mut str>` - `String` implements `From<&str>` - `String` implements `From<Box<str>>` - `String` implements `From<Cow<'_, str>>` - `String` implements `From<char>` + = help: `String` implements trait `From<T>`: + From<&String> + From<&mut str> + From<&str> + From<Box<str>> + From<Cow<'_, str>> + From<char> help: you likely meant to call the associated function `from` for type `&str`, but the code as written calls associated function `from` on type `str` | LL | let _ = <&str>::from("value");
diff --git a/tests/ui/suggestions/dont-suggest-private-trait-method.rs b/tests/ui/suggestions/dont-suggest-private-trait-method.rs index 6e2b1ab..6a220b0 100644 --- a/tests/ui/suggestions/dont-suggest-private-trait-method.rs +++ b/tests/ui/suggestions/dont-suggest-private-trait-method.rs
@@ -2,5 +2,5 @@ fn main() { T::new(); - //~^ ERROR no function or associated item named `new` found + //~^ ERROR no associated function or constant named `new` found }
diff --git a/tests/ui/suggestions/dont-suggest-private-trait-method.stderr b/tests/ui/suggestions/dont-suggest-private-trait-method.stderr index f251ad5..b53a827 100644 --- a/tests/ui/suggestions/dont-suggest-private-trait-method.stderr +++ b/tests/ui/suggestions/dont-suggest-private-trait-method.stderr
@@ -1,11 +1,11 @@ -error[E0599]: no function or associated item named `new` found for struct `T` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `T` in the current scope --> $DIR/dont-suggest-private-trait-method.rs:4:8 | LL | struct T; - | -------- function or associated item `new` not found for this struct + | -------- associated function or constant `new` not found for this struct ... LL | T::new(); - | ^^^ function or associated item not found in `T` + | ^^^ associated function or constant not found in `T` error: aborting due to 1 previous error
diff --git a/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.fixed b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.fixed new file mode 100644 index 0000000..50beced --- /dev/null +++ b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.fixed
@@ -0,0 +1,11 @@ +//@ run-rustfix +#![allow(dead_code)] + +fn main() { + struct Error; + + const ERROR: Error = Error; + //~^ ERROR missing type for `const` item + //~| HELP provide a type for the constant + //~| SUGGESTION : Error +}
diff --git a/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.rs b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.rs new file mode 100644 index 0000000..f3c4aed --- /dev/null +++ b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.rs
@@ -0,0 +1,11 @@ +//@ run-rustfix +#![allow(dead_code)] + +fn main() { + struct Error; + + const ERROR = Error; + //~^ ERROR missing type for `const` item + //~| HELP provide a type for the constant + //~| SUGGESTION : Error +}
diff --git a/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.stderr b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.stderr new file mode 100644 index 0000000..4111f9d --- /dev/null +++ b/tests/ui/suggestions/function-local-item-type-suggestion-issue-146786.stderr
@@ -0,0 +1,8 @@ +error: missing type for `const` item + --> $DIR/function-local-item-type-suggestion-issue-146786.rs:7:16 + | +LL | const ERROR = Error; + | ^ help: provide a type for the constant: `: Error` + +error: aborting due to 1 previous error +
diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg index d2c1f6c..54eaee2 100644 --- a/tests/ui/suggestions/incorrect-variant-literal.svg +++ b/tests/ui/suggestions/incorrect-variant-literal.svg
@@ -1,4 +1,4 @@ -<svg width="886px" height="9524px" xmlns="http://www.w3.org/2000/svg"> +<svg width="1012px" height="9524px" xmlns="http://www.w3.org/2000/svg"> <style> .fg { fill: #AAAAAA } .bg { fill: #000000 } @@ -437,7 +437,7 @@ </tspan> <tspan x="10px" y="3754px"> </tspan> - <tspan x="10px" y="3772px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `unit` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="3772px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `unit` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="3790px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:34:11</tspan> </tspan> @@ -445,13 +445,13 @@ </tspan> <tspan x="10px" y="3826px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="3844px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `unit` not found for this enum</tspan> + <tspan x="10px" y="3844px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `unit` not found for this enum</tspan> </tspan> <tspan x="10px" y="3862px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="3880px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::unit;</tspan> </tspan> - <tspan x="10px" y="3898px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="3898px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="3916px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -467,7 +467,7 @@ </tspan> <tspan x="10px" y="4024px"> </tspan> - <tspan x="10px" y="4042px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `tuple` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="4042px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `tuple` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="4060px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:35:11</tspan> </tspan> @@ -475,13 +475,13 @@ </tspan> <tspan x="10px" y="4096px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="4114px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `tuple` not found for this enum</tspan> + <tspan x="10px" y="4114px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `tuple` not found for this enum</tspan> </tspan> <tspan x="10px" y="4132px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="4150px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::tuple;</tspan> </tspan> - <tspan x="10px" y="4168px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="4168px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="4186px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -497,7 +497,7 @@ </tspan> <tspan x="10px" y="4294px"> </tspan> - <tspan x="10px" y="4312px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `r#struct` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="4312px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `r#struct` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="4330px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:36:11</tspan> </tspan> @@ -505,13 +505,13 @@ </tspan> <tspan x="10px" y="4366px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="4384px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `r#struct` not found for this enum</tspan> + <tspan x="10px" y="4384px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `r#struct` not found for this enum</tspan> </tspan> <tspan x="10px" y="4402px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="4420px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::r#struct;</tspan> </tspan> - <tspan x="10px" y="4438px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="4438px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="4456px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -527,7 +527,7 @@ </tspan> <tspan x="10px" y="4564px"> </tspan> - <tspan x="10px" y="4582px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `unit` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="4582px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `unit` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="4600px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:37:11</tspan> </tspan> @@ -535,13 +535,13 @@ </tspan> <tspan x="10px" y="4636px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="4654px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `unit` not found for this enum</tspan> + <tspan x="10px" y="4654px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `unit` not found for this enum</tspan> </tspan> <tspan x="10px" y="4672px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="4690px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::unit();</tspan> </tspan> - <tspan x="10px" y="4708px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="4708px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="4726px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -557,7 +557,7 @@ </tspan> <tspan x="10px" y="4834px"> </tspan> - <tspan x="10px" y="4852px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `tuple` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="4852px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `tuple` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="4870px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:38:11</tspan> </tspan> @@ -565,13 +565,13 @@ </tspan> <tspan x="10px" y="4906px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="4924px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `tuple` not found for this enum</tspan> + <tspan x="10px" y="4924px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `tuple` not found for this enum</tspan> </tspan> <tspan x="10px" y="4942px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="4960px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::tuple();</tspan> </tspan> - <tspan x="10px" y="4978px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="4978px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="4996px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -587,7 +587,7 @@ </tspan> <tspan x="10px" y="5104px"> </tspan> - <tspan x="10px" y="5122px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `r#struct` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="5122px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `r#struct` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="5140px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:39:11</tspan> </tspan> @@ -595,13 +595,13 @@ </tspan> <tspan x="10px" y="5176px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="5194px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `r#struct` not found for this enum</tspan> + <tspan x="10px" y="5194px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `r#struct` not found for this enum</tspan> </tspan> <tspan x="10px" y="5212px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="5230px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::r#struct();</tspan> </tspan> - <tspan x="10px" y="5248px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="5248px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="5266px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -707,7 +707,7 @@ </tspan> <tspan x="10px" y="6184px"> </tspan> - <tspan x="10px" y="6202px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `unit` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="6202px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `unit` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="6220px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:43:11</tspan> </tspan> @@ -715,13 +715,13 @@ </tspan> <tspan x="10px" y="6256px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="6274px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `unit` not found for this enum</tspan> + <tspan x="10px" y="6274px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `unit` not found for this enum</tspan> </tspan> <tspan x="10px" y="6292px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="6310px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::unit(0);</tspan> </tspan> - <tspan x="10px" y="6328px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="6328px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="6346px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -737,7 +737,7 @@ </tspan> <tspan x="10px" y="6454px"> </tspan> - <tspan x="10px" y="6472px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `tuple` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="6472px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `tuple` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="6490px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:44:11</tspan> </tspan> @@ -745,13 +745,13 @@ </tspan> <tspan x="10px" y="6526px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="6544px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `tuple` not found for this enum</tspan> + <tspan x="10px" y="6544px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `tuple` not found for this enum</tspan> </tspan> <tspan x="10px" y="6562px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="6580px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::tuple(0);</tspan> </tspan> - <tspan x="10px" y="6598px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="6598px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="6616px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -767,7 +767,7 @@ </tspan> <tspan x="10px" y="6724px"> </tspan> - <tspan x="10px" y="6742px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `r#struct` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="6742px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `r#struct` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="6760px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:45:11</tspan> </tspan> @@ -775,13 +775,13 @@ </tspan> <tspan x="10px" y="6796px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="6814px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `r#struct` not found for this enum</tspan> + <tspan x="10px" y="6814px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `r#struct` not found for this enum</tspan> </tspan> <tspan x="10px" y="6832px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="6850px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::r#struct(0);</tspan> </tspan> - <tspan x="10px" y="6868px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="6868px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="6886px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -887,7 +887,7 @@ </tspan> <tspan x="10px" y="7804px"> </tspan> - <tspan x="10px" y="7822px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `unit` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="7822px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `unit` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="7840px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:49:11</tspan> </tspan> @@ -895,13 +895,13 @@ </tspan> <tspan x="10px" y="7876px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="7894px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `unit` not found for this enum</tspan> + <tspan x="10px" y="7894px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `unit` not found for this enum</tspan> </tspan> <tspan x="10px" y="7912px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="7930px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::unit(0, 0);</tspan> </tspan> - <tspan x="10px" y="7948px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="7948px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="7966px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -917,7 +917,7 @@ </tspan> <tspan x="10px" y="8074px"> </tspan> - <tspan x="10px" y="8092px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `tuple` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="8092px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `tuple` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="8110px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:50:11</tspan> </tspan> @@ -925,13 +925,13 @@ </tspan> <tspan x="10px" y="8146px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="8164px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `tuple` not found for this enum</tspan> + <tspan x="10px" y="8164px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `tuple` not found for this enum</tspan> </tspan> <tspan x="10px" y="8182px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="8200px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::tuple(0, 0);</tspan> </tspan> - <tspan x="10px" y="8218px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="8218px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="8236px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan> @@ -947,7 +947,7 @@ </tspan> <tspan x="10px" y="8344px"> </tspan> - <tspan x="10px" y="8362px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant or associated item named `r#struct` found for enum `Enum` in the current scope</tspan> + <tspan x="10px" y="8362px"><tspan class="fg-bright-red bold">error[E0599]</tspan><tspan class="bold">: no variant, associated function, or constant named `r#struct` found for enum `Enum` in the current scope</tspan> </tspan> <tspan x="10px" y="8380px"><tspan> </tspan><tspan class="fg-bright-blue bold">--> </tspan><tspan>$DIR/incorrect-variant-literal.rs:51:11</tspan> </tspan> @@ -955,13 +955,13 @@ </tspan> <tspan x="10px" y="8416px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> enum Enum {</tspan> </tspan> - <tspan x="10px" y="8434px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant or associated item `r#struct` not found for this enum</tspan> + <tspan x="10px" y="8434px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">---------</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">variant, associated function, or constant `r#struct` not found for this enum</tspan> </tspan> <tspan x="10px" y="8452px"><tspan class="fg-bright-blue bold">...</tspan> </tspan> <tspan x="10px" y="8470px"><tspan class="fg-bright-blue bold">LL</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> Enum::r#struct(0, 0);</tspan> </tspan> - <tspan x="10px" y="8488px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant or associated item not found in `Enum`</tspan> + <tspan x="10px" y="8488px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-bright-red bold">variant, associated function, or constant not found in `Enum`</tspan> </tspan> <tspan x="10px" y="8506px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan> </tspan>
diff --git a/tests/ui/suggestions/into-str.stderr b/tests/ui/suggestions/into-str.stderr index d02d318..cfb8f33 100644 --- a/tests/ui/suggestions/into-str.stderr +++ b/tests/ui/suggestions/into-str.stderr
@@ -7,13 +7,13 @@ | required by a bound introduced by this call | = note: to coerce a `String` into a `&str`, use `&*` as a prefix - = help: the following other types implement trait `From<T>`: - `String` implements `From<&String>` - `String` implements `From<&mut str>` - `String` implements `From<&str>` - `String` implements `From<Box<str>>` - `String` implements `From<Cow<'_, str>>` - `String` implements `From<char>` + = help: `String` implements trait `From<T>`: + From<&String> + From<&mut str> + From<&str> + From<Box<str>> + From<Cow<'_, str>> + From<char> = note: required for `String` to implement `Into<&str>` note: required by a bound in `foo` --> $DIR/into-str.rs:1:31
diff --git a/tests/ui/suggestions/issue-109291.rs b/tests/ui/suggestions/issue-109291.rs index 1947b16..5b27970 100644 --- a/tests/ui/suggestions/issue-109291.rs +++ b/tests/ui/suggestions/issue-109291.rs
@@ -1,4 +1,4 @@ fn main() { println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); - //~^ ERROR no function or associated item name + //~^ ERROR no associated function or constant name }
diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr index c2c36f1..c588689 100644 --- a/tests/ui/suggestions/issue-109291.stderr +++ b/tests/ui/suggestions/issue-109291.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `forced_capture` found for struct `Backtrace` in the current scope +error[E0599]: no associated function or constant named `forced_capture` found for struct `Backtrace` in the current scope --> $DIR/issue-109291.rs:2:65 | LL | println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); - | ^^^^^^^^^^^^^^ function or associated item not found in `Backtrace` + | ^^^^^^^^^^^^^^ associated function or constant not found in `Backtrace` | note: if you're trying to build a new `Backtrace` consider using one of the following associated functions: Backtrace::capture
diff --git a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr index c5984f5..29e1c6b 100644 --- a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr +++ b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr
@@ -5,15 +5,15 @@ | ^^ no implementation for `String == T` | = help: the trait `PartialEq<T>` is not implemented for `String` - = help: the following other types implement trait `PartialEq<Rhs>`: - `String` implements `PartialEq<&str>` - `String` implements `PartialEq<ByteStr>` - `String` implements `PartialEq<ByteString>` - `String` implements `PartialEq<Cow<'_, str>>` - `String` implements `PartialEq<Path>` - `String` implements `PartialEq<PathBuf>` - `String` implements `PartialEq<str>` - `String` implements `PartialEq` + = help: `String` implements trait `PartialEq<Rhs>`: + PartialEq<&str> + PartialEq<ByteStr> + PartialEq<ByteString> + PartialEq<Cow<'_, str>> + PartialEq<Path> + PartialEq<PathBuf> + PartialEq<str> + PartialEq = note: `T` implements `PartialEq<String>` help: consider swapping the equality |
diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr index 9f34d27..6dd4b1e 100644 --- a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr
@@ -20,15 +20,15 @@ | required by a bound introduced by this call | = help: the trait `FromIterator<()>` is not implemented for `String` - = help: the following other types implement trait `FromIterator<A>`: - `String` implements `FromIterator<&char>` - `String` implements `FromIterator<&std::ascii::Char>` - `String` implements `FromIterator<&str>` - `String` implements `FromIterator<Box<str, A>>` - `String` implements `FromIterator<Cow<'_, str>>` - `String` implements `FromIterator<String>` - `String` implements `FromIterator<char>` - `String` implements `FromIterator<std::ascii::Char>` + = help: `String` implements trait `FromIterator<A>`: + FromIterator<&char> + FromIterator<&std::ascii::Char> + FromIterator<&str> + FromIterator<Box<str, A>> + FromIterator<Cow<'_, str>> + FromIterator<String> + FromIterator<char> + FromIterator<std::ascii::Char> note: the method call chain might not have had the expected associated types --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:20:10 |
diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 541c625..a1b66c2 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -5,14 +5,16 @@ | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` -help: the following other types implement trait `SliceIndex<T>` +help: `usize` implements trait `SliceIndex<T>` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | - = note: `usize` implements `SliceIndex<[T]>` + = note: `SliceIndex<[T]>` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | - = note: `usize` implements `SliceIndex<ByteStr>` + = note: `SliceIndex<ByteStr>` = note: required for `[{integer}]` to implement `Index<&usize>` + = note: 1 redundant requirement hidden + = note: required for `[{integer}; 3]` to implement `Index<&usize>` help: dereference this index | LL | let one_item_please: i32 = [1, 2, 3][*i];
diff --git a/tests/ui/suggestions/suggest-variants.stderr b/tests/ui/suggestions/suggest-variants.stderr index 13518a9..41c2662 100644 --- a/tests/ui/suggestions/suggest-variants.stderr +++ b/tests/ui/suggestions/suggest-variants.stderr
@@ -36,14 +36,14 @@ LL | println!("My shape is {:?}", Shape::Rombus{ size: 5}); | ^^^^^^ variant not found in `Shape` -error[E0599]: no variant or associated item named `Squareee` found for enum `Shape` in the current scope +error[E0599]: no variant, associated function, or constant named `Squareee` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:15:12 | LL | enum Shape { - | ---------- variant or associated item `Squareee` not found for this enum + | ---------- variant, associated function, or constant `Squareee` not found for this enum ... LL | Shape::Squareee; - | ^^^^^^^^ variant or associated item not found in `Shape` + | ^^^^^^^^ variant, associated function, or constant not found in `Shape` | help: there is a variant with a similar name | @@ -51,37 +51,37 @@ LL + Shape::Square { size: /* value */ }; | -error[E0599]: no variant or associated item named `Circl` found for enum `Shape` in the current scope +error[E0599]: no variant, associated function, or constant named `Circl` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:16:12 | LL | enum Shape { - | ---------- variant or associated item `Circl` not found for this enum + | ---------- variant, associated function, or constant `Circl` not found for this enum ... LL | Shape::Circl; - | ^^^^^ variant or associated item not found in `Shape` + | ^^^^^ variant, associated function, or constant not found in `Shape` | help: there is a variant with a similar name | LL | Shape::Circle { radius: /* value */ }; | +++++++++++++++++++++++++ -error[E0599]: no variant or associated item named `Rombus` found for enum `Shape` in the current scope +error[E0599]: no variant, associated function, or constant named `Rombus` found for enum `Shape` in the current scope --> $DIR/suggest-variants.rs:17:12 | LL | enum Shape { - | ---------- variant or associated item `Rombus` not found for this enum + | ---------- variant, associated function, or constant `Rombus` not found for this enum ... LL | Shape::Rombus; - | ^^^^^^ variant or associated item not found in `Shape` + | ^^^^^^ variant, associated function, or constant not found in `Shape` -error[E0599]: no variant or associated item named `Redd` found for enum `Color` in the current scope +error[E0599]: no variant, associated function, or constant named `Redd` found for enum `Color` in the current scope --> $DIR/suggest-variants.rs:28:13 | LL | enum Color { - | ---------- variant or associated item `Redd` not found for this enum + | ---------- variant, associated function, or constant `Redd` not found for this enum ... LL | Ok(Color::Redd) - | ^^^^ variant or associated item not found in `Color` + | ^^^^ variant, associated function, or constant not found in `Color` | help: there is a variant with a similar name | @@ -89,14 +89,14 @@ LL + Ok(Color::Red) | -error[E0599]: no variant or associated item named `Greenn` found for enum `Color` in the current scope +error[E0599]: no variant, associated function, or constant named `Greenn` found for enum `Color` in the current scope --> $DIR/suggest-variants.rs:32:13 | LL | enum Color { - | ---------- variant or associated item `Greenn` not found for this enum + | ---------- variant, associated function, or constant `Greenn` not found for this enum ... LL | Ok(Color::Greenn(())) - | ^^^^^^ variant or associated item not found in `Color` + | ^^^^^^ variant, associated function, or constant not found in `Color` | help: there is a variant with a similar name | @@ -104,14 +104,14 @@ LL + Ok(Color::Green(())) | -error[E0599]: no variant or associated item named `Blu` found for enum `Color` in the current scope +error[E0599]: no variant, associated function, or constant named `Blu` found for enum `Color` in the current scope --> $DIR/suggest-variants.rs:36:13 | LL | enum Color { - | ---------- variant or associated item `Blu` not found for this enum + | ---------- variant, associated function, or constant `Blu` not found for this enum ... LL | Ok(Color::Blu) - | ^^^ variant or associated item not found in `Color` + | ^^^ variant, associated function, or constant not found in `Color` | help: there is a variant with a similar name |
diff --git a/tests/ui/target-feature/packedstack-combinations.backchain_attr.stderr b/tests/ui/target-feature/packedstack-combinations.backchain_attr.stderr new file mode 100644 index 0000000..6270e43 --- /dev/null +++ b/tests/ui/target-feature/packedstack-combinations.backchain_attr.stderr
@@ -0,0 +1,6 @@ +error: `-Zpacked-stack` is incompatible with `backchain` target feature + | + = note: enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes + +error: aborting due to 1 previous error +
diff --git a/tests/ui/target-feature/packedstack-combinations.need_softfloat.stderr b/tests/ui/target-feature/packedstack-combinations.need_softfloat.stderr new file mode 100644 index 0000000..6f45319 --- /dev/null +++ b/tests/ui/target-feature/packedstack-combinations.need_softfloat.stderr
@@ -0,0 +1,10 @@ +warning: unstable feature specified for `-Ctarget-feature`: `backchain` + | + = note: this feature is not stably supported; its behavior can change in the future + +error: packedstack with backchain needs softfloat + | + = note: enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes + +error: aborting due to 1 previous error; 1 warning emitted +
diff --git a/tests/ui/target-feature/packedstack-combinations.rs b/tests/ui/target-feature/packedstack-combinations.rs new file mode 100644 index 0000000..5dc0f6a --- /dev/null +++ b/tests/ui/target-feature/packedstack-combinations.rs
@@ -0,0 +1,44 @@ +//@ add-minicore +//@ revisions: wrong_arch only_packedstack backchain_attr backchain_cli with_softfloat +//@ compile-flags: -Zpacked-stack --crate-type=rlib +//@ ignore-backends: gcc + +//@ [wrong_arch] compile-flags: --target=x86_64-unknown-linux-gnu +//@ [wrong_arch] should-fail +//@ [wrong_arch] needs-llvm-components: x86 + +//@ [only_packedstack] compile-flags: --target=s390x-unknown-linux-gnu +//@ [only_packedstack] build-pass +//@ [only_packedstack] needs-llvm-components: systemz + +//@ [backchain_attr] compile-flags: --target=s390x-unknown-linux-gnu +//@ [backchain_attr] build-fail +//@ [backchain_attr] needs-llvm-components: systemz + +//@ [backchain_cli] compile-flags: -Ctarget-feature=+backchain --target=s390x-unknown-linux-gnu +//@ [backchain_cli] should-fail +//@ [backchain_cli] needs-llvm-components: systemz + +//@ [with_softfloat] compile-flags: -Ctarget-feature=+backchain +//@ [with_softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@ [with_softfloat] build-pass +//@ [with_softfloat] needs-llvm-components: systemz + +#![feature(s390x_target_feature)] +#![crate_type = "rlib"] +#![feature(no_core,lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +#[cfg_attr(backchain_attr,target_feature(enable = "backchain"))] +pub fn test() { +} + +//[wrong_arch]~? ERROR `-Zpacked-stack` is only supported on s390x +//[backchain_cli]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain` +//[backchain_cli]~? ERROR `-Zpacked-stack` is incompatible with `backchain` target feature +//[backchain_attr]~? ERROR `-Zpacked-stack` is incompatible with `backchain` target feature +//[with_softfloat]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain`
diff --git a/tests/ui/target-feature/packedstack-combinations.with_softfloat.stderr b/tests/ui/target-feature/packedstack-combinations.with_softfloat.stderr new file mode 100644 index 0000000..b8c06fc --- /dev/null +++ b/tests/ui/target-feature/packedstack-combinations.with_softfloat.stderr
@@ -0,0 +1,6 @@ +warning: unstable feature specified for `-Ctarget-feature`: `backchain` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: 1 warning emitted +
diff --git a/tests/ui/target-feature/packedstack-combinations.wrong_arch.stderr b/tests/ui/target-feature/packedstack-combinations.wrong_arch.stderr new file mode 100644 index 0000000..aa178ad --- /dev/null +++ b/tests/ui/target-feature/packedstack-combinations.wrong_arch.stderr
@@ -0,0 +1,4 @@ +error: `-Zpacked-stack` is only supported on s390x + +error: aborting due to 1 previous error +
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr index ba314c1..9ac5674 100644 --- a/tests/ui/track-diagnostics/track.stderr +++ b/tests/ui/track-diagnostics/track.stderr
@@ -40,7 +40,7 @@ note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics query stack during panic: -#0 [typeck] type-checking `main` +#0 [typeck_root] type-checking `main` #1 [analysis] running analysis passes on crate `track` end of query stack error: aborting due to 3 previous errors
diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed b/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed new file mode 100644 index 0000000..d575413 --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed
@@ -0,0 +1,38 @@ +//@ run-rustfix + +#![allow(dead_code)] + +use std::marker::PhantomData; + +trait Visitor<'de> { + type Value; +} + +trait Deserializer<'de> { + type Error; + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; +} + +struct Wrapper<'de, T, E>(Result<T, E>, PhantomData<&'de ()>); + +impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> +where + T: Deserializer<'de, Error = E>, +{ + type Error = E; + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.0 { + Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types + Err(error) => Err(error), + } + } +} + +fn main() {}
diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs b/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs new file mode 100644 index 0000000..7b33cec --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs
@@ -0,0 +1,38 @@ +//@ run-rustfix + +#![allow(dead_code)] + +use std::marker::PhantomData; + +trait Visitor<'de> { + type Value; +} + +trait Deserializer<'de> { + type Error; + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>; +} + +struct Wrapper<'de, T, E>(Result<T, E>, PhantomData<&'de ()>); + +impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> +where + T: Deserializer<'de>, +{ + type Error = E; + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: Visitor<'de>, + { + match self.0 { + Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types + Err(error) => Err(error), + } + } +} + +fn main() {}
diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr new file mode 100644 index 0000000..18cfece --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr
@@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/associated-error-bound-issue-145586.rs:32:33 + | +LL | impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> + | - expected this type parameter +... +LL | fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + | ----------------------------- expected `Result<<V as Visitor<'de>>::Value, E>` because of return type +... +LL | Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<<V as Visitor<'_>>::Value, E>`, found `Result<<V as Visitor<'_>>::Value, ...>` + | + = note: expected enum `Result<_, E>` + found enum `Result<_, <T as Deserializer<'de>>::Error>` +help: consider further restricting this bound + | +LL | T: Deserializer<'de, Error = E>, + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.rs b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.rs similarity index 100% rename from tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.rs rename to tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.rs
diff --git a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr similarity index 76% rename from tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr rename to tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr index 7b59fe7..3776c35 100644 --- a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr +++ b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr
@@ -1,5 +1,5 @@ error[E0277]: `Rc<Foo>` cannot be shared between threads safely - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:14:7 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<Foo>` cannot be shared between threads safely @@ -8,24 +8,24 @@ | = help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>` note: required because it appears within the type `Bar` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:6:6 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:6:6 | LL | enum Bar { | ^^^ = note: required for `Arc<Bar>` to implement `Send` note: required because it appears within the type `Foo` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:4:8 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:4:8 | LL | struct Foo(Arc<Bar>); | ^^^ note: required by a bound in `f` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:11:9 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:11:9 | LL | fn f<T: Send>(_: T) {} | ^^^^ required by this bound in `f` error[E0277]: `Rc<Foo>` cannot be sent between threads safely - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:14:7 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<Foo>` cannot be sent between threads safely @@ -34,18 +34,18 @@ | = help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>` note: required because it appears within the type `Bar` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:6:6 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:6:6 | LL | enum Bar { | ^^^ = note: required for `Arc<Bar>` to implement `Send` note: required because it appears within the type `Foo` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:4:8 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:4:8 | LL | struct Foo(Arc<Bar>); | ^^^ note: required by a bound in `f` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:11:9 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:11:9 | LL | fn f<T: Send>(_: T) {} | ^^^^ required by this bound in `f`
diff --git a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr index 49a4db7..1884ba6 100644 --- a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr +++ b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr
@@ -1,11 +1,11 @@ -error[E0599]: the function or associated item `f` exists for struct `Foo<()>`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `f` exists for struct `Foo<()>`, but its trait bounds were not satisfied --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:14:16 | LL | struct Foo<I>(I); - | ------------- function or associated item `f` not found for this struct + | ------------- associated function or constant `f` not found for this struct ... LL | Foo::<()>::f() - | ^ function or associated item cannot be called on `Foo<()>` due to unsatisfied trait bounds + | ^ associated function or constant cannot be called on `Foo<()>` due to unsatisfied trait bounds | note: trait bound `(): Iterator` was not satisfied --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:5:23
diff --git a/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr index 42969de..f26c321 100644 --- a/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr +++ b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr
@@ -1,11 +1,11 @@ -error[E0599]: the function or associated item `bat` exists for struct `Foo`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `bat` exists for struct `Foo`, but its trait bounds were not satisfied --> $DIR/associated-item-unsatisfied-trait-bounds.rs:8:10 | LL | struct Foo; - | ---------- function or associated item `bat` not found for this struct because `Foo` doesn't implement `Bar` or `Baz` + | ---------- associated function or constant `bat` not found for this struct because `Foo` doesn't implement `Bar` or `Baz` ... LL | Foo::bat(()); - | ^^^ function or associated item cannot be called on `Foo` due to unsatisfied trait bounds + | ^^^ associated function or constant cannot be called on `Foo` due to unsatisfied trait bounds | note: for `bat` to be available, `Foo` must implement `Bar` and `Baz` --> $DIR/associated-item-unsatisfied-trait-bounds.rs:5:38
diff --git a/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.next.stderr b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.next.stderr new file mode 100644 index 0000000..8b5c4f5 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.next.stderr
@@ -0,0 +1,21 @@ +error[E0277]: the trait bound `Vec<u8>: const Destruct` is not satisfied + --> $DIR/const-closure-with-indestructible-indestructible.rs:10:16 + | +LL | i_need(const || { + | _________------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | let y = v; +LL | | }) + | |_________^ + | +note: required by a bound in `i_need` + --> $DIR/const-closure-with-indestructible-indestructible.rs:5:20 + | +LL | const fn i_need<F: [const] std::marker::Destruct>(x: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `i_need` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.old.stderr b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.old.stderr new file mode 100644 index 0000000..8b5c4f5 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.old.stderr
@@ -0,0 +1,21 @@ +error[E0277]: the trait bound `Vec<u8>: const Destruct` is not satisfied + --> $DIR/const-closure-with-indestructible-indestructible.rs:10:16 + | +LL | i_need(const || { + | _________------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | let y = v; +LL | | }) + | |_________^ + | +note: required by a bound in `i_need` + --> $DIR/const-closure-with-indestructible-indestructible.rs:5:20 + | +LL | const fn i_need<F: [const] std::marker::Destruct>(x: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `i_need` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.rs b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.rs new file mode 100644 index 0000000..d26260d --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-with-indestructible-indestructible.rs
@@ -0,0 +1,15 @@ +//@revisions: next old +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +#![feature(const_trait_impl, const_closures, const_destruct)] +const fn i_need<F: [const] std::marker::Destruct>(x: F) {} + +fn main() { + const { + let v = Vec::<u8>::new(); + i_need(const || { + //~^ ERROR the trait bound + let y = v; + }) + }; +}
diff --git a/tests/ui/traits/const-traits/const-traits-core.rs b/tests/ui/traits/const-traits/const-traits-core.rs index 2cafde4..ed244c2 100644 --- a/tests/ui/traits/const-traits/const-traits-core.rs +++ b/tests/ui/traits/const-traits/const-traits-core.rs
@@ -36,8 +36,8 @@ const OPT: Option<i32> = Default::default(); // core::iter::sources::empty const EMPTY: std::iter::Empty<()> = Default::default(); -// core::ptr::alignment -const ALIGNMENT: std::ptr::Alignment = Default::default(); +// core::mem::alignment +const ALIGNMENT: std::mem::Alignment = Default::default(); // core::slice const SLICE: &[()] = Default::default(); const MUT_SLICE: &mut [()] = Default::default();
diff --git a/tests/ui/traits/const-traits/mismatched_generic_args.rs b/tests/ui/traits/const-traits/mismatched_generic_args.rs index 21e91c7..409a704 100644 --- a/tests/ui/traits/const-traits/mismatched_generic_args.rs +++ b/tests/ui/traits/const-traits/mismatched_generic_args.rs
@@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN: the feature `generic_const_exprs` is incomplete // Regression test for #125770 which would ICE under the old effects desugaring that // created a const generic parameter for constness on `Add`.
diff --git a/tests/ui/traits/const-traits/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/mismatched_generic_args.stderr index e810331..3094cb5 100644 --- a/tests/ui/traits/const-traits/mismatched_generic_args.stderr +++ b/tests/ui/traits/const-traits/mismatched_generic_args.stderr
@@ -1,5 +1,5 @@ error[E0425]: cannot find value `y` in this scope - --> $DIR/mismatched_generic_args.rs:20:9 + --> $DIR/mismatched_generic_args.rs:19:9 | LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> { | - similarly named const parameter `U` defined here @@ -13,17 +13,8 @@ LL + x + U | -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mismatched_generic_args.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error: `Dimension` is forbidden as the type of a const generic parameter - --> $DIR/mismatched_generic_args.rs:11:33 + --> $DIR/mismatched_generic_args.rs:10:33 | LL | pub struct Quantity<S, const D: Dimension>(S); | ^^^^^^^^^ @@ -35,13 +26,13 @@ | error[E0107]: trait takes at most 1 generic argument but 2 generic arguments were supplied - --> $DIR/mismatched_generic_args.rs:14:36 + --> $DIR/mismatched_generic_args.rs:13:36 | LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {} | ^^^ expected at most 1 generic argument error: `Dimension` is forbidden as the type of a const generic parameter - --> $DIR/mismatched_generic_args.rs:14:15 + --> $DIR/mismatched_generic_args.rs:13:15 | LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {} | ^^^^^^^^^ @@ -53,7 +44,7 @@ | error: `Dimension` is forbidden as the type of a const generic parameter - --> $DIR/mismatched_generic_args.rs:18:21 + --> $DIR/mismatched_generic_args.rs:17:21 | LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> { | ^^^^^^^^^ @@ -64,7 +55,7 @@ LL + #![feature(adt_const_params)] | -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors Some errors have detailed explanations: E0107, E0425. For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr index a6bd861..57bb556 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr
@@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` - --> $DIR/overlap-const-with-nonconst.rs:21:1 + --> $DIR/overlap-const-with-nonconst.rs:20:1 | LL | / impl<T> const Foo for T LL | | where
diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs index 10dfb20..0e21d31 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs
@@ -2,7 +2,6 @@ #![feature(const_trait_impl)] #![cfg_attr(spec, feature(specialization))] -//[spec]~^ WARN the feature `specialization` is incomplete #![cfg_attr(min_spec, feature(min_specialization))] const trait Bar {}
diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr index 91628f6..57bb556 100644 --- a/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-const-with-nonconst.rs:4:27 - | -LL | #![cfg_attr(spec, feature(specialization))] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` - --> $DIR/overlap-const-with-nonconst.rs:21:1 + --> $DIR/overlap-const-with-nonconst.rs:20:1 | LL | / impl<T> const Foo for T LL | | where @@ -19,6 +9,6 @@ LL | impl<T> Foo for (T,) { | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_,)` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr index 520a683..ad3c177 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr
@@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/const-default-impl-non-const-specialized-impl.rs:21:1 + --> $DIR/const-default-impl-non-const-specialized-impl.rs:20:1 | LL | impl<T> const Value for T { | ------------------------- first implementation here
diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs index f7cd459..b26e655 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -3,7 +3,6 @@ #![feature(const_trait_impl)] #![cfg_attr(spec, feature(specialization))] -//[spec]~^ WARN the feature `specialization` is incomplete #![cfg_attr(min_spec, feature(min_specialization))] const trait Value {
diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr index 397d678..ad3c177 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-default-impl-non-const-specialized-impl.rs:5:27 - | -LL | #![cfg_attr(spec, feature(specialization))] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/const-default-impl-non-const-specialized-impl.rs:21:1 + --> $DIR/const-default-impl-non-const-specialized-impl.rs:20:1 | LL | impl<T> const Value for T { | ------------------------- first implementation here @@ -17,6 +7,6 @@ LL | impl Value for FortyTwo { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs new file mode 100644 index 0000000..83687f3 --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs
@@ -0,0 +1,21 @@ +trait Output<'a> { + type Type; +} + +struct Wrapper; + +impl Wrapper { + fn do_something_wrapper<O, F>(self, _: F) + where + for<'a> F: Output<'a>, + for<'a> O: From<<F as Output<'a>>::Type>, + { + } +} + +fn main() { + let wrapper = Wrapper; + wrapper.do_something_wrapper(|value| ()); + //~^ ERROR the trait bound `for<'a> {closure@ + //~| ERROR the trait bound `for<'a> _: From<<{closure@ +}
diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr new file mode 100644 index 0000000..1e4cb7f --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr
@@ -0,0 +1,47 @@ +error[E0277]: the trait bound `for<'a> {closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}: Output<'a>` is not satisfied + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:34 + | +LL | wrapper.do_something_wrapper(|value| ()); + | -------------------- ^^^^^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}` +help: this trait has no implementations, consider adding one + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1 + | +LL | trait Output<'a> { + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `Wrapper::do_something_wrapper` + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:10:20 + | +LL | fn do_something_wrapper<O, F>(self, _: F) + | -------------------- required by a bound in this associated function +LL | where +LL | for<'a> F: Output<'a>, + | ^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` + +error[E0277]: the trait bound `for<'a> _: From<<{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41} as Output<'a>>::Type>` is not satisfied + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:13 + | +LL | wrapper.do_something_wrapper(|value| ()); + | ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}` +help: this trait has no implementations, consider adding one + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1 + | +LL | trait Output<'a> { + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `Wrapper::do_something_wrapper` + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:11:20 + | +LL | fn do_something_wrapper<O, F>(self, _: F) + | -------------------- required by a bound in this associated function +... +LL | for<'a> O: From<<F as Output<'a>>::Type>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/explicit-reference-cast.rs b/tests/ui/traits/explicit-reference-cast.rs index efb4f10..b9ccc18 100644 --- a/tests/ui/traits/explicit-reference-cast.rs +++ b/tests/ui/traits/explicit-reference-cast.rs
@@ -7,7 +7,7 @@ //~^ HELP the trait `From<&PathBuf>` is not implemented for `ToolA` impl From<&Path> for ToolA { - //~^ HELP the following other types implement trait `From<T>` + //~^ HELP `ToolA` implements trait `From<T>` fn from(p: &Path) -> ToolA { ToolA(p.to_path_buf()) }
diff --git a/tests/ui/traits/explicit-reference-cast.stderr b/tests/ui/traits/explicit-reference-cast.stderr index 924de3d..78eb25b 100644 --- a/tests/ui/traits/explicit-reference-cast.stderr +++ b/tests/ui/traits/explicit-reference-cast.stderr
@@ -10,14 +10,14 @@ | LL | pub struct ToolA(PathBuf); | ^^^^^^^^^^^^^^^^ -help: the following other types implement trait `From<T>` +help: `ToolA` implements trait `From<T>` --> $DIR/explicit-reference-cast.rs:9:1 | LL | impl From<&Path> for ToolA { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&Path>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<&Path>` ... LL | impl From<&str> for ToolA { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&str>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `From<&str>` error[E0277]: the trait bound `ToolB: TryFrom<&PathBuf>` is not satisfied --> $DIR/explicit-reference-cast.rs:43:13
diff --git a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr index e58f5c3..9b27491 100644 --- a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr
@@ -6,14 +6,14 @@ | | | required by a bound introduced by this call | -help: the following other types implement trait `CompareTo<T>` +help: `i64` implements trait `CompareTo<T>` --> $DIR/repeated-supertrait-ambig.rs:15:1 | LL | impl CompareTo<i64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<i64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<i64>` ... LL | impl CompareTo<u64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<u64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<u64>` error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied --> $DIR/repeated-supertrait-ambig.rs:30:15 @@ -34,14 +34,14 @@ LL | <dyn CompareToInts>::same_as(c, 22) | ^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts` | -help: the following other types implement trait `CompareTo<T>` +help: `i64` implements trait `CompareTo<T>` --> $DIR/repeated-supertrait-ambig.rs:15:1 | LL | impl CompareTo<i64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<i64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<i64>` ... LL | impl CompareTo<u64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<u64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<u64>` error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied --> $DIR/repeated-supertrait-ambig.rs:38:24 @@ -64,14 +64,14 @@ | | | required by a bound introduced by this call | -help: the following other types implement trait `CompareTo<T>` +help: `i64` implements trait `CompareTo<T>` --> $DIR/repeated-supertrait-ambig.rs:15:1 | LL | impl CompareTo<i64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<i64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<i64>` ... LL | impl CompareTo<u64> for i64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `i64` implements `CompareTo<u64>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CompareTo<u64>` error: aborting due to 5 previous errors
diff --git a/tests/ui/traits/issue-3973.rs b/tests/ui/traits/issue-3973.rs index a5ed5b8..96e581c 100644 --- a/tests/ui/traits/issue-3973.rs +++ b/tests/ui/traits/issue-3973.rs
@@ -20,6 +20,6 @@ fn to_string(&self) -> String { fn main() { let p = Point::new(0.0, 0.0); - //~^ ERROR no function or associated item named `new` found for struct `Point` + //~^ ERROR no associated function or constant named `new` found for struct `Point` println!("{}", p.to_string()); }
diff --git a/tests/ui/traits/issue-3973.stderr b/tests/ui/traits/issue-3973.stderr index 87ee080..9da3617 100644 --- a/tests/ui/traits/issue-3973.stderr +++ b/tests/ui/traits/issue-3973.stderr
@@ -7,14 +7,14 @@ LL | | } | |_____^ not a member of trait `ToString_` -error[E0599]: no function or associated item named `new` found for struct `Point` in the current scope +error[E0599]: no associated function or constant named `new` found for struct `Point` in the current scope --> $DIR/issue-3973.rs:22:20 | LL | struct Point { - | ------------ function or associated item `new` not found for this struct + | ------------ associated function or constant `new` not found for this struct ... LL | let p = Point::new(0.0, 0.0); - | ^^^ function or associated item not found in `Point` + | ^^^ associated function or constant not found in `Point` error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/item-privacy.rs b/tests/ui/traits/item-privacy.rs index 44ba876..519a95c 100644 --- a/tests/ui/traits/item-privacy.rs +++ b/tests/ui/traits/item-privacy.rs
@@ -77,9 +77,9 @@ fn check_method() { // Methods, UFCS // a, b, c are resolved as trait items, their traits need to be in scope S::a(&S); - //~^ ERROR no function or associated item named `a` found + //~^ ERROR no associated function or constant named `a` found S::b(&S); - //~^ ERROR no function or associated item named `b` found + //~^ ERROR no associated function or constant named `b` found S::c(&S); // OK // a, b, c are resolved as inherent items, their traits don't need to be in scope <dyn C>::a(&S); //~ ERROR method `a` is private @@ -95,8 +95,8 @@ fn check_assoc_const() { // Associated constants // A, B, C are resolved as trait items, their traits need to be in scope - S::A; //~ ERROR no associated item named `A` found - S::B; //~ ERROR no associated item named `B` found + S::A; //~ ERROR no associated function or constant named `A` found + S::B; //~ ERROR no associated function or constant named `B` found S::C; // OK // A, B, C are resolved as inherent items, their traits don't need to be in scope <dyn C>::A;
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index 8c33bb6..7b19954 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr
@@ -47,14 +47,14 @@ LL | c.a(); | ^ private method -error[E0599]: no function or associated item named `a` found for struct `S` in the current scope +error[E0599]: no associated function or constant named `a` found for struct `S` in the current scope --> $DIR/item-privacy.rs:79:8 | LL | struct S; - | -------- function or associated item `a` not found for this struct + | -------- associated function or constant `a` not found for this struct ... LL | S::a(&S); - | ^ function or associated item not found in `S` + | ^ associated function or constant not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope = help: trait `method::A` which provides `a` is implemented but not reachable @@ -64,14 +64,14 @@ LL | const B: u8 = 0; | ^^^^^^^^^^^ -error[E0599]: no function or associated item named `b` found for struct `S` in the current scope +error[E0599]: no associated function or constant named `b` found for struct `S` in the current scope --> $DIR/item-privacy.rs:81:8 | LL | struct S; - | -------- function or associated item `b` not found for this struct + | -------- associated function or constant `b` not found for this struct ... LL | S::b(&S); - | ^ function or associated item not found in `S` + | ^ associated function or constant not found in `S` | = help: items from traits can only be used if the trait is in scope help: there is an associated constant `B` with a similar name @@ -93,14 +93,14 @@ LL | <dyn C>::a(&S); | ^ private method -error[E0599]: no associated item named `A` found for struct `S` in the current scope +error[E0599]: no associated function or constant named `A` found for struct `S` in the current scope --> $DIR/item-privacy.rs:98:8 | LL | struct S; - | -------- associated item `A` not found for this struct + | -------- associated function or constant `A` not found for this struct ... LL | S::A; - | ^ associated item not found in `S` + | ^ associated function or constant not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope = help: trait `assoc_const::A` which provides `A` is implemented but not reachable @@ -110,14 +110,14 @@ LL + S::B; | -error[E0599]: no associated item named `B` found for struct `S` in the current scope +error[E0599]: no associated function or constant named `B` found for struct `S` in the current scope --> $DIR/item-privacy.rs:99:8 | LL | struct S; - | -------- associated item `B` not found for this struct + | -------- associated function or constant `B` not found for this struct ... LL | S::B; - | ^ associated item not found in `S` + | ^ associated function or constant not found in `S` | = help: items from traits can only be used if the trait is in scope help: there is a method `b` with a similar name
diff --git a/tests/ui/traits/negative-impls/negative-default-impls.rs b/tests/ui/traits/negative-impls/negative-default-impls.rs index c68bca4..2d50bc8 100644 --- a/tests/ui/traits/negative-impls/negative-default-impls.rs +++ b/tests/ui/traits/negative-impls/negative-default-impls.rs
@@ -1,6 +1,5 @@ #![feature(negative_impls)] #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait MyTrait { type Foo;
diff --git a/tests/ui/traits/negative-impls/negative-default-impls.stderr b/tests/ui/traits/negative-impls/negative-default-impls.stderr index 328e744..b321898 100644 --- a/tests/ui/traits/negative-impls/negative-default-impls.stderr +++ b/tests/ui/traits/negative-impls/negative-default-impls.stderr
@@ -1,19 +1,9 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/negative-default-impls.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0750]: negative impls cannot be default impls - --> $DIR/negative-default-impls.rs:9:1 + --> $DIR/negative-default-impls.rs:8:1 | LL | default impl !MyTrait for u32 {} | ^^^^^^^ ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0750`.
diff --git a/tests/ui/traits/negative-impls/negative-specializes-negative.rs b/tests/ui/traits/negative-impls/negative-specializes-negative.rs index bb2856a..fe5165a 100644 --- a/tests/ui/traits/negative-impls/negative-specializes-negative.rs +++ b/tests/ui/traits/negative-impls/negative-specializes-negative.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #![feature(negative_impls)] // Test a negative impl that "specializes" another negative impl.
diff --git a/tests/ui/traits/negative-impls/negative-specializes-negative.stderr b/tests/ui/traits/negative-impls/negative-specializes-negative.stderr deleted file mode 100644 index 751e29c..0000000 --- a/tests/ui/traits/negative-impls/negative-specializes-negative.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/negative-specializes-negative.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/negative-impls/negative-specializes-positive-item.rs b/tests/ui/traits/negative-impls/negative-specializes-positive-item.rs index 4281eed..da22e43 100644 --- a/tests/ui/traits/negative-impls/negative-specializes-positive-item.rs +++ b/tests/ui/traits/negative-impls/negative-specializes-positive-item.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #![feature(negative_impls)] // Negative impl for u32 cannot "specialize" the base impl.
diff --git a/tests/ui/traits/negative-impls/negative-specializes-positive-item.stderr b/tests/ui/traits/negative-impls/negative-specializes-positive-item.stderr index 97727da..e281969 100644 --- a/tests/ui/traits/negative-impls/negative-specializes-positive-item.stderr +++ b/tests/ui/traits/negative-impls/negative-specializes-positive-item.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/negative-specializes-positive-item.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive-item.rs:11:1 | @@ -17,6 +7,6 @@ LL | impl !MyTrait for u32 {} | ^^^^^^^^^^^^^^^^^^^^^ negative implementation here -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/traits/negative-impls/negative-specializes-positive.rs b/tests/ui/traits/negative-impls/negative-specializes-positive.rs index 0e22769..1939a09 100644 --- a/tests/ui/traits/negative-impls/negative-specializes-positive.rs +++ b/tests/ui/traits/negative-impls/negative-specializes-positive.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #![feature(negative_impls)] // Negative impl for u32 cannot "specialize" the base impl.
diff --git a/tests/ui/traits/negative-impls/negative-specializes-positive.stderr b/tests/ui/traits/negative-impls/negative-specializes-positive.stderr index 100f97a..6eab4aa 100644 --- a/tests/ui/traits/negative-impls/negative-specializes-positive.stderr +++ b/tests/ui/traits/negative-impls/negative-specializes-positive.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/negative-specializes-positive.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive.rs:7:1 | @@ -16,6 +6,6 @@ LL | impl !MyTrait for u32 {} | ^^^^^^^^^^^^^^^^^^^^^ negative implementation here -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/traits/negative-impls/positive-specializes-negative.rs b/tests/ui/traits/negative-impls/positive-specializes-negative.rs index a06b357..f2c5f50 100644 --- a/tests/ui/traits/negative-impls/positive-specializes-negative.rs +++ b/tests/ui/traits/negative-impls/positive-specializes-negative.rs
@@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #![feature(negative_impls)] trait MyTrait {}
diff --git a/tests/ui/traits/negative-impls/positive-specializes-negative.stderr b/tests/ui/traits/negative-impls/positive-specializes-negative.stderr index 1655cb0..7c3f5f6 100644 --- a/tests/ui/traits/negative-impls/positive-specializes-negative.stderr +++ b/tests/ui/traits/negative-impls/positive-specializes-negative.stderr
@@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/positive-specializes-negative.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/positive-specializes-negative.rs:7:1 | @@ -16,6 +6,6 @@ LL | impl MyTrait for u32 {} | ^^^^^^^^^^^^^^^^^^^^ positive implementation here -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index 7b91078..b2015b3 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -26,8 +26,8 @@ impl Foo for () { fn main() { let x = String::from("hello, world"); let _ = identity(<() as Foo>::copy_me(&x)); - //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed` - //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed` + //~^ ERROR overflow evaluating whether `<() as Foo>::Item` is well-formed + //~| ERROR overflow evaluating whether `&<() as Foo>::Item` is well-formed //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == String` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index 3509aea..ebfaf46 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -32,13 +32,13 @@ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed` +error[E0275]: overflow evaluating whether `&<() as Foo>::Item` is well-formed --> $DIR/alias-bound-unsound.rs:28:43 | LL | let _ = identity(<() as Foo>::copy_me(&x)); | ^^ -error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed` +error[E0275]: overflow evaluating whether `<() as Foo>::Item` is well-formed --> $DIR/alias-bound-unsound.rs:28:22 | LL | let _ = identity(<() as Foo>::copy_me(&x));
diff --git a/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.rs b/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.rs index d98cd11..327f731 100644 --- a/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.rs +++ b/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.rs
@@ -10,7 +10,6 @@ // which is provided by the first impl that it is specializing. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete #![feature(with_negative_coherence)] trait BoxIter {
diff --git a/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.stderr b/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.stderr deleted file mode 100644 index 4127f51f..0000000 --- a/tests/ui/traits/next-solver/coherence/negative-coherence-bounds.stderr +++ /dev/null
@@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/negative-coherence-bounds.rs:12:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr index 451c144..ed6e595 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr
@@ -30,7 +30,7 @@ | = note: the return type of a function must have a statically known size -error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof well-formed` +error[E0275]: overflow evaluating whether `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof` is well-formed --> $DIR/item-bound-via-impl-where-clause.rs:31:21 | LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs index 39381d1..6ac0c14 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs
@@ -33,7 +33,7 @@ fn main() { //[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _` //[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == String` //[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof: Sized` - //[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof well-formed` + //[next]~| ERROR overflow evaluating whether `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof` is well-formed //[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _` println!("{}", s); // ABC }
diff --git a/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr index 42b76a8..04a4c70 100644 --- a/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr +++ b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr
@@ -5,7 +5,7 @@ | ^^^^^^^ cannot infer type for struct `Head<_>` | = note: cannot satisfy `Head<_>: Trait` -help: the following types implement trait `Trait` +help: `Head<T>` implements trait `Trait` --> $DIR/forced_ambiguity-use-head-maybe-cause.rs:23:1 | LL | / impl<T> Trait for Head<T>
diff --git a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr index 8b24e68..cea95eb 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr
@@ -21,7 +21,7 @@ | LL | struct MultipleCandidates; | ^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the following other types implement trait `Trait` +help: `MultipleCandidates` implements trait `Trait` --> $DIR/inductive-cycle-but-err.rs:26:1 | LL | / impl Trait for MultipleCandidates
diff --git a/tests/ui/traits/next-solver/generalize/constrain-inference-during-normalize.rs b/tests/ui/traits/next-solver/generalize/constrain-inference-during-normalize.rs new file mode 100644 index 0000000..c3942b0 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/constrain-inference-during-normalize.rs
@@ -0,0 +1,25 @@ +// revisions: next old +//[next] compile-flags: -Znext-solver +//@ check-pass +// Regression test for https://github.com/rust-lang/rust/issues/154173. +// The ICE there was caused by a (flawed) attempt to eagerly normalize during generalization. +// The normalize would constrain other inference variables, which we couldn't deal with. + +trait Trait<T> { + type Assoc; +} + +impl Trait<u32> for () { + type Assoc = u32; +} + +trait Eq {} +impl<C: Trait<T>, T> Eq for (C, T, <C as Trait<T>>::Assoc) {} +fn foo<A>() +where + ((), A, A): Eq +{} + +fn main() { + foo::<_>(); +}
diff --git a/tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs b/tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs deleted file mode 100644 index 463fe49..0000000 --- a/tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs +++ /dev/null
@@ -1,26 +0,0 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver -//@ ignore-compare-mode-next-solver (explicit revisions) -//@ check-pass -// Regression test for trait-system-refactor-initiative#262 - -trait View {} -trait HasAssoc { - type Assoc; -} - -struct StableVec<T>(T); -impl<T> View for StableVec<T> {} - -fn assert_view<F: View>(f: F) -> F { f } - - -fn store<T>(x: StableVec<T::Assoc>) -where - T: HasAssoc, - StableVec<T>: View, -{ - let _: StableVec<T::Assoc> = assert_view(x); -} - -fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 84e2f4c..7a4cd2a 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -3,7 +3,6 @@ // This is a gnarly test but I don't know how to minimize it, frankly. #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete trait ToUnit<'a> { type Unit;
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 74cbb5b..a4c8d25 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -1,32 +1,23 @@ error[E0425]: cannot find type `Missing` in this scope - --> $DIR/issue-118950-root-region.rs:19:55 + --> $DIR/issue-118950-root-region.rs:18:55 | LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} | ^^^^^^^ not found in this scope -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-118950-root-region.rs:5:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `*const T: ToUnit<'a>` is not satisfied - --> $DIR/issue-118950-root-region.rs:14:1 + --> $DIR/issue-118950-root-region.rs:13:1 | LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; | ^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T` | help: this trait has no implementations, consider adding one - --> $DIR/issue-118950-root-region.rs:8:1 + --> $DIR/issue-118950-root-region.rs:7:1 | LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error: aborting due to 2 previous errors; 1 warning emitted + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index 82a5f33..cb1bbd4 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr
@@ -27,7 +27,7 @@ LL | Self::Assoc: A<T>, | ^^^^ -error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed` +error[E0275]: overflow evaluating whether `<() as A<T>>::Assoc` is well-formed --> $DIR/normalize-param-env-2.rs:24:22 | LL | Self::Assoc: A<T>,
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr deleted file mode 100644 index ef63681..0000000 --- a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/normalize-self-type-constrains-trait-args.rs:8:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr deleted file mode 100644 index ef63681..0000000 --- a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/normalize-self-type-constrains-trait-args.rs:8:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs index c2a0167..921d753 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs
@@ -6,7 +6,6 @@ // This goal is also possible w/ a GAT, but lazy_type_alias // makes the behavior a bit more readable. #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete struct Wr<T>(T); trait Foo {}
diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs index f1447cd..ba8b49c9 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.rs +++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -1,6 +1,5 @@ //@ compile-flags: -Znext-solver #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Default { type Id;
diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr index 8bd290e..bdc03e5 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.stderr +++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
@@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-transmute.rs:2:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/specialization-transmute.rs:14:9 + --> $DIR/specialization-transmute.rs:13:9 | LL | fn intu(&self) -> &Self::Id { | --------- expected `&<T as Default>::Id` because of return type @@ -20,7 +10,7 @@ found reference `&T` error[E0271]: type mismatch resolving `<u8 as Default>::Id == Option<NonZero<u8>>` - --> $DIR/specialization-transmute.rs:25:50 + --> $DIR/specialization-transmute.rs:24:50 | LL | let s = transmute::<u8, Option<NonZero<u8>>>(0); | ------------------------------------ ^ types differ @@ -28,12 +18,12 @@ | required by a bound introduced by this call | note: required by a bound in `transmute` - --> $DIR/specialization-transmute.rs:18:25 + --> $DIR/specialization-transmute.rs:17:25 | LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U { | ^^^^^^ required by this bound in `transmute` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.rs b/tests/ui/traits/next-solver/specialization-unconstrained.rs index 6835c07..27f6d00 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.rs +++ b/tests/ui/traits/next-solver/specialization-unconstrained.rs
@@ -1,7 +1,6 @@ //@ compile-flags: -Znext-solver #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete // Do not treat the RHS of a projection-goal as an unconstrained `Certainty::Yes` response // if the impl is still further specializable.
diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr index 1bcf5ed..3e36381 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr
@@ -1,25 +1,15 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-unconstrained.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0271]: type mismatch resolving `<u32 as Default>::Id == ()` - --> $DIR/specialization-unconstrained.rs:20:12 + --> $DIR/specialization-unconstrained.rs:19:12 | LL | test::<u32, ()>(); | ^^^ types differ | note: required by a bound in `test` - --> $DIR/specialization-unconstrained.rs:17:20 + --> $DIR/specialization-unconstrained.rs:16:20 | LL | fn test<T: Default<Id = U>, U>() {} | ^^^^^^ required by this bound in `test` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr index 8202b6e..ce68c2f 100644 --- a/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr +++ b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr
@@ -4,13 +4,13 @@ LL | needs::<1>(); | ^ the trait `Trait<1>` is not implemented for `()` | -help: the following other types implement trait `Trait<N>` +help: `()` implements trait `Trait<N>` --> $DIR/unevaluated-const-impl-trait-ref.rs:7:1 | LL | impl Trait<{ 1 - 1 }> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` implements `Trait<0>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Trait<0>` LL | impl Trait<{ 1 + 1 }> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` implements `Trait<2>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Trait<2>` note: required by a bound in `needs` --> $DIR/unevaluated-const-impl-trait-ref.rs:10:38 |
diff --git a/tests/ui/traits/non-lifetime-via-dyn-builtin.current.stderr b/tests/ui/traits/non-lifetime-via-dyn-builtin.current.stderr deleted file mode 100644 index 5393db6..0000000 --- a/tests/ui/traits/non-lifetime-via-dyn-builtin.current.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non-lifetime-via-dyn-builtin.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non-lifetime-via-dyn-builtin.next.stderr b/tests/ui/traits/non-lifetime-via-dyn-builtin.next.stderr deleted file mode 100644 index 5393db6..0000000 --- a/tests/ui/traits/non-lifetime-via-dyn-builtin.next.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non-lifetime-via-dyn-builtin.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs index ac61f8b..00bf237 100644 --- a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs +++ b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs
@@ -4,7 +4,6 @@ //@ check-pass #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete and may not be safe fn trivial<A>() where
diff --git a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.rs b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.rs index 506cad2..9d792ad 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn foo() where for<T> T: Copy {}
diff --git a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr index 4694e7d..f77d562 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr
@@ -1,24 +1,15 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-copy-cond.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/bad-copy-cond.rs:7:5 + --> $DIR/bad-copy-cond.rs:6:5 | LL | foo(); | ^^^^^ the trait `Copy` is not implemented for `T` | note: required by a bound in `foo` - --> $DIR/bad-copy-cond.rs:4:26 + --> $DIR/bad-copy-cond.rs:3:26 | LL | fn foo() where for<T> T: Copy {} | ^^^^ required by this bound in `foo` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs index dfc800c..244ac2f 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe pub fn foo() where
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr index f4deb16..0b3aa5c 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
@@ -1,21 +1,12 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-sized-cond.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the size for values of type `V` cannot be known at compilation time - --> $DIR/bad-sized-cond.rs:17:5 + --> $DIR/bad-sized-cond.rs:16:5 | LL | foo(); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `V` note: required by a bound in `foo` - --> $DIR/bad-sized-cond.rs:6:15 + --> $DIR/bad-sized-cond.rs:5:15 | LL | pub fn foo() | --- required by a bound in this function @@ -24,7 +15,7 @@ | ^^^^^ required by this bound in `foo` error[E0277]: `V` is not an iterator - --> $DIR/bad-sized-cond.rs:20:5 + --> $DIR/bad-sized-cond.rs:19:5 | LL | bar(); | ^^^^^ `V` is not an iterator @@ -32,7 +23,7 @@ = help: the trait `Iterator` is not implemented for `V` = note: required for `V` to implement `IntoIterator` note: required by a bound in `bar` - --> $DIR/bad-sized-cond.rs:12:15 + --> $DIR/bad-sized-cond.rs:11:15 | LL | pub fn bar() | --- required by a bound in this function @@ -41,7 +32,7 @@ | ^^^^^^^^^^^^ required by this bound in `bar` error[E0277]: the size for values of type `V` cannot be known at compilation time - --> $DIR/bad-sized-cond.rs:20:5 + --> $DIR/bad-sized-cond.rs:19:5 | LL | bar(); | ^^^^^ doesn't have a size known at compile-time @@ -49,7 +40,7 @@ = help: the trait `Sized` is not implemented for `V` = note: required for `V` to implement `IntoIterator` note: required by a bound in `bar` - --> $DIR/bad-sized-cond.rs:12:15 + --> $DIR/bad-sized-cond.rs:11:15 | LL | pub fn bar() | --- required by a bound in this function @@ -57,6 +48,6 @@ LL | for<V> V: IntoIterator, | ^^^^^^^^^^^^ required by this bound in `bar` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs index b61a21e..8ad2ecf 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs +++ b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.rs
@@ -1,7 +1,5 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete // Test for <https://github.com/rust-lang/rust/issues/115497>, // which originally relied on associated_type_bounds, but was
diff --git a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr index e891df3..0f0d2af 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-suggestion-on-missing-assoc.stderr
@@ -1,40 +1,23 @@ error: late-bound const parameters cannot be used currently - --> $DIR/bad-suggestion-on-missing-assoc.rs:20:15 + --> $DIR/bad-suggestion-on-missing-assoc.rs:18:15 | LL | for<const N: u8 = { T::A }> T: TraitA<AsA = impl TraitB<AsB = impl TraitC>>, | ^ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-suggestion-on-missing-assoc.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-suggestion-on-missing-assoc.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - error: defaults for generic parameters are not allowed in `for<...>` binders - --> $DIR/bad-suggestion-on-missing-assoc.rs:20:9 + --> $DIR/bad-suggestion-on-missing-assoc.rs:18:9 | LL | for<const N: u8 = { T::A }> T: TraitA<AsA = impl TraitB<AsB = impl TraitC>>, | ^^^^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/bad-suggestion-on-missing-assoc.rs:20:49 + --> $DIR/bad-suggestion-on-missing-assoc.rs:18:49 | LL | for<const N: u8 = { T::A }> T: TraitA<AsA = impl TraitB<AsB = impl TraitC>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error: aborting due to 3 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/traits/non_lifetime_binders/basic.rs b/tests/ui/traits/non_lifetime_binders/basic.rs index 09c0244..893bfd8 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.rs +++ b/tests/ui/traits/non_lifetime_binders/basic.rs
@@ -3,7 +3,6 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/basic.stderr b/tests/ui/traits/non_lifetime_binders/basic.stderr deleted file mode 100644 index 9f2df22..0000000 --- a/tests/ui/traits/non_lifetime_binders/basic.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:5:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs index 13f9f19..894f11c 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete pub fn bar() where
diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr index 608e813..7383a55 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr
@@ -1,5 +1,5 @@ error[E0425]: cannot find type `V` in this scope - --> $DIR/binder-defaults-112547.rs:10:4 + --> $DIR/binder-defaults-112547.rs:9:4 | LL | }> V: IntoIterator | ^ not found in this scope @@ -10,22 +10,13 @@ | +++ error: late-bound const parameters cannot be used currently - --> $DIR/binder-defaults-112547.rs:6:15 + --> $DIR/binder-defaults-112547.rs:5:15 | LL | for<const N: usize = { | ^ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/binder-defaults-112547.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: defaults for generic parameters are not allowed in `for<...>` binders - --> $DIR/binder-defaults-112547.rs:6:9 + --> $DIR/binder-defaults-112547.rs:5:9 | LL | for<const N: usize = { | _________^ @@ -35,6 +26,6 @@ LL | | }> V: IntoIterator | |_^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs index bdfe41c..509bdfc 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.rs
@@ -1,6 +1,4 @@ #![feature(non_lifetime_binders, generic_const_exprs)] -//~^ WARN the feature `non_lifetime_binders` is incomplete -//~| WARN the feature `generic_const_exprs` is incomplete fn fun() where
diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr index 947dd3a..4fb7c26 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-119489.stderr
@@ -1,37 +1,20 @@ error: late-bound const parameters cannot be used currently - --> $DIR/binder-defaults-119489.rs:7:23 + --> $DIR/binder-defaults-119489.rs:5:23 | LL | for<T = (), const N: usize = 1> ():, | ^ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/binder-defaults-119489.rs:1:12 - | -LL | #![feature(non_lifetime_binders, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/binder-defaults-119489.rs:1:34 - | -LL | #![feature(non_lifetime_binders, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - error: defaults for generic parameters are not allowed in `for<...>` binders - --> $DIR/binder-defaults-119489.rs:7:9 + --> $DIR/binder-defaults-119489.rs:5:9 | LL | for<T = (), const N: usize = 1> ():, | ^^^^^^ error: defaults for generic parameters are not allowed in `for<...>` binders - --> $DIR/binder-defaults-119489.rs:7:17 + --> $DIR/binder-defaults-119489.rs:5:17 | LL | for<T = (), const N: usize = 1> ():, | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors
diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs index 22044c2..a2a926e 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs
@@ -3,7 +3,6 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr index 8270fbe..0277abf 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr
@@ -1,31 +1,22 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/diagnostic-hir-wf-check.rs:5:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:16:12 + --> $DIR/diagnostic-hir-wf-check.rs:15:12 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:13:1 + --> $DIR/diagnostic-hir-wf-check.rs:12:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:14:13 + --> $DIR/diagnostic-hir-wf-check.rs:13:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:16:42 + --> $DIR/diagnostic-hir-wf-check.rs:15:42 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | - ^^ the trait `B` is not implemented for `()` @@ -33,33 +24,33 @@ | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:13:1 + --> $DIR/diagnostic-hir-wf-check.rs:12:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:14:13 + --> $DIR/diagnostic-hir-wf-check.rs:13:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:16:40 + --> $DIR/diagnostic-hir-wf-check.rs:15:40 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:13:1 + --> $DIR/diagnostic-hir-wf-check.rs:12:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:14:13 + --> $DIR/diagnostic-hir-wf-check.rs:13:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr index 1f13207..9a4d36a 100644 --- a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr +++ b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.no.stderr
@@ -1,24 +1,15 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/drop-impl-pred.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0367]: `Drop` impl requires `H: Foo` but the struct it is implemented for does not - --> $DIR/drop-impl-pred.rs:19:15 + --> $DIR/drop-impl-pred.rs:18:15 | LL | for<H> H: Foo, | ^^^ | note: the implementor must specify the same requirement - --> $DIR/drop-impl-pred.rs:12:1 + --> $DIR/drop-impl-pred.rs:11:1 | LL | struct Bar<T>(T) where T: Foo; | ^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0367`.
diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs index db8f3de..3444f10 100644 --- a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs +++ b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs
@@ -4,7 +4,6 @@ // Issue 110557 #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete pub trait Foo {}
diff --git a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr b/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr deleted file mode 100644 index 165cf2e..0000000 --- a/tests/ui/traits/non_lifetime_binders/drop-impl-pred.yes.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/drop-impl-pred.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/fail.rs b/tests/ui/traits/non_lifetime_binders/fail.rs index 460f689..7d916c4 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.rs +++ b/tests/ui/traits/non_lifetime_binders/fail.rs
@@ -1,7 +1,6 @@ // Error reporting for where `for<T> T: Trait` doesn't hold #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete trait Trait {}
diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr index 9a324c9..38a0eab 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.stderr +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr
@@ -1,25 +1,16 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/fail.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/fail.rs:19:5 + --> $DIR/fail.rs:18:5 | LL | fail(); | ^^^^^^ the trait `Trait` is not implemented for `T` | help: this trait has no implementations, consider adding one - --> $DIR/fail.rs:6:1 + --> $DIR/fail.rs:5:1 | LL | trait Trait {} | ^^^^^^^^^^^ note: required by a bound in `fail` - --> $DIR/fail.rs:10:15 + --> $DIR/fail.rs:9:15 | LL | fn fail() | ---- required by a bound in this function @@ -28,14 +19,14 @@ | ^^^^^ required by this bound in `fail` error[E0277]: `T` cannot be sent between threads safely - --> $DIR/fail.rs:21:5 + --> $DIR/fail.rs:20:5 | LL | auto_trait(); | ^^^^^^^^^^^^ `T` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `T` note: required by a bound in `auto_trait` - --> $DIR/fail.rs:15:15 + --> $DIR/fail.rs:14:15 | LL | fn auto_trait() | ---------- required by a bound in this function @@ -43,6 +34,6 @@ LL | for<T> T: Send, | ^^^^ required by this bound in `auto_trait` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs index 96a7424..0c4347b 100644 --- a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs +++ b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn auto_trait() where
diff --git a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr index abbdecf..b621f5c 100644 --- a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr +++ b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr
@@ -1,21 +1,12 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/foreach-partial-eq.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: can't compare `T` with `T` - --> $DIR/foreach-partial-eq.rs:10:5 + --> $DIR/foreach-partial-eq.rs:9:5 | LL | auto_trait(); | ^^^^^^^^^^^^ no implementation for `T < T` and `T > T` | = help: the trait `PartialOrd` is not implemented for `T` note: required by a bound in `auto_trait` - --> $DIR/foreach-partial-eq.rs:6:27 + --> $DIR/foreach-partial-eq.rs:5:27 | LL | fn auto_trait() | ---------- required by a bound in this function @@ -23,6 +14,6 @@ LL | for<T> T: PartialEq + PartialOrd, | ^^^^^^^^^^ required by this bound in `auto_trait` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs index 94733f8..e8b7139 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs
@@ -1,6 +1,4 @@ #![feature(non_lifetime_binders, generic_const_exprs)] -//~^ WARN the feature `non_lifetime_binders` is incomplete -//~| WARN the feature `generic_const_exprs` is incomplete fn foo() -> usize where
diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr index cc48288..cd8bc33 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr
@@ -1,27 +1,10 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/late-bound-in-anon-ct.rs:1:12 - | -LL | #![feature(non_lifetime_binders, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/late-bound-in-anon-ct.rs:1:34 - | -LL | #![feature(non_lifetime_binders, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - error: cannot capture late-bound type parameter in constant - --> $DIR/late-bound-in-anon-ct.rs:7:27 + --> $DIR/late-bound-in-anon-ct.rs:5:27 | LL | for<T> [i32; { let _: T = todo!(); 0 }]:, | - ^ | | | parameter defined here -error: aborting due to 1 previous error; 2 warnings emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs index 2d44388..75117e1 100644 --- a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs +++ b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn b() where
diff --git a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr index 136d533..98558dc 100644 --- a/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr +++ b/tests/ui/traits/non_lifetime_binders/late-const-param-wf.stderr
@@ -1,17 +1,8 @@ error: late-bound const parameters cannot be used currently - --> $DIR/late-const-param-wf.rs:6:15 + --> $DIR/late-const-param-wf.rs:5:15 | LL | for<const C: usize> [(); C]: Copy, | ^ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/late-const-param-wf.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/traits/non_lifetime_binders/method-probe.rs b/tests/ui/traits/non_lifetime_binders/method-probe.rs index 5f8e314..3d16252 100644 --- a/tests/ui/traits/non_lifetime_binders/method-probe.rs +++ b/tests/ui/traits/non_lifetime_binders/method-probe.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete trait Foo: for<T> Bar<T> {}
diff --git a/tests/ui/traits/non_lifetime_binders/method-probe.stderr b/tests/ui/traits/non_lifetime_binders/method-probe.stderr deleted file mode 100644 index 8f61792..0000000 --- a/tests/ui/traits/non_lifetime_binders/method-probe.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/method-probe.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.rs b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.rs index 50f0152e..1e645f3 100644 --- a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.rs +++ b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn f() where
diff --git a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr index 0229530..4de30e7 100644 --- a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr +++ b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr
@@ -1,14 +1,5 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing-assoc-item.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0223]: ambiguous associated type - --> $DIR/missing-assoc-item.rs:6:12 + --> $DIR/missing-assoc-item.rs:5:12 | LL | for<B> B::Item: Send, | ^^^^^^^ @@ -19,6 +10,6 @@ LL + for<B> <B as Example>::Item: Send, | -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.rs b/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.rs index e9ae00d..e5ab8d6 100644 --- a/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.rs +++ b/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete trait Trait<Input> { type Assoc;
diff --git a/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.stderr b/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.stderr index 8304469..12eb6c3 100644 --- a/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.stderr +++ b/tests/ui/traits/non_lifetime_binders/nested-apit-mentioning-outer-bound-var.stderr
@@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/nested-apit-mentioning-outer-bound-var.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: `impl Trait` can only mention type parameters from an fn or impl - --> $DIR/nested-apit-mentioning-outer-bound-var.rs:8:52 + --> $DIR/nested-apit-mentioning-outer-bound-var.rs:7:52 | LL | fn uwu(_: impl for<T> Trait<(), Assoc = impl Trait<T>>) {} | - type parameter declared here ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.rs b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.rs new file mode 100644 index 0000000..52f8396 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.rs
@@ -0,0 +1,22 @@ +//@ compile-flags: --crate-type=lib + +// Regression test for <https://github.com/rust-lang/rust/issues/120033> + +#![feature(rustc_attrs)] +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] +#![rustc_no_implicit_bounds] + +pub trait Foo<T> { + type Bar<K>; +} + +pub struct Bar<T: ?AutoTrait> {} //~ ERROR cannot find trait `AutoTrait` + +pub fn f<T1, T2>() +where + T1: for<T> Foo<usize, Bar = Bar<T>>, //~ ERROR missing generics for associated type `Foo::Bar` + //~| ERROR missing generics for associated type `Foo::Bar` + T2: for<L, T> Foo<usize, Bar<T> = T1::Bar<T>>, +{ +}
diff --git a/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr new file mode 100644 index 0000000..c95e6c6 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr
@@ -0,0 +1,43 @@ +error[E0405]: cannot find trait `AutoTrait` in this scope + --> $DIR/normalized-param-env-unconstrained-type-120033.rs:14:20 + | +LL | pub struct Bar<T: ?AutoTrait> {} + | ^^^^^^^^^ not found in this scope + +error[E0107]: missing generics for associated type `Foo::Bar` + --> $DIR/normalized-param-env-unconstrained-type-120033.rs:18:27 + | +LL | T1: for<T> Foo<usize, Bar = Bar<T>>, + | ^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `K` + --> $DIR/normalized-param-env-unconstrained-type-120033.rs:11:10 + | +LL | type Bar<K>; + | ^^^ - +help: add missing generic argument + | +LL | T1: for<T> Foo<usize, Bar<K> = Bar<T>>, + | +++ + +error[E0107]: missing generics for associated type `Foo::Bar` + --> $DIR/normalized-param-env-unconstrained-type-120033.rs:18:27 + | +LL | T1: for<T> Foo<usize, Bar = Bar<T>>, + | ^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `K` + --> $DIR/normalized-param-env-unconstrained-type-120033.rs:11:10 + | +LL | type Bar<K>; + | ^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | T1: for<T> Foo<usize, Bar<K> = Bar<T>>, + | +++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0405. +For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.rs b/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.rs index e776d5f..4ccf4db 100644 --- a/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.rs +++ b/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.rs
@@ -2,6 +2,5 @@ //@ compile-flags: --crate-type=lib #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete pub fn f<T>() where for<U> (T, U): Copy {}
diff --git a/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.stderr b/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.stderr deleted file mode 100644 index 667575b..0000000 --- a/tests/ui/traits/non_lifetime_binders/object-lifetime-default-for-late.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/object-lifetime-default-for-late.rs:4:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/on-dyn.rs b/tests/ui/traits/non_lifetime_binders/on-dyn.rs index 8fb7dd2..a081974 100644 --- a/tests/ui/traits/non_lifetime_binders/on-dyn.rs +++ b/tests/ui/traits/non_lifetime_binders/on-dyn.rs
@@ -1,7 +1,6 @@ // Tests to make sure that we reject polymorphic dyn trait. #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete trait Test<T> {}
diff --git a/tests/ui/traits/non_lifetime_binders/on-dyn.stderr b/tests/ui/traits/non_lifetime_binders/on-dyn.stderr index 2d330f6..8d7cb51 100644 --- a/tests/ui/traits/non_lifetime_binders/on-dyn.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-dyn.stderr
@@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-dyn.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on trait object types - --> $DIR/on-dyn.rs:8:30 + --> $DIR/on-dyn.rs:7:30 | LL | fn foo() -> &'static dyn for<T> Test<T> { | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/traits/non_lifetime_binders/on-ptr.rs b/tests/ui/traits/non_lifetime_binders/on-ptr.rs index 0aaff52..96c155a 100644 --- a/tests/ui/traits/non_lifetime_binders/on-ptr.rs +++ b/tests/ui/traits/non_lifetime_binders/on-ptr.rs
@@ -1,7 +1,6 @@ // Tests to make sure that we reject polymorphic fn ptrs. #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn foo() -> for<T> fn(T) { //~^ ERROR late-bound type parameter not allowed on function pointer types
diff --git a/tests/ui/traits/non_lifetime_binders/on-ptr.stderr b/tests/ui/traits/non_lifetime_binders/on-ptr.stderr index fbd723a..680df6d 100644 --- a/tests/ui/traits/non_lifetime_binders/on-ptr.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-ptr.stderr
@@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-ptr.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on function pointer types - --> $DIR/on-ptr.rs:6:17 + --> $DIR/on-ptr.rs:5:17 | LL | fn foo() -> for<T> fn(T) { | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error
diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 1364f63..092f838 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs
@@ -2,7 +2,6 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr deleted file mode 100644 index c8396c3..0000000 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-rpit.rs:4:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.bad.stderr b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.bad.stderr index d51927a..f8de7c7 100644 --- a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.bad.stderr +++ b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.bad.stderr
@@ -1,14 +1,5 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/placeholders-dont-outlive-static.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0310]: the placeholder type `T` may not live long enough - --> $DIR/placeholders-dont-outlive-static.rs:13:5 + --> $DIR/placeholders-dont-outlive-static.rs:12:5 | LL | foo(); | ^^^^^ @@ -21,6 +12,6 @@ LL | fn bad() where T: 'static { | ++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.good.stderr b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.good.stderr index bc1a199..cc76a8e 100644 --- a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.good.stderr +++ b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.good.stderr
@@ -1,14 +1,5 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/placeholders-dont-outlive-static.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0310]: the placeholder type `T` may not live long enough - --> $DIR/placeholders-dont-outlive-static.rs:19:5 + --> $DIR/placeholders-dont-outlive-static.rs:18:5 | LL | foo(); | ^^^^^ @@ -21,6 +12,6 @@ LL | fn good() where for<T> T: 'static, T: 'static { | ++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.rs b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.rs index 3133d6a..ca39eb6 100644 --- a/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.rs +++ b/tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.rs
@@ -4,7 +4,6 @@ // `for<T> T: 'static` doesn't imply itself when processing outlives obligations #![feature(non_lifetime_binders)] -//[bad]~^ WARN the feature `non_lifetime_binders` is incomplete fn foo() where for<T> T: 'static {}
diff --git a/tests/ui/traits/non_lifetime_binders/shadowed.rs b/tests/ui/traits/non_lifetime_binders/shadowed.rs index 1c480e3..ff8d3f7 100644 --- a/tests/ui/traits/non_lifetime_binders/shadowed.rs +++ b/tests/ui/traits/non_lifetime_binders/shadowed.rs
@@ -1,5 +1,4 @@ #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete fn function<T>() where for<T> (): Sized {} //~^ ERROR the name `T` is already used for a generic parameter
diff --git a/tests/ui/traits/non_lifetime_binders/shadowed.stderr b/tests/ui/traits/non_lifetime_binders/shadowed.stderr index 59a073a..982bd93 100644 --- a/tests/ui/traits/non_lifetime_binders/shadowed.stderr +++ b/tests/ui/traits/non_lifetime_binders/shadowed.stderr
@@ -1,5 +1,5 @@ error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/shadowed.rs:4:28 + --> $DIR/shadowed.rs:3:28 | LL | fn function<T>() where for<T> (): Sized {} | - ^ already used @@ -7,7 +7,7 @@ | first use of `T` error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/shadowed.rs:7:31 + --> $DIR/shadowed.rs:6:31 | LL | struct Struct<T>(T) where for<T> (): Sized; | - ^ already used @@ -15,7 +15,7 @@ | first use of `T` error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/shadowed.rs:11:27 + --> $DIR/shadowed.rs:10:27 | LL | impl<T> Struct<T> { | - first use of `T` @@ -23,22 +23,13 @@ | ^ already used error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/shadowed.rs:15:28 + --> $DIR/shadowed.rs:14:28 | LL | fn repeated() where for<T, T> (): Sized {} | - ^ already used | | | first use of `T` -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/shadowed.rs:1:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0403`.
diff --git a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs index e4c3b4d..981edc7 100644 --- a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs +++ b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe pub fn foo() where
diff --git a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr b/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr deleted file mode 100644 index e75d812..0000000 --- a/tests/ui/traits/non_lifetime_binders/sized-late-bound-issue-114872.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/sized-late-bound-issue-114872.rs:3:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs index aab5479..3ef1201 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs
@@ -1,6 +1,5 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr index b32915f..f118278 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr
@@ -1,21 +1,12 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-dyn-compatibility.rs:2:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:22:17 + --> $DIR/supertrait-dyn-compatibility.rs:21:17 | LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:7:12 + --> $DIR/supertrait-dyn-compatibility.rs:6:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -23,6 +14,6 @@ | this trait is not dyn compatible... = help: only type `()` implements `Foo`; consider using it directly instead. -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index c325718..e70ff4a 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
@@ -1,12 +1,3 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-match-with-late-bound.rs:6:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0309]: the placeholder type `F` may not live long enough --> $DIR/type-match-with-late-bound.rs:8:32 | @@ -54,6 +45,6 @@ LL | for<F> F: 'a, F: 'a | +++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr deleted file mode 100644 index 6551253..0000000 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr deleted file mode 100644 index 6551253..0000000 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs index d900bd4..2962a5b 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs
@@ -5,7 +5,6 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr deleted file mode 100644 index fecdc86..0000000 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:7:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr deleted file mode 100644 index fecdc86..0000000 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:7:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs index 04e3453..caad8bf 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs
@@ -5,7 +5,6 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs index b4e8e3a..1c99794 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.rs +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs
@@ -1,6 +1,5 @@ #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] -//~^ WARN the feature `non_lifetime_binders` is incomplete use std::marker::PointeeSized;
diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr index b997e73..899378b 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr
@@ -1,20 +1,11 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/universe-error1.rs:2:12 - | -LL | #![feature(non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `T: Other<_>` is not satisfied - --> $DIR/universe-error1.rs:17:11 + --> $DIR/universe-error1.rs:16:11 | LL | foo::<_>(); | ^ the trait `Other<_>` is not implemented for `T` | note: required by a bound in `foo` - --> $DIR/universe-error1.rs:14:15 + --> $DIR/universe-error1.rs:13:15 | LL | fn foo<U: PointeeSized>() | --- required by a bound in this function @@ -22,6 +13,6 @@ LL | for<T> T: Other<U> {} | ^^^^^^^^ required by this bound in `foo` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs index dfea4b9..f9ca6e0 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.rs +++ b/tests/ui/traits/question-mark-result-err-mismatch.rs
@@ -35,7 +35,7 @@ fn bar() -> Result<(), String> { //~ NOTE expected `String` because of this //~| NOTE the trait `From<()>` is not implemented for `String` //~| NOTE the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait //~| NOTE required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>` - //~| HELP the following other types implement trait `From<T>`: + //~| HELP `String` implements trait `From<T>`: Ok(one) }
diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index be3f17c..3739b50 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr
@@ -30,13 +30,13 @@ | this can't be annotated with `?` because it has type `Result<_, ()>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `From<T>`: - `String` implements `From<&String>` - `String` implements `From<&mut str>` - `String` implements `From<&str>` - `String` implements `From<Box<str>>` - `String` implements `From<Cow<'_, str>>` - `String` implements `From<char>` + = help: `String` implements trait `From<T>`: + From<&String> + From<&mut str> + From<&str> + From<Box<str>> + From<Cow<'_, str>> + From<char> = note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>` error[E0277]: `?` couldn't convert the error to `String`
diff --git a/tests/ui/traits/question-mark-span-144304.stderr b/tests/ui/traits/question-mark-span-144304.stderr index a412da0..37452cd 100644 --- a/tests/ui/traits/question-mark-span-144304.stderr +++ b/tests/ui/traits/question-mark-span-144304.stderr
@@ -9,12 +9,12 @@ | this has type `Result<_, &str>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `From<T>`: - `i32` implements `From<bool>` - `i32` implements `From<i16>` - `i32` implements `From<i8>` - `i32` implements `From<u16>` - `i32` implements `From<u8>` + = help: `i32` implements trait `From<T>`: + From<bool> + From<i16> + From<i8> + From<u16> + From<u8> error[E0277]: `?` couldn't convert the error to `i32` --> $DIR/question-mark-span-144304.rs:4:42 @@ -29,12 +29,12 @@ | this has type `Result<_, &str>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `From<T>`: - `i32` implements `From<bool>` - `i32` implements `From<i16>` - `i32` implements `From<i8>` - `i32` implements `From<u16>` - `i32` implements `From<u8>` + = help: `i32` implements trait `From<T>`: + From<bool> + From<i16> + From<i8> + From<u16> + From<u8> error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/self-referential-param-env-normalization.rs b/tests/ui/traits/self-referential-param-env-normalization.rs new file mode 100644 index 0000000..a40c8cc --- /dev/null +++ b/tests/ui/traits/self-referential-param-env-normalization.rs
@@ -0,0 +1,18 @@ +//~ ERROR overflow evaluating the requirement `Self: StreamingIterator<'_>` [E0275] +// Regression test for <https://github.com/rust-lang/rust/issues/153354>. + +trait StreamingIterator<'a> { + type Item: 'a; +} + +impl<'b, I, T> StreamingIterator<'b> for I +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates [E0207] +where + I: IntoIterator, + T: FnMut(Self::Item, I::Item), +{ + type Item = T; + //~^ ERROR overflow evaluating the requirement `I: IntoIterator` [E0275] +} + +fn main() {}
diff --git a/tests/ui/traits/self-referential-param-env-normalization.stderr b/tests/ui/traits/self-referential-param-env-normalization.stderr new file mode 100644 index 0000000..5e9c2c9 --- /dev/null +++ b/tests/ui/traits/self-referential-param-env-normalization.stderr
@@ -0,0 +1,42 @@ +error[E0275]: overflow evaluating the requirement `Self: StreamingIterator<'_>` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`self_referential_param_env_normalization`) +note: required for `Self` to implement `StreamingIterator<'_>` + --> $DIR/self-referential-param-env-normalization.rs:8:16 + | +LL | impl<'b, I, T> StreamingIterator<'b> for I + | ^^^^^^^^^^^^^^^^^^^^^ ^ +... +LL | T: FnMut(Self::Item, I::Item), + | -------------------------- unsatisfied trait bound introduced here + = note: 127 redundant requirements hidden + = note: required for `Self` to implement `StreamingIterator<'a>` + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/self-referential-param-env-normalization.rs:8:13 + | +LL | impl<'b, I, T> StreamingIterator<'b> for I + | ^ unconstrained type parameter + +error[E0275]: overflow evaluating the requirement `I: IntoIterator` + --> $DIR/self-referential-param-env-normalization.rs:14:17 + | +LL | type Item = T; + | ^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`self_referential_param_env_normalization`) +note: required for `I` to implement `StreamingIterator<'_>` + --> $DIR/self-referential-param-env-normalization.rs:8:16 + | +LL | impl<'b, I, T> StreamingIterator<'b> for I + | ^^^^^^^^^^^^^^^^^^^^^ ^ +... +LL | T: FnMut(Self::Item, I::Item), + | -------------------------- unsatisfied trait bound introduced here + = note: 127 redundant requirements hidden + = note: required for `I` to implement `StreamingIterator<'b>` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0207, E0275. +For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.rs b/tests/ui/traits/unspecified-self-in-trait-ref.rs index f175a8e..fbc95e0 100644 --- a/tests/ui/traits/unspecified-self-in-trait-ref.rs +++ b/tests/ui/traits/unspecified-self-in-trait-ref.rs
@@ -9,19 +9,19 @@ pub trait Bar<X=usize, A=Self> { fn main() { let a = Foo::lol(); - //~^ ERROR no function or associated item named + //~^ ERROR no associated function or constant named //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let b = Foo::<_>::lol(); - //~^ ERROR no function or associated item named + //~^ ERROR no associated function or constant named //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let c = Bar::lol(); - //~^ ERROR no function or associated item named + //~^ ERROR no associated function or constant named //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let d = Bar::<usize, _>::lol(); - //~^ ERROR no function or associated item named + //~^ ERROR no associated function or constant named //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let e = Bar::<usize>::lol();
diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr index b7d78a3..e76187d 100644 --- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr +++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
@@ -12,11 +12,11 @@ LL | let a = <dyn Foo>::lol(); | ++++ + -error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope +error[E0599]: no associated function or constant named `lol` found for trait object `dyn Foo<_>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:11:18 | LL | let a = Foo::lol(); - | ^^^ function or associated item not found in `dyn Foo<_>` + | ^^^ associated function or constant not found in `dyn Foo<_>` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/unspecified-self-in-trait-ref.rs:15:13 @@ -31,11 +31,11 @@ LL | let b = <dyn Foo::<_>>::lol(); | ++++ + -error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope +error[E0599]: no associated function or constant named `lol` found for trait object `dyn Foo<_>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:15:23 | LL | let b = Foo::<_>::lol(); - | ^^^ function or associated item not found in `dyn Foo<_>` + | ^^^ associated function or constant not found in `dyn Foo<_>` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/unspecified-self-in-trait-ref.rs:19:13 @@ -50,11 +50,11 @@ LL | let c = <dyn Bar>::lol(); | ++++ + -error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope +error[E0599]: no associated function or constant named `lol` found for trait object `dyn Bar<_, _>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:19:18 | LL | let c = Bar::lol(); - | ^^^ function or associated item not found in `dyn Bar<_, _>` + | ^^^ associated function or constant not found in `dyn Bar<_, _>` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/unspecified-self-in-trait-ref.rs:23:13 @@ -69,11 +69,11 @@ LL | let d = <dyn Bar::<usize, _>>::lol(); | ++++ + -error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<usize, _>` in the current scope +error[E0599]: no associated function or constant named `lol` found for trait object `dyn Bar<usize, _>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:23:30 | LL | let d = Bar::<usize, _>::lol(); - | ^^^ function or associated item not found in `dyn Bar<usize, _>` + | ^^^ associated function or constant not found in `dyn Bar<usize, _>` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/unspecified-self-in-trait-ref.rs:27:13
diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs index eeb0777..67e5760 100644 --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs
@@ -1,6 +1,5 @@ #![feature(transmutability)] #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete use std::mem::{Assume, TransmuteFrom};
diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr index 6f7e9e1..5c59fb9 100644 --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
@@ -1,26 +1,17 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:2:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:13:23 | LL | is_transmutable::<{}>(); | ^^ expected `bool`, found `()` error[E0277]: the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not satisfied - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:13:23 | LL | is_transmutable::<{}>(); | ^^ the nightly-only, unstable trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()` | note: required by a bound in `is_transmutable` - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:9:9 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:8:9 | LL | pub fn is_transmutable<const ASSUME_ALIGNMENT: bool>() | --------------- required by a bound in this function @@ -28,7 +19,7 @@ LL | (): TransmuteFrom<(), { Assume::SAFETY }>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/generic-transmute-from-regression.rs b/tests/ui/transmutability/generic-transmute-from-regression.rs new file mode 100644 index 0000000..3856824 --- /dev/null +++ b/tests/ui/transmutability/generic-transmute-from-regression.rs
@@ -0,0 +1,11 @@ +//! Regression test for: <https://github.com/rust-lang/rust/issues/153755> +#![feature(transmutability)] + +fn foo<T, U>(x: T) -> U { + unsafe { + std::mem::TransmuteFrom::transmute(x) + //~^ ERROR: the trait bound `U: TransmuteFrom<T, _>` is not satisfied [E0277] + } +} + +fn main() {}
diff --git a/tests/ui/transmutability/generic-transmute-from-regression.stderr b/tests/ui/transmutability/generic-transmute-from-regression.stderr new file mode 100644 index 0000000..3912aec --- /dev/null +++ b/tests/ui/transmutability/generic-transmute-from-regression.stderr
@@ -0,0 +1,11 @@ +error[E0277]: the trait bound `U: TransmuteFrom<T, _>` is not satisfied + --> $DIR/generic-transmute-from-regression.rs:6:44 + | +LL | std::mem::TransmuteFrom::transmute(x) + | ---------------------------------- ^ the nightly-only, unstable trait `TransmuteFrom<T, _>` is not implemented for `U` + | | + | required by a bound introduced by this call + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/non_scalar_alignment_value.rs b/tests/ui/transmutability/non_scalar_alignment_value.rs index 45c9e61..3b21cdd 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.rs +++ b/tests/ui/transmutability/non_scalar_alignment_value.rs
@@ -1,5 +1,4 @@ #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(transmutability)]
diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr index d22c6d0..99d1852 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.stderr +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr
@@ -1,35 +1,26 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non_scalar_alignment_value.rs:1:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information - = note: `#[warn(incomplete_features)]` on by default - error: struct expression with missing field initialiser for `alignment` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `lifetimes` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `safety` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `validity` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors
diff --git a/tests/ui/transmutability/transmute-from-const-args-ice-150457.rs b/tests/ui/transmutability/transmute-from-const-args-ice-150457.rs new file mode 100644 index 0000000..8c1b709 --- /dev/null +++ b/tests/ui/transmutability/transmute-from-const-args-ice-150457.rs
@@ -0,0 +1,31 @@ +//! Ensure `TransmuteFrom` with `min_generic_const_args` doesn't ICE +//! during well-formedness checking. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/150457>. + +//@ check-pass + +#![feature(transmutability)] +#![feature(min_generic_const_args)] + +use std::mem::{Assume, TransmuteFrom}; + +struct W<'a>(&'a ()); + +fn test<'a>() +where + W<'a>: TransmuteFrom< + (), + { + Assume { + alignment: const { true }, + lifetimes: const { true }, + safety: const { true }, + validity: true, + } + }, + >, +{ +} + +fn main() {}
diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs b/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs deleted file mode 100644 index 980f97c..0000000 --- a/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs +++ /dev/null
@@ -1,12 +0,0 @@ -//@ check-pass -//@ edition: 2018 - -// For historical reasons this is only a warning, not an error. -// See <https://github.com/rust-lang/rust/issues/152501> - -fn main() { - #[cfg(false)] - try {} - //~^ warn `try` blocks are unstable - //~| warn unstable syntax can change at any point -}
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index a566800..e1cc7a4 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -9,16 +9,16 @@ | this can't be annotated with `?` because it has type `Result<_, i32>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait -help: the following other types implement trait `From<T>` +help: `u8` implements trait `From<T>` --> $SRC_DIR/core/src/convert/num.rs:LL:COL | - = note: `u8` implements `From<bool>` + = note: `From<bool>` ::: $SRC_DIR/core/src/convert/num.rs:LL:COL | = note: in this macro invocation --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | - = note: `u8` implements `From<std::ascii::Char>` + = note: `From<std::ascii::Char>` ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | = note: in this macro invocation
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index d17a821..fc6bf3f 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr
@@ -9,14 +9,14 @@ | LL | struct Foo; | ^^^^^^^^^^ -help: the following other types implement trait `Trait<T>` +help: `Foo` implements trait `Trait<T>` --> $DIR/constrain_in_projection2.rs:18:1 | LL | impl Trait<()> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^ `Foo` implements `Trait<()>` + | ^^^^^^^^^^^^^^^^^^^^^^ `Trait<()>` ... LL | impl Trait<u32> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^ `Foo` implements `Trait<u32>` + | ^^^^^^^^^^^^^^^^^^^^^^^ `Trait<u32>` error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied --> $DIR/constrain_in_projection2.rs:28:13 @@ -29,14 +29,14 @@ | LL | struct Foo; | ^^^^^^^^^^ -help: the following other types implement trait `Trait<T>` +help: `Foo` implements trait `Trait<T>` --> $DIR/constrain_in_projection2.rs:18:1 | LL | impl Trait<()> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^ `Foo` implements `Trait<()>` + | ^^^^^^^^^^^^^^^^^^^^^^ `Trait<()>` ... LL | impl Trait<u32> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^ `Foo` implements `Trait<u32>` + | ^^^^^^^^^^^^^^^^^^^^^^^ `Trait<u32>` error: aborting due to 2 previous errors
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index 4cc69da..6744427 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr
@@ -7,13 +7,13 @@ LL | () | -- return type was inferred to be `()` here | -help: the following other types implement trait `Foo<A>` +help: `()` implements trait `Foo<A>` --> $DIR/nested-tait-inference2.rs:14:1 | LL | impl Foo<()> for () {} - | ^^^^^^^^^^^^^^^^^^^ `()` implements `Foo<()>` + | ^^^^^^^^^^^^^^^^^^^ `Foo<()>` LL | impl Foo<u32> for () {} - | ^^^^^^^^^^^^^^^^^^^^ `()` implements `Foo<u32>` + | ^^^^^^^^^^^^^^^^^^^^ `Foo<u32>` error: aborting due to 1 previous error
diff --git a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs b/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs new file mode 100644 index 0000000..4b36336 --- /dev/null +++ b/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.rs
@@ -0,0 +1,14 @@ +//! Ensure a self-referencing lazy type alias with `min_generic_const_args` +//! doesn't ICE during normalization. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/152633>. + +#![feature(lazy_type_alias)] +#![feature(min_generic_const_args)] + +trait Trait { + type const ASSOC: (); +} +type Arr2 = [usize; <Arr2 as Trait>::ASSOC]; //~ ERROR E0275 + +fn main() {}
diff --git a/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr b/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr new file mode 100644 index 0000000..a8e68a0 --- /dev/null +++ b/tests/ui/type-alias/recursive-lazy-type-alias-ice-152633.stderr
@@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the type alias `Arr2` + --> $DIR/recursive-lazy-type-alias-ice-152633.rs:12:1 + | +LL | type Arr2 = [usize; <Arr2 as Trait>::ASSOC]; + | ^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type/issue-103271.rs b/tests/ui/type/issue-103271.rs index 98cfaaf..e949bb1 100644 --- a/tests/ui/type/issue-103271.rs +++ b/tests/ui/type/issue-103271.rs
@@ -1,15 +1,15 @@ fn main() { let iter_fun = <&[u32]>::iter; - //~^ ERROR no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599] - //~| NOTE function or associated item not found in `&[u32]` + //~^ ERROR no associated function or constant named `iter` found for reference `&[u32]` in the current scope [E0599] + //~| NOTE associated function or constant not found in `&[u32]` //~| HELP the function `iter` is implemented on `[u32]` for item in iter_fun(&[1,1]) { let x: &u32 = item; assert_eq!(x, &1); } let iter_fun2 = <(&[u32])>::iter; - //~^ ERROR no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599] - //~| NOTE function or associated item not found in `&[u32]` + //~^ ERROR no associated function or constant named `iter` found for reference `&[u32]` in the current scope [E0599] + //~| NOTE associated function or constant not found in `&[u32]` //~| HELP the function `iter` is implemented on `[u32]` for item2 in iter_fun2(&[1,1]) { let x: &u32 = item2;
diff --git a/tests/ui/type/issue-103271.stderr b/tests/ui/type/issue-103271.stderr index 1b84033..a83b782 100644 --- a/tests/ui/type/issue-103271.stderr +++ b/tests/ui/type/issue-103271.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope +error[E0599]: no associated function or constant named `iter` found for reference `&[u32]` in the current scope --> $DIR/issue-103271.rs:2:30 | LL | let iter_fun = <&[u32]>::iter; - | ^^^^ function or associated item not found in `&[u32]` + | ^^^^ associated function or constant not found in `&[u32]` | help: the function `iter` is implemented on `[u32]` | @@ -10,11 +10,11 @@ LL + let iter_fun = <[u32]>::iter; | -error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope +error[E0599]: no associated function or constant named `iter` found for reference `&[u32]` in the current scope --> $DIR/issue-103271.rs:10:33 | LL | let iter_fun2 = <(&[u32])>::iter; - | ^^^^ function or associated item not found in `&[u32]` + | ^^^^ associated function or constant not found in `&[u32]` | help: the function `iter` is implemented on `[u32]` |
diff --git a/tests/ui/type/pattern_types/validity.rs b/tests/ui/type/pattern_types/validity.rs index 8323049..6c630fc 100644 --- a/tests/ui/type/pattern_types/validity.rs +++ b/tests/ui/type/pattern_types/validity.rs
@@ -8,7 +8,7 @@ use std::pat::pattern_type; const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; -//~^ ERROR: constructing invalid value: encountered 0 +//~^ ERROR: encountered 0 const BAD_UNINIT: pattern_type!(u32 is 1..) = //~^ ERROR: this operation requires initialized memory @@ -18,22 +18,22 @@ //~^ ERROR: unable to turn pointer into integer const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0); -//~^ ERROR: constructing invalid value at .0: encountered 0 +//~^ ERROR: at .0, encountered 0 struct Foo(Bar); struct Bar(pattern_type!(u32 is 1..)); const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) })); -//~^ ERROR: constructing invalid value at .0.0: encountered 0 +//~^ ERROR: at .0.0, encountered 0 const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') = //~^ ERROR: this operation requires initialized memory unsafe { std::mem::transmute(std::mem::MaybeUninit::<u32>::uninit()) }; const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') }; -//~^ ERROR: constructing invalid value: encountered 97, but expected something in the range 65..=89 +//~^ ERROR: encountered 97, but expected something in the range 65..=89 const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) }; -//~^ ERROR: constructing invalid value: encountered 0xffffffff +//~^ ERROR: encountered 0xffffffff fn main() {}
diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr index e19915a..a4fb46c 100644 --- a/tests/ui/type/pattern_types/validity.stderr +++ b/tests/ui/type/pattern_types/validity.stderr
@@ -1,4 +1,4 @@ -error[E0080]: constructing invalid value: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type (u32) is 1..: encountered 0, but expected something greater or equal to 1 --> $DIR/validity.rs:10:1 | LL | const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; @@ -28,7 +28,7 @@ = 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[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type ((u32) is 1.., u32): at .0, encountered 0, but expected something greater or equal to 1 --> $DIR/validity.rs:20:1 | LL | const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0); @@ -39,7 +39,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value of type Foo: at .0.0, encountered 0, but expected something greater or equal to 1 --> $DIR/validity.rs:26:1 | LL | const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) })); @@ -60,7 +60,7 @@ __ __ __ __ │ ░░░░ } -error[E0080]: constructing invalid value: encountered 97, but expected something in the range 65..=89 +error[E0080]: constructing invalid value of type (char) is 'A'..='Y': encountered 97, but expected something in the range 65..=89 --> $DIR/validity.rs:33:1 | LL | const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') }; @@ -71,7 +71,7 @@ HEX_DUMP } -error[E0080]: constructing invalid value: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) +error[E0080]: constructing invalid value of type (char) is 'A'..='Y': encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) --> $DIR/validity.rs:36:1 | LL | const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
diff --git a/tests/ui/typeck/derive-sugg-arg-arity.rs b/tests/ui/typeck/derive-sugg-arg-arity.rs index 094c93a..1a233e6 100644 --- a/tests/ui/typeck/derive-sugg-arg-arity.rs +++ b/tests/ui/typeck/derive-sugg-arg-arity.rs
@@ -3,6 +3,6 @@ fn main() { match () { _ => match A::partial_cmp() {}, - //~^ ERROR the function or associated item `partial_cmp` exists for struct `A`, but its trait bounds were not satisfied + //~^ ERROR the associated function or constant `partial_cmp` exists for struct `A`, but its trait bounds were not satisfied } }
diff --git a/tests/ui/typeck/derive-sugg-arg-arity.stderr b/tests/ui/typeck/derive-sugg-arg-arity.stderr index 382b324..029d8df 100644 --- a/tests/ui/typeck/derive-sugg-arg-arity.stderr +++ b/tests/ui/typeck/derive-sugg-arg-arity.stderr
@@ -1,11 +1,11 @@ -error[E0599]: the function or associated item `partial_cmp` exists for struct `A`, but its trait bounds were not satisfied +error[E0599]: the associated function or constant `partial_cmp` exists for struct `A`, but its trait bounds were not satisfied --> $DIR/derive-sugg-arg-arity.rs:5:23 | LL | pub struct A; - | ------------ function or associated item `partial_cmp` not found for this struct because it doesn't satisfy `A: Iterator` or `A: PartialOrd<_>` + | ------------ associated function or constant `partial_cmp` not found for this struct because it doesn't satisfy `A: Iterator` or `A: PartialOrd<_>` ... LL | _ => match A::partial_cmp() {}, - | ^^^^^^^^^^^ function or associated item cannot be called on `A` due to unsatisfied trait bounds + | ^^^^^^^^^^^ associated function or constant cannot be called on `A` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `A: PartialOrd<_>`
diff --git a/tests/ui/typeck/dont-suggest-private-dependencies.rs b/tests/ui/typeck/dont-suggest-private-dependencies.rs index ee5224e..23debbf 100644 --- a/tests/ui/typeck/dont-suggest-private-dependencies.rs +++ b/tests/ui/typeck/dont-suggest-private-dependencies.rs
@@ -31,7 +31,7 @@ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn main() { let _ = u8::cast_from_lossy(9); - //~^ ERROR no function or associated item named `cast_from_lossy` found for type `u8` + //~^ ERROR no associated function or constant named `cast_from_lossy` found for type `u8` let _ = B::foo(); - //~^ ERROR no function or associated item named `foo` found for struct `B` + //~^ ERROR no associated function or constant named `foo` found for struct `B` }
diff --git a/tests/ui/typeck/dont-suggest-private-dependencies.stderr b/tests/ui/typeck/dont-suggest-private-dependencies.stderr index b7b14ee..d17964c 100644 --- a/tests/ui/typeck/dont-suggest-private-dependencies.stderr +++ b/tests/ui/typeck/dont-suggest-private-dependencies.stderr
@@ -10,17 +10,17 @@ LL | fn read1(&self) {} | ^^^^^^^^^^^^^^^ -error[E0599]: no function or associated item named `cast_from_lossy` found for type `u8` in the current scope +error[E0599]: no associated function or constant named `cast_from_lossy` found for type `u8` in the current scope --> $DIR/dont-suggest-private-dependencies.rs:33:17 | LL | let _ = u8::cast_from_lossy(9); - | ^^^^^^^^^^^^^^^ function or associated item not found in `u8` + | ^^^^^^^^^^^^^^^ associated function or constant not found in `u8` -error[E0599]: no function or associated item named `foo` found for struct `B` in the current scope +error[E0599]: no associated function or constant named `foo` found for struct `B` in the current scope --> $DIR/dont-suggest-private-dependencies.rs:35:16 | LL | let _ = B::foo(); - | ^^^ function or associated item not found in `B` + | ^^^ associated function or constant not found in `B` error: aborting due to 3 previous errors
diff --git a/tests/ui/typeck/issue-90101.stderr b/tests/ui/typeck/issue-90101.stderr index 2e14046..fe9af5a 100644 --- a/tests/ui/typeck/issue-90101.stderr +++ b/tests/ui/typeck/issue-90101.stderr
@@ -6,12 +6,12 @@ | | | required by a bound introduced by this call | - = help: the following other types implement trait `From<T>`: - `PathBuf` implements `From<&T>` - `PathBuf` implements `From<Box<Path>>` - `PathBuf` implements `From<Cow<'_, Path>>` - `PathBuf` implements `From<OsString>` - `PathBuf` implements `From<String>` + = help: `PathBuf` implements trait `From<T>`: + From<&T> + From<Box<Path>> + From<Cow<'_, Path>> + From<OsString> + From<String> = note: required for `Cow<'_, str>` to implement `Into<PathBuf>` note: required by a bound in `func` --> $DIR/issue-90101.rs:3:20
diff --git a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs index 3cb775e..56d46fd 100644 --- a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs +++ b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs
@@ -7,5 +7,5 @@ fn main() { Bar::foo(); - //~^ ERROR: no function or associated item named `foo` found for struct `Bar` in the current scope [E0599] + //~^ ERROR: no associated function or constant named `foo` found for struct `Bar` in the current scope [E0599] }
diff --git a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr index 9128ee684..7f78d2a 100644 --- a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr +++ b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `foo` found for struct `Bar` in the current scope +error[E0599]: no associated function or constant named `foo` found for struct `Bar` in the current scope --> $DIR/suggest-trait-reexported-as-not-doc-visible.rs:9:10 | LL | Bar::foo(); - | ^^^ function or associated item not found in `Bar` + | ^^^ associated function or constant not found in `Bar` | = help: items from traits can only be used if the trait is in scope help: trait `Foo` which provides `foo` is implemented but not in scope; perhaps you want to import it
diff --git a/tests/ui/typeck/unit-type-add-error-11771.stderr b/tests/ui/typeck/unit-type-add-error-11771.stderr index 155cc09..4b8f59e 100644 --- a/tests/ui/typeck/unit-type-add-error-11771.stderr +++ b/tests/ui/typeck/unit-type-add-error-11771.stderr
@@ -2,7 +2,9 @@ --> $DIR/unit-type-add-error-11771.rs:5:7 | LL | 1 + - | ^ no implementation for `{integer} + ()` + | - ^ no implementation for `{integer} + ()` +LL | x + | - | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add<Rhs>`: @@ -20,7 +22,9 @@ --> $DIR/unit-type-add-error-11771.rs:10:7 | LL | 1 + - | ^ no implementation for `{integer} + ()` + | - ^ no implementation for `{integer} + ()` +LL | x + | - | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add<Rhs>`:
diff --git a/tests/ui/ufcs/bad-builder.rs b/tests/ui/ufcs/bad-builder.rs index 350c96a..53d174b 100644 --- a/tests/ui/ufcs/bad-builder.rs +++ b/tests/ui/ufcs/bad-builder.rs
@@ -1,6 +1,6 @@ fn hello<Q>() -> Vec<Q> { Vec::<Q>::mew() - //~^ ERROR no function or associated item named `mew` found for struct `Vec<Q>` in the current scope + //~^ ERROR no associated function or constant named `mew` found for struct `Vec<Q>` in the current scope } fn main() {}
diff --git a/tests/ui/ufcs/bad-builder.stderr b/tests/ui/ufcs/bad-builder.stderr index 2504a3d..5fae626 100644 --- a/tests/ui/ufcs/bad-builder.stderr +++ b/tests/ui/ufcs/bad-builder.stderr
@@ -1,8 +1,8 @@ -error[E0599]: no function or associated item named `mew` found for struct `Vec<Q>` in the current scope +error[E0599]: no associated function or constant named `mew` found for struct `Vec<Q>` in the current scope --> $DIR/bad-builder.rs:2:15 | LL | Vec::<Q>::mew() - | ^^^ function or associated item not found in `Vec<Q>` + | ^^^ associated function or constant not found in `Vec<Q>` | note: if you're trying to build a new `Vec<Q>` consider using one of the following associated functions: Vec::<T>::new
diff --git a/tests/ui/ufcs/ufcs-partially-resolved.rs b/tests/ui/ufcs/ufcs-partially-resolved.rs index 7126687..ac98aef 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.rs +++ b/tests/ui/ufcs/ufcs-partially-resolved.rs
@@ -35,7 +35,7 @@ fn main() { <u8 as A>::N::NN; //~ ERROR expected trait, found type alias `A` let _: <u8 as Tr>::Y::NN; //~ ERROR ambiguous associated type let _: <u8 as E>::Y::NN; //~ ERROR expected trait, found enum `E` - <u8 as Tr>::Y::NN; //~ ERROR no associated item named `NN` found for type `u16` + <u8 as Tr>::Y::NN; //~ ERROR no associated function or constant named `NN` found for type `u16` <u8 as E>::Y::NN; //~ ERROR expected trait, found enum `E` let _: <u8 as Tr::N>::NN; //~ ERROR cannot find trait `N` in trait `Tr` @@ -52,5 +52,5 @@ fn main() { let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found associated function `Dr::Z` <u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X` let _: <u8 as Dr>::Z::N; //~ ERROR expected associated type, found associated function `Dr::Z` - <u8 as Dr>::X::N; //~ ERROR no associated item named `N` found for type `u16` + <u8 as Dr>::X::N; //~ ERROR no associated function or constant named `N` found for type `u16` }
diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index e1df200..9efadec 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr
@@ -335,17 +335,17 @@ LL + let _: <<u8 as Tr>::Y as Example>::NN; | -error[E0599]: no associated item named `NN` found for type `u16` in the current scope +error[E0599]: no associated function or constant named `NN` found for type `u16` in the current scope --> $DIR/ufcs-partially-resolved.rs:38:20 | LL | <u8 as Tr>::Y::NN; - | ^^ associated item not found in `u16` + | ^^ associated function or constant not found in `u16` -error[E0599]: no associated item named `N` found for type `u16` in the current scope +error[E0599]: no associated function or constant named `N` found for type `u16` in the current scope --> $DIR/ufcs-partially-resolved.rs:55:20 | LL | <u8 as Dr>::X::N; - | ^ associated item not found in `u16` + | ^ associated function or constant not found in `u16` error: aborting due to 32 previous errors
diff --git a/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.rs b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.rs new file mode 100644 index 0000000..40816c3 --- /dev/null +++ b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.rs
@@ -0,0 +1,12 @@ +#![feature(rustc_attrs, unboxed_closures)] +#![allow(internal_features)] + +#[rustc_paren_sugar] +trait Tr { + fn method(); +} + +fn main() { + <u8 as Tr>::method(); + //~^ ERROR the trait bound `u8: Tr` is not satisfied +}
diff --git a/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.stderr b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.stderr new file mode 100644 index 0000000..99699d8 --- /dev/null +++ b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-issue-153855.stderr
@@ -0,0 +1,15 @@ +error[E0277]: the trait bound `u8: Tr` is not satisfied + --> $DIR/paren-sugar-non-fn-trait-issue-153855.rs:10:6 + | +LL | <u8 as Tr>::method(); + | ^^ the trait `Tr` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/paren-sugar-non-fn-trait-issue-153855.rs:5:1 + | +LL | trait Tr { + | ^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.rs b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.rs new file mode 100644 index 0000000..c49a2fe --- /dev/null +++ b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.rs
@@ -0,0 +1,16 @@ +#![feature(rustc_attrs, unboxed_closures)] +#![allow(internal_features)] + +// Regression test for #153855: diagnostics should not ICE when a +// `#[rustc_paren_sugar]` trait is used with parenthesized syntax but does not +// have an `Fn`-family generic layout. +#[rustc_paren_sugar] +trait Tr<'a, 'b, T> { + fn method() {} +} + +fn main() { + <u8 as Tr(&u8)>::method; + //~^ ERROR associated item constraints are not allowed here + //~| ERROR the trait bound `u8: Tr<'_, '_, (&u8,)>` is not satisfied +}
diff --git a/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.stderr b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.stderr new file mode 100644 index 0000000..c4ce904 --- /dev/null +++ b/tests/ui/unboxed-closures/paren-sugar-non-fn-trait-ufcs-issue-153855.stderr
@@ -0,0 +1,22 @@ +error[E0229]: associated item constraints are not allowed here + --> $DIR/paren-sugar-non-fn-trait-ufcs-issue-153855.rs:13:12 + | +LL | <u8 as Tr(&u8)>::method; + | ^^^^^^^ associated item constraint not allowed here + +error[E0277]: the trait bound `u8: Tr<'_, '_, (&u8,)>` is not satisfied + --> $DIR/paren-sugar-non-fn-trait-ufcs-issue-153855.rs:13:6 + | +LL | <u8 as Tr(&u8)>::method; + | ^^ the trait `Tr<'_, '_, (&u8,)>` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/paren-sugar-non-fn-trait-ufcs-issue-153855.rs:8:1 + | +LL | trait Tr<'a, 'b, T> { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0229, E0277. +For more information about an error, try `rustc --explain E0229`.
diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 6860b0b..739182e 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr
@@ -7,7 +7,7 @@ LL | return c(); | - type must be known at this point | -help: consider giving `closure0` an explicit type, where the type for type parameter `T` is specified +help: consider giving `closure0` an explicit type, where the placeholders `_` are specified | LL | let mut closure0: Option<T> = None; | +++++++++++
diff --git a/tests/ui/unsafe/access_union_field.rs b/tests/ui/union/access_union_field.rs similarity index 100% rename from tests/ui/unsafe/access_union_field.rs rename to tests/ui/union/access_union_field.rs
diff --git a/tests/ui/unsafe/access_union_field.stderr b/tests/ui/union/access_union_field.stderr similarity index 100% rename from tests/ui/unsafe/access_union_field.stderr rename to tests/ui/union/access_union_field.stderr
diff --git a/tests/ui/unsafe/union-assignop.rs b/tests/ui/union/union-assignop.rs similarity index 100% rename from tests/ui/unsafe/union-assignop.rs rename to tests/ui/union/union-assignop.rs
diff --git a/tests/ui/unsafe/union-assignop.stderr b/tests/ui/union/union-assignop.stderr similarity index 100% rename from tests/ui/unsafe/union-assignop.stderr rename to tests/ui/union/union-assignop.stderr
diff --git a/tests/ui/unsafe/union-modification.rs b/tests/ui/union/union-modification.rs similarity index 100% rename from tests/ui/unsafe/union-modification.rs rename to tests/ui/union/union-modification.rs
diff --git a/tests/ui/unsafe/union-pat-in-param.rs b/tests/ui/union/union-pat-in-param.rs similarity index 100% rename from tests/ui/unsafe/union-pat-in-param.rs rename to tests/ui/union/union-pat-in-param.rs
diff --git a/tests/ui/unsafe/union-pat-in-param.stderr b/tests/ui/union/union-pat-in-param.stderr similarity index 100% rename from tests/ui/unsafe/union-pat-in-param.stderr rename to tests/ui/union/union-pat-in-param.stderr
diff --git a/tests/ui/unsafe/union.rs b/tests/ui/union/union.rs similarity index 100% rename from tests/ui/unsafe/union.rs rename to tests/ui/union/union.rs
diff --git a/tests/ui/unsafe/union.stderr b/tests/ui/union/union.stderr similarity index 100% rename from tests/ui/unsafe/union.stderr rename to tests/ui/union/union.stderr
diff --git a/tests/ui/unsafe/union_access_through_block.rs b/tests/ui/union/union_access_through_block.rs similarity index 100% rename from tests/ui/unsafe/union_access_through_block.rs rename to tests/ui/union/union_access_through_block.rs
diff --git a/tests/ui/unsafe/union_destructure.rs b/tests/ui/union/union_destructure.rs similarity index 100% rename from tests/ui/unsafe/union_destructure.rs rename to tests/ui/union/union_destructure.rs
diff --git a/tests/ui/unsafe/union_wild_or_wild.rs b/tests/ui/union/union_wild_or_wild.rs similarity index 100% rename from tests/ui/unsafe/union_wild_or_wild.rs rename to tests/ui/union/union_wild_or_wild.rs
diff --git a/tests/ui/unsafe-binders/binder-sized-crit.rs b/tests/ui/unsafe-binders/binder-sized-crit.rs index 37677c0..cda8071 100644 --- a/tests/ui/unsafe-binders/binder-sized-crit.rs +++ b/tests/ui/unsafe-binders/binder-sized-crit.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::wrap_binder;
diff --git a/tests/ui/unsafe-binders/binder-sized-crit.stderr b/tests/ui/unsafe-binders/binder-sized-crit.stderr deleted file mode 100644 index 3ba6cf2..0000000 --- a/tests/ui/unsafe-binders/binder-sized-crit.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/binder-sized-crit.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs index d437d8f..9feb294 100644 --- a/tests/ui/unsafe-binders/expr.rs +++ b/tests/ui/unsafe-binders/expr.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::{wrap_binder, unwrap_binder};
diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr deleted file mode 100644 index 07026e1..0000000 --- a/tests/ui/unsafe-binders/expr.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/expr.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/unsafe-binders/lifetime-resolution.rs b/tests/ui/unsafe-binders/lifetime-resolution.rs index d243154..9935edf 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.rs +++ b/tests/ui/unsafe-binders/lifetime-resolution.rs
@@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn foo<'a>() { let good: unsafe<'b> &'a &'b ();
diff --git a/tests/ui/unsafe-binders/lifetime-resolution.stderr b/tests/ui/unsafe-binders/lifetime-resolution.stderr index 69660c2..2f445e9 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.stderr +++ b/tests/ui/unsafe-binders/lifetime-resolution.stderr
@@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/lifetime-resolution.rs:7:28 + --> $DIR/lifetime-resolution.rs:6:28 | LL | let missing: unsafe<> &'missing (); | ^^^^^^^^ undeclared lifetime @@ -15,7 +15,7 @@ | +++++++++ error[E0401]: can't use generic parameters from outer item - --> $DIR/lifetime-resolution.rs:11:30 + --> $DIR/lifetime-resolution.rs:10:30 | LL | fn foo<'a>() { | -- lifetime parameter from outer item @@ -32,16 +32,7 @@ LL | fn inner<'a, 'b>() { | +++ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/lifetime-resolution.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0401. For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs index 840d938..8da94cc 100644 --- a/tests/ui/unsafe-binders/mismatch.rs +++ b/tests/ui/unsafe-binders/mismatch.rs
@@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::{wrap_binder, unwrap_binder};
diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr index f64db92..5e0720f 100644 --- a/tests/ui/unsafe-binders/mismatch.stderr +++ b/tests/ui/unsafe-binders/mismatch.stderr
@@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mismatch.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/mismatch.rs:7:46 + --> $DIR/mismatch.rs:6:46 | LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&()); | ^^^ expected `&i32`, found `&()` @@ -17,7 +8,7 @@ found reference `&()` error: `wrap_binder!()` can only wrap into unsafe binder, not `i32` - --> $DIR/mismatch.rs:12:18 + --> $DIR/mismatch.rs:11:18 | LL | let _: i32 = wrap_binder!(&()); | ^^^^^^^^^^^^^^^^^ @@ -26,7 +17,7 @@ = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected unsafe binder, found integer as input of `unwrap_binder!()` - --> $DIR/mismatch.rs:18:20 + --> $DIR/mismatch.rs:17:20 | LL | unwrap_binder!(y); | ^ @@ -34,7 +25,7 @@ = note: only an unsafe binder type can be unwrapped error[E0282]: type annotations needed - --> $DIR/mismatch.rs:23:9 + --> $DIR/mismatch.rs:22:9 | LL | let unknown = Default::default(); | ^^^^^^^ @@ -48,12 +39,12 @@ | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/mismatch.rs:29:26 + --> $DIR/mismatch.rs:28:26 | LL | let x = wrap_binder!(&42); | ^^^ cannot infer type -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors Some errors have detailed explanations: E0282, E0308. For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/unsafe/move-out-of-non-copy.rs b/tests/ui/unsafe-binders/move-out-of-non-copy.rs similarity index 100% rename from tests/ui/unsafe/move-out-of-non-copy.rs rename to tests/ui/unsafe-binders/move-out-of-non-copy.rs
diff --git a/tests/ui/unsafe/move-out-of-non-copy.stderr b/tests/ui/unsafe-binders/move-out-of-non-copy.stderr similarity index 100% rename from tests/ui/unsafe/move-out-of-non-copy.stderr rename to tests/ui/unsafe-binders/move-out-of-non-copy.stderr
diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs index 9397c2b..df2cb22 100644 --- a/tests/ui/unsafe-binders/moves.rs +++ b/tests/ui/unsafe-binders/moves.rs
@@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::mem::{ManuallyDrop, drop}; use std::unsafe_binder::{unwrap_binder, wrap_binder};
diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr index bd48015..a6d6380 100644 --- a/tests/ui/unsafe-binders/moves.stderr +++ b/tests/ui/unsafe-binders/moves.stderr
@@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/moves.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0382]: use of moved value: `base` - --> $DIR/moves.rs:15:14 + --> $DIR/moves.rs:14:14 | LL | let base = NotCopy::default(); | ---- move occurs because `base` has type `ManuallyDrop<NotCopyInner>`, which does not implement the `Copy` trait @@ -18,7 +9,7 @@ | ^^^^ value used here after move | note: if `NotCopyInner` implemented `Clone`, you could clone the value - --> $DIR/moves.rs:8:1 + --> $DIR/moves.rs:7:1 | LL | struct NotCopyInner; | ^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type @@ -27,7 +18,7 @@ | ---- you could clone this value error[E0382]: use of moved value: `binder` - --> $DIR/moves.rs:24:14 + --> $DIR/moves.rs:23:14 | LL | drop(unwrap_binder!(binder)); | ---------------------- value moved here @@ -38,7 +29,7 @@ = note: this error originates in the macro `unwrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0382]: use of moved value: `binder.0` - --> $DIR/moves.rs:36:14 + --> $DIR/moves.rs:35:14 | LL | drop(unwrap_binder!(binder).0); | ------------------------ value moved here @@ -48,6 +39,6 @@ | = note: move occurs because `binder.0` has type `ManuallyDrop<NotCopyInner>`, which does not implement the `Copy` trait -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/unsafe-binders/simple.rs b/tests/ui/unsafe-binders/simple.rs index 6172a9e..99f20d6 100644 --- a/tests/ui/unsafe-binders/simple.rs +++ b/tests/ui/unsafe-binders/simple.rs
@@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn main() { let x: unsafe<'a> &'a ();
diff --git a/tests/ui/unsafe-binders/simple.stderr b/tests/ui/unsafe-binders/simple.stderr deleted file mode 100644 index e4b82c1..0000000 --- a/tests/ui/unsafe-binders/simple.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/simple.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/unsafe-binders/type-mismatch.rs b/tests/ui/unsafe-binders/type-mismatch.rs index 9ac4e81..22937bb 100644 --- a/tests/ui/unsafe-binders/type-mismatch.rs +++ b/tests/ui/unsafe-binders/type-mismatch.rs
@@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn main() { let x: unsafe<> i32 = 0;
diff --git a/tests/ui/unsafe-binders/type-mismatch.stderr b/tests/ui/unsafe-binders/type-mismatch.stderr index e694b5d..6262620 100644 --- a/tests/ui/unsafe-binders/type-mismatch.stderr +++ b/tests/ui/unsafe-binders/type-mismatch.stderr
@@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-mismatch.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/type-mismatch.rs:5:27 + --> $DIR/type-mismatch.rs:4:27 | LL | let x: unsafe<> i32 = 0; | ------------ ^ expected `unsafe<> i32`, found integer @@ -19,7 +10,7 @@ found type `{integer}` error[E0308]: mismatched types - --> $DIR/type-mismatch.rs:7:33 + --> $DIR/type-mismatch.rs:6:33 | LL | let x: unsafe<'a> &'a i32 = &0; | ------------------ ^^ expected `unsafe<'a> &i32`, found `&{integer}` @@ -29,6 +20,6 @@ = note: expected unsafe binder `unsafe<'a> &'a i32` found reference `&{integer}` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs index 15245d9..21f8fe7 100644 --- a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs +++ b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs
@@ -3,7 +3,6 @@ //@ compile-flags: -Cdebuginfo=2 //@ ignore-backends: gcc #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::wrap_binder; fn main() {
diff --git a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr deleted file mode 100644 index 283b8b9c..0000000 --- a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unsafe-binders-debuginfo.rs:5:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted -
diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/initializing-ranged-via-ctor.rs similarity index 100% rename from tests/ui/unsafe/initializing-ranged-via-ctor.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/initializing-ranged-via-ctor.rs
diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/initializing-ranged-via-ctor.stderr similarity index 100% rename from tests/ui/unsafe/initializing-ranged-via-ctor.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/initializing-ranged-via-ctor.stderr
diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged-ctor-as-fn-ptr.rs similarity index 100% rename from tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged-ctor-as-fn-ptr.rs
diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged-ctor-as-fn-ptr.stderr similarity index 100% rename from tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged-ctor-as-fn-ptr.stderr
diff --git a/tests/ui/unsafe/ranged_ints.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints.rs
diff --git a/tests/ui/unsafe/ranged_ints.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints.stderr
diff --git a/tests/ui/unsafe/ranged_ints2.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints2.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2.rs
diff --git a/tests/ui/unsafe/ranged_ints2.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints2.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2.stderr
diff --git a/tests/ui/unsafe/ranged_ints2_const.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2_const.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints2_const.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2_const.rs
diff --git a/tests/ui/unsafe/ranged_ints2_const.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2_const.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints2_const.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints2_const.stderr
diff --git a/tests/ui/unsafe/ranged_ints3.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints3.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3.rs
diff --git a/tests/ui/unsafe/ranged_ints3.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints3.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3.stderr
diff --git a/tests/ui/unsafe/ranged_ints3_const.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_const.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints3_const.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_const.rs
diff --git a/tests/ui/unsafe/ranged_ints3_const.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_const.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints3_const.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_const.stderr
diff --git a/tests/ui/unsafe/ranged_ints3_match.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_match.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints3_match.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_match.rs
diff --git a/tests/ui/unsafe/ranged_ints3_match.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_match.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints3_match.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints3_match.stderr
diff --git a/tests/ui/unsafe/ranged_ints4.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints4.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4.rs
diff --git a/tests/ui/unsafe/ranged_ints4.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints4.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4.stderr
diff --git a/tests/ui/unsafe/ranged_ints4_const.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4_const.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints4_const.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4_const.rs
diff --git a/tests/ui/unsafe/ranged_ints4_const.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4_const.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints4_const.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints4_const.stderr
diff --git a/tests/ui/unsafe/ranged_ints_const.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_const.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints_const.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_const.rs
diff --git a/tests/ui/unsafe/ranged_ints_const.stderr b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_const.stderr similarity index 100% rename from tests/ui/unsafe/ranged_ints_const.stderr rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_const.stderr
diff --git a/tests/ui/unsafe/ranged_ints_macro.rs b/tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_macro.rs similarity index 100% rename from tests/ui/unsafe/ranged_ints_macro.rs rename to tests/ui/unsafe/rustc_layout_scalar_valid_range/ranged_ints_macro.rs
diff --git a/tests/ui/unsized/thin-ptr-to-unsized-projection.rs b/tests/ui/unsized/thin-ptr-to-unsized-projection.rs new file mode 100644 index 0000000..79918e6 --- /dev/null +++ b/tests/ui/unsized/thin-ptr-to-unsized-projection.rs
@@ -0,0 +1,6 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/152682> +struct Foo<'a>(<& /*'a*/ [fn()] as core::ops::Deref>::Target); // adding the lifetime solves the ice + //~^ ERROR: missing lifetime specifier [E0106] +const _: *const Foo = 0 as _; + //~^ ERROR: cannot cast `i32` to a pointer that is wide [E0606] +fn main() {}
diff --git a/tests/ui/unsized/thin-ptr-to-unsized-projection.stderr b/tests/ui/unsized/thin-ptr-to-unsized-projection.stderr new file mode 100644 index 0000000..256523c --- /dev/null +++ b/tests/ui/unsized/thin-ptr-to-unsized-projection.stderr
@@ -0,0 +1,23 @@ +error[E0106]: missing lifetime specifier + --> $DIR/thin-ptr-to-unsized-projection.rs:2:17 + | +LL | struct Foo<'a>(<& /*'a*/ [fn()] as core::ops::Deref>::Target); // adding the lifetime solves the ice + | ^ expected named lifetime parameter + | +help: consider using the `'a` lifetime + | +LL | struct Foo<'a>(<&'a /*'a*/ [fn()] as core::ops::Deref>::Target); // adding the lifetime solves the ice + | ++ + +error[E0606]: cannot cast `i32` to a pointer that is wide + --> $DIR/thin-ptr-to-unsized-projection.rs:4:28 + | +LL | const _: *const Foo = 0 as _; + | - ^ creating a `*const Foo<'_>` requires both an address and a length + | | + | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0606. +For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/use/pub-use-self-super-crate.rs b/tests/ui/use/pub-use-self-super-crate.rs new file mode 100644 index 0000000..1a799ac --- /dev/null +++ b/tests/ui/use/pub-use-self-super-crate.rs
@@ -0,0 +1,24 @@ +mod foo { + pub use self as this; + //~^ ERROR `self` is only public within the crate, and cannot be re-exported outside + + pub mod bar { + pub use super as parent; + //~^ ERROR `super` is only public within the crate, and cannot be re-exported outside + pub use self::super as parent2; + //~^ ERROR `super` is only public within the crate, and cannot be re-exported outside + pub use super::{self as parent3}; + //~^ ERROR `super` is only public within the crate, and cannot be re-exported outside + pub use self::{super as parent4}; + //~^ ERROR `super` is only public within the crate, and cannot be re-exported outside + + pub use crate as root; + pub use crate::{self as root2}; + pub use super::super as root3; + } +} + +pub use foo::*; +pub use foo::bar::*; + +pub fn main() {}
diff --git a/tests/ui/use/pub-use-self-super-crate.stderr b/tests/ui/use/pub-use-self-super-crate.stderr new file mode 100644 index 0000000..3b33680 --- /dev/null +++ b/tests/ui/use/pub-use-self-super-crate.stderr
@@ -0,0 +1,43 @@ +error[E0365]: `self` is only public within the crate, and cannot be re-exported outside + --> $DIR/pub-use-self-super-crate.rs:2:13 + | +LL | pub use self as this; + | ^^^^^^^^^^^^ re-export of crate public `self` + | + = note: consider declaring type or module `self` with `pub` + +error[E0365]: `super` is only public within the crate, and cannot be re-exported outside + --> $DIR/pub-use-self-super-crate.rs:6:17 + | +LL | pub use super as parent; + | ^^^^^^^^^^^^^^^ re-export of crate public `super` + | + = note: consider declaring type or module `super` with `pub` + +error[E0365]: `super` is only public within the crate, and cannot be re-exported outside + --> $DIR/pub-use-self-super-crate.rs:8:17 + | +LL | pub use self::super as parent2; + | ^^^^^^^^^^^^^^^^^^^^^^ re-export of crate public `super` + | + = note: consider declaring type or module `super` with `pub` + +error[E0365]: `super` is only public within the crate, and cannot be re-exported outside + --> $DIR/pub-use-self-super-crate.rs:10:25 + | +LL | pub use super::{self as parent3}; + | ^^^^^^^^^^^^^^^ re-export of crate public `super` + | + = note: consider declaring type or module `super` with `pub` + +error[E0365]: `super` is only public within the crate, and cannot be re-exported outside + --> $DIR/pub-use-self-super-crate.rs:12:24 + | +LL | pub use self::{super as parent4}; + | ^^^^^^^^^^^^^^^^ re-export of crate public `super` + | + = note: consider declaring type or module `super` with `pub` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0365`.
diff --git a/tests/ui/use/use-path-segment-kw.rs b/tests/ui/use/use-path-segment-kw.rs index be64f23..164f645 100644 --- a/tests/ui/use/use-path-segment-kw.rs +++ b/tests/ui/use/use-path-segment-kw.rs
@@ -70,7 +70,7 @@ macro_rules! macro_dollar_crate { fn outer() {} -mod foo { +pub mod foo { pub mod bar { pub mod foobar { pub mod qux {
diff --git a/tests/ui/issues/issue-17546.rs b/tests/ui/variants/variant-result-noresult-used-as-type.rs similarity index 93% rename from tests/ui/issues/issue-17546.rs rename to tests/ui/variants/variant-result-noresult-used-as-type.rs index 1f0afc3..14433c1 100644 --- a/tests/ui/issues/issue-17546.rs +++ b/tests/ui/variants/variant-result-noresult-used-as-type.rs
@@ -1,5 +1,6 @@ //@ edition:2015 //@ ignore-sgx std::os::fortanix_sgx::usercalls::raw::Result changes compiler suggestions +// https://github.com/rust-lang/rust/issues/17546 use foo::MyEnum::Result; use foo::NoResult; // Through a re-export
diff --git a/tests/ui/issues/issue-17546.stderr b/tests/ui/variants/variant-result-noresult-used-as-type.stderr similarity index 88% rename from tests/ui/issues/issue-17546.stderr rename to tests/ui/variants/variant-result-noresult-used-as-type.stderr index d4aa354..511cb35 100644 --- a/tests/ui/issues/issue-17546.stderr +++ b/tests/ui/variants/variant-result-noresult-used-as-type.stderr
@@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `NoResult` - --> $DIR/issue-17546.rs:15:17 + --> $DIR/variant-result-noresult-used-as-type.rs:16:17 | LL | fn new() -> NoResult<MyEnum, String> { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ | error[E0573]: expected type, found variant `Result` - --> $DIR/issue-17546.rs:25:17 + --> $DIR/variant-result-noresult-used-as-type.rs:26:17 | LL | fn new() -> Result<foo::MyEnum, String> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type @@ -36,7 +36,7 @@ | error[E0573]: expected type, found variant `Result` - --> $DIR/issue-17546.rs:31:13 + --> $DIR/variant-result-noresult-used-as-type.rs:32:13 | LL | fn new() -> Result<foo::MyEnum, String> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type @@ -53,7 +53,7 @@ | error[E0573]: expected type, found variant `NoResult` - --> $DIR/issue-17546.rs:36:15 + --> $DIR/variant-result-noresult-used-as-type.rs:37:15 | LL | fn newer() -> NoResult<foo::MyEnum, String> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed new file mode 100644 index 0000000..01da737 --- /dev/null +++ b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.fixed
@@ -0,0 +1,17 @@ +//@ check-pass +//@ run-rustfix +//@ compile-flags: --force-warn deprecated_where_clause_location + + +#![allow(dead_code)] + +trait Trait { + type Assoc; +} + +impl Trait for i32 { + type Assoc = () where i32: Copy; + //~^ WARNING where clause not allowed here +} + +fn main() {}
diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs new file mode 100644 index 0000000..cdee4c7 --- /dev/null +++ b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.rs
@@ -0,0 +1,17 @@ +//@ check-pass +//@ run-rustfix +//@ compile-flags: --force-warn deprecated_where_clause_location + + +#![allow(dead_code)] + +trait Trait { + type Assoc; +} + +impl Trait for i32 { + type Assoc where i32: Copy = () where; + //~^ WARNING where clause not allowed here +} + +fn main() {}
diff --git a/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr new file mode 100644 index 0000000..d342150 --- /dev/null +++ b/tests/ui/where-clauses/alias-type-where-suggest-issue-153567.stderr
@@ -0,0 +1,16 @@ +warning: where clause not allowed here + --> $DIR/alias-type-where-suggest-issue-153567.rs:13:16 + | +LL | type Assoc where i32: Copy = () where; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information + = note: requested on the command line with `--force-warn deprecated-where-clause-location` +help: move it to the end of the type declaration + | +LL - type Assoc where i32: Copy = () where; +LL + type Assoc = () where i32: Copy; + | + +warning: 1 warning emitted +
diff --git a/tests/ui/where-clauses/cfg_attribute.a.stderr b/tests/ui/where-clauses/cfg_attribute.a.stderr index ee81072..5bfa65d 100644 --- a/tests/ui/where-clauses/cfg_attribute.a.stderr +++ b/tests/ui/where-clauses/cfg_attribute.a.stderr
@@ -93,6 +93,38 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:42:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:45:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:53:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:56:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:65:5 | LL | #[derive(Clone)] ():, @@ -109,6 +141,38 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:75:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:78:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:86:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:89:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:99:5 | LL | #[derive(Clone)] ():, @@ -189,86 +253,6 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:177:5 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:180:5 - | -LL | #[rustfmt::skip] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:42:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:45:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:53:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:56:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:75:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:78:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:86:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:89:9 - | -LL | #[rustfmt::skip] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:164:9 | LL | #[derive(Clone)] ():, @@ -284,5 +268,21 @@ | = help: only `#[cfg]` and `#[cfg_attr]` are supported +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:177:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:180:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + error: aborting due to 39 previous errors
diff --git a/tests/ui/where-clauses/cfg_attribute.b.stderr b/tests/ui/where-clauses/cfg_attribute.b.stderr index ee81072..5bfa65d 100644 --- a/tests/ui/where-clauses/cfg_attribute.b.stderr +++ b/tests/ui/where-clauses/cfg_attribute.b.stderr
@@ -93,6 +93,38 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:42:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:45:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:53:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:56:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:65:5 | LL | #[derive(Clone)] ():, @@ -109,6 +141,38 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:75:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:78:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:86:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:89:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:99:5 | LL | #[derive(Clone)] ():, @@ -189,86 +253,6 @@ = help: only `#[cfg]` and `#[cfg_attr]` are supported error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:177:5 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:180:5 - | -LL | #[rustfmt::skip] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:42:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:45:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:53:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:56:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:75:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:78:9 - | -LL | #[rustfmt::skip] ():; - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:86:9 - | -LL | #[derive(Clone)] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/cfg_attribute.rs:89:9 - | -LL | #[rustfmt::skip] ():, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses --> $DIR/cfg_attribute.rs:164:9 | LL | #[derive(Clone)] ():, @@ -284,5 +268,21 @@ | = help: only `#[cfg]` and `#[cfg_attr]` are supported +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:177:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:180:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + error: aborting due to 39 previous errors
diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr index e55a7c3..11f13ff 100644 --- a/tests/ui/where-clauses/unsupported_attribute.stderr +++ b/tests/ui/where-clauses/unsupported_attribute.stderr
@@ -10,6 +10,22 @@ LL | #[derive(Clone)] 'a: 'static, | ^^^^^^ not a non-macro attribute +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:13:5 + | +LL | #[doc = "doc"] T: Trait, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:14:5 + | +LL | #[doc = "doc"] 'a: 'static, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + error: `#[ignore]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:15:5 | @@ -58,6 +74,22 @@ | = help: `#[macro_use]` can be applied to crates, extern crates, and modules +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:21:5 + | +LL | #[allow(unused)] T: Trait, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:22:5 + | +LL | #[allow(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + error: `#[deprecated]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:23:5 | @@ -91,38 +123,6 @@ = help: `#[automatically_derived]` can only be applied to trait impl blocks error: most attributes are not supported in `where` clauses - --> $DIR/unsupported_attribute.rs:13:5 - | -LL | #[doc = "doc"] T: Trait, - | ^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/unsupported_attribute.rs:14:5 - | -LL | #[doc = "doc"] 'a: 'static, - | ^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/unsupported_attribute.rs:21:5 - | -LL | #[allow(unused)] T: Trait, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses - --> $DIR/unsupported_attribute.rs:22:5 - | -LL | #[allow(unused)] 'a: 'static, - | ^^^^^^^^^^^^^^^^ - | - = help: only `#[cfg]` and `#[cfg_attr]` are supported - -error: most attributes are not supported in `where` clauses --> $DIR/unsupported_attribute.rs:27:5 | LL | #[derive(Clone)] T: Trait,
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed index 9b935b1..5f3882c 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed
@@ -14,12 +14,12 @@ impl Trait for u32 { // Not fine, suggests moving. - type Assoc = () where u32: Copy; + type Assoc = () where u32: Copy; //~^ WARNING where clause not allowed here // Not fine, suggests moving `u32: Copy` - type Assoc2 = () where i32: Copy, u32: Copy; + type Assoc2 = () where i32: Copy, u32: Copy; //~^ WARNING where clause not allowed here - type Assoc3 = () where; + type Assoc3 = () where; //~^ WARNING where clause not allowed here } @@ -27,7 +27,7 @@ // Fine. type Assoc = () where u32: Copy; // Not fine, suggests moving both. - type Assoc2 = () where u32: Copy, i32: Copy; + type Assoc2 = () where u32: Copy, i32: Copy; //~^ WARNING where clause not allowed here type Assoc3 = () where; //~^ WARNING where clause not allowed here
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr index 5809ff8..f31c8b2 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr
@@ -9,7 +9,7 @@ help: move it to the end of the type declaration | LL - type Assoc where u32: Copy = (); -LL + type Assoc = () where u32: Copy; +LL + type Assoc = () where u32: Copy; | warning: where clause not allowed here @@ -22,7 +22,7 @@ help: move it to the end of the type declaration | LL - type Assoc2 where u32: Copy = () where i32: Copy; -LL + type Assoc2 = () where i32: Copy, u32: Copy; +LL + type Assoc2 = () where i32: Copy, u32: Copy; | warning: where clause not allowed here @@ -35,7 +35,7 @@ help: move it to the end of the type declaration | LL - type Assoc3 where = (); -LL + type Assoc3 = () where; +LL + type Assoc3 = () where; | warning: where clause not allowed here @@ -48,7 +48,7 @@ help: move it to the end of the type declaration | LL - type Assoc2 where u32: Copy, i32: Copy = (); -LL + type Assoc2 = () where u32: Copy, i32: Copy; +LL + type Assoc2 = () where u32: Copy, i32: Copy; | warning: where clause not allowed here
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed index 719f1d2..02dba8f 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed
@@ -6,10 +6,10 @@ trait Trait { // Not fine, suggests moving. - type Assoc = () where u32: Copy; + type Assoc = () where u32: Copy; //~^ WARNING where clause not allowed here // Not fine, suggests moving `u32: Copy` - type Assoc2 = () where i32: Copy, u32: Copy; + type Assoc2 = () where i32: Copy, u32: Copy; //~^ WARNING where clause not allowed here }
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr index 9e9967e..1b7c098 100644 --- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr +++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr
@@ -9,7 +9,7 @@ help: move it to the end of the type declaration | LL - type Assoc where u32: Copy = (); -LL + type Assoc = () where u32: Copy; +LL + type Assoc = () where u32: Copy; | warning: where clause not allowed here @@ -22,7 +22,7 @@ help: move it to the end of the type declaration | LL - type Assoc2 where u32: Copy = () where i32: Copy; -LL + type Assoc2 = () where i32: Copy, u32: Copy; +LL + type Assoc2 = () where i32: Copy, u32: Copy; | warning: 2 warnings emitted
diff --git a/triagebot.toml b/triagebot.toml index 8619229..f99d700 100644 --- a/triagebot.toml +++ b/triagebot.toml
@@ -194,6 +194,11 @@ adjusting release notes. Could you take a look if available? Thanks <3 """ +[ping.gpu-target] +message = """\ +Hi GPU experts, this issue/PR could use some guidance on how this should be +resolved/implemented. Could you take a look if available? Thanks <3 +""" # ------------------------------------------------------------------------------ # Autolabels @@ -1068,6 +1073,10 @@ """ cc = ["@Amanieu", "@folkertdev", "@sayantn"] +[mentions."library/std_detect"] +message = "Some changes occurred in `std_detect`" +cc = ["@Amanieu", "@folkertdev", "@sayantn"] + [mentions."library/core/src/intrinsics/simd.rs"] message = """ Some changes occurred to the platform-builtins intrinsics. Make sure the @@ -1407,6 +1416,15 @@ [mentions."compiler/rustc_ast_lowering/src/format.rs"] cc = ["@m-ou-se"] +[mentions."src/ci/github-actions/jobs.yml"] +message = """ +> [!WARNING] +> +> If you are changing how CI LLVM is built or linked, make sure to bump +> `src/bootstrap/download-ci-llvm-stamp`. +""" +cc = ["@jieyouxu"] + # Content-based mentions [mentions."#[miri::intrinsic_fallback_is_spec]"] @@ -1587,6 +1605,7 @@ "/library/std" = ["libs", "@ChrisDenton"] "/library/std/src/sys/pal/windows" = ["@ChrisDenton"] "/library/stdarch" = ["libs"] +"/library/std_detect" = ["libs"] "/library/test" = ["libs"] "/src/bootstrap" = ["bootstrap"] "/src/ci" = ["infra-ci"]
diff --git a/typos.toml b/typos.toml index 82e2b98..8e14ce5 100644 --- a/typos.toml +++ b/typos.toml
@@ -48,6 +48,7 @@ # the non-empty form can be automatically fixed by `--bless`. # # tidy-alphabetical-start +atomicaly = "atomically" definitinon = "definition" dependy = "" similarlty = "similarity"
diff --git a/x b/x index a8acbd4..768ed16 100755 --- a/x +++ b/x
@@ -46,7 +46,7 @@ fi done -python=$(bash -c "compgen -c python" | grep '^python[2-3]\.[0-9]+$' | head -n1) +python=$(bash -c "compgen -c python" | grep -E '^python[2-3](\.[0-9]+)?$' | head -n1) if ! [ "$python" = "" ]; then exec "$python" "$xpy" "$@" fi
diff --git a/yarn.lock b/yarn.lock index 89380ba..22149b0 100644 --- a/yarn.lock +++ b/yarn.lock
@@ -102,18 +102,17 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@puppeteer/browsers@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.3.0.tgz#791ea7d80450fea24eb19fb1d70c367ad4e08cae" - integrity sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA== +"@puppeteer/browsers@2.13.0": + version "2.13.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.13.0.tgz#10f980c6d65efeff77f8a3cac6e1a7ac10604500" + integrity sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA== dependencies: - debug "^4.3.5" + debug "^4.4.3" extract-zip "^2.0.1" progress "^2.0.3" - proxy-agent "^6.4.0" - semver "^7.6.3" - tar-fs "^3.0.6" - unbzip2-stream "^1.4.3" + proxy-agent "^6.5.0" + semver "^7.7.4" + tar-fs "^3.1.1" yargs "^17.7.2" "@so-ric/colorspace@^1.1.6": @@ -266,11 +265,6 @@ dependencies: bare-path "^3.0.0" -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - baseline-browser-mapping@^2.8.19: version "2.8.25" resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz#947dc6f81778e0fa0424a2ab9ea09a3033e71109" @@ -296,14 +290,14 @@ dependencies: fill-range "^7.1.1" -browser-ui-test@^0.22.2: - version "0.22.3" - resolved "https://registry.yarnpkg.com/browser-ui-test/-/browser-ui-test-0.22.3.tgz#83a3dccc93b738887f555d52aae64cb2b7885d66" - integrity sha512-y3TmrJ146stGQ4+Pk6I8Erxb1Uj5kzIPGGoWJmK9V73Kv9L+u0L4yjW5/4pNszFCy07FqC9FxQvOAL+/4RTorg== +browser-ui-test@^0.23.3: + version "0.23.3" + resolved "https://registry.yarnpkg.com/browser-ui-test/-/browser-ui-test-0.23.3.tgz#fe3b978cfe43d09ee9edd4b9d939a936dd654c30" + integrity sha512-VWiRH7sSwpnQSe1Rll5iOPS+IeFa1rMThCXrP5Pwspm95OOA8Wylv2B6yqreEw25DE3qPmgJUeZZC7Uh9wnjSg== dependencies: css-unit-converter "^1.1.2" pngjs "^3.4.0" - puppeteer "^22.15.0" + puppeteer "^24.31.0" readline-sync "^1.4.10" browserslist@^4.23.3: @@ -322,14 +316,6 @@ resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -buffer@^5.2.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -348,14 +334,13 @@ ansi-styles "^4.1.0" supports-color "^7.1.0" -chromium-bidi@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.6.3.tgz#363fe1ca6b9c6122b9f1b2a47f9449ecf712f755" - integrity sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A== +chromium-bidi@14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-14.0.0.tgz#15a12ab083ae519a49a724e94994ca0a9ced9c8e" + integrity sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw== dependencies: - mitt "3.0.1" - urlpattern-polyfill "10.0.0" - zod "3.23.8" + mitt "^3.0.1" + zod "^3.24.1" cliui@^8.0.1: version "8.0.1" @@ -444,7 +429,7 @@ resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6: +debug@4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -465,10 +450,10 @@ escodegen "^2.1.0" esprima "^4.0.1" -devtools-protocol@0.0.1312386: - version "0.0.1312386" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz#5ab824d6f1669ec6c6eb0fba047e73601d969052" - integrity sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA== +devtools-protocol@0.0.1581282: + version "0.0.1581282" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz#7f289b837e052ad04eb16e9575877801c2b3716c" + integrity sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ== doctrine@^3.0.0: version "3.0.0" @@ -842,11 +827,6 @@ agent-base "^7.1.2" debug "4" -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^5.2.0: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" @@ -1036,7 +1016,7 @@ dependencies: brace-expansion "^1.1.7" -mitt@3.0.1: +mitt@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== @@ -1185,7 +1165,7 @@ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -proxy-agent@^6.4.0: +proxy-agent@^6.5.0: version "6.5.0" resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.5.0.tgz#9e49acba8e4ee234aacb539f89ed9c23d02f232d" integrity sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A== @@ -1217,26 +1197,30 @@ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -puppeteer-core@22.15.0: - version "22.15.0" - resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-22.15.0.tgz#c76926cce5dbc177572797a9dacc325c313fa91a" - integrity sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA== +puppeteer-core@24.40.0: + version "24.40.0" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.40.0.tgz#1f389cd9432cb077f703ca2cb6758490cdccbc7e" + integrity sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag== dependencies: - "@puppeteer/browsers" "2.3.0" - chromium-bidi "0.6.3" - debug "^4.3.6" - devtools-protocol "0.0.1312386" - ws "^8.18.0" + "@puppeteer/browsers" "2.13.0" + chromium-bidi "14.0.0" + debug "^4.4.3" + devtools-protocol "0.0.1581282" + typed-query-selector "^2.12.1" + webdriver-bidi-protocol "0.4.1" + ws "^8.19.0" -puppeteer@^22.15.0: - version "22.15.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-22.15.0.tgz#4f842087090f1d9017ce947512e7baff55a10e75" - integrity sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q== +puppeteer@^24.31.0: + version "24.40.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.40.0.tgz#6df6aeee9dabf29bed3bb2be5c209d00518d4a79" + integrity sha512-IxQbDq93XHVVLWHrAkFP7F7iHvb9o0mgfsSIMlhHb+JM+JjM1V4v4MNSQfcRWJopx9dsNOr9adYv0U5fm9BJBQ== dependencies: - "@puppeteer/browsers" "2.3.0" + "@puppeteer/browsers" "2.13.0" + chromium-bidi "14.0.0" cosmiconfig "^9.0.0" - devtools-protocol "0.0.1312386" - puppeteer-core "22.15.0" + devtools-protocol "0.0.1581282" + puppeteer-core "24.40.0" + typed-query-selector "^2.12.1" queue-microtask@^1.2.2: version "1.2.3" @@ -1296,10 +1280,10 @@ resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== -semver@^7.6.3: - version "7.7.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== +semver@^7.7.4: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== shebang-command@^2.0.0: version "2.0.0" @@ -1401,10 +1385,10 @@ dependencies: has-flag "^4.0.0" -tar-fs@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.1.tgz#4f164e59fb60f103d472360731e8c6bb4a7fe9ef" - integrity sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg== +tar-fs@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.2.tgz#114b012f54796f31e62f3e57792820a80b83ae6e" + integrity sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw== dependencies: pump "^3.0.0" tar-stream "^3.1.5" @@ -1438,11 +1422,6 @@ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1472,19 +1451,16 @@ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +typed-query-selector@^2.12.1: + version "2.12.1" + resolved "https://registry.yarnpkg.com/typed-query-selector/-/typed-query-selector-2.12.1.tgz#04423bfb71b8f3aee3df1c29598ed6c7c8f55284" + integrity sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA== + typescript@^5.8.3: version "5.9.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== -unbzip2-stream@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - undici-types@~7.16.0: version "7.16.0" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" @@ -1505,16 +1481,16 @@ dependencies: punycode "^2.1.0" -urlpattern-polyfill@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz#f0a03a97bfb03cdf33553e5e79a2aadd22cac8ec" - integrity sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg== - util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +webdriver-bidi-protocol@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz#d411e7b8e158408d83bb166b0b4f1054fa3f077e" + integrity sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw== + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -1567,10 +1543,10 @@ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^8.18.0: - version "8.18.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== +ws@^8.19.0: + version "8.20.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8" + integrity sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA== y18n@^5.0.5: version "5.0.8" @@ -1608,7 +1584,7 @@ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zod@3.23.8: - version "3.23.8" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" - integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== +zod@^3.24.1: + version "3.25.76" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" + integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==