Rollup merge of #154671 - jakubadamw:issue-127423, r=Kivooeo Add a test for a past ICE when calling a const fn of an unresolved type with the wrong number of args The ICE is fixed, but there needs to be a regression test for it. Closes rust-lang/rust#127423.
diff --git a/Cargo.lock b/Cargo.lock index 02da343..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", ]
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 253dff6..42e272f 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs
@@ -67,12 +67,6 @@ #[cfg(feature = "nightly")] pub use layout::{Layout, TyAbiInterface, TyAndLayout}; -/// Requirements for a `StableHashingContext` to be used in this crate. -/// This is a hack to allow using the `HashStable_Generic` derive macro -/// instead of implementing everything in `rustc_middle`. -#[cfg(feature = "nightly")] -pub trait HashStableContext {} - #[derive(Clone, Copy, PartialEq, Eq, Default)] #[cfg_attr( feature = "nightly",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 71ec1c5..87633ca 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs
@@ -31,7 +31,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable}; pub use rustc_span::AttrId; use rustc_span::{ - ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, respan, sym, + ByteSymbol, DUMMY_SP, ErrorGuaranteed, HashStableContext, Ident, Span, Spanned, Symbol, kw, + respan, sym, }; use thin_vec::{ThinVec, thin_vec}; @@ -120,7 +121,7 @@ fn eq(&self, names: &&[Symbol]) -> bool { } } -impl<Hcx: rustc_span::HashStableContext> HashStable<Hcx> for Path { +impl<Hcx: 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 {
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index ac3e77b..4178db1 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs
@@ -36,8 +36,3 @@ pub mod util { pub use self::ast::*; pub use self::ast_traits::{AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; - -/// Requirements for a `StableHashingContext` to be used in this crate. -/// This is a hack to allow using the `HashStable_Generic` derive macro -/// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: rustc_span::HashStableContext {}
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 8953391..06bd6f0 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -14,7 +14,7 @@ use rustc_data_structures::sync; use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable}; use rustc_serialize::{Decodable, Encodable}; -use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym}; +use rustc_span::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, Symbol, sym}; use thin_vec::ThinVec; use crate::ast::AttrStyle; @@ -826,7 +826,7 @@ fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self { impl<Hcx> HashStable<Hcx> for TokenStream where - Hcx: crate::HashStableContext, + Hcx: HashStableContext, { fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { for sub_tt in self.iter() {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5fcc8f0..6d9fe98 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2683,7 +2683,7 @@ fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> overly_complex_const(self) } ExprKind::Lit(literal) => { - let span = expr.span; + let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); ConstArg { @@ -2695,7 +2695,7 @@ fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> ExprKind::Unary(UnOp::Neg, inner_expr) if let ExprKind::Lit(literal) = &inner_expr.kind => { - let span = expr.span; + let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); if !matches!(literal.node, LitKind::Int(..)) {
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 830eb3d6..1b615b6 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -14,31 +14,22 @@ /// The common case. macro_rules! gate { - ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{ + ($visitor:expr, $feature:ident, $span:expr, $explain:expr $(, $help:expr)?) => {{ if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { - feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit(); - } - }}; - ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{ - if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { - feature_err(&$visitor.sess, sym::$feature, $span, $explain).with_help($help).emit(); + feature_err($visitor.sess, sym::$feature, $span, $explain) + $(.with_help($help))? + .emit(); } }}; } /// The unusual case, where the `has_feature` condition is non-standard. macro_rules! gate_alt { - ($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{ + ($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr $(, $notes:expr)?) => {{ if !$has_feature && !$span.allows_unstable($name) { - feature_err(&$visitor.sess, $name, $span, $explain).emit(); - } - }}; - ($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr, $notes: expr) => {{ - if !$has_feature && !$span.allows_unstable($name) { - let mut diag = feature_err(&$visitor.sess, $name, $span, $explain); - for note in $notes { - diag.note(*note); - } + #[allow(unused_mut)] + let mut diag = feature_err($visitor.sess, $name, $span, $explain); + $(for ¬e in $notes { diag.note(note); })? diag.emit(); } }}; @@ -51,21 +42,12 @@ macro_rules! gate_multi { let spans: Vec<_> = $spans.filter(|span| !span.allows_unstable(sym::$feature)).collect(); if !spans.is_empty() { - feature_err(&$visitor.sess, sym::$feature, spans, $explain).emit(); + feature_err($visitor.sess, sym::$feature, spans, $explain).emit(); } } }}; } -/// The legacy case. -macro_rules! gate_legacy { - ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{ - if !$visitor.features.$feature() && !$span.allows_unstable(sym::$feature) { - feature_warn(&$visitor.sess, sym::$feature, $span, $explain); - } - }}; -} - pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) { PostExpansionVisitor { sess, features }.visit_attribute(attr) } @@ -77,6 +59,15 @@ struct PostExpansionVisitor<'a> { features: &'a Features, } +// ----------------------------------------------------------------------------- +// POST-EXPANSION FEATURE GATES FOR UNSTABLE ATTRIBUTES ETC. +// **LEGACY** POST-EXPANSION FEATURE GATES FOR UNSTABLE SYNTAX **LEGACY** +// ----------------------------------------------------------------------------- + +// IMPORTANT: Don't add any new post-expansion feature gates for new unstable syntax! +// It's a legacy mechanism for them. +// Instead, register a pre-expansion feature gate using `gate_all` in fn `check_crate`. + impl<'a> PostExpansionVisitor<'a> { /// Feature gate `impl Trait` inside `type Alias = $type_expr;`. fn check_impl_trait(&self, ty: &ast::Ty, in_associated_ty: bool) { @@ -89,14 +80,14 @@ fn visit_ty(&mut self, ty: &ast::Ty) { if let ast::TyKind::ImplTrait(..) = ty.kind { if self.in_associated_ty { gate!( - &self.vis, + self.vis, impl_trait_in_assoc_type, ty.span, "`impl Trait` in associated types is unstable" ); } else { gate!( - &self.vis, + self.vis, type_alias_impl_trait, ty.span, "`impl Trait` in type aliases is unstable" @@ -211,7 +202,7 @@ fn visit_item(&mut self, i: &'a ast::Item) { for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(sym::simd) { gate!( - &self, + self, repr_simd, attr.span, "SIMD types are experimental and possibly buggy" @@ -224,35 +215,30 @@ fn visit_item(&mut self, i: &'a ast::Item) { ast::ItemKind::Impl(ast::Impl { of_trait: Some(of_trait), .. }) => { if let ast::ImplPolarity::Negative(span) = of_trait.polarity { gate!( - &self, + self, negative_impls, span.to(of_trait.trait_ref.path.span), - "negative trait bounds are not fully implemented; \ - use marker types for now" + "negative impls are experimental", + "use marker types for now" ); } if let ast::Defaultness::Default(_) = of_trait.defaultness { - gate!(&self, specialization, i.span, "specialization is unstable"); + gate!(self, specialization, i.span, "specialization is experimental"); } } ast::ItemKind::Trait(box ast::Trait { is_auto: ast::IsAuto::Yes, .. }) => { - gate!( - &self, - auto_traits, - i.span, - "auto traits are experimental and possibly buggy" - ); + gate!(self, auto_traits, i.span, "auto traits are experimental and possibly buggy"); } ast::ItemKind::TraitAlias(..) => { - gate!(&self, trait_alias, i.span, "trait aliases are experimental"); + gate!(self, trait_alias, i.span, "trait aliases are experimental"); } ast::ItemKind::MacroDef(_, ast::MacroDef { macro_rules: false, .. }) => { let msg = "`macro` is experimental"; - gate!(&self, decl_macro, i.span, msg); + gate!(self, decl_macro, i.span, msg); } ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { @@ -264,7 +250,7 @@ fn visit_item(&mut self, i: &'a ast::Item) { }) => { // Make sure this is only allowed if the feature gate is enabled. // #![feature(min_generic_const_args)] - gate!(&self, min_generic_const_args, i.span, "top-level `type const` are unstable"); + gate!(self, min_generic_const_args, i.span, "top-level `type const` are unstable"); } _ => {} @@ -280,7 +266,7 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) { let links_to_llvm = link_name.is_some_and(|val| val.as_str().starts_with("llvm.")); if links_to_llvm { gate!( - &self, + self, link_llvm_intrinsics, i.span, "linking to LLVM intrinsics is experimental" @@ -288,7 +274,7 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) { } } ast::ForeignItemKind::TyAlias(..) => { - gate!(&self, extern_types, i.span, "extern types are experimental"); + gate!(self, extern_types, i.span, "extern types are experimental"); } ast::ForeignItemKind::MacCall(..) => {} } @@ -303,10 +289,10 @@ fn visit_ty(&mut self, ty: &'a ast::Ty) { self.check_late_bound_lifetime_defs(&fn_ptr_ty.generic_params); } ast::TyKind::Never => { - gate!(&self, never_type, ty.span, "the `!` type is experimental"); + gate!(self, never_type, ty.span, "the `!` type is experimental"); } ast::TyKind::Pat(..) => { - gate!(&self, pattern_types, ty.span, "pattern types are unstable"); + gate!(self, pattern_types, ty.span, "pattern types are unstable"); } _ => {} } @@ -339,7 +325,7 @@ fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) { && let ast::FnRetTy::Ty(ref ty) = generic_args.output && matches!(ty.kind, ast::TyKind::Never) { - gate!(&self, never_type, ty.span, "the `!` type is experimental"); + gate!(self, never_type, ty.span, "the `!` type is experimental"); } visit::walk_generic_args(self, args); } @@ -348,7 +334,7 @@ fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { ast::ExprKind::TryBlock(_, None) => { // `try { ... }` is old and is only gated post-expansion here. - gate!(&self, try_blocks, e.span, "`try` expression is experimental"); + gate!(self, try_blocks, e.span, "`try` expression is experimental"); } ast::ExprKind::TryBlock(_, Some(_)) => { // `try_blocks_heterogeneous` is new, and gated pre-expansion instead. @@ -359,10 +345,10 @@ fn visit_expr(&mut self, e: &'a ast::Expr) { .. }) => match suffix { Some(sym::f16) => { - gate!(&self, f16, e.span, "the type `f16` is unstable") + gate!(self, f16, e.span, "the type `f16` is unstable") } Some(sym::f128) => { - gate!(&self, f128, e.span, "the type `f128` is unstable") + gate!(self, f128, e.span, "the type `f128` is unstable") } _ => (), }, @@ -381,7 +367,7 @@ fn visit_pat(&mut self, pattern: &'a ast::Pat) { }; if let PatKind::Range(Some(_), None, Spanned { .. }) = inner_pat.kind { gate!( - &self, + self, half_open_range_patterns_in_slices, pat.span, "`X..` patterns in slices are experimental" @@ -390,7 +376,7 @@ fn visit_pat(&mut self, pattern: &'a ast::Pat) { } } PatKind::Box(..) => { - gate!(&self, box_patterns, pattern.span, "box pattern syntax is experimental"); + gate!(self, box_patterns, pattern.span, "box pattern syntax is experimental"); } _ => {} } @@ -412,7 +398,7 @@ fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) } if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() { - gate!(&self, c_variadic, span, "C-variadic functions are unstable"); + gate!(self, c_variadic, span, "C-variadic functions are unstable"); } visit::walk_fn(self, fn_kind) @@ -424,7 +410,7 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate!( - &self, + self, associated_type_defaults, i.span, "associated type defaults are unstable" @@ -441,18 +427,13 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { }) => { // Make sure this is only allowed if the feature gate is enabled. // #![feature(min_generic_const_args)] - gate!( - &self, - min_generic_const_args, - i.span, - "associated `type const` are unstable" - ); + gate!(self, min_generic_const_args, i.span, "associated `type const` are unstable"); // Make sure associated `type const` defaults in traits are only allowed // if the feature gate is enabled. // #![feature(associated_type_defaults)] if ctxt == AssocCtxt::Trait && rhs.is_some() { gate!( - &self, + self, associated_type_defaults, i.span, "associated type defaults are unstable" @@ -469,13 +450,15 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { self.features.specialization() || (is_fn && self.features.min_specialization()), sym::specialization, i.span, - "specialization is unstable" + "specialization is experimental" ); } visit::walk_assoc_item(self, i, ctxt) } } +// ----------------------------------------------------------------------------- + pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { maybe_stage_features(sess, features, krate); check_incompatible_features(sess, features); @@ -484,166 +467,170 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { let mut visitor = PostExpansionVisitor { sess, features }; + // ----------------------------------------------------------------------------- + // PRE-EXPANSION FEATURE GATES FOR UNSTABLE SYNTAX + // ----------------------------------------------------------------------------- + let spans = sess.psess.gated_spans.spans.borrow(); macro_rules! gate_all { - ($gate:ident, $msg:literal) => { - if let Some(spans) = spans.get(&sym::$gate) { - for span in spans { - gate!(&visitor, $gate, *span, $msg); - } - } - }; - ($gate:ident, $msg:literal, $help:literal) => { - if let Some(spans) = spans.get(&sym::$gate) { - for span in spans { - gate!(&visitor, $gate, *span, $msg, $help); - } + ($feature:ident, $explain:literal $(, $help:literal)?) => { + for &span in spans.get(&sym::$feature).into_iter().flatten() { + gate!(visitor, $feature, span, $explain $(, $help)?); } }; } + + // tidy-alphabetical-start + gate_all!(async_for_loop, "`for await` loops are experimental"); + gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); + gate_all!(const_block_items, "const block items are experimental"); + gate_all!(const_closures, "const closures are experimental"); + gate_all!(const_trait_impl, "const trait impls are experimental"); + gate_all!(contracts, "contracts are incomplete"); + gate_all!(contracts_internals, "contract internal machinery is for internal use only"); + gate_all!(coroutines, "coroutine syntax is experimental"); + gate_all!(default_field_values, "default values on fields are experimental"); + gate_all!(ergonomic_clones, "ergonomic clones are experimental"); + gate_all!(explicit_tail_calls, "`become` expression is experimental"); + gate_all!(final_associated_functions, "`final` on trait functions is experimental"); + gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); + gate_all!(frontmatter, "frontmatters are experimental"); + gate_all!(gen_blocks, "gen blocks are experimental"); + gate_all!(generic_const_items, "generic const items are experimental"); + gate_all!(global_registration, "global registration is experimental"); + gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards"); + gate_all!(impl_restriction, "`impl` restrictions are experimental"); + gate_all!(min_generic_const_args, "unbraced const blocks as const args are experimental"); + gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental"); + gate_all!(mut_ref, "mutable by-reference bindings are experimental"); + gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); + gate_all!(postfix_match, "postfix match is experimental"); + gate_all!(return_type_notation, "return type notation is experimental"); + gate_all!(super_let, "`super let` is experimental"); + gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental"); + gate_all!(unsafe_binders, "unsafe binder types are experimental"); + gate_all!(unsafe_fields, "`unsafe` fields are experimental"); + gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); + gate_all!(yeet_expr, "`do yeet` expression is experimental"); + // tidy-alphabetical-end + gate_all!( async_trait_bounds, "`async` trait bounds are unstable", "use the desugared name of the async trait, such as `AsyncFn`" ); - gate_all!(async_for_loop, "`for await` loops are experimental"); gate_all!( closure_lifetime_binder, "`for<...>` binders for closures are experimental", "consider removing `for<...>`" ); - gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental"); - // yield can be enabled either by `coroutines` or `gen_blocks` - if let Some(spans) = spans.get(&sym::yield_expr) { - for span in spans { - if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines)) - && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks)) - && (!visitor.features.yield_expr() && !span.allows_unstable(sym::yield_expr)) - { - // Emit yield_expr as the error, since that will be sufficient. You can think of it - // as coroutines and gen_blocks imply yield_expr. - feature_err(&visitor.sess, sym::yield_expr, *span, "yield syntax is experimental") - .emit(); - } - } - } - gate_all!(gen_blocks, "gen blocks are experimental"); - gate_all!(const_trait_impl, "const trait impls are experimental"); gate_all!( half_open_range_patterns_in_slices, "half-open range patterns in slices are unstable" ); - gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental"); - gate_all!(yeet_expr, "`do yeet` expression is experimental"); - gate_all!(const_closures, "const closures are experimental"); - gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); - gate_all!(ergonomic_clones, "ergonomic clones are experimental"); - gate_all!(explicit_tail_calls, "`become` expression is experimental"); - gate_all!(generic_const_items, "generic const items are experimental"); - gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards"); - gate_all!(default_field_values, "default values on fields are experimental"); - gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); - gate_all!(postfix_match, "postfix match is experimental"); - gate_all!(mut_ref, "mutable by-reference bindings are experimental"); - gate_all!(min_generic_const_args, "unbraced const blocks as const args are experimental"); - // associated_const_equality is stabilized as part of min_generic_const_args - if let Some(spans) = spans.get(&sym::associated_const_equality) { - for span in spans { - if !visitor.features.min_generic_const_args() - && !span.allows_unstable(sym::min_generic_const_args) - { - feature_err( - &visitor.sess, - sym::min_generic_const_args, - *span, - "associated const equality is incomplete", - ) - .emit(); - } - } - } - // `mgca_type_const_syntax` is part of `min_generic_const_args` so either - // or both are enabled we don't need to emit a feature error. - if let Some(spans) = spans.get(&sym::mgca_type_const_syntax) { - for span in spans { - if visitor.features.min_generic_const_args() - || visitor.features.mgca_type_const_syntax() - || span.allows_unstable(sym::min_generic_const_args) - || span.allows_unstable(sym::mgca_type_const_syntax) - { - continue; - } - feature_err( - &visitor.sess, - sym::min_generic_const_args, - *span, - "`type const` syntax is experimental", - ) - .emit(); - } + + // `associated_const_equality` will be stabilized as part of `min_generic_const_args`. + for &span in spans.get(&sym::associated_const_equality).into_iter().flatten() { + gate!(visitor, min_generic_const_args, span, "associated const equality is incomplete"); } - gate_all!(global_registration, "global registration is experimental"); - gate_all!(return_type_notation, "return type notation is experimental"); - gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); - gate_all!(unsafe_fields, "`unsafe` fields are experimental"); - gate_all!(unsafe_binders, "unsafe binder types are experimental"); - gate_all!(contracts, "contracts are incomplete"); - gate_all!(contracts_internals, "contract internal machinery is for internal use only"); - gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); - gate_all!(super_let, "`super let` is experimental"); - gate_all!(frontmatter, "frontmatters are experimental"); - gate_all!(coroutines, "coroutine syntax is experimental"); - gate_all!(const_block_items, "const block items are experimental"); - gate_all!(final_associated_functions, "`final` on trait functions is experimental"); - gate_all!(impl_restriction, "`impl` restrictions are experimental"); - - if !visitor.features.never_patterns() { - if let Some(spans) = spans.get(&sym::never_patterns) { - for &span in spans { - if span.allows_unstable(sym::never_patterns) { - continue; - } - let sm = sess.source_map(); - // We gate two types of spans: the span of a `!` pattern, and the span of a - // match arm without a body. For the latter we want to give the user a normal - // error. - if let Ok(snippet) = sm.span_to_snippet(span) - && snippet == "!" - { - feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental") - .emit(); - } else { - let suggestion = span.shrink_to_hi(); - sess.dcx().emit_err(errors::MatchArmWithNoBody { span, suggestion }); - } - } + // `mgca_type_const_syntax` is part of `min_generic_const_args` so if + // either or both are enabled we don't need to emit a feature error. + for &span in spans.get(&sym::mgca_type_const_syntax).into_iter().flatten() { + if visitor.features.min_generic_const_args() + || visitor.features.mgca_type_const_syntax() + || span.allows_unstable(sym::min_generic_const_args) + || span.allows_unstable(sym::mgca_type_const_syntax) + { + continue; } + feature_err( + visitor.sess, + sym::min_generic_const_args, + span, + "`type const` syntax is experimental", + ) + .emit(); } + // Negative bounds are *super* internal. + // Under no circumstances do we want to advertise the feature name to users! if !visitor.features.negative_bounds() { - for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { + for &span in spans.get(&sym::negative_bounds).into_iter().flatten() { sess.dcx().emit_err(errors::NegativeBoundUnsupported { span }); } } - // All uses of `gate_all_legacy_dont_use!` below this point were added in #65742, - // and subsequently disabled (with the non-early gating readded). - // We emit an early future-incompatible warning for these. - // New syntax gates should go above here to get a hard error gate. - macro_rules! gate_all_legacy_dont_use { - ($gate:ident, $msg:literal) => { - for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { - gate_legacy!(&visitor, $gate, *span, $msg); + if !visitor.features.never_patterns() { + for &span in spans.get(&sym::never_patterns).into_iter().flatten() { + if span.allows_unstable(sym::never_patterns) { + continue; + } + // We gate two types of spans: the span of a `!` pattern, and the span of a + // match arm without a body. For the latter we want to give the user a normal + // error. + if let Ok("!") = sess.source_map().span_to_snippet(span).as_deref() { + feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental") + .emit(); + } else { + let suggestion = span.shrink_to_hi(); + sess.dcx().emit_err(errors::MatchArmWithNoBody { span, suggestion }); + } + } + } + + // Yield exprs can be enabled either by `yield_expr`, by `coroutines` or by `gen_blocks`. + for &span in spans.get(&sym::yield_expr).into_iter().flatten() { + if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines)) + && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks)) + && (!visitor.features.yield_expr() && !span.allows_unstable(sym::yield_expr)) + { + // Only mentioned `yield_expr` in the diagnostic since that'll be sufficient. + // You can think of it as `coroutines` and `gen_blocks` implying `yield_expr`. + feature_err(visitor.sess, sym::yield_expr, span, "yield syntax is experimental").emit(); + } + } + + // ----------------------------------------------------------------------------- + // **LEGACY** SOFT PRE-EXPANSION FEATURE GATES FOR UNSTABLE SYNTAX **LEGACY** + // ----------------------------------------------------------------------------- + + // IMPORTANT: Do not extend the list below! New syntax should go above and use `gate_all`. + + // FIXME(#154045): Migrate all of these to erroring feature gates and + // remove the corresponding post-expansion feature gates. + + macro_rules! soft_gate_all_legacy_dont_use { + ($feature:ident, $explain:literal) => { + for &span in spans.get(&sym::$feature).into_iter().flatten() { + if !visitor.features.$feature() && !span.allows_unstable(sym::$feature) { + feature_warn(&visitor.sess, sym::$feature, span, $explain); + } } }; } - gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental"); - gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental"); - gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental"); - gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); - gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable"); + // tidy-alphabetical-start + soft_gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable"); + soft_gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental"); + soft_gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental"); + soft_gate_all_legacy_dont_use!(negative_impls, "negative impls are experimental"); + soft_gate_all_legacy_dont_use!(specialization, "specialization is experimental"); + soft_gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental"); + soft_gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); + // tidy-alphabetical-end + + for &span in spans.get(&sym::min_specialization).into_iter().flatten() { + if !visitor.features.specialization() + && !visitor.features.min_specialization() + && !span.allows_unstable(sym::specialization) + && !span.allows_unstable(sym::min_specialization) + { + feature_warn(visitor.sess, sym::specialization, span, "specialization is experimental"); + } + } + + // ----------------------------------------------------------------------------- visit::walk_crate(&mut visitor, krate); }
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 3eb0fd9..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,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index f3508c1..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,
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index e02c4ae..80d939a 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -1134,11 +1134,7 @@ fn handle_fn_abi_err( fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { match err { - FnAbiError::Layout( - LayoutError::SizeOverflow(_) - | LayoutError::Cycle(_) - | LayoutError::InvalidSimd { .. }, - ) => { + FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) => { self.tcx.dcx().emit_fatal(Spanned { span, node: err }); } _ => match fn_abi_request {
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/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0bfe012..04f0e70 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -107,8 +107,7 @@ fn handle_layout_err( | LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. } | LayoutError::TooGeneric(_) - | LayoutError::ReferencesError(_) - | LayoutError::Cycle(_) => {} + | LayoutError::ReferencesError(_) => {} } err_inval!(Layout(err)) }
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_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 224b727..a9ad07b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs
@@ -520,6 +520,8 @@ pub fn internal(&self, feature: Symbol) -> bool { (unstable, frontmatter, "1.88.0", Some(136889)), /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), + /// Allows using generics in more complex const expressions, based on definitional equality. + (unstable, generic_const_args, "1.95.0", Some(151972)), /// Allows non-trivial generic constants which have to have wfness manually propagated to callers (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. @@ -623,8 +625,6 @@ pub fn internal(&self, feature: Symbol) -> bool { (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "1.81.0", Some(126151)), - /// Allows using generics in more complex const expressions, based on definitional equality. - (unstable, opaque_generic_const_args, "1.95.0", Some(151972)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. @@ -806,6 +806,6 @@ struct FeatureUsage { /// Some features require one or more other features to be enabled. pub const DEPENDENT_FEATURES: &[(Symbol, &[Symbol])] = &[ - (sym::opaque_generic_const_args, &[sym::min_generic_const_args]), + (sym::generic_const_args, &[sym::min_generic_const_args]), (sym::unsized_const_params, &[sym::adt_const_params]), ];
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 78bd709..cae8bb8 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs
@@ -8,9 +8,9 @@ use rustc_data_structures::unord::UnordMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; -use rustc_span::Symbol; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::MacroKind; +use rustc_span::{HashStableContext, Symbol}; use crate::definitions::DefPathData; use crate::hir; @@ -712,7 +712,7 @@ fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { } } -impl<Hcx: crate::HashStableContext> ToStableHashKey<Hcx> for Namespace { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for Namespace { type KeyType = Namespace; #[inline]
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 9c2fec8..c2d9f87 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs
@@ -43,7 +43,6 @@ pub use lang_items::{LangItem, LanguageItems}; pub use rustc_ast::attr::version::*; pub use stability::*; -pub use stable_hash_impls::HashStableContext; pub use target::{MethodKind, Target}; arena_types!(rustc_arena::declare_arena);
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 58649a6..a157fc0 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -1,4 +1,5 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +use rustc_span::HashStableContext; use rustc_span::def_id::DefPathHash; use crate::HashIgnoredAttrId; @@ -8,53 +9,48 @@ use crate::hir_id::ItemLocalId; use crate::lints::DelayedLints; -/// Requirements for a `StableHashingContext` to be used in this crate. -/// This is a hack to allow using the `HashStable_Generic` derive macro -/// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext {} - -impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for BodyId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for BodyId { type KeyType = (DefPathHash, ItemLocalId); #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) { + fn to_stable_hash_key(&self, hcx: &Hcx) -> (DefPathHash, ItemLocalId) { let BodyId { hir_id } = *self; hir_id.to_stable_hash_key(hcx) } } -impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for ItemId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { self.owner_id.def_id.to_stable_hash_key(hcx) } } -impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for TraitItemId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { self.owner_id.def_id.to_stable_hash_key(hcx) } } -impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for ImplItemId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { self.owner_id.def_id.to_stable_hash_key(hcx) } } -impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for ForeignItemId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &Hcx) -> DefPathHash { self.owner_id.def_id.to_stable_hash_key(hcx) } } @@ -66,8 +62,8 @@ fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash { // want to pick up on a reference changing its target, so we hash the NodeIds // in "DefPath Mode". -impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<'tcx, Hcx: HashStableContext> HashStable<Hcx> for OwnerNodes<'tcx> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { // We ignore the `nodes` and `bodies` fields since these refer to information included in // `hash` which is hashed in the collector and used for the crate hash. // `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing @@ -78,15 +74,15 @@ fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { } } -impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for DelayedLints { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<Hcx: HashStableContext> HashStable<Hcx> for DelayedLints { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let DelayedLints { opt_hash, .. } = *self; opt_hash.unwrap().hash_stable(hcx, hasher); } } -impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<'tcx, Hcx: HashStableContext> HashStable<Hcx> for AttributeMap<'tcx> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { // We ignore the `map` since it refers to information included in `opt_hash` which is // hashed in the collector and used for the crate hash. let AttributeMap { opt_hash, define_opaque: _, map: _ } = *self; @@ -94,8 +90,8 @@ fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { } } -impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HashIgnoredAttrId { - fn hash_stable(&self, _hcx: &mut HirCtx, _hasher: &mut StableHasher) { +impl<Hcx: HashStableContext> HashStable<Hcx> for HashIgnoredAttrId { + fn hash_stable(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { /* we don't hash HashIgnoredAttrId, we ignore them */ } }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 80ef200..cfda030 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1598,8 +1598,8 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id)); if tcx.features().generic_const_exprs() { ty::AnonConstKind::GCE - } else if tcx.features().opaque_generic_const_args() { - // Only anon consts that are the RHS of a const item can be OGCA. + } else if tcx.features().generic_const_args() { + // Only anon consts that are the RHS of a const item can be GCA. // Note: We can't just check tcx.parent because it needs to be EXACTLY // the RHS, not just part of the RHS. if !is_anon_const_rhs_of_const_item(tcx, def) { @@ -1607,9 +1607,9 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin } let body = tcx.hir_body_owned_by(def); - let mut visitor = OGCAParamVisitor(tcx); + let mut visitor = GCAParamVisitor(tcx); match visitor.visit_body(body) { - ControlFlow::Break(UsesParam) => ty::AnonConstKind::OGCA, + ControlFlow::Break(UsesParam) => ty::AnonConstKind::GCA, ControlFlow::Continue(()) => ty::AnonConstKind::MCG, } } else if tcx.features().min_generic_const_args() { @@ -1650,11 +1650,11 @@ fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) def_id == rhs_anon.def_id } -struct OGCAParamVisitor<'tcx>(TyCtxt<'tcx>); +struct GCAParamVisitor<'tcx>(TyCtxt<'tcx>); struct UsesParam; -impl<'tcx> Visitor<'tcx> for OGCAParamVisitor<'tcx> { +impl<'tcx> Visitor<'tcx> for GCAParamVisitor<'tcx> { type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<UsesParam>;
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index ea98beb9..3647c91 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -97,8 +97,8 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { match tcx.anon_const_kind(def_id) { // Stable: anon consts are not able to use any generic parameters... ty::AnonConstKind::MCG => None, - // OGCA anon consts inherit their parent's generics. - ty::AnonConstKind::OGCA => Some(parent_did), + // GCA anon consts inherit their parent's generics. + ty::AnonConstKind::GCA => Some(parent_did), // we provide generics to repeat expr counts as a backwards compatibility hack. #76200 ty::AnonConstKind::RepeatExprCount => Some(parent_did),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 58c296d..a1b169c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -194,8 +194,7 @@ fn should_emit_layout_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError< | SizeOverflow(..) | InvalidSimd { .. } | NormalizationFailure(..) - | ReferencesError(..) - | Cycle(..) => { + | ReferencesError(..) => { false // not our job to report these } }
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 91660fc..9ec5632 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -387,7 +387,7 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { fn error(&self) -> ErrorGuaranteed { let msg = if self.is_self_alias { "generic `Self` types are currently not permitted in anonymous constants" - } else if self.tcx.features().opaque_generic_const_args() { + } else if self.tcx.features().generic_const_args() { "generic parameters in const blocks are only allowed as the direct value of a `type const`" } else { "generic parameters may not be used in const operations" @@ -408,8 +408,8 @@ fn error(&self) -> ErrorGuaranteed { } } if self.tcx.features().min_generic_const_args() { - if !self.tcx.features().opaque_generic_const_args() { - diag.help("add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items"); + if !self.tcx.features().generic_const_args() { + diag.help("add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items"); } else { diag.help("consider factoring the expression into a `type const` item and use it as the const argument instead"); }
diff --git a/compiler/rustc_hir_id/src/lib.rs b/compiler/rustc_hir_id/src/lib.rs index ffff3f9..064ce4e 100644 --- a/compiler/rustc_hir_id/src/lib.rs +++ b/compiler/rustc_hir_id/src/lib.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; -pub use rustc_span::HashStableContext; +use rustc_span::HashStableContext; use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] @@ -176,7 +176,7 @@ impl StableOrd for ItemLocalId { pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID }; -impl<Hcx: rustc_span::HashStableContext> ToStableHashKey<Hcx> for HirId { +impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for HirId { type KeyType = (DefPathHash, ItemLocalId); #[inline]
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 8723285..184c0d5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1871,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/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/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_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 89ea632..87d389a 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -341,7 +341,7 @@ fn fold_ty(&mut self, mut t: Ty<'tcx>) -> Ty<'tcx> { } debug!("canonical: type var found with vid {:?}", vid); - match self.infcx.unwrap().probe_ty_var(vid) { + match self.infcx.unwrap().try_resolve_ty_var(vid) { // `t` could be a float / int variable; canonicalize that instead. Ok(t) => { debug!("(resolved to {:?})", t); @@ -443,7 +443,7 @@ fn fold_const(&mut self, mut ct: ty::Const<'tcx>) -> ty::Const<'tcx> { } debug!("canonical: const var found with vid {:?}", vid); - match self.infcx.unwrap().probe_const_var(vid) { + match self.infcx.unwrap().try_resolve_const_var(vid) { Ok(c) => { debug!("(resolved to {:?})", c); return self.fold_const(c);
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 0940351..fada30f 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs
@@ -35,7 +35,7 @@ fn create_next_universe(&self) -> ty::UniverseIndex { } fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> { - match self.probe_ty_var(vid) { + match self.try_resolve_ty_var(vid) { Err(universe) => Some(universe), Ok(_) => None, } @@ -49,7 +49,7 @@ fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> { } fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> { - match self.probe_const_var(ct) { + match self.try_resolve_const_var(ct) { Err(universe) => Some(universe), Ok(_) => None, } @@ -68,7 +68,7 @@ fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid { } fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { - match self.probe_ty_var(vid) { + match self.try_resolve_ty_var(vid) { Ok(ty) => ty, Err(_) => Ty::new_var(self.tcx, self.root_var(vid)), } @@ -83,7 +83,7 @@ fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { } fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { - match self.probe_const_var(vid) { + match self.try_resolve_const_var(vid) { Ok(ct) => ct, Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), } @@ -103,7 +103,7 @@ fn is_changed_arg(&self, arg: ty::GenericArg<'tcx>) -> bool { if let ty::Infer(infer_ty) = *ty.kind() { match infer_ty { ty::InferTy::TyVar(vid) => { - !self.probe_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid) + !self.try_resolve_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid) } ty::InferTy::IntVar(vid) => { let mut inner = self.inner.borrow_mut(); @@ -133,7 +133,7 @@ fn is_changed_arg(&self, arg: ty::GenericArg<'tcx>) -> bool { if let ty::ConstKind::Infer(infer_ct) = ct.kind() { match infer_ct { ty::InferConst::Var(vid) => !self - .probe_const_var(vid) + .try_resolve_const_var(vid) .is_err_and(|_| self.root_const_var(vid) == vid), ty::InferConst::Fresh(_) => true, }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 10e7b1e..2057eeb 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1074,7 +1074,7 @@ pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { /// If `TyVar(vid)` resolves to a type, return that type. Else, return the /// universe index of `TyVar(vid)`. - pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> { + pub fn try_resolve_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> { use self::type_variable::TypeVariableValue; match self.inner.borrow_mut().type_variables().probe(vid) { @@ -1099,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, } } @@ -1151,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(_) @@ -1184,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); } @@ -1250,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>>, @@ -1291,7 +1228,10 @@ pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T value.fold_with(&mut r) } - pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result<ty::Const<'tcx>, ty::UniverseIndex> { + pub fn try_resolve_const_var( + &self, + vid: ty::ConstVid, + ) -> Result<ty::Const<'tcx>, ty::UniverseIndex> { match self.inner.borrow_mut().const_unification_table().probe_value(vid) { ConstVariableValue::Known { value } => Ok(value), ConstVariableValue::Unknown { origin: _, universe } => Err(universe),
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 3ab39e8..0b29421 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -300,10 +300,10 @@ fn generalize( assert!(!source_term.has_escaping_bound_vars()); 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))) + (self.try_resolve_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid))) } TermVid::Const(ct_vid) => ( - self.probe_const_var(ct_vid).unwrap_err(), + self.try_resolve_const_var(ct_vid).unwrap_err(), TermVid::Const(self.inner.borrow_mut().const_unification_table().find(ct_vid).vid), ), };
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_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index af1d185..1c86d55 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -8,11 +8,11 @@ HashStable, StableCompare, StableHasher, ToStableHashKey, }; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; -use rustc_hir_id::{HashStableContext, HirId, ItemLocalId}; +use rustc_hir_id::{HirId, ItemLocalId}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::def_id::DefPathHash; pub use rustc_span::edition::Edition; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{HashStableContext, Ident, Span, Symbol, sym}; use serde::{Deserialize, Serialize}; pub use self::Level::*;
diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index fa67adb..adb93e3 100644 --- a/compiler/rustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs
@@ -84,7 +84,7 @@ fn hash_stable_derive_with_mode( match mode { HashStableMode::Normal => {} HashStableMode::Generic => { - s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext }); + s.add_where_predicate(parse_quote! { __CTX: ::rustc_span::HashStableContext }); } HashStableMode::NoContext => {} }
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ad56e46..814b333 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -21,7 +21,7 @@ use rustc_hir::*; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{ErrorGuaranteed, ExpnId, Span}; +use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span}; use crate::query::Providers; use crate::ty::{ResolverAstLowering, TyCtxt}; @@ -77,8 +77,8 @@ pub fn owner(&self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> MaybeOwner<'hir> { } } -impl<HirCtx: HashStableContext> HashStable<HirCtx> for Crate<'_> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<Hcx: HashStableContext> HashStable<Hcx> for Crate<'_> { + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { let Crate { opt_hir_hash, .. } = self; opt_hir_hash.unwrap().hash_stable(hcx, hasher) }
diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs index 2e118dc..0e1cee2 100644 --- a/compiler/rustc_middle/src/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs
@@ -6,7 +6,7 @@ use rustc_session::Session; use rustc_session::cstore::Untracked; use rustc_span::source_map::SourceMap; -use rustc_span::{CachingSourceMapView, DUMMY_SP, Pos, Span}; +use rustc_span::{CachingSourceMapView, DUMMY_SP, HashStableContext, Pos, Span}; // Very often, we are hashing something that does not need the `CachingSourceMapView`, so we // initialize it lazily. @@ -73,7 +73,7 @@ pub fn hashing_controls(&self) -> HashingControls { } } -impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { +impl<'a> HashStableContext for StableHashingContext<'a> { /// Hashes a span in a stable way. We can't directly hash the span's `BytePos` fields (that /// would be similar to hashing pointers, since those are just offsets into the `SourceMap`). /// Instead, we hash the (file name, line, column) triple, which stays the same even if the @@ -189,8 +189,3 @@ fn assert_default_hashing_controls(&self, msg: &str) { ); } } - -impl<'a> rustc_abi::HashStableContext for StableHashingContext<'a> {} -impl<'a> rustc_ast::HashStableContext for StableHashingContext<'a> {} -impl<'a> rustc_hir::HashStableContext for StableHashingContext<'a> {} -impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}
diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 179998c..35e33fd 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs
@@ -1436,8 +1436,10 @@ query def_kind(def_id: DefId) -> DefKind { desc { "looking up definition kind of `{}`", tcx.def_path_str(def_id) } - cache_on_disk 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 }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index b6fd306..4dbceba 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -231,7 +231,7 @@ pub fn serialize(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult { 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(), @@ -783,7 +783,7 @@ 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. @@ -900,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/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4ca51c0..46682ab 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -260,8 +260,6 @@ pub enum LayoutError<'tcx> { NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), /// A non-layout error is reported elsewhere. ReferencesError(ErrorGuaranteed), - /// A type has cyclic layout, i.e. the type contains itself without indirection. - Cycle(ErrorGuaranteed), } impl<'tcx> fmt::Display for LayoutError<'tcx> { @@ -286,7 +284,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { t, e.get_type_for_failure() ), - LayoutError::Cycle(_) => write!(f, "a cycle occurred during layout computation"), LayoutError::ReferencesError(_) => write!(f, "the type has an unknown layout"), } } @@ -358,8 +355,7 @@ pub fn compute( Err(err @ LayoutError::TooGeneric(_)) => err, // We can't extract SizeSkeleton info from other layout errors Err( - e @ LayoutError::Cycle(_) - | e @ LayoutError::Unknown(_) + e @ LayoutError::Unknown(_) | e @ LayoutError::SizeOverflow(_) | e @ LayoutError::InvalidSimd { .. } | e @ LayoutError::NormalizationFailure(..)
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_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index f58318b..c815eba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -9,7 +9,6 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::search_graph::CandidateHeadUsages; -use rustc_type_ir::solve::Certainty::Maybe; use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; use rustc_type_ir::{ self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -1286,28 +1285,34 @@ fn visit_ty(&mut self, ty: ty::Ty<I>) -> Self::Result { return ControlFlow::Break(Err(NoSolution)); }; - if let ty::Placeholder(p) = ty.kind() { - if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(Certainty::Yes)) - } else { - ControlFlow::Continue(()) + match ty.kind() { + ty::Placeholder(p) => { + if p.universe() == ty::UniverseIndex::ROOT { + ControlFlow::Break(Ok(Certainty::Yes)) + } else { + ControlFlow::Continue(()) + } } - } else if ty.has_type_flags(TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_RE_INFER) { - self.recursion_depth += 1; - if self.recursion_depth > self.ecx.cx().recursion_limit() { - return ControlFlow::Break(Ok(Maybe { - cause: MaybeCause::Overflow { - suggest_increasing_limit: true, - keep_constraints: false, - }, - opaque_types_jank: OpaqueTypesJank::AllGood, - })); + ty::Infer(_) => ControlFlow::Break(Ok(Certainty::AMBIGUOUS)), + _ if ty.has_type_flags( + TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_INFER | TypeFlags::HAS_ALIAS, + ) => + { + self.recursion_depth += 1; + if self.recursion_depth > self.ecx.cx().recursion_limit() { + return ControlFlow::Break(Ok(Certainty::Maybe { + cause: MaybeCause::Overflow { + suggest_increasing_limit: true, + keep_constraints: false, + }, + opaque_types_jank: OpaqueTypesJank::AllGood, + })); + } + let result = ty.super_visit_with(self); + self.recursion_depth -= 1; + result } - let result = ty.super_visit_with(self); - self.recursion_depth -= 1; - result - } else { - ControlFlow::Continue(()) + _ => ControlFlow::Continue(()), } } @@ -1317,16 +1322,23 @@ fn visit_const(&mut self, ct: I::Const) -> Self::Result { return ControlFlow::Break(Err(NoSolution)); }; - if let ty::ConstKind::Placeholder(p) = ct.kind() { - if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(Certainty::Yes)) - } else { - ControlFlow::Continue(()) + match ct.kind() { + ty::ConstKind::Placeholder(p) => { + if p.universe() == ty::UniverseIndex::ROOT { + ControlFlow::Break(Ok(Certainty::Yes)) + } else { + ControlFlow::Continue(()) + } } - } else if ct.has_type_flags(TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_RE_INFER) { - ct.super_visit_with(self) - } else { - ControlFlow::Continue(()) + ty::ConstKind::Infer(_) => ControlFlow::Break(Ok(Certainty::AMBIGUOUS)), + _ if ct.has_type_flags( + TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_INFER | TypeFlags::HAS_ALIAS, + ) => + { + // FIXME(mgca): we should also check the recursion limit here + ct.super_visit_with(self) + } + _ => ControlFlow::Continue(()), } }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index eb6a1b5..46312be 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs
@@ -1,4 +1,4 @@ -use rustc_type_ir::{self as ty, Interner, TypingMode}; +use rustc_type_ir::{self as ty, Interner}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -14,18 +14,7 @@ pub(super) fn normalize_anon_const( &mut self, goal: Goal<I, ty::NormalizesTo<I>>, ) -> QueryResult<I> { - if self.typing_mode() == TypingMode::Coherence - && self.cx().anon_const_kind(goal.predicate.alias.def_id) == ty::AnonConstKind::OGCA - { - // During coherence, OGCA consts should be normalized ambiguously - // because they are opaque but eventually resolved to a real value. - // We don't want two OGCAs that have the same value to be treated - // as distinct for coherence purposes. (Just like opaque types.) - // - // We can't rely on evaluate_const below because that particular wrapper - // treats too-generic consts as a successful evaluation. - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } else if let Some(normalized_const) = self.evaluate_const( + if let Some(normalized_const) = self.evaluate_const( goal.param_env, ty::UnevaluatedConst::new( goal.predicate.alias.def_id.try_into().unwrap(),
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0f49274..79b79db 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs
@@ -248,10 +248,18 @@ fn parse_item_kind( self.parse_use_item()? } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM + let defaultness = def_(); + if let Defaultness::Default(span) = defaultness { + // Default functions should only require feature `min_specialization`. We remove the + // `specialization` tag again as such spans *require* feature `specialization` to be + // enabled. In a later stage, we make `specialization` imply `min_specialization`. + self.psess.gated_spans.gate(sym::min_specialization, span); + self.psess.gated_spans.ungate_last(sym::specialization, span); + } let (ident, sig, generics, contract, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; ItemKind::Fn(Box::new(Fn { - defaultness: def_(), + defaultness, ident, sig, generics, @@ -603,6 +611,7 @@ fn is_async_fn(&self) -> bool { fn parse_polarity(&mut self) -> ast::ImplPolarity { // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) { + self.psess.gated_spans.gate(sym::negative_impls, self.token.span); self.bump(); // `!` ast::ImplPolarity::Negative(self.prev_token.span) } else { @@ -1015,6 +1024,7 @@ fn parse_defaultness(&mut self) -> Defaultness { if self.check_keyword(exp!(Default)) && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As)) { + self.psess.gated_spans.gate(sym::specialization, self.token.span); self.bump(); // `default` Defaultness::Default(self.prev_token_uninterpolated_span()) } else if self.eat_keyword(exp!(Final)) {
diff --git a/compiler/rustc_query_impl/src/handle_cycle_error.rs b/compiler/rustc_query_impl/src/handle_cycle_error.rs index 5676669..22f8ac9 100644 --- a/compiler/rustc_query_impl/src/handle_cycle_error.rs +++ b/compiler/rustc_query_impl/src/handle_cycle_error.rs
@@ -12,7 +12,6 @@ use rustc_middle::queries::{QueryVTables, TaggedQueryKey}; 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}; @@ -203,8 +202,7 @@ fn layout_of<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> &'tcx ty::layout::L || create_cycle_error(tcx, &cycle), ); - let guar = diag.emit(); - tcx.arena.alloc(LayoutError::Cycle(guar)) + diag.emit().raise_fatal() } // item_and_field_ids should form a cycle where each field contains the
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index de36f01..0acc42a 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -209,12 +209,15 @@ fn visit_item(&mut self, i: &'a Item) { fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { match fn_kind { FnKind::Fn( - _ctxt, + ctxt, _vis, Fn { sig: FnSig { header, decl, span: _ }, ident, generics, contract, body, .. }, - ) if let Some(coroutine_kind) = header.coroutine_kind => { + ) if let Some(coroutine_kind) = header.coroutine_kind + // Foreign ones are denied, so don't create them here. + && ctxt != visit::FnCtxt::Foreign => + { self.visit_ident(ident); self.visit_fn_header(header); self.visit_generics(generics);
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 97c88064..cab37f5 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1011,14 +1011,14 @@ pub(crate) fn into_struct_error( ResolutionError::ParamInTyOfConstParam { name } => { self.dcx().create_err(errs::ParamInTyOfConstParam { span, name }) } - ResolutionError::ParamInNonTrivialAnonConst { is_ogca, name, param_kind: is_type } => { + ResolutionError::ParamInNonTrivialAnonConst { is_gca, name, param_kind: is_type } => { self.dcx().create_err(errs::ParamInNonTrivialAnonConst { span, name, param_kind: is_type, help: self.tcx.sess.is_nightly_build(), - is_ogca, - help_ogca: is_ogca, + is_gca, + help_gca: is_gca, }) } ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index c9dad4d..43b006d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs
@@ -407,7 +407,7 @@ pub(crate) struct SelfInConstGenericTy { #[derive(Diagnostic)] #[diag( - "{$is_ogca -> + "{$is_gca -> [true] generic parameters in const blocks are only allowed as the direct value of a `type const` *[false] generic parameters may not be used in const operations }" @@ -421,11 +421,11 @@ pub(crate) struct ParamInNonTrivialAnonConst { pub(crate) param_kind: ParamKindInNonTrivialAnonConst, #[help("add `#![feature(generic_const_exprs)]` to allow generic const expressions")] pub(crate) help: bool, - pub(crate) is_ogca: bool, + pub(crate) is_gca: bool, #[help( "consider factoring the expression into a `type const` item and use it as the const argument instead" )] - pub(crate) help_ogca: bool, + pub(crate) help_gca: bool, } #[derive(Debug)] @@ -1199,6 +1199,15 @@ pub(crate) struct AttributesStartingWithRustcAreReserved { } #[derive(Diagnostic)] +#[diag( + "attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler" +)] +pub(crate) struct AttributesContainingRustcAreReserved { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] #[diag("cannot use {$article} {$descr} through an import")] pub(crate) struct CannotUseThroughAnImport { #[primary_span]
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 0690181..b7561d5 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs
@@ -1568,10 +1568,7 @@ fn validate_res_from_ribs( } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_ogca: self - .tcx - .features() - .opaque_generic_const_args(), + is_gca: self.tcx.features().generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Type, } @@ -1663,10 +1660,7 @@ fn validate_res_from_ribs( } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_ogca: self - .tcx - .features() - .opaque_generic_const_args(), + is_gca: self.tcx.features().generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Const { name: rib_ident.name,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cf04823..7539e3c 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -3921,8 +3921,8 @@ pub(crate) fn emit_forbidden_non_static_lifetime_error( name: lifetime_ref.ident.name, param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime, help: self.r.tcx.sess.is_nightly_build(), - is_ogca: self.r.tcx.features().opaque_generic_const_args(), - help_ogca: self.r.tcx.features().opaque_generic_const_args(), + is_gca: self.r.tcx.features().generic_const_args(), + help_gca: self.r.tcx.features().generic_const_args(), }) .emit() }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 72d5cdc..d75f298 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs
@@ -308,7 +308,7 @@ enum ResolutionError<'ra> { /// /// This error is only emitted when using `min_const_generics`. ParamInNonTrivialAnonConst { - is_ogca: bool, + is_gca: bool, name: Symbol, param_kind: ParamKindInNonTrivialAnonConst, },
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6ae9d3a..619e612 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs
@@ -618,14 +618,20 @@ fn smart_resolve_macro_path( } // Report errors for the resolved macro. - for segment in &path.segments { + for (idx, segment) in path.segments.iter().enumerate() { if let Some(args) = &segment.args { self.dcx().emit_err(errors::GenericArgumentsInMacroPath { span: args.span() }); } if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") { - self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { - span: segment.ident.span, - }); + if idx == 0 { + self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { + span: segment.ident.span, + }); + } else { + self.dcx().emit_err(errors::AttributesContainingRustcAreReserved { + span: segment.ident.span, + }); + } } }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e37247d..1e95482 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs
@@ -23,7 +23,8 @@ use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::{ - FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym, + FileName, HashStableContext, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, + Symbol, sym, }; use rustc_target::spec::{ FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo, @@ -38,7 +39,7 @@ pub use crate::options::*; use crate::search_paths::SearchPath; use crate::utils::CanonicalizedPath; -use crate::{EarlyDiagCtxt, HashStableContext, Session, filesearch, lint}; +use crate::{EarlyDiagCtxt, Session, filesearch, lint}; mod cfg; mod externs;
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 1741dde..04e12f1 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs
@@ -11,30 +11,21 @@ #![recursion_limit = "256"] // tidy-alphabetical-end -pub mod errors; - -pub mod utils; +pub use getopts; pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass}; pub use rustc_lint_defs as lint; -pub mod parse; +pub use session::*; pub mod code_stats; +pub mod errors; +pub mod parse; +pub mod utils; #[macro_use] pub mod config; pub mod cstore; pub mod filesearch; mod macros; mod options; -pub mod search_paths; - -mod session; -pub use session::*; - pub mod output; - -pub use getopts; - -/// Requirements for a `StableHashingContext` to be used in this crate. -/// This is a hack to allow using the `HashStable_Generic` derive macro -/// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: rustc_ast::HashStableContext + rustc_hir::HashStableContext {} +pub mod search_paths; +mod session;
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/lib.rs b/compiler/rustc_span/src/lib.rs index 6794ffb..97de708 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs
@@ -2796,10 +2796,10 @@ pub fn new(start: usize, end: usize) -> InnerSpan { } } -/// Requirements for a `StableHashingContext` to be used in this crate. -/// -/// This is a hack to allow using the [`HashStable_Generic`] derive macro -/// instead of implementing everything in rustc_middle. +/// This trait lets `HashStable` and `derive(HashStable_Generic)` be used in +/// this crate (and other crates upstream of `rustc_middle`), while leaving +/// certain operations to be defined in `rustc_middle` where more things are +/// visible. pub trait HashStableContext { /// The main event: stable hashing of a span. fn span_hash_stable(&mut self, span: Span, hasher: &mut StableHasher);
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 30bf8dd..53e2527 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs
@@ -1014,6 +1014,7 @@ generic_assert, generic_associated_types, generic_associated_types_extended, + generic_const_args, generic_const_exprs, generic_const_items, generic_const_parameter_types, @@ -1414,7 +1415,6 @@ on_move, on_unimplemented, opaque, - opaque_generic_const_args, opaque_module_name_placeholder: "<opaque>", ops, opt_out_copy,
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 1dc62cb..d46802b 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs
@@ -24,8 +24,6 @@ #[cfg(test)] mod tests; -use rustc_abi::HashStableContext; - /// The name of rustc's own place to organize libraries. /// /// Used to be `rustc`, now the default is `rustlib`.
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 46bc9bd..d891cb3 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
@@ -255,7 +255,7 @@ fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> { let mut p = FmtPrinter::new(infcx.tcx, ns); let ty_getter = move |ty_vid| { - if infcx.probe_ty_var(ty_vid).is_ok() { + if infcx.try_resolve_ty_var(ty_vid).is_ok() { warn!("resolved ty var in error message"); }
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/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bdad1b2..94ce763 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -676,21 +676,10 @@ pub fn try_evaluate_const<'tcx>( (args, typing_env) } - Some(ty::AnonConstKind::OGCA) => { - if infcx.typing_mode() != TypingMode::PostAnalysis { - // OGCA anon consts should be treated as always having generics - // during anything before codegen (or maybe MIR opts too). - return Err(EvaluateConstErr::HasGenericsOrInfers); - } - - if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { - return Err(EvaluateConstErr::HasGenericsOrInfers); - } - - let typing_env = ty::TypingEnv::fully_monomorphized(); - (uv.args, typing_env) - } - Some(ty::AnonConstKind::MCG) | Some(ty::AnonConstKind::NonTypeSystem) | None => { + Some(ty::AnonConstKind::GCA) + | Some(ty::AnonConstKind::MCG) + | Some(ty::AnonConstKind::NonTypeSystem) + | None => { // We are only dealing with "truly" generic/uninferred constants here: // - GCEConsts have been handled separately // - Repeat expr count back compat consts have also been handled separately
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_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 1202ed2..1bfe6e9 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -282,7 +282,6 @@ fn from(err: &LayoutError<'tcx>) -> Self { | LayoutError::InvalidSimd { .. } | LayoutError::NormalizationFailure(..) => Self::UnknownLayout, LayoutError::SizeOverflow(..) => Self::SizeOverflow, - LayoutError::Cycle(err) => Self::TypeError(*err), } } }
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/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 9786608..2877364 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -210,9 +210,9 @@ pub enum AnonConstKind { GCE, /// stable `min_const_generics` anon consts are not allowed to use any generic parameters MCG, - /// `feature(opaque_generic_const_args)` anon consts are allowed to use arbitrary + /// `feature(generic_const_args)` anon consts are allowed to use arbitrary /// generic parameters in scope, but only if they syntactically reference them. - OGCA, + GCA, /// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters /// but must not depend on the actual instantiation. See #76200 for more information RepeatExprCount,
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6962a7a..f311298 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs
@@ -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); @@ -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/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index e0c6c77..535af27 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs
@@ -926,9 +926,10 @@ fn clear_dependent_provisional_results_for_rerun(&mut self) { /// heads from the stack. This may not necessarily mean that we've actually /// reached a fixpoint for that cycle head, which impacts the way we rebase /// provisional cache entries. -#[derive(Debug)] -enum RebaseReason { +#[derive_where(Debug; X: Cx)] +enum RebaseReason<X: Cx> { NoCycleUsages, + Ambiguity(X::AmbiguityInfo), Overflow, /// We've actually reached a fixpoint. /// @@ -965,7 +966,7 @@ fn rebase_provisional_cache_entries( &mut self, cx: X, stack_entry: &StackEntry<X>, - rebase_reason: RebaseReason, + rebase_reason: RebaseReason<X>, ) { let popped_head_index = self.stack.next_index(); // Rebasing decisions depend only on each provisional entry and the current stack state, @@ -1046,6 +1047,9 @@ fn rebase_provisional_cache_entries( // is not actually equal to the final provisional result. We // need to discard the provisional cache entry in this case. RebaseReason::NoCycleUsages => return false, + RebaseReason::Ambiguity(info) => { + *result = D::propagate_ambiguity(cx, input, info); + } RebaseReason::Overflow => *result = D::fixpoint_overflow_result(cx, input), RebaseReason::ReachedFixpoint(None) => {} RebaseReason::ReachedFixpoint(Some(path_kind)) => { @@ -1362,6 +1366,27 @@ fn evaluate_goal_in_task( return EvaluationResult::finalize(stack_entry, encountered_overflow, result); } + // If computing this goal results in ambiguity with no constraints, + // we do not rerun it. It's incredibly difficult to get a different + // response in the next iteration in this case. These changes would + // likely either be caused by incompleteness or can change the maybe + // cause from ambiguity to overflow. Returning ambiguity always + // preserves soundness and completeness even if the goal is be known + // to succeed or fail. + // + // This prevents exponential blowup affecting multiple major crates. + // As we only get to this branch if we haven't yet reached a fixpoint, + // we also taint all provisional cache entries which depend on the + // current goal. + if let Some(info) = D::is_ambiguous_result(result) { + self.rebase_provisional_cache_entries( + cx, + &stack_entry, + RebaseReason::Ambiguity(info), + ); + return EvaluationResult::finalize(stack_entry, encountered_overflow, result); + }; + // If we've reached the fixpoint step limit, we bail with overflow and taint all // provisional cache entries which depend on the current goal. i += 1;
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 1ee4bff..cfb4588 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs
@@ -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)]
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index bcd9e09..aff10c4 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs
@@ -111,6 +111,7 @@ #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] +#![feature(diagnostic_on_move)] #![feature(dispatch_from_dyn)] #![feature(ergonomic_clones)] #![feature(error_generic_member_access)]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b3e49af..af1eaf2 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs
@@ -261,6 +261,11 @@ macro_rules! acquire { #[rustc_diagnostic_item = "Arc"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] +#[diagnostic::on_move( + message = "the type `{Self}` does not implement `Copy`", + label = "this move could be avoided by cloning the original `{Self}`, which is inexpensive", + note = "consider using `Arc::clone`" +)] pub struct Arc< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
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/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/lib.rs b/library/core/src/lib.rs index 35f93d8f..3122951 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. @@ -227,6 +236,8 @@ pub mod autodiff { #[unstable(feature = "contracts", issue = "128044")] pub mod contracts; +#[unstable(feature = "derive_macro_global_path", issue = "154645")] +pub use crate::macros::builtin::derive; #[stable(feature = "cfg_select", since = "1.95.0")] pub use crate::macros::cfg_select;
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7f35e94..33397e5 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs
@@ -1720,7 +1720,7 @@ macro_rules! trace_macros { /// /// See [the reference] for more info. /// - /// [the reference]: ../../../reference/attributes/derive.html + /// [the reference]: ../reference/attributes/derive.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] pub macro derive($item:item) {
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 27dbe6d..e048f8f 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs
@@ -4107,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/prelude/v1.rs b/library/core/src/prelude/v1.rs index f2eb047..6122ab1 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs
@@ -120,9 +120,13 @@ mod panic {} // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] pub use crate::macros::builtin::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, + alloc_error_handler, bench, global_allocator, test, test_case, }; +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use crate::macros::builtin::derive; + #[unstable(feature = "derive_const", issue = "118304")] pub use crate::macros::builtin::derive_const;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1730742..70ccd34 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs
@@ -706,6 +706,8 @@ pub mod arch { reason = "`concat_bytes` is not stable enough for use and is subject to change" )] pub use core::concat_bytes; +#[unstable(feature = "derive_macro_global_path", issue = "154645")] +pub use core::derive; #[stable(feature = "matches_macro", since = "1.42.0")] #[allow(deprecated, deprecated_in_future)] pub use core::matches;
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index ee57e03..aeefec8 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs
@@ -115,9 +115,13 @@ mod panic {} // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] pub use core::prelude::v1::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, + alloc_error_handler, bench, global_allocator, test, test_case, }; +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use core::prelude::v1::derive; + #[unstable(feature = "derive_const", issue = "118304")] pub use core::prelude::v1::derive_const;
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/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ad70fc1..7d40bc9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs
@@ -465,6 +465,15 @@ pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { .unwrap_or(false) } + /// Returns true if item is an associated function with a `self` parameter. + pub(crate) fn has_self_param(&self) -> bool { + if let ItemKind::MethodItem(box Function { decl, .. }, _) = &self.inner.kind { + decl.receiver_type().is_some() + } else { + false + } + } + pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> { let kind = match &self.kind { ItemKind::StrippedItem(k) => k,
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index a453579..d40c950 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs
@@ -433,6 +433,7 @@ fn sidebar_assoc_items<'a>( let mut assoc_consts = Vec::new(); let mut assoc_types = Vec::new(); + let mut assoc_fns = Vec::new(); let mut methods = Vec::new(); if let Some(v) = cache.impls.get(&did) { let mut used_links = FxHashSet::default(); @@ -443,7 +444,12 @@ fn sidebar_assoc_items<'a>( for impl_ in v.iter().map(|i| i.inner_impl()).filter(|i| i.trait_.is_none()) { assoc_consts.extend(get_associated_constants(impl_, used_links_bor)); assoc_types.extend(get_associated_types(impl_, used_links_bor)); - methods.extend(get_methods(impl_, false, used_links_bor, false, cx.tcx())); + methods.extend(get_methods( + impl_, + GetMethodsMode::AlsoCollectAssocFns { assoc_fns: &mut assoc_fns }, + used_links_bor, + cx.tcx(), + )); } // We want links' order to be reproducible so we don't use unstable sort. assoc_consts.sort(); @@ -462,6 +468,11 @@ fn sidebar_assoc_items<'a>( "associatedtype", assoc_types, ), + LinkBlock::new( + Link::new("implementations", "Associated Functions"), + "method", + assoc_fns, + ), LinkBlock::new(Link::new("implementations", "Methods"), "method", methods), ]; @@ -546,7 +557,15 @@ fn sidebar_deref_methods<'a>( i.inner_impl().trait_.is_none() && real_target.is_doc_subtype_of(&i.inner_impl().for_, c) }) - .flat_map(|i| get_methods(i.inner_impl(), true, used_links, deref_mut, cx.tcx())) + .flat_map(|i| { + get_methods( + i.inner_impl(), + GetMethodsMode::Deref { deref_mut }, + used_links, + cx.tcx(), + ) + .collect::<Vec<_>>() + }) .collect::<Vec<_>>(); if !ret.is_empty() { let id = if let Some(target_def_id) = real_target.def_id(c) { @@ -734,69 +753,82 @@ fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String { format!("{url}-{add}") } +enum GetMethodsMode<'r, 'l> { + Deref { deref_mut: bool }, + AlsoCollectAssocFns { assoc_fns: &'r mut Vec<Link<'l>> }, +} + fn get_methods<'a>( i: &'a clean::Impl, - for_deref: bool, + mut mode: GetMethodsMode<'_, 'a>, used_links: &mut FxHashSet<String>, - deref_mut: bool, tcx: TyCtxt<'_>, -) -> Vec<Link<'a>> { - i.items - .iter() - .filter_map(|item| { - if let Some(ref name) = item.name - && item.is_method() - && (!for_deref || super::should_render_item(item, deref_mut, tcx)) - { - Some(Link::new( +) -> impl Iterator<Item = Link<'a>> { + i.items.iter().filter_map(move |item| { + if let Some(ref name) = item.name + && item.is_method() + { + let mut build_link = || { + Link::new( get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)), name.as_str(), - )) - } else { - None + ) + }; + match &mut mode { + &mut GetMethodsMode::Deref { deref_mut } => { + if super::should_render_item(item, deref_mut, tcx) { + Some(build_link()) + } else { + None + } + } + GetMethodsMode::AlsoCollectAssocFns { assoc_fns } => { + if item.has_self_param() { + Some(build_link()) + } else { + assoc_fns.push(build_link()); + None + } + } } - }) - .collect() + } else { + None + } + }) } fn get_associated_constants<'a>( i: &'a clean::Impl, used_links: &mut FxHashSet<String>, -) -> Vec<Link<'a>> { - i.items - .iter() - .filter_map(|item| { - if let Some(ref name) = item.name - && item.is_associated_const() - { - Some(Link::new( - get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)), - name.as_str(), - )) - } else { - None - } - }) - .collect() +) -> impl Iterator<Item = Link<'a>> { + i.items.iter().filter_map(|item| { + if let Some(ref name) = item.name + && item.is_associated_const() + { + Some(Link::new( + get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)), + name.as_str(), + )) + } else { + None + } + }) } fn get_associated_types<'a>( i: &'a clean::Impl, used_links: &mut FxHashSet<String>, -) -> Vec<Link<'a>> { - i.items - .iter() - .filter_map(|item| { - if let Some(ref name) = item.name - && item.is_associated_type() - { - Some(Link::new( - get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)), - name.as_str(), - )) - } else { - None - } - }) - .collect() +) -> impl Iterator<Item = Link<'a>> { + i.items.iter().filter_map(|item| { + if let Some(ref name) = item.name + && item.is_associated_type() + { + Some(Link::new( + get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)), + name.as_str(), + )) + } else { + None + } + }) }
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index 49153d5..4d4222a 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html
@@ -60,11 +60,6 @@ <strong>Note:</strong> Encountered an error during type layout; {#+ #} the type failed to be normalized. {# #} </p> - {% when Err(LayoutError::Cycle(_)) %} - <p> {# #} - <strong>Note:</strong> Encountered an error during type layout; {#+ #} - the type's layout depended on the type's layout itself. {# #} - </p> {% when Err(LayoutError::InvalidSimd {..}) %} <p> {# #} <strong>Note:</strong> Encountered an error during type layout; {#+ #}
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 1e75df7..cf4f7d6 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs
@@ -10,6 +10,7 @@ use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::FatalErrorMarker; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutCx}; @@ -477,7 +478,11 @@ pub fn eval_entry<'tcx>( let res: thread::Result<InterpResult<'_, !>> = panic::catch_unwind(AssertUnwindSafe(|| ecx.run_threads())); let res = res.unwrap_or_else(|panic_payload| { - ecx.handle_ice(); + // rustc "handles" some errors by unwinding with FatalErrorMarker + // (after emitting suitable diagnostics), so do not treat those as ICEs. + if !panic_payload.is::<FatalErrorMarker>() { + ecx.handle_ice(); + } panic::resume_unwind(panic_payload) }); // Obtain the result of the execution. This is always an `Err`, but that doesn't necessarily
diff --git a/src/tools/miri/tests/fail/layout_cycle.rs b/src/tools/miri/tests/fail/layout_cycle.rs index 3e0dd88..8d5f191 100644 --- a/src/tools/miri/tests/fail/layout_cycle.rs +++ b/src/tools/miri/tests/fail/layout_cycle.rs
@@ -1,5 +1,4 @@ -//@error-in-other-file: a cycle occurred during layout computation -//~^ ERROR: cycle detected when computing layout of +//~ ERROR: cycle detected when computing layout of use std::mem;
diff --git a/src/tools/miri/tests/fail/layout_cycle.stderr b/src/tools/miri/tests/fail/layout_cycle.stderr index dae6934..f8d555e 100644 --- a/src/tools/miri/tests/fail/layout_cycle.stderr +++ b/src/tools/miri/tests/fail/layout_cycle.stderr
@@ -9,13 +9,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[E0080]: a cycle occurred during layout computation - --> RUSTLIB/core/src/mem/mod.rs:LL:CC - | -LL | const SIZE: usize = intrinsics::size_of::<Self>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `<S<S<()>> as std::mem::SizedTypeProperties>::SIZE` failed here +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0080, E0391. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0391`.
diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 4ef1775..77cbdcb 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs
@@ -215,7 +215,11 @@ fn check_lines<'a>(path: &Path, content: &'a str, tidy_ctx: &TidyCtx, check: &mu // oh nyooo :( if sorted != section { if !tidy_ctx.is_bless_enabled() { - let base_line_number = content[..offset + start_nl_end].lines().count(); + let pre = &content[..offset + start_nl_end]; + assert_eq!(pre.chars().rev().next(), Some('\n')); + // start_nl_end spans right after the , so it gets ignored by `lines()`, + // but we do want to count it! so we add 1 to the result. + let base_line_number = pre.lines().count() + 1; let line_offset = sorted .lines() .zip(section.lines())
diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index c119298..96dad53 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs
@@ -115,7 +115,7 @@ fn test_rust_bad() { def // tidy-alphabetical-end "; - bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -127,7 +127,7 @@ fn test_toml_bad() { def # tidy-alphabetical-end "; - bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -141,7 +141,7 @@ fn test_features_bad() { #![feature(def)] tidy-alphabetical-end "; - bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -154,7 +154,7 @@ fn test_indent_bad() { def $ tidy-alphabetical-end "; - bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -170,7 +170,7 @@ fn test_split_bad() { ) && tidy-alphabetical-end "; - bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:4: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -339,7 +339,7 @@ fn test_numeric_bad() { item2 # tidy-alphabetical-end "; - bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ # tidy-alphabetical-start @@ -347,7 +347,7 @@ fn test_numeric_bad() { zve64d # tidy-alphabetical-end "; - bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ # tidy-alphabetical-start @@ -355,7 +355,7 @@ fn test_numeric_bad() { 00 # tidy-alphabetical-end "; - bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -394,7 +394,7 @@ fn multiline() { ); tidy-alphabetical-end "; - bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ tidy-alphabetical-start @@ -406,7 +406,7 @@ fn multiline() { a); tidy-alphabetical-end "; - bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
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/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/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/rustdoc-gui/hash-item-expansion.goml b/tests/rustdoc-gui/hash-item-expansion.goml index a7a5c3c..8661641 100644 --- a/tests/rustdoc-gui/hash-item-expansion.goml +++ b/tests/rustdoc-gui/hash-item-expansion.goml
@@ -5,7 +5,7 @@ // We first check that the impl block is open by default. assert-attribute: ("#implementations-list details", {"open": ""}) // To ensure that we will click on the currently hidden method. -assert-text: (".sidebar-elems section .block li > a", "must_use") -click: ".sidebar-elems section .block li > a" +assert-text: (".sidebar-elems section ul:nth-of-type(2) li > a", "must_use") +click: ".sidebar-elems ul:nth-of-type(2) li > a" // We check that the impl block was opened as expected so that we can see the method. assert-attribute: ("#implementations-list > details", {"open": ""})
diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index 3183650..61c1555 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml
@@ -48,7 +48,7 @@ // Check that clicking an element from the sidebar scrolls to the right place // so the target is not obscured by the topbar. click: ".sidebar-menu-toggle" -click: ".sidebar-elems section .block li > a" +click: ".sidebar-elems section ul:nth-of-type(2) li > a" assert-position: ("#method\.must_use", {"y": 45}) // Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
diff --git a/tests/rustdoc-html/sidebar/sidebar-items.rs b/tests/rustdoc-html/sidebar/sidebar-items.rs index 6e13457..bd0893d 100644 --- a/tests/rustdoc-html/sidebar/sidebar-items.rs +++ b/tests/rustdoc-html/sidebar/sidebar-items.rs
@@ -42,6 +42,14 @@ pub struct Bar { waza: u32, } +//@ has foo/struct.Bar.html +//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#implementations"]' 'Associated Functions' +//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#implementations"]' 'Methods' +impl Bar { + pub fn method(&self) {} + pub fn assoc_fn() {} +} + //@ has foo/enum.En.html //@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#variants"]' 'Variants' //@ has - '//*[@class="sidebar-elems"]//section//a' 'Foo'
diff --git a/tests/rustdoc-html/typedef.rs b/tests/rustdoc-html/typedef.rs index 3fdc278..4eae3c7 100644 --- a/tests/rustdoc-html/typedef.rs +++ b/tests/rustdoc-html/typedef.rs
@@ -13,7 +13,7 @@ pub fn method_on_mystruct() {} //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'impl MyTrait for MyAlias' //@ hasraw - 'Alias docstring' //@ has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias' -//@ has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods' +//@ has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Associated Functions' //@ has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations' /// Alias docstring pub type MyAlias = MyStruct;
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/auto-traits/ungated-impl.rs b/tests/ui/auto-traits/ungated-impl.rs deleted file mode 100644 index d46b4b0..0000000 --- a/tests/ui/auto-traits/ungated-impl.rs +++ /dev/null
@@ -1,7 +0,0 @@ -auto trait MyTrait {} -//~^ ERROR auto traits are experimental and possibly buggy - -impl<T> !MyTrait for *mut T {} -//~^ ERROR negative trait bounds are not fully implemented - -fn main() {}
diff --git a/tests/ui/auto-traits/ungated-impl.stderr b/tests/ui/auto-traits/ungated-impl.stderr deleted file mode 100644 index 9d10d46..0000000 --- a/tests/ui/auto-traits/ungated-impl.stderr +++ /dev/null
@@ -1,23 +0,0 @@ -error[E0658]: auto traits are experimental and possibly buggy - --> $DIR/ungated-impl.rs:1:1 - | -LL | auto trait MyTrait {} - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information - = help: add `#![feature(auto_traits)]` 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]: negative trait bounds are not fully implemented; use marker types for now - --> $DIR/ungated-impl.rs:4:9 - | -LL | impl<T> !MyTrait for *mut T {} - | ^^^^^^^^ - | - = note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information - = help: add `#![feature(negative_impls)]` 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/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/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/ogca/basic-fail.rs b/tests/ui/const-generics/gca/basic-different-definitions.rs similarity index 78% rename from tests/ui/const-generics/ogca/basic-fail.rs rename to tests/ui/const-generics/gca/basic-different-definitions.rs index e3db3de..d96c718 100644 --- a/tests/ui/const-generics/ogca/basic-fail.rs +++ b/tests/ui/const-generics/gca/basic-different-definitions.rs
@@ -1,6 +1,8 @@ +//@ check-pass + #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] type const ADD1<const N: usize>: usize = const { N + 1 }; @@ -11,8 +13,6 @@ type const OTHER_ONE: usize = INC::<0>; -// Not definitionally equal. const ARR: [(); ADD1::<0>] = [(); INC::<0>]; -//~^ ERROR mismatched types fn main() {}
diff --git a/tests/ui/const-generics/ogca/basic.rs b/tests/ui/const-generics/gca/basic.rs similarity index 90% rename from tests/ui/const-generics/ogca/basic.rs rename to tests/ui/const-generics/gca/basic.rs index e736484..e80540d 100644 --- a/tests/ui/const-generics/ogca/basic.rs +++ b/tests/ui/const-generics/gca/basic.rs
@@ -2,7 +2,7 @@ #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] type const ADD1<const N: usize>: usize = const { N + 1 };
diff --git a/tests/ui/const-generics/gca/coherence-fail.rs b/tests/ui/const-generics/gca/coherence-fail.rs new file mode 100644 index 0000000..1b181d7 --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-fail.rs
@@ -0,0 +1,28 @@ +#![feature(generic_const_items, min_generic_const_args, generic_const_args)] +#![expect(incomplete_features)] + +// computing the same value with different constant items but same generic arguments should fail +trait Trait1 {} +type const FOO<const N: usize>: usize = const { N + 1 }; +type const BAR<const N: usize>: usize = const { N + 1 }; +impl Trait1 for [(); FOO::<1>] {} +impl Trait1 for [(); BAR::<1>] {} +//~^ ERROR conflicting implementations of trait `Trait1` for type `[(); 2]` + +// computing the same value with the same constant item but different generic arguments should fail +type const DIV2<const N: usize>: usize = const { N / 2 }; +trait Trait2 {} +impl Trait2 for [(); DIV2::<2>] {} +impl Trait2 for [(); DIV2::<3>] {} +//~^ ERROR conflicting implementations of trait `Trait2` for type `[(); 1]` + +// computing the same value with different constant items and different generic arguments should +// fail +trait Trait3 {} +type const ADD1<const N: usize>: usize = const { N + 1 }; +type const SUB1<const N: usize>: usize = const { N - 1 }; +impl Trait3 for [(); ADD1::<1>] {} +impl Trait3 for [(); SUB1::<3>] {} +//~^ ERROR conflicting implementations of trait `Trait3` for type `[(); 2]` + +fn main() {}
diff --git a/tests/ui/const-generics/gca/coherence-fail.stderr b/tests/ui/const-generics/gca/coherence-fail.stderr new file mode 100644 index 0000000..e8122c1 --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-fail.stderr
@@ -0,0 +1,27 @@ +error[E0119]: conflicting implementations of trait `Trait1` for type `[(); 2]` + --> $DIR/coherence-fail.rs:9:1 + | +LL | impl Trait1 for [(); FOO::<1>] {} + | ------------------------------ first implementation here +LL | impl Trait1 for [(); BAR::<1>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 2]` + +error[E0119]: conflicting implementations of trait `Trait2` for type `[(); 1]` + --> $DIR/coherence-fail.rs:16:1 + | +LL | impl Trait2 for [(); DIV2::<2>] {} + | ------------------------------- first implementation here +LL | impl Trait2 for [(); DIV2::<3>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 1]` + +error[E0119]: conflicting implementations of trait `Trait3` for type `[(); 2]` + --> $DIR/coherence-fail.rs:25:1 + | +LL | impl Trait3 for [(); ADD1::<1>] {} + | ------------------------------- first implementation here +LL | impl Trait3 for [(); SUB1::<3>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 2]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/const-generics/gca/coherence-ok.rs b/tests/ui/const-generics/gca/coherence-ok.rs new file mode 100644 index 0000000..447f25b --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-ok.rs
@@ -0,0 +1,14 @@ +//@ check-pass +#![feature(generic_const_items, min_generic_const_args, generic_const_args)] +#![expect(incomplete_features)] + +// computing different values with the same type const item should be fine + +type const ADD1<const N: usize>: usize = const { N + 1 }; + +trait Trait {} + +impl Trait for [(); ADD1::<1>] {} +impl Trait for [(); ADD1::<2>] {} + +fn main() {}
diff --git a/tests/ui/const-generics/ogca/generic-param-rhs.rs b/tests/ui/const-generics/gca/generic-param-rhs.rs similarity index 79% rename from tests/ui/const-generics/ogca/generic-param-rhs.rs rename to tests/ui/const-generics/gca/generic-param-rhs.rs index a62b509..ed4467d 100644 --- a/tests/ui/const-generics/ogca/generic-param-rhs.rs +++ b/tests/ui/const-generics/gca/generic-param-rhs.rs
@@ -1,4 +1,4 @@ -#![feature(min_generic_const_args, opaque_generic_const_args)] +#![feature(min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] fn foo<const N: usize>() {}
diff --git a/tests/ui/const-generics/ogca/generic-param-rhs.stderr b/tests/ui/const-generics/gca/generic-param-rhs.stderr similarity index 100% rename from tests/ui/const-generics/ogca/generic-param-rhs.stderr rename to tests/ui/const-generics/gca/generic-param-rhs.stderr
diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.rs b/tests/ui/const-generics/gca/rhs-but-not-root.rs similarity index 77% rename from tests/ui/const-generics/ogca/rhs-but-not-root.rs rename to tests/ui/const-generics/gca/rhs-but-not-root.rs index bb6c6b6..6c0337d 100644 --- a/tests/ui/const-generics/ogca/rhs-but-not-root.rs +++ b/tests/ui/const-generics/gca/rhs-but-not-root.rs
@@ -1,9 +1,9 @@ #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] -// Anon consts must be the root of the RHS to be OGCA. +// Anon consts must be the root of the RHS to be GCA. type const FOO<const N: usize>: usize = ID::<const { N + 1 }>; //~^ ERROR generic parameters in const blocks are only allowed as the direct value of a `type const` type const ID<const N: usize>: usize = N;
diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr b/tests/ui/const-generics/gca/rhs-but-not-root.stderr similarity index 100% rename from tests/ui/const-generics/ogca/rhs-but-not-root.stderr rename to tests/ui/const-generics/gca/rhs-but-not-root.stderr
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/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/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index f1d5e5c..0060c94 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr
@@ -10,7 +10,7 @@ LL | foo::<{ Some::<u32> { 0: const { N + 1 } } }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr index e080415..b25199b 100644 --- a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr
@@ -4,7 +4,7 @@ LL | T: Trait<const { let a: &'a (); 1 }> | ^^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 1c72afc..f634ec1 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr
@@ -40,7 +40,7 @@ LL | type const ITEM3<const N: usize>: usize = const { N }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:60:31 @@ -48,7 +48,7 @@ LL | T3: Trait<ASSOC = const { N }>, | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:69:58 @@ -56,7 +56,7 @@ LL | struct Default3<const N: usize, const M: usize = const { N }>; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:28:27 @@ -64,7 +64,7 @@ LL | let _3 = [(); const { N }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:33:26 @@ -72,7 +72,7 @@ LL | let _6: [(); const { N }] = todo!(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:11:41 @@ -80,7 +80,7 @@ LL | type Adt3<const N: usize> = Foo<const { N }>; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:19:42 @@ -88,7 +88,7 @@ LL | type Arr3<const N: usize> = [(); const { N }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 13 previous errors
diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr index 1c841e3..cf5974f 100644 --- a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr
@@ -9,7 +9,7 @@ | LL | impl<const N: usize> S<N> { | ^^^^ - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr index c3e0770..74d8f08 100644 --- a/tests/ui/const-generics/mgca/selftyparam.stderr +++ b/tests/ui/const-generics/mgca/selftyparam.stderr
@@ -4,7 +4,7 @@ LL | fn foo() -> [(); const { let _: Self; 1 }]; | ^^^^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error
diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index 61e9343..694d4c8 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr
@@ -10,7 +10,7 @@ LL | [0; const { size_of::<*mut T>() }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr index 2961c71..3a873ec3 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr
@@ -10,7 +10,7 @@ LL | with_point::<{ Point(const { N + 1 }, N) }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index 95a98d8..a9d4129 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr
@@ -22,7 +22,7 @@ LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 4 previous errors
diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs new file mode 100644 index 0000000..74c945b --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs
@@ -0,0 +1,15 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/152653> +//! <https://github.com/rust-lang/rust/issues/154636> +//@ incremental +#![feature(min_generic_const_args)] +type const R: usize = 1_i32; //~ ERROR: the constant `1` is not of type `usize` +type const U: usize = -1_i32; //~ ERROR: the constant `-1` is not of type `usize` +type const S: bool = 1i32; //~ ERROR: the constant `1` is not of type `bool` +type const T: bool = -1i32; //~ ERROR: the constant `-1` is not of type `bool` + +fn main() { + R; + U; + S; + T; +}
diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr new file mode 100644 index 0000000..b09ac22 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr
@@ -0,0 +1,26 @@ +error: the constant `1` is not of type `usize` + --> $DIR/type_const-mismatched-type-incremental.rs:5:1 + | +LL | type const R: usize = 1_i32; + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: the constant `-1` is not of type `usize` + --> $DIR/type_const-mismatched-type-incremental.rs:6:1 + | +LL | type const U: usize = -1_i32; + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: the constant `1` is not of type `bool` + --> $DIR/type_const-mismatched-type-incremental.rs:7:1 + | +LL | type const S: bool = 1i32; + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: the constant `-1` is not of type `bool` + --> $DIR/type_const-mismatched-type-incremental.rs:8:1 + | +LL | type const T: bool = -1i32; + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: aborting due to 4 previous errors +
diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 475d2cf..0c88fbf 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr
@@ -4,7 +4,7 @@ LL | type const FREE1<T>: usize = const { std::mem::size_of::<T>() }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic-expr.rs:8:51 @@ -12,7 +12,7 @@ LL | type const FREE2<const I: usize>: usize = const { I + 1 }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr index e13d6fb..78e38d8 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr
@@ -4,7 +4,7 @@ LL | type const N1<T>: usize = const { std::mem::size_of::<T>() }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:15:52 @@ -12,7 +12,7 @@ LL | type const N2<const I: usize>: usize = const { I + 1 }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:17:40 @@ -20,7 +20,7 @@ LL | type const N3: usize = const { 2 & X }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 3 previous errors
diff --git a/tests/ui/const-generics/ogca/basic-fail.stderr b/tests/ui/const-generics/ogca/basic-fail.stderr deleted file mode 100644 index b1808de..0000000 --- a/tests/ui/const-generics/ogca/basic-fail.stderr +++ /dev/null
@@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/basic-fail.rs:15:30 - | -LL | const ARR: [(); ADD1::<0>] = [(); INC::<0>]; - | --------------- ^^^^^^^^^^^^^^ expected an array with a size of const { N + 1 }, found one with a size of const { N + 1 } - | | - | expected because of the type of the constant - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs deleted file mode 100644 index bb20c04..0000000 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.rs +++ /dev/null
@@ -1,18 +0,0 @@ -//@ check-fail - -#![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] -#![expect(incomplete_features)] - -type const FOO<const N: usize>: usize = const { N + 1 }; - -type const BAR<const N: usize>: usize = const { N + 1 }; - -trait Trait {} - -impl Trait for [(); FOO::<1>] {} -impl Trait for [(); BAR::<1>] {} -//~^ ERROR conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` -impl Trait for [(); BAR::<2>] {} -//~^ 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 deleted file mode 100644 index 919a0c8..0000000 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.stderr +++ /dev/null
@@ -1,20 +0,0 @@ -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/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/enum/enum_u8_variant.rs b/tests/ui/enum/enum_u8_variant.rs new file mode 100644 index 0000000..f61d42c --- /dev/null +++ b/tests/ui/enum/enum_u8_variant.rs
@@ -0,0 +1,14 @@ +//@ run-pass +//Test that checks pattern matching works correctly on a repr(u8) enum +// whose only variant contains an inner 'u8' field +//https://github.com/rust-lang/rust/issues/34571 +#[repr(u8)] +enum Foo { + Foo(#[allow(dead_code)] u8), +} + +fn main() { + match Foo::Foo(1) { + _ => () + } +}
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/extern/bad-external-async-fn-issue-146754.rs b/tests/ui/extern/bad-external-async-fn-issue-146754.rs new file mode 100644 index 0000000..394341c --- /dev/null +++ b/tests/ui/extern/bad-external-async-fn-issue-146754.rs
@@ -0,0 +1,8 @@ +//@ edition:2024 +#![crate_type = "lib"] + +unsafe extern "C" { + async fn function() -> [(); || {}]; + //~^ ERROR functions in `extern` blocks cannot have `async` qualifier + //~^^ ERROR mismatched types +}
diff --git a/tests/ui/extern/bad-external-async-fn-issue-146754.stderr b/tests/ui/extern/bad-external-async-fn-issue-146754.stderr new file mode 100644 index 0000000..2a04b23 --- /dev/null +++ b/tests/ui/extern/bad-external-async-fn-issue-146754.stderr
@@ -0,0 +1,21 @@ +error: functions in `extern` blocks cannot have `async` qualifier + --> $DIR/bad-external-async-fn-issue-146754.rs:5:5 + | +LL | unsafe extern "C" { + | ----------------- in this `extern` block +LL | async fn function() -> [(); || {}]; + | ^^^^^ help: remove the `async` qualifier + +error[E0308]: mismatched types + --> $DIR/bad-external-async-fn-issue-146754.rs:5:33 + | +LL | async fn function() -> [(); || {}]; + | ^^^^^ expected `usize`, found closure + | + = note: expected type `usize` + found closure `{closure@$DIR/bad-external-async-fn-issue-146754.rs:5:33: 5:35}` + = note: array length can only be `usize` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/feature-gates/feature-gate-auto-traits.rs b/tests/ui/feature-gates/feature-gate-auto-traits.rs index aab9e78..e900fb8 100644 --- a/tests/ui/feature-gates/feature-gate-auto-traits.rs +++ b/tests/ui/feature-gates/feature-gate-auto-traits.rs
@@ -1,12 +1,5 @@ -// Test that default and negative trait implementations are gated by -// `auto_traits` feature gate +auto trait DummyAutoTrait {} //~ ERROR auto traits are experimental and possibly buggy -struct DummyStruct; - -auto trait AutoDummyTrait {} -//~^ ERROR auto traits are experimental and possibly buggy - -impl !AutoDummyTrait for DummyStruct {} -//~^ ERROR negative trait bounds are not fully implemented; use marker types for now +pub unsafe auto trait AnotherAutoTrait {} //~ ERROR auto traits are experimental and possibly buggy fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-auto-traits.stderr b/tests/ui/feature-gates/feature-gate-auto-traits.stderr index 8fa5168..d476b4f 100644 --- a/tests/ui/feature-gates/feature-gate-auto-traits.stderr +++ b/tests/ui/feature-gates/feature-gate-auto-traits.stderr
@@ -1,21 +1,21 @@ error[E0658]: auto traits are experimental and possibly buggy - --> $DIR/feature-gate-auto-traits.rs:6:1 + --> $DIR/feature-gate-auto-traits.rs:1:1 | -LL | auto trait AutoDummyTrait {} +LL | auto trait DummyAutoTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information = help: add `#![feature(auto_traits)]` 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]: negative trait bounds are not fully implemented; use marker types for now - --> $DIR/feature-gate-auto-traits.rs:9:6 +error[E0658]: auto traits are experimental and possibly buggy + --> $DIR/feature-gate-auto-traits.rs:3:1 | -LL | impl !AutoDummyTrait for DummyStruct {} - | ^^^^^^^^^^^^^^^ +LL | pub unsafe auto trait AnotherAutoTrait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information - = help: add `#![feature(negative_impls)]` to the crate attributes to enable + = note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information + = help: add `#![feature(auto_traits)]` 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
diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-generic-const-args.rs similarity index 80% rename from tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs rename to tests/ui/feature-gates/feature-gate-generic-const-args.rs index f18f59c..b62e7fb 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.rs
@@ -3,6 +3,6 @@ type const INC<const N: usize>: usize = const { N + 1 }; //~^ ERROR generic parameters may not be used in const operations -//~| HELP add `#![feature(opaque_generic_const_args)]` +//~| HELP add `#![feature(generic_const_args)]` fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr new file mode 100644 index 0000000..27794b4 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr
@@ -0,0 +1,10 @@ +error: generic parameters may not be used in const operations + --> $DIR/feature-gate-generic-const-args.rs:4:49 + | +LL | type const INC<const N: usize>: usize = const { N + 1 }; + | ^ + | + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 1 previous error +
diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr deleted file mode 100644 index ef771e7..0000000 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr +++ /dev/null
@@ -1,10 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/feature-gate-opaque-generic-const-args.rs:4:49 - | -LL | type const INC<const N: usize>: usize = const { N + 1 }; - | ^ - | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items - -error: aborting due to 1 previous error -
diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs index e7b2eca..6382af3 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs
@@ -12,7 +12,7 @@ mod unknown { pub macro rustc() {} } fn f() {} #[unknown::rustc] -//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~^ ERROR attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler //~| ERROR expected attribute, found macro `unknown::rustc` //~| NOTE not an attribute fn g() {}
diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index d586038..bc0db8b 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr
@@ -10,7 +10,7 @@ LL | #[rustc::unknown] | ^^^^^^^^^^^^^^ not an attribute -error: attributes starting with `rustc` are reserved for use by the `rustc` compiler +error: attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/feature-gate-rustc-attrs.rs:14:12 | LL | #[unknown::rustc]
diff --git a/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs b/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs index 0ccbaf1..01f44df 100644 --- a/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs +++ b/tests/ui/feature-gates/soft-feature-gate-auto_traits.rs
@@ -1,6 +1,6 @@ -// 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. +// For historical reasons, auto traits don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. // As part of this, move these test cases into `feature-gate-auto-traits.rs`. //@ check-pass
diff --git a/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs b/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs index 8ab0e80..9fdaa7a 100644 --- a/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs +++ b/tests/ui/feature-gates/soft-feature-gate-box_patterns.rs
@@ -1,6 +1,6 @@ -// 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. +// For historical reasons, box patterns don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. // As part of this, move these test cases into `feature-gate-box_patterns.rs`. //@ check-pass
diff --git a/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs b/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs index 7d2d485..dbc0b94 100644 --- a/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs +++ b/tests/ui/feature-gates/soft-feature-gate-decl_macro.rs
@@ -1,6 +1,6 @@ -// 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. +// For historical reasons, decl macros 2.0 don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. // As part of this, move these test cases into `feature-gate-decl_macro.rs`. //@ check-pass
diff --git a/tests/ui/feature-gates/soft-feature-gate-negative_impls.rs b/tests/ui/feature-gates/soft-feature-gate-negative_impls.rs new file mode 100644 index 0000000..0071ce6 --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-negative_impls.rs
@@ -0,0 +1,12 @@ +// For historical reasons, negative impls don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. +// As part of this, move these test cases into `feature-gate-negative_impls.rs`. +//@ check-pass + +#[cfg(false)] +impl !Trait for () {} +//~^ WARN negative impls 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-negative_impls.stderr b/tests/ui/feature-gates/soft-feature-gate-negative_impls.stderr new file mode 100644 index 0000000..35e125c --- /dev/null +++ b/tests/ui/feature-gates/soft-feature-gate-negative_impls.stderr
@@ -0,0 +1,14 @@ +warning: negative impls are experimental + --> $DIR/soft-feature-gate-negative_impls.rs:8:6 + | +LL | impl !Trait for () {} + | ^ + | + = note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information + = help: add `#![feature(negative_impls)]` 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: 1 warning 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 index 553e883..7f929f5 100644 --- a/tests/ui/feature-gates/soft-feature-gate-trait_alias.rs +++ b/tests/ui/feature-gates/soft-feature-gate-trait_alias.rs
@@ -1,6 +1,6 @@ -// 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. +// For historical reasons, trait aliases don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. // As part of this, move these test cases into `feature-gate-trait-alias.rs`. //@ check-pass
diff --git a/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs b/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs index aa51e60..3f439d0 100644 --- a/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs +++ b/tests/ui/feature-gates/soft-feature-gate-try_blocks.rs
@@ -1,6 +1,6 @@ -// 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. +// For historical reasons, try blocks don't have an erroring pre-expansion feature gate. +// We're now at least issuing a warning for those that only exist before macro expansion. +// FIXME(#154045): Turn this pre-expansion warning into an error and remove the post-expansion gate. // As part of this, move these test cases into `feature-gate-try_blocks.rs`. //@ edition: 2018 //@ check-pass
diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index deab31c..4a05322 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr
@@ -46,6 +46,16 @@ LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope +error[E0658]: const trait impls are experimental + --> $DIR/bound-modifiers.rs:12:32 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^^^ + | + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` 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]: `async` trait bounds are unstable --> $DIR/bound-modifiers.rs:7:32 | @@ -57,16 +67,6 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: const trait impls are experimental - --> $DIR/bound-modifiers.rs:12:32 - | -LL | fn constness() -> impl Sized + const use<> {} - | ^^^^^ - | - = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information - = help: add `#![feature(const_trait_impl)]` 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 10 previous errors Some errors have detailed explanations: E0405, E0658.
diff --git a/tests/ui/imports/global-derive-path.rs b/tests/ui/imports/global-derive-path.rs new file mode 100644 index 0000000..5f0a6bb8 --- /dev/null +++ b/tests/ui/imports/global-derive-path.rs
@@ -0,0 +1,10 @@ +//@ edition: 2024 +//@ check-pass +#![crate_type = "lib"] +#![feature(derive_macro_global_path)] + +#[::core::derive(Clone)] +struct Y; + +#[::std::derive(Clone)] +struct X;
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/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 9e974c8..17ef331 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -13,6 +13,8 @@ | = 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/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs deleted file mode 100644 index 54ed408..0000000 --- a/tests/ui/issues/issue-28625.rs +++ /dev/null
@@ -1,22 +0,0 @@ -//@ normalize-stderr: "\d+ bits" -> "N bits" - -trait Bar { - type Bar; -} - -struct ArrayPeano<T: Bar> { - data: T::Bar, -} - -fn foo<T>(a: &ArrayPeano<T>) -> &[T] where T: Bar { - unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes -} - -impl Bar for () { - type Bar = (); -} - -fn main() { - let x: ArrayPeano<()> = ArrayPeano { data: () }; - foo(&x); -}
diff --git a/tests/ui/issues/issue-34571.rs b/tests/ui/issues/issue-34571.rs deleted file mode 100644 index 1242a9e..0000000 --- a/tests/ui/issues/issue-34571.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-pass -#[repr(u8)] -enum Foo { - Foo(#[allow(dead_code)] u8), -} - -fn main() { - match Foo::Foo(1) { - _ => () - } -}
diff --git a/tests/ui/issues/issue-49973.rs b/tests/ui/issues/issue-49973.rs deleted file mode 100644 index c8f7c8e..0000000 --- a/tests/ui/issues/issue-49973.rs +++ /dev/null
@@ -1,11 +0,0 @@ -//@ run-pass -#[derive(Debug)] -#[repr(i32)] -enum E { - Min = -2147483648i32, - _Max = 2147483647i32, -} - -fn main() { - assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); -}
diff --git a/tests/ui/layout/layout-cycle.rs b/tests/ui/layout/layout-cycle.rs index b38bd52..846ce08 100644 --- a/tests/ui/layout/layout-cycle.rs +++ b/tests/ui/layout/layout-cycle.rs
@@ -1,6 +1,5 @@ //@ build-fail //~^ ERROR: cycle detected when computing layout of -//~? ERROR: a cycle occurred during layout computation // Issue #111176 -- ensure that we do not emit ICE on layout cycles
diff --git a/tests/ui/layout/layout-cycle.stderr b/tests/ui/layout/layout-cycle.stderr index e05ff61..28c35d4 100644 --- a/tests/ui/layout/layout-cycle.stderr +++ b/tests/ui/layout/layout-cycle.stderr
@@ -6,18 +6,6 @@ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL = 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[E0080]: a cycle occurred during layout computation - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: evaluation of `<S<S<()>> as std::mem::SizedTypeProperties>::SIZE` failed here +error: aborting due to 1 previous error -note: the above error was encountered while instantiating `fn std::mem::size_of::<S<S<()>>>` - --> $DIR/layout-cycle.rs:26:5 - | -LL | mem::size_of::<S<T>>() - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0080, E0391. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/layout/opt-repr-i32-min.rs b/tests/ui/layout/opt-repr-i32-min.rs new file mode 100644 index 0000000..10e54c6 --- /dev/null +++ b/tests/ui/layout/opt-repr-i32-min.rs
@@ -0,0 +1,14 @@ +//@ run-pass +// Tests that Option<E> niche optimisation does not incorrectly use i32::MIN +// as the None niche when a repr(i32) enum variant already holds that value. +// github.com/rust-lang/rust/issues/49973 +#[derive(Debug)] +#[repr(i32)] +enum E { + Min = -2147483648i32, + _Max = 2147483647i32, +} + +fn main() { + assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); +}
diff --git a/tests/ui/layout/post-mono-layout-cycle.stderr b/tests/ui/layout/post-mono-layout-cycle.stderr index 7f246b3..b9b1b98 100644 --- a/tests/ui/layout/post-mono-layout-cycle.stderr +++ b/tests/ui/layout/post-mono-layout-cycle.stderr
@@ -5,12 +5,6 @@ = note: cycle used when computing layout of `core::option::Option<Wrapper<()>>` = 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 -note: the above error was encountered while instantiating `fn abi::<()>` - --> $DIR/post-mono-layout-cycle.rs:19:5 - | -LL | abi::<T>(None); - | ^^^^^^^^^^^^^^ - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/issues/issue-38160.rs b/tests/ui/macros/macro-const-stringify.rs similarity index 64% rename from tests/ui/issues/issue-38160.rs rename to tests/ui/macros/macro-const-stringify.rs index 0395aea..e2a110f 100644 --- a/tests/ui/issues/issue-38160.rs +++ b/tests/ui/macros/macro-const-stringify.rs
@@ -1,19 +1,16 @@ //@ check-pass - +//Tests to check that a macro generating an impl block with stringify for a trait associated const +//https://github.com/rust-lang/rust/issues/38160 trait MyTrait { const MY_CONST: &'static str; } - macro_rules! my_macro { () => { struct MyStruct; - impl MyTrait for MyStruct { const MY_CONST: &'static str = stringify!(abc); } } } - my_macro!(); - fn main() {}
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index af2ba7a..46f5059 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs
@@ -9,12 +9,13 @@ #![feature(const_trait_impl)] #![feature(coroutines)] #![feature(decl_macro)] +#![feature(macro_guard_matcher)] #![feature(more_qualified_paths)] #![feature(never_patterns)] +#![feature(specialization)] #![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
diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.rs b/tests/ui/moves/arc-consumed-in-looped-closure.rs index 8700c78..6016850 100644 --- a/tests/ui/moves/arc-consumed-in-looped-closure.rs +++ b/tests/ui/moves/arc-consumed-in-looped-closure.rs
@@ -19,7 +19,7 @@ fn execute<F>(&self, f: F) } fn main() { - let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because + let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE this move could be avoided by cloning the original `Arc`, which is inexpensive let pool = ThreadPool { workers: vec![], queue: Arc::new(()), @@ -29,6 +29,7 @@ fn main() { // let results = Arc::clone(&results); // Forgot this. pool.execute(move || { //~ ERROR E0382 //~^ NOTE value moved into closure here, in previous iteration of loop + //~| NOTE consider using `Arc::clone` //~| HELP consider cloning the value before moving it into the closure let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure r.push(i);
diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.stderr b/tests/ui/moves/arc-consumed-in-looped-closure.stderr index 47d6fd6..462eb27 100644 --- a/tests/ui/moves/arc-consumed-in-looped-closure.stderr +++ b/tests/ui/moves/arc-consumed-in-looped-closure.stderr
@@ -1,8 +1,8 @@ -error[E0382]: use of moved value: `results` +error[E0382]: the type `Arc` does not implement `Copy` --> $DIR/arc-consumed-in-looped-closure.rs:30:22 | LL | let results = Arc::new(Mutex::new(Vec::new())); - | ------- move occurs because `results` has type `Arc<std::sync::Mutex<Vec<i32>>>`, which does not implement the `Copy` trait + | ------- this move could be avoided by cloning the original `Arc`, which is inexpensive ... LL | for i in 0..20 { | -------------- inside of this loop @@ -13,12 +13,14 @@ LL | let mut r = results.lock().unwrap(); | ------- use occurs due to use in closure | + = note: consider using `Arc::clone` help: consider cloning the value before moving it into the closure | LL ~ let value = results.clone(); LL ~ pool.execute(move || { LL | LL | +LL | LL ~ let mut r = value.lock().unwrap(); |
diff --git a/tests/ui/moves/no-capture-arc.rs b/tests/ui/moves/no-capture-arc.rs index 9c957a4..eea9858 100644 --- a/tests/ui/moves/no-capture-arc.rs +++ b/tests/ui/moves/no-capture-arc.rs
@@ -9,7 +9,7 @@ fn main() { assert_eq!((*arc_v)[3], 4); }); - assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v` + assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy` println!("{:?}", *arc_v); }
diff --git a/tests/ui/moves/no-capture-arc.stderr b/tests/ui/moves/no-capture-arc.stderr index 6d4a867..e0fce32 100644 --- a/tests/ui/moves/no-capture-arc.stderr +++ b/tests/ui/moves/no-capture-arc.stderr
@@ -1,8 +1,8 @@ -error[E0382]: borrow of moved value: `arc_v` +error[E0382]: the type `Arc` does not implement `Copy` --> $DIR/no-capture-arc.rs:12:18 | LL | let arc_v = Arc::new(v); - | ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait + | ----- this move could be avoided by cloning the original `Arc`, which is inexpensive LL | LL | thread::spawn(move|| { | ------ value moved into closure here @@ -12,6 +12,7 @@ LL | assert_eq!((*arc_v)[2], 3); | ^^^^^ value borrowed here after move | + = note: consider using `Arc::clone` = note: borrow occurs due to deref coercion to `Vec<i32>` help: consider cloning the value before moving it into the closure |
diff --git a/tests/ui/moves/no-reuse-move-arc.fixed b/tests/ui/moves/no-reuse-move-arc.fixed index a5dac8c..c9094cb 100644 --- a/tests/ui/moves/no-reuse-move-arc.fixed +++ b/tests/ui/moves/no-reuse-move-arc.fixed
@@ -11,7 +11,7 @@ assert_eq!((*value)[3], 4); }); - assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v` + assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy` println!("{:?}", *arc_v); }
diff --git a/tests/ui/moves/no-reuse-move-arc.rs b/tests/ui/moves/no-reuse-move-arc.rs index 0d67aa5..2945222 100644 --- a/tests/ui/moves/no-reuse-move-arc.rs +++ b/tests/ui/moves/no-reuse-move-arc.rs
@@ -10,7 +10,7 @@ fn main() { assert_eq!((*arc_v)[3], 4); }); - assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v` + assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy` println!("{:?}", *arc_v); }
diff --git a/tests/ui/moves/no-reuse-move-arc.stderr b/tests/ui/moves/no-reuse-move-arc.stderr index aff979a..8f56b32 100644 --- a/tests/ui/moves/no-reuse-move-arc.stderr +++ b/tests/ui/moves/no-reuse-move-arc.stderr
@@ -1,8 +1,8 @@ -error[E0382]: borrow of moved value: `arc_v` +error[E0382]: the type `Arc` does not implement `Copy` --> $DIR/no-reuse-move-arc.rs:13:18 | LL | let arc_v = Arc::new(v); - | ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait + | ----- this move could be avoided by cloning the original `Arc`, which is inexpensive LL | LL | thread::spawn(move|| { | ------ value moved into closure here @@ -12,6 +12,7 @@ LL | assert_eq!((*arc_v)[2], 3); | ^^^^^ value borrowed here after move | + = note: consider using `Arc::clone` = note: borrow occurs due to deref coercion to `Vec<i32>` help: consider cloning the value before moving it into the closure |
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/trait-item-with-defaultness-pass.rs b/tests/ui/parser/trait-item-with-defaultness-pass.rs index 164d0b1..e8452fc 100644 --- a/tests/ui/parser/trait-item-with-defaultness-pass.rs +++ b/tests/ui/parser/trait-item-with-defaultness-pass.rs
@@ -1,4 +1,5 @@ //@ check-pass +#![feature(specialization)] fn main() {}
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/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr deleted file mode 100644 index d097b80..0000000 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr +++ /dev/null
@@ -1,21 +0,0 @@ -error[E0391]: cycle detected when computing layout of `Foo` - | - = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`... - = note: ...which again requires computing layout of `Foo`, completing the cycle -note: cycle used when const-evaluating + checking `_` - --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 - | -LL | const _: *const Foo = 0 as _; - | ^^^^^^^^^^^^^^^^^^^ - = 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[E0080]: a cycle occurred during layout computation - --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 - | -LL | const _: *const Foo = 0 as _; - | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0080, E0391. -For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr deleted file mode 100644 index d097b80..0000000 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr +++ /dev/null
@@ -1,21 +0,0 @@ -error[E0391]: cycle detected when computing layout of `Foo` - | - = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`... - = note: ...which again requires computing layout of `Foo`, completing the cycle -note: cycle used when const-evaluating + checking `_` - --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 - | -LL | const _: *const Foo = 0 as _; - | ^^^^^^^^^^^^^^^^^^^ - = 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[E0080]: a cycle occurred during layout computation - --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 - | -LL | const _: *const Foo = 0 as _; - | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0080, E0391. -For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.rs b/tests/ui/sized/stack-overflow-trait-infer-98842.rs index 1c9f6c5..d6522e3 100644 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.rs +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.rs
@@ -2,8 +2,7 @@ // issue: rust-lang/rust#98842 //@ check-fail //@ edition:2021 -//@ stderr-per-bitwidth -//~^^^^^ ERROR cycle detected when computing layout of `Foo` +//~^^^^ ERROR cycle detected when computing layout of `Foo` // If the inner `Foo` is named through an associated type, // the "infinite size" error does not occur. @@ -12,6 +11,5 @@ // and it will infinitely recurse somewhere trying to figure out the // size of this pointer (is my guess): const _: *const Foo = 0 as _; -//~^ ERROR a cycle occurred during layout computation pub fn main() {}
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr new file mode 100644 index 0000000..5557a6fc --- /dev/null +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr
@@ -0,0 +1,14 @@ +error[E0391]: cycle detected when computing layout of `Foo` + | + = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`... + = note: ...which again requires computing layout of `Foo`, completing the cycle +note: cycle used when const-evaluating + checking `_` + --> $DIR/stack-overflow-trait-infer-98842.rs:13:1 + | +LL | const _: *const Foo = 0 as _; + | ^^^^^^^^^^^^^^^^^^^ + = 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/specialization/feature-gate-specialization.rs b/tests/ui/specialization/feature-gate-specialization.rs new file mode 100644 index 0000000..82e467a --- /dev/null +++ b/tests/ui/specialization/feature-gate-specialization.rs
@@ -0,0 +1,21 @@ +trait Trait { + type Ty; + const CT: (); + fn fn_(&self); +} + +impl<T> Trait for T { + default type Ty = (); //~ ERROR specialization is experimental + default const CT: () = (); //~ ERROR specialization is experimental + default fn fn_(&self) {} //~ ERROR specialization is experimental +} + +trait OtherTrait { + fn fn_(); +} + +default impl<T> OtherTrait for T { //~ ERROR specialization is experimental + fn fn_() {} +} + +fn main() {}
diff --git a/tests/ui/specialization/feature-gate-specialization.stderr b/tests/ui/specialization/feature-gate-specialization.stderr new file mode 100644 index 0000000..2efc0fa --- /dev/null +++ b/tests/ui/specialization/feature-gate-specialization.stderr
@@ -0,0 +1,45 @@ +error[E0658]: specialization is experimental + --> $DIR/feature-gate-specialization.rs:8:5 + | +LL | default type Ty = (); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = 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[E0658]: specialization is experimental + --> $DIR/feature-gate-specialization.rs:9:5 + | +LL | default const CT: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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[E0658]: specialization is experimental + --> $DIR/feature-gate-specialization.rs:10:5 + | +LL | default fn fn_(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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[E0658]: specialization is experimental + --> $DIR/feature-gate-specialization.rs:17:1 + | +LL | / default impl<T> OtherTrait for T { +LL | | fn fn_() {} +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 4 previous errors + +For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/specialization/soft-feature-gate-specialization.default.stderr b/tests/ui/specialization/soft-feature-gate-specialization.default.stderr new file mode 100644 index 0000000..f596109 --- /dev/null +++ b/tests/ui/specialization/soft-feature-gate-specialization.default.stderr
@@ -0,0 +1,62 @@ +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:21:5 + | +LL | default type Ty = (); + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:24:5 + | +LL | default const CT: () = (); + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:40:1 + | +LL | default impl Trait for () {} + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:27:5 + | +LL | default fn fn_(); + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:35:1 + | +LL | default fn fn_() {} + | ^^^^^^^ + | + = 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 + = 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: 5 warnings emitted +
diff --git a/tests/ui/specialization/soft-feature-gate-specialization.min.stderr b/tests/ui/specialization/soft-feature-gate-specialization.min.stderr new file mode 100644 index 0000000..aa4ce0c --- /dev/null +++ b/tests/ui/specialization/soft-feature-gate-specialization.min.stderr
@@ -0,0 +1,38 @@ +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:21:5 + | +LL | default type Ty = (); + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:24:5 + | +LL | default const CT: () = (); + | ^^^^^^^ + | + = 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 + = 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: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:40:1 + | +LL | default impl Trait for () {} + | ^^^^^^^ + | + = 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 + = 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: 3 warnings emitted +
diff --git a/tests/ui/specialization/soft-feature-gate-specialization.rs b/tests/ui/specialization/soft-feature-gate-specialization.rs new file mode 100644 index 0000000..46e4b28 --- /dev/null +++ b/tests/ui/specialization/soft-feature-gate-specialization.rs
@@ -0,0 +1,44 @@ +// For historical reasons, item modifier `default` doesn'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 this pre-expansion warning into an error and remove the post-expansion gate. +// As part of this, move these test cases into `feature-gate-specialization.rs`. +// +// Moreover, `specialization` implies `min_specialization` similar to the post-expansion gate. +// +// However, while we only gate `default` *associated* functions only behind `min_specialization` OR +// `specialization` in the post-expansion case, in the pre-expansion case we gate all kinds of +// functions (free, assoc, foreign) behind `min_specialization` OR `specialization` if marked with +// `default` for simplicity of implementation. Ultimately it doesn't matter since we later reject +// `default` on anything other than impls & impl assoc items during semantic analysis. +// +//@ revisions: default min full +//@ check-pass +#![cfg_attr(min, feature(min_specialization))] +#![cfg_attr(full, feature(specialization))] + +#[cfg(false)] +impl Trait for () { + default type Ty = (); + //[default,min]~^ WARN specialization is experimental + //[default,min]~| WARN unstable syntax can change at any point in the future + default const CT: () = (); + //[default,min]~^ WARN specialization is experimental + //[default,min]~| WARN unstable syntax can change at any point in the future + default fn fn_(); + //[default]~^ WARN specialization is experimental + //[default]~| WARN unstable syntax can change at any point in the future +} + +// While free ty/ct/fn items marked `default` are +// semantically malformed we still need to gate the keyword! +#[cfg(false)] +default fn fn_() {} +//[default]~^ WARN specialization is experimental +//[default]~| WARN unstable syntax can change at any point in the future + +#[cfg(false)] +default impl Trait for () {} +//[default,min]~^ WARN specialization is experimental +//[default,min]~| WARN unstable syntax can change at any point in the future + +fn main() {}
diff --git a/tests/ui/specialization/specialization-feature-gate-default.rs b/tests/ui/specialization/specialization-feature-gate-default.rs deleted file mode 100644 index 8bad3ac..0000000 --- a/tests/ui/specialization/specialization-feature-gate-default.rs +++ /dev/null
@@ -1,13 +0,0 @@ -// Check that specialization must be ungated to use the `default` keyword - -// gate-test-specialization - -trait Foo { - fn foo(&self); -} - -impl<T> Foo for T { - default fn foo(&self) {} //~ ERROR specialization is unstable -} - -fn main() {}
diff --git a/tests/ui/specialization/specialization-feature-gate-default.stderr b/tests/ui/specialization/specialization-feature-gate-default.stderr deleted file mode 100644 index 3e651b6..0000000 --- a/tests/ui/specialization/specialization-feature-gate-default.stderr +++ /dev/null
@@ -1,13 +0,0 @@ -error[E0658]: specialization is unstable - --> $DIR/specialization-feature-gate-default.rs:10:5 - | -LL | default fn foo(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index cee5ffc..a1b66c2 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -13,6 +13,8 @@ | = 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/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index aa75c56..38d34f4 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs
@@ -12,7 +12,7 @@ pub trait Foo { impl<T> Foo for T { default fn bar() {} - //~^ ERROR specialization is unstable + //~^ ERROR specialization is experimental //~| NOTE created at }
diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr index a61f785..30d518a 100644 --- a/tests/ui/track-diagnostics/track6.stderr +++ b/tests/ui/track-diagnostics/track6.stderr
@@ -1,4 +1,4 @@ -error[E0658]: specialization is unstable +error[E0658]: specialization is experimental --> $DIR/track6.rs:LL:CC | LL | default fn bar() {}
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/negative-impls/feature-gate-negative_impls.rs b/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs index 8d3f6ff..1b3c5ab 100644 --- a/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs +++ b/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs
@@ -1,3 +1,5 @@ trait MyTrait {} -impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not fully implemented + +impl !MyTrait for u32 {} //~ ERROR negative impls are experimental + fn main() {}
diff --git a/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr b/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr index 1777dfc..36bc5bb 100644 --- a/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr +++ b/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr
@@ -1,5 +1,5 @@ -error[E0658]: negative trait bounds are not fully implemented; use marker types for now - --> $DIR/feature-gate-negative_impls.rs:2:6 +error[E0658]: negative impls are experimental + --> $DIR/feature-gate-negative_impls.rs:3:6 | LL | impl !MyTrait for u32 {} | ^^^^^^^^ @@ -7,6 +7,7 @@ = note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information = help: add `#![feature(negative_impls)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: use marker types for now error: aborting due to 1 previous error
diff --git a/tests/ui/traits/next-solver/global-where-bound-normalization.rs b/tests/ui/traits/next-solver/global-where-bound-normalization.rs deleted file mode 100644 index e57fbf3..0000000 --- a/tests/ui/traits/next-solver/global-where-bound-normalization.rs +++ /dev/null
@@ -1,45 +0,0 @@ -//@ check-pass -//@ compile-flags: -Znext-solver - -// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/257. - -#![feature(rustc_attrs)] -#![expect(internal_features)] -#![rustc_no_implicit_bounds] - -pub trait Bound {} -impl Bound for u8 {} - -pub trait Proj { - type Assoc; -} -impl<U: Bound> Proj for U { - type Assoc = U; -} -impl Proj for MyField { - type Assoc = u8; -} - -// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a -// cycle in the search graph along a particular probe path, which was not an actual solution. -// That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the -// search graph and then ended up floundering the root goal evaluation. -pub trait Field: Proj<Assoc: Bound + 'static> {} - -struct MyField; -impl Field for MyField {} - -trait IdReqField { - type This; -} -impl<F: Field> IdReqField for F { - type This = F; -} - -fn foo() -where - <MyField as IdReqField>::This: Field, -{ -} - -fn main() {}
diff --git a/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.current.stderr b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.current.stderr new file mode 100644 index 0000000..0ad8e34 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.current.stderr
@@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/is-global-norm-concrete-alias-to-generic.rs:26:5 + | +LL | fn foo<T>(x: <(*const T,) as Id>::This) -> (*const T,) + | ----------- expected `(*const T,)` because of return type +... +LL | x + | ^ expected `(*const T,)`, found associated type + | + = note: expected tuple `(*const T,)` + found associated type `<(*const T,) as Id>::This` + = help: consider constraining the associated type `<(*const T,) as Id>::This` to `(*const T,)` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<(*const T,) as Id>::This` is defined as `(*const T,)` in the implementation, but the where-bound `(*const T,)` shadows this definition + see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.next.stderr b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.next.stderr new file mode 100644 index 0000000..f16a178 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.next.stderr
@@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/is-global-norm-concrete-alias-to-generic.rs:26:5 + | +LL | fn foo<T>(x: <(*const T,) as Id>::This) -> (*const T,) + | ----------- expected `(*const T,)` because of return type +... +LL | x + | ^ types differ + | + = note: expected tuple `(*const T,)` + found associated type `<(*const T,) as Id>::This` + = help: consider constraining the associated type `<(*const T,) as Id>::This` to `(*const T,)` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<(*const T,) as Id>::This` is defined as `(*const T,)` in the implementation, but the where-bound `(*const T,)` shadows this definition + see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.rs b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.rs new file mode 100644 index 0000000..c3f8bc7 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-concrete-alias-to-generic.rs
@@ -0,0 +1,29 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// A regression test making sure that where-bounds with concrete aliases +// which normalize to something mentioning a generic parameters are +// considered non-global. +// +// When checking this, we previously didn't recur into types if they didn't +// mention any generic parameters, causing us to consider the `(<() as Id>::This,): Id` +// where-bound as global, even though it normalizes to `(T,): Id`. + +trait Id { + type This; +} + +impl<T> Id for T { + type This = T; +} + +fn foo<T>(x: <(*const T,) as Id>::This) -> (*const T,) +where + (): Id<This = *const T>, + (<() as Id>::This,): Id, +{ + x //~ ERROR mismatched types +} + +fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index f5fd9ce..47d3836 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
@@ -4,6 +4,24 @@ LL | <T as Trait>::Assoc: Trait, | ^^^^^ -error: aborting due to 1 previous error +error[E0275]: overflow evaluating whether `<T as Trait>::Assoc` is well-formed + --> $DIR/normalize-param-env-4.rs:19:26 + | +LL | <T as Trait>::Assoc: Trait, + | ^^^^^ + +error[E0275]: overflow evaluating the requirement `T: Trait` + --> $DIR/normalize-param-env-4.rs:32:19 + | +LL | impls_trait::<T>(); + | ^ + | +note: required by a bound in `impls_trait` + --> $DIR/normalize-param-env-4.rs:15:19 + | +LL | fn impls_trait<T: Trait>() {} + | ^^^^^ required by this bound in `impls_trait` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.rs b/tests/ui/transmute/transmute-associated-type-to-slice.rs new file mode 100644 index 0000000..9521a94 --- /dev/null +++ b/tests/ui/transmute/transmute-associated-type-to-slice.rs
@@ -0,0 +1,23 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/28625> +//@ normalize-stderr: "\d+ bits" -> "N bits" + +trait MyTrait { + type MyType; +} + +struct ArrayPeano<T: MyTrait> { + data: T::MyType, +} + +fn foo<T>(a: &ArrayPeano<T>) -> &[T] where T: MyTrait { + unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes +} + +impl MyTrait for () { + type MyType = (); +} + +fn main() { + let x: ArrayPeano<()> = ArrayPeano { data: () }; + foo(&x); +}
diff --git a/tests/ui/issues/issue-28625.stderr b/tests/ui/transmute/transmute-associated-type-to-slice.stderr similarity index 86% rename from tests/ui/issues/issue-28625.stderr rename to tests/ui/transmute/transmute-associated-type-to-slice.stderr index 3600622..ada3153 100644 --- a/tests/ui/issues/issue-28625.stderr +++ b/tests/ui/transmute/transmute-associated-type-to-slice.stderr
@@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/issue-28625.rs:12:14 + --> $DIR/transmute-associated-type-to-slice.rs:13:14 | LL | unsafe { std::mem::transmute(a) } | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/issues/issue-23477.rs b/tests/ui/transmute/transmute-slice-to-dst.rs similarity index 76% rename from tests/ui/issues/issue-23477.rs rename to tests/ui/transmute/transmute-slice-to-dst.rs index fa69a1d..c1f77be 100644 --- a/tests/ui/issues/issue-23477.rs +++ b/tests/ui/transmute/transmute-slice-to-dst.rs
@@ -1,3 +1,4 @@ +//! regression test for <https://github.com/rust-lang/rust/issues/23477> //@ build-pass //@ compile-flags: -g
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/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/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==