diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 253dff6f8e75c..42e272fdafb5d 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -67,12 +67,6 @@ pub use layout::{FIRST_VARIANT, FieldIdx, LayoutCalculator, LayoutCalculatorErro #[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 71ec1c5042fda..87633cade1b6a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -31,7 +31,8 @@ use rustc_data_structures::tagged_ptr::Tag; 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 @@ impl PartialEq<&[Symbol]> for Path { } } -impl HashStable for Path { +impl HashStable 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 ac3e77b0b5d6f..4178db1bfb09d 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -36,8 +36,3 @@ pub mod visit; 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 8953391ac58bf..06bd6f03e9350 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -14,7 +14,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; 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 @@ impl FromIterator for TokenStream { impl HashStable 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 5fcc8f0161194..6d9fe9870c42e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2683,7 +2683,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { 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 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { 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 830eb3d6d8170..1b615b611258f 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -14,31 +14,22 @@ use crate::errors; /// 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 @@ impl<'a> PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { }) => { // 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { && 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { .. }) => 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { }; 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { }) => { // 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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { 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(); - } - } + + // `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"); } - // `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(); + + // `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(); } - 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"); + // 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).into_iter().flatten() { + sess.dcx().emit_err(errors::NegativeBoundUnsupported { span }); + } + } 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 }); - } + 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 }); } } } - if !visitor.features.negative_bounds() { - for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { - sess.dcx().emit_err(errors::NegativeBoundUnsupported { span }); + // 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(); } } - // 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); + // ----------------------------------------------------------------------------- + // **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_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index e02c4ae6ea695..80d939a25701e 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1134,11 +1134,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { 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_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0bfe012bfe7a4..04f0e7099d840 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 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> { | LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. } | LayoutError::TooGeneric(_) - | LayoutError::ReferencesError(_) - | LayoutError::Cycle(_) => {} + | LayoutError::ReferencesError(_) => {} } err_inval!(Layout(err)) } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 224b7273314b5..a9ad07be319c3 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -520,6 +520,8 @@ declare_features! ( (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 @@ declare_features! ( (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 @@ pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[ /// 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 78bd709dd4844..cae8bb89233b2 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -8,9 +8,9 @@ use rustc_data_structures::stable_hasher::ToStableHashKey; 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 @@ impl IntoDiagArg for Namespace { } } -impl ToStableHashKey for Namespace { +impl ToStableHashKey for Namespace { type KeyType = Namespace; #[inline] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 9c2fec8677854..c2d9f879cd601 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -43,7 +43,6 @@ pub use hir::*; 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 58649a694880b..a157fc0ccbb0c 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::{ 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 ToStableHashKey for BodyId { +impl ToStableHashKey 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 ToStableHashKey for ItemId { +impl ToStableHashKey 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 ToStableHashKey for TraitItemId { +impl ToStableHashKey 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 ToStableHashKey for ImplItemId { +impl ToStableHashKey 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 ToStableHashKey for ForeignItemId { +impl ToStableHashKey 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 @@ impl ToStableHashKey for ForeignItemId // want to pick up on a reference changing its target, so we hash the NodeIds // in "DefPath Mode". -impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerNodes<'tcx> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<'tcx, Hcx: HashStableContext> HashStable 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 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerNodes<' } } -impl HashStable for DelayedLints { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl HashStable 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 for AttributeMap<'tcx> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl<'tcx, Hcx: HashStableContext> HashStable 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 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap } } -impl HashStable for HashIgnoredAttrId { - fn hash_stable(&self, _hcx: &mut HirCtx, _hasher: &mut StableHasher) { +impl HashStable 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 80ef2001cc72e..cfda0300f3f02 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; diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index ea98beb955805..3647c91fb7f15 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 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { 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 58c296d92c24e..a1b169c6a1661 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 91660fc655377..9ec5632a74982 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 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { } } 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 ffff3f979f9e3..064ce4ed4cafe 100644 --- a/compiler/rustc_hir_id/src/lib.rs +++ b/compiler/rustc_hir_id/src/lib.rs @@ -8,7 +8,7 @@ use std::fmt::{self, Debug}; 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 @@ pub const CRATE_HIR_ID: HirId = pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID }; -impl ToStableHashKey for HirId { +impl ToStableHashKey for HirId { type KeyType = (DefPathHash, ItemLocalId); #[inline] diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 89ea6324d8543..87d389a5dea5a 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -341,7 +341,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, '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 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, '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 09403513aa08c..fada30ff30633 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -35,7 +35,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn universe_of_ty(&self, vid: ty::TyVid) -> Option { - match self.probe_ty_var(vid) { + match self.try_resolve_ty_var(vid) { Err(universe) => Some(universe), Ok(_) => None, } @@ -49,7 +49,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn universe_of_ct(&self, ct: ty::ConstVid) -> Option { - match self.probe_const_var(ct) { + match self.try_resolve_const_var(ct) { Err(universe) => Some(universe), Ok(_) => None, } @@ -68,7 +68,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } 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 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'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 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { 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 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { 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 e15b25500bb57..2057eeb875970 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1074,7 +1074,7 @@ impl<'tcx> InferCtxt<'tcx> { /// 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::UniverseIndex> { + pub fn try_resolve_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { use self::type_variable::TypeVariableValue; match self.inner.borrow_mut().type_variables().probe(vid) { @@ -1228,7 +1228,10 @@ impl<'tcx> InferCtxt<'tcx> { value.fold_with(&mut r) } - pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result, ty::UniverseIndex> { + pub fn try_resolve_const_var( + &self, + vid: ty::ConstVid, + ) -> Result, 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 3ab39e83f3123..0b29421a8da8b 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -300,10 +300,10 @@ impl<'tcx> InferCtxt<'tcx> { 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_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index af1d1854fa5a0..1c86d553f9b6a 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -8,11 +8,11 @@ use rustc_data_structures::stable_hasher::{ 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 fa67adb406ed2..adb93e375c32c 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 ad56e462d2934..814b333cfb0f8 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -21,7 +21,7 @@ use rustc_hir::lints::DelayedLint; 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 @@ impl<'hir> Crate<'hir> { } } -impl HashStable for Crate<'_> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { +impl HashStable 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 2e118dc3359fa..0e1cee2970f71 100644 --- a/compiler/rustc_middle/src/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs @@ -6,7 +6,7 @@ use rustc_hir::definitions::DefPathHash; 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 @@ impl<'a> StableHashingContext<'a> { } } -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 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { ); } } - -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/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4ca51c078bef5..46682abc823d8 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 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { 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 @@ impl<'tcx> SizeSkeleton<'tcx> { 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 a497501ef19d5..798b98c5def5c 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -291,7 +291,7 @@ impl<'tcx> Region<'tcx> { } 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/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 5a0f149fd0550..ce2be24adc586 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -78,7 +78,7 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate, I: Interner /// We can simply cache based on the ty itself, because we use /// `ty::BoundVarIndexKind::Canonical`. - cache: HashMap, ty::Ty>, + cache: HashMap, } impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { @@ -316,7 +316,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { (max_universe, self.variables, var_kinds) } - fn inner_fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty { let kind = match t.kind() { ty::Infer(i) => match i { ty::TyVar(vid) => { @@ -475,7 +475,7 @@ impl, I: Interner> TypeFolder for Canonicaliz Region::new_canonical_bound(self.cx(), var) } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.flags().intersects(NEEDS_CANONICAL) { t } else if let Some(&ty) = self.cache.get(&t) { diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index cd42bf8b57b60..1f64f09fe787f 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -16,7 +16,7 @@ use rustc_index::IndexVec; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::{ - self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Ty, + self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, }; use tracing::instrument; @@ -53,7 +53,7 @@ impl ResponseT for inspect::State { pub(super) fn canonicalize_goal( delegate: &D, goal: Goal, - opaque_types: &[(ty::OpaqueTypeKey, Ty)], + opaque_types: &[(ty::OpaqueTypeKey, I::Ty)], ) -> (Vec, CanonicalInput) where D: SolverDelegate, @@ -264,7 +264,7 @@ fn register_region_constraints( fn register_new_opaque_types( delegate: &D, - opaque_types: &[(ty::OpaqueTypeKey, Ty)], + opaque_types: &[(ty::OpaqueTypeKey, I::Ty)], span: I::Span, ) where D: SolverDelegate, diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index 69cebb0a3dc64..c370fd24a1bb3 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -47,7 +47,7 @@ pub enum Conflict { pub fn trait_ref_is_knowable( infcx: &Infcx, trait_ref: ty::TraitRef, - mut lazily_normalize_ty: impl FnMut(ty::Ty) -> Result, E>, + mut lazily_normalize_ty: impl FnMut(I::Ty) -> Result, ) -> Result, E> where Infcx: InferCtxtLike, @@ -115,14 +115,14 @@ impl From for IsFirstInputType { #[derive_where(Debug; I: Interner, T: Debug)] pub enum OrphanCheckErr { - NonLocalInputType(Vec<(ty::Ty, IsFirstInputType)>), + NonLocalInputType(Vec<(I::Ty, IsFirstInputType)>), UncoveredTyParams(UncoveredTyParams), } #[derive_where(Debug; I: Interner, T: Debug)] pub struct UncoveredTyParams { pub uncovered: T, - pub local_ty: Option>, + pub local_ty: Option, } /// Checks whether a trait-ref is potentially implementable by a crate. @@ -222,8 +222,8 @@ pub fn orphan_check_trait_ref( infcx: &Infcx, trait_ref: ty::TraitRef, in_crate: InCrate, - lazily_normalize_ty: impl FnMut(ty::Ty) -> Result, E>, -) -> Result>>, E> + lazily_normalize_ty: impl FnMut(I::Ty) -> Result, +) -> Result>, E> where Infcx: InferCtxtLike, I: Interner, @@ -262,14 +262,14 @@ struct OrphanChecker<'a, Infcx, I: Interner, F> { lazily_normalize_ty: F, /// Ignore orphan check failures and exclusively search for the first local type. search_first_local_ty: bool, - non_local_tys: Vec<(ty::Ty, IsFirstInputType)>, + non_local_tys: Vec<(I::Ty, IsFirstInputType)>, } impl<'a, Infcx, I, F, E> OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike, I: Interner, - F: FnOnce(ty::Ty) -> Result, E>, + F: FnOnce(I::Ty) -> Result, { fn new(infcx: &'a Infcx, in_crate: InCrate, lazily_normalize_ty: F) -> Self { OrphanChecker { @@ -282,15 +282,12 @@ where } } - fn found_non_local_ty(&mut self, t: ty::Ty) -> ControlFlow> { + fn found_non_local_ty(&mut self, t: I::Ty) -> ControlFlow> { self.non_local_tys.push((t, self.in_self_ty.into())); ControlFlow::Continue(()) } - fn found_uncovered_ty_param( - &mut self, - ty: ty::Ty, - ) -> ControlFlow> { + fn found_uncovered_ty_param(&mut self, ty: I::Ty) -> ControlFlow> { if self.search_first_local_ty { return ControlFlow::Continue(()); } @@ -308,15 +305,15 @@ where enum OrphanCheckEarlyExit { NormalizationFailure(E), - UncoveredTyParam(ty::Ty), - LocalTy(ty::Ty), + UncoveredTyParam(I::Ty), + LocalTy(I::Ty), } impl<'a, Infcx, I, F, E> TypeVisitor for OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike, I: Interner, - F: FnMut(ty::Ty) -> Result, E>, + F: FnMut(I::Ty) -> Result, { type Result = ControlFlow>; @@ -324,7 +321,7 @@ where ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: ty::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { let ty = self.infcx.shallow_resolve(ty); let ty = match (self.lazily_normalize_ty)(ty) { Ok(norm_ty) if norm_ty.is_ty_var() => ty, diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 1714ae3dd6b2e..9d5aa8bc124b6 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use rustc_type_ir::solve::{Certainty, Goal, NoSolution}; -use rustc_type_ir::{self as ty, InferCtxtLike, Interner, Ty, TypeFoldable}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable}; pub trait SolverDelegate: Deref + Sized { type Infcx: InferCtxtLike; @@ -70,7 +70,7 @@ pub trait SolverDelegate: Deref + Sized { def_id: ::DefId, args: ::GenericArgs, param_env: ::ParamEnv, - hidden_ty: Ty, + hidden_ty: ::Ty, goals: &mut Vec::Predicate>>, ); @@ -86,8 +86,8 @@ pub trait SolverDelegate: Deref + Sized { fn is_transmutable( &self, - src: Ty, - dst: Ty, + src: ::Ty, + dst: ::Ty, assume: ::Const, ) -> Result; } diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index fe7521c86e9be..83f3bdf01dc83 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -113,7 +113,7 @@ where } } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { match t.kind() { ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) if debruijn.as_usize() + 1 diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index 86bf05bdb57cc..c3c57eccd6eff 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs @@ -1,7 +1,7 @@ use rustc_type_ir::data_structures::DelayedMap; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, + self as ty, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -19,7 +19,7 @@ where delegate: &'a D, /// We're able to use a cache here as the folder does not have any /// mutable state. - cache: DelayedMap, Ty>, + cache: DelayedMap, } pub fn eager_resolve_vars>( @@ -45,7 +45,7 @@ impl, I: Interner> TypeFolder for EagerResolv self.delegate.cx() } - fn fold_ty(&mut self, t: Ty) -> Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { match t.kind() { ty::Infer(ty::TyVar(vid)) => { let resolved = self.delegate.opportunistic_resolve_ty_var(vid); diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index f58318b83625d..34a3673fa60bb 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 derive_where::derive_where; 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, @@ -46,11 +45,11 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty; + fn self_ty(self) -> I::Ty; fn trait_ref(self, cx: I) -> ty::TraitRef; - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self; + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self; fn trait_def_id(self, cx: I) -> I::TraitId; @@ -683,7 +682,7 @@ where // hitting another overflow error something. Add a depth parameter needed later. fn assemble_alias_bound_candidates_recur>( &mut self, - self_ty: ty::Ty, + self_ty: I::Ty, goal: Goal, candidates: &mut Vec>, consider_self_bounds: AliasBoundKind, @@ -1017,13 +1016,13 @@ where struct ReplaceOpaque { cx: I, alias_ty: ty::AliasTy, - self_ty: ty::Ty, + self_ty: I::Ty, } impl TypeFolder for ReplaceOpaque { fn cx(&self) -> I { self.cx } - fn fold_ty(&mut self, ty: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() { if alias_ty == self.alias_ty { return self.self_ty; @@ -1280,34 +1279,40 @@ where ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: ty::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { let ty = self.ecx.replace_bound_vars(ty, &mut self.universes); let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else { return ControlFlow::Break(Err(NoSolution)); }; - 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 @@ where 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/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index cbdf0b0a4cc72..433cad188bb6c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -21,8 +21,8 @@ use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution}; #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait( ecx: &EvalCtxt<'_, D>, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -108,8 +108,8 @@ where pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait( ecx: &EvalCtxt<'_, D>, sizedness: SizedTraitKind, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -186,8 +186,8 @@ where #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait( ecx: &EvalCtxt<'_, D>, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -268,9 +268,9 @@ where // Returns a binder of the tupled inputs types and output type from a builtin callable type. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, goal_kind: ty::ClosureKind, -) -> Result, ty::Ty)>>, NoSolution> { +) -> Result>, NoSolution> { match self_ty.kind() { // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. ty::FnDef(def_id, args) => { @@ -408,13 +408,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable { - pub tupled_inputs_ty: ty::Ty, + pub tupled_inputs_ty: I::Ty, /// Type returned by calling the closure /// i.e. `f()`. - pub output_coroutine_ty: ty::Ty, + pub output_coroutine_ty: I::Ty, /// Type returned by `await`ing the output /// i.e. `f().await`. - pub coroutine_return_ty: ty::Ty, + pub coroutine_return_ty: I::Ty, } // Returns a binder of the tupled inputs types, output type, and coroutine type @@ -424,7 +424,7 @@ pub(in crate::solve) struct AsyncCallableRelevantTypes { // know the kind already, we can short-circuit this check. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, goal_kind: ty::ClosureKind, env_region: I::Region, ) -> Result<(ty::Binder>, Vec), NoSolution> { @@ -608,7 +608,7 @@ fn coroutine_closure_to_certain_coroutine( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs, sig: ty::CoroutineClosureSignature, -) -> ty::Ty { +) -> I::Ty { sig.to_coroutine_given_kind_and_upvars( cx, args.parent_args(), @@ -632,7 +632,7 @@ fn coroutine_closure_to_ambiguous_coroutine( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs, sig: ty::CoroutineClosureSignature, -) -> ty::Ty { +) -> I::Ty { let upvars_projection_def_id = cx.require_lang_item(SolverLangItem::AsyncFnKindUpvars); let tupled_upvars_ty = Ty::new_projection( cx, @@ -664,8 +664,8 @@ fn coroutine_closure_to_ambiguous_coroutine( #[instrument(level = "trace", skip(cx), ret)] pub(in crate::solve) fn extract_fn_def_from_const_callable( cx: I, - self_ty: ty::Ty, -) -> Result<(ty::Binder, ty::Ty)>, I::DefId, I::GenericArgs), NoSolution> { + self_ty: I::Ty, +) -> Result<(ty::Binder, I::DefId, I::GenericArgs), NoSolution> { match self_ty.kind() { ty::FnDef(def_id, args) => { let sig = cx.fn_sig(def_id); @@ -742,7 +742,7 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable( // the old solver, for as long as that exists. pub(in crate::solve) fn const_conditions_for_destruct( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, ) -> Result>, NoSolution> { let destruct_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Destruct); @@ -927,7 +927,7 @@ where struct ReplaceProjectionWith<'a, 'b, I: Interner, D: SolverDelegate> { ecx: &'a mut EvalCtxt<'b, D>, param_env: I::ParamEnv, - self_ty: ty::Ty, + self_ty: I::Ty, mapping: &'a HashMap>>>, nested: Vec>, } @@ -1013,7 +1013,7 @@ where self.ecx.cx() } - fn try_fold_ty(&mut self, ty: ty::Ty) -> Result, Ambiguous> { + fn try_fold_ty(&mut self, ty: I::Ty) -> Result { if let ty::Alias(ty::Projection, alias_ty) = ty.kind() && let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? { diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 9a0a82acbc931..4b1e4b2de571d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -13,7 +13,7 @@ use super::assembly::{Candidate, structural_traits}; use crate::delegate::SolverDelegate; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, - QueryResult, Ty, assembly, + QueryResult, assembly, }; impl assembly::GoalKind for ty::HostEffectPredicate @@ -21,7 +21,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -29,7 +29,7 @@ where self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index d6ed220909732..6841fe1c5124e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -10,7 +10,7 @@ use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind}; use rustc_type_ir::solve::OpaqueTypesJank; use rustc_type_ir::{ - self as ty, CanonicalVarValues, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, + self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; @@ -781,7 +781,7 @@ where region } - pub(super) fn next_ty_infer(&mut self) -> Ty { + pub(super) fn next_ty_infer(&mut self) -> I::Ty { let ty = self.delegate.next_ty_infer(); self.inspect.add_var_value(ty); ty @@ -829,7 +829,7 @@ where term: I::Term, universe_of_term: ty::UniverseIndex, delegate: &'a D, - cache: HashSet>, + cache: HashSet, } impl, I: Interner> ContainsTermOrNotNameable<'_, D, I> { @@ -846,7 +846,7 @@ where for ContainsTermOrNotNameable<'_, D, I> { type Result = ControlFlow<()>; - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { if self.cache.contains(&t) { return ControlFlow::Continue(()); } @@ -1072,7 +1072,7 @@ where self.delegate.resolve_vars_if_possible(value) } - pub(super) fn shallow_resolve(&self, ty: Ty) -> Ty { + pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty { self.delegate.shallow_resolve(ty) } @@ -1092,7 +1092,7 @@ where args } - pub(super) fn register_ty_outlives(&self, ty: Ty, lt: I::Region) { + pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) { self.delegate.register_ty_outlives(ty, lt, self.origin_span); } @@ -1134,8 +1134,8 @@ where pub(super) fn register_hidden_type_in_storage( &mut self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, - ) -> Option> { + hidden_ty: I::Ty, + ) -> Option { self.delegate.register_hidden_type_in_storage(opaque_type_key, hidden_ty, self.origin_span) } @@ -1144,7 +1144,7 @@ where opaque_def_id: I::DefId, opaque_args: I::GenericArgs, param_env: I::ParamEnv, - hidden_ty: Ty, + hidden_ty: I::Ty, ) { let mut goals = Vec::new(); self.delegate.add_item_bounds_for_hidden_type( @@ -1170,8 +1170,8 @@ where pub(super) fn is_transmutable( &mut self, - src: Ty, - dst: Ty, + src: I::Ty, + dst: I::Ty, assume: I::Const, ) -> Result { self.delegate.is_transmutable(dst, src, assume) @@ -1195,7 +1195,7 @@ where pub(crate) fn opaques_with_sub_unified_hidden_type( &self, - self_ty: Ty, + self_ty: I::Ty, ) -> Vec> { if let ty::Infer(ty::TyVar(vid)) = self_ty.kind() { self.delegate.opaques_with_sub_unified_hidden_type(vid) @@ -1389,7 +1389,7 @@ where ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv, normalization_goal_source: GoalSource, - cache: HashMap, Ty>, + cache: HashMap, } impl<'me, 'a, D, I> ReplaceAliasWithInfer<'me, 'a, D, I> @@ -1421,7 +1421,7 @@ where self.ecx.cx() } - fn fold_ty(&mut self, ty: Ty) -> Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { match ty.kind() { ty::Alias(..) if !ty.has_escaping_bound_vars() => { let infer_ty = self.ecx.next_ty_infer(); diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 71b28cf1ad277..58bd7cf663d98 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -24,7 +24,7 @@ mod trait_goals; use derive_where::derive_where; use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Interner, Ty, TyVid, TypingMode}; +use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode}; use tracing::instrument; pub use self::eval_ctxt::{ @@ -88,7 +88,7 @@ where #[instrument(level = "trace", skip(self))] fn compute_type_outlives_goal( &mut self, - goal: Goal>>, + goal: Goal>, ) -> QueryResult { let ty::OutlivesPredicate(ty, lt) = goal.predicate; self.register_ty_outlives(ty, lt); @@ -205,7 +205,7 @@ where #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, - goal: Goal)>, + goal: Goal, ) -> QueryResult { let (ct, ty) = goal.predicate; let ct = self.structurally_normalize_const(goal.param_env, ct)?; @@ -315,8 +315,8 @@ where fn structurally_normalize_ty( &mut self, param_env: I::ParamEnv, - ty: Ty, - ) -> Result, NoSolution> { + ty: I::Ty, + ) -> Result { self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index eb6a1b51421ca..46312be5ea9a9 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 @@ where &mut self, goal: Goal>, ) -> QueryResult { - 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_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 13ed945857db2..13f2ad8f82eba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -125,7 +125,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -133,7 +133,7 @@ where self.alias.trait_ref(cx) } - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 82051b2fea4ef..6589a12c4cc2d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -29,7 +29,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -37,7 +37,7 @@ where self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } @@ -929,7 +929,7 @@ where /// ``` fn consider_builtin_dyn_upcast_candidates( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, a_data: I::BoundExistentialPredicates, a_region: I::Region, b_data: I::BoundExistentialPredicates, @@ -977,7 +977,7 @@ where fn consider_builtin_unsize_to_dyn_candidate( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, b_data: I::BoundExistentialPredicates, b_region: I::Region, ) -> Result, NoSolution> { @@ -1018,7 +1018,7 @@ where fn consider_builtin_upcast_to_principal( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, source: CandidateSource, a_data: I::BoundExistentialPredicates, a_region: I::Region, @@ -1132,9 +1132,9 @@ where /// `#[rustc_deny_explicit_impl]` in this case. fn consider_builtin_array_unsize( &mut self, - goal: Goal, ty::Ty)>, - a_elem_ty: ty::Ty, - b_elem_ty: ty::Ty, + goal: Goal, + a_elem_ty: I::Ty, + b_elem_ty: I::Ty, ) -> Result, NoSolution> { self.eq(goal.param_env, a_elem_ty, b_elem_ty)?; self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) @@ -1156,7 +1156,7 @@ where /// ``` fn consider_builtin_struct_unsize( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, def: I::AdtDef, a_args: I::GenericArgs, b_args: I::GenericArgs, @@ -1319,8 +1319,8 @@ where goal: Goal>, constituent_tys: impl Fn( &EvalCtxt<'_, D>, - ty::Ty, - ) -> Result>>, NoSolution>, + I::Ty, + ) -> Result>, NoSolution>, ) -> Result, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { let goals = @@ -1542,10 +1542,7 @@ where self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info) } - fn try_stall_coroutine( - &mut self, - self_ty: ty::Ty, - ) -> Option, NoSolution>> { + fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option, NoSolution>> { if let ty::Coroutine(def_id, _) = self_ty.kind() { match self.typing_mode() { TypingMode::Analysis { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0f4927432f6fa..79b79db6ccc07 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -248,10 +248,18 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 5676669bf1c0e..22f8ac9837f6d 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::bug; 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 de36f01b6d0e5..0acc42a6efbe1 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -209,12 +209,15 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { 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 97c88064e9799..cab37f5c0faa6 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1011,14 +1011,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { 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 c9dad4dcd4a75..43b006d72e500 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)] @@ -1198,6 +1198,15 @@ pub(crate) struct AttributesStartingWithRustcAreReserved { pub(crate) span: Span, } +#[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 { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 069018139145d..b7561d58401ab 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1568,10 +1568,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } 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 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } 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 cf048231bd607..7539e3c4f499f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3921,8 +3921,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { 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 72d5cdcf1f3b6..d75f2981a7724 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 6ae9d3aaeb236..619e61211984d 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -618,14 +618,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // 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 e37247d7dd837..1e95482a8c7e6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -23,7 +23,8 @@ use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; 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 @@ use crate::errors::FileWriteFail; 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 1741dde90f5cf..04e12f1afce68 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 output; 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 {} diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 6794ffb311e32..97de708290fb4 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -2796,10 +2796,10 @@ impl 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 30bf8dd7c2206..53e2527057bc2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1014,6 +1014,7 @@ symbols! { 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 @@ symbols! { on_move, on_unimplemented, opaque, - opaque_generic_const_args, opaque_module_name_placeholder: "", ops, opt_out_copy, diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 1dc62cb3659cc..d46802bf45d1a 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -24,8 +24,6 @@ pub mod target_features; #[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 46bc9bdee04b8..d891cb3fb800d 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 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, '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/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bdad1b259b733..94ce7631b3c88 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 3df5c9e33438a..72d3ba9629f4d 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 1202ed2384315..1bfe6e94cc3b6 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -282,7 +282,6 @@ pub(crate) mod rustc { | LayoutError::InvalidSimd { .. } | LayoutError::NormalizationFailure(..) => Self::UnknownLayout, LayoutError::SizeOverflow(..) => Self::SizeOverflow, - LayoutError::Cycle(err) => Self::TypeError(*err), } } } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 6528aa7526b21..0b0f0fd2f4249 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -16,7 +16,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner, Ty, UniverseIndex}; +use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -274,7 +274,7 @@ pub struct ValidateBoundVars { // We only cache types because any complex const will have to step through // a type at some point anyways. We may encounter the same variable at // different levels of binding, so this can't just be `Ty`. - visited: SsoHashSet<(ty::DebruijnIndex, Ty)>, + visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>, } impl ValidateBoundVars { @@ -297,7 +297,7 @@ impl TypeVisitor for ValidateBoundVars { result } - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { if t.outer_exclusive_binder() < self.binder_index || !self.visited.insert((self.binder_index, t)) { @@ -724,7 +724,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } } - fn fold_ty(&mut self, t: Ty) -> Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.has_param() { return t; } @@ -753,7 +753,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } impl<'a, I: Interner> ArgFolder<'a, I> { - fn ty_for_param(&self, p: I::ParamTy, source_ty: Ty) -> Ty { + fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty { // Look up the type in the args. It really should be in there. let opt_ty = self.args.get(p.index() as usize).map(|arg| arg.kind()); let ty = match opt_ty { @@ -767,7 +767,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { #[cold] #[inline(never)] - fn type_param_expected(&self, p: I::ParamTy, ty: Ty, kind: ty::GenericArgKind) -> ! { + fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind) -> ! { panic!( "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}", p, @@ -780,7 +780,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { #[cold] #[inline(never)] - fn type_param_out_of_range(&self, p: I::ParamTy, ty: Ty) -> ! { + fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! { panic!( "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}", p, @@ -1277,7 +1277,7 @@ impl PlaceholderConst { Self { universe: ui, bound, _tcx: PhantomData } } - pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> Ty { + pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() { diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 9786608ab4bc0..2877364762f46 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/error.rs b/compiler/rustc_type_ir/src/error.rs index ef542af7f1f9a..eba4c7c6644ac 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -2,7 +2,7 @@ use derive_where::derive_where; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::NoSolution; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)] @@ -36,15 +36,15 @@ pub enum TypeError { RegionsInsufficientlyPolymorphic(ty::BoundRegion, I::Region), RegionsPlaceholderMismatch, - Sorts(ExpectedFound>), - ArgumentSorts(ExpectedFound>, usize), + Sorts(ExpectedFound), + ArgumentSorts(ExpectedFound, usize), Traits(ExpectedFound), VariadicMismatch(ExpectedFound), /// Instantiating a type variable with the given type would have /// created a cycle (because it appears somewhere within that /// type). - CyclicTy(Ty), + CyclicTy(I::Ty), CyclicConst(I::Const), ProjectionMismatched(ExpectedFound), ExistentialMismatch(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 6bd985a20ae01..5e24e53c62d9a 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -113,7 +113,7 @@ pub enum TreatParams { /// ¹ meaning that if the outermost layers are different, then the whole types are also different. pub fn simplify_type( cx: I, - ty: ty::Ty, + ty: I::Ty, treat_params: TreatParams, ) -> Option> { match ty.kind() { @@ -236,16 +236,11 @@ impl, rhs: ty::Ty) -> bool { + pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool { self.types_may_unify_inner(lhs, rhs, Self::STARTING_DEPTH) } - pub fn types_may_unify_with_depth( - self, - lhs: ty::Ty, - rhs: ty::Ty, - depth_limit: usize, - ) -> bool { + pub fn types_may_unify_with_depth(self, lhs: I::Ty, rhs: I::Ty, depth_limit: usize) -> bool { self.types_may_unify_inner(lhs, rhs, depth_limit) } @@ -273,7 +268,7 @@ impl, rhs: ty::Ty, depth: usize) -> bool { + fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool { if lhs == rhs { return true; } @@ -532,7 +527,7 @@ impl) -> bool { + fn var_and_ty_may_unify(self, var: ty::InferTy, ty: I::Ty) -> bool { if !ty.is_known_rigid() { return true; } diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6962a7ab1d727..0c24181cc4857 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -1,6 +1,6 @@ use crate::inherent::*; use crate::visit::Flags; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; bitflags::bitflags! { /// Flags that we track on types. These flags are propagated upwards @@ -91,19 +91,24 @@ bitflags::bitflags! { | 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 @@ bitflags::bitflags! { | 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 @@ bitflags::bitflags! { | 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 @@ impl FlagComputation { | ty::Str | ty::Foreign(..) => {} - ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), + ty::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR), ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); @@ -430,7 +435,7 @@ impl FlagComputation { } } - fn add_ty(&mut self, ty: Ty) { + fn add_ty(&mut self, ty: I::Ty) { self.add_flags(ty.flags()); self.add_exclusive_binder(ty.outer_exclusive_binder()); } @@ -489,7 +494,7 @@ impl FlagComputation { } } ty::ConstKind::Expr(e) => self.add_args(e.args().as_slice()), - ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), + ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR), } } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index ef162b21b660e..d1a50599e8b9c 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -135,7 +135,7 @@ pub trait TypeFolder: Sized { t.super_fold_with(self) } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { t.super_fold_with(self) } @@ -177,7 +177,7 @@ pub trait FallibleTypeFolder: Sized { t.try_super_fold_with(self) } - fn try_fold_ty(&mut self, t: ty::Ty) -> Result, Self::Error> { + fn try_fold_ty(&mut self, t: I::Ty) -> Result { t.try_super_fold_with(self) } @@ -408,7 +408,7 @@ impl TypeFolder for Shifter { } } - fn fold_ty(&mut self, ty: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { match ty.kind() { ty::Bound(BoundVarIndexKind::Bound(debruijn), bound_ty) if debruijn >= self.current_index => @@ -538,7 +538,7 @@ where } } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if t.has_type_flags( TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, ) { diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index 22a4ebd03b69c..5d612740fdd84 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -3,7 +3,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::GenericTypeVisitable; -use crate::{Interner, Ty}; +use crate::Interner; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] #[derive(GenericTypeVisitable)] @@ -13,7 +13,7 @@ use crate::{Interner, Ty}; )] pub enum GenericArgKind { Lifetime(I::Region), - Type(Ty), + Type(I::Ty), Const(I::Const), } @@ -26,7 +26,7 @@ impl Eq for GenericArgKind {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub enum TermKind { - Ty(Ty), + Ty(I::Ty), Const(I::Const), } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 843d1eb37b7d9..feafcee7bad9e 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -6,7 +6,7 @@ use crate::fold::TypeFoldable; use crate::inherent::*; use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; -use crate::{self as ty, Interner, Ty, TyVid}; +use crate::{self as ty, Interner, TyVid}; /// The current typing mode of an inference context. We unfortunately have some /// slightly different typing rules depending on the current context. See the @@ -161,9 +161,12 @@ pub trait InferCtxtLike: Sized { fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid; fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty; - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty; - fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty; + fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; + fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; + fn opportunistic_resolve_float_var( + &self, + vid: ty::FloatVid, + ) -> ::Ty; fn opportunistic_resolve_ct_var( &self, vid: ty::ConstVid, @@ -176,7 +179,7 @@ pub trait InferCtxtLike: Sized { fn is_changed_arg(&self, arg: ::GenericArg) -> bool; fn next_region_infer(&self) -> ::Region; - fn next_ty_infer(&self) -> Ty; + fn next_ty_infer(&self) -> ::Ty; fn next_const_infer(&self) -> ::Const; fn fresh_args_for_item( &self, @@ -206,7 +209,7 @@ pub trait InferCtxtLike: Sized { target_is_expected: bool, target_vid: ty::TyVid, instantiation_variance: ty::Variance, - source_ty: Ty, + source_ty: ::Ty, ) -> RelateResult; fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue); fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue); @@ -220,7 +223,10 @@ pub trait InferCtxtLike: Sized { fn set_tainted_by_errors(&self, e: ::ErrorGuaranteed); - fn shallow_resolve(&self, ty: Ty) -> Ty; + fn shallow_resolve( + &self, + ty: ::Ty, + ) -> ::Ty; fn shallow_resolve_const( &self, ty: ::Const, @@ -248,7 +254,7 @@ pub trait InferCtxtLike: Sized { fn register_ty_outlives( &self, - ty: Ty, + ty: ::Ty, r: ::Region, span: ::Span, ); @@ -257,26 +263,26 @@ pub trait InferCtxtLike: Sized { fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries; fn clone_opaque_types_lookup_table( &self, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn clone_duplicate_opaque_types( &self, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn clone_opaque_types_added_since( &self, prev_entries: Self::OpaqueTypeStorageEntries, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec>; fn register_hidden_type_in_storage( &self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, + hidden_ty: ::Ty, span: ::Span, - ) -> Option>; + ) -> Option<::Ty>; fn add_duplicate_opaque_type( &self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, + hidden_ty: ::Ty, span: ::Span, ); diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 45590561d9d08..fcadeb6174812 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -108,7 +108,7 @@ pub trait Ty>: fn new_slice(interner: I, ty: Self) -> Self; - fn new_tup(interner: I, tys: &[ty::Ty]) -> Self; + fn new_tup(interner: I, tys: &[I::Ty]) -> Self; fn new_tup_from_iter(interner: I, iter: It) -> T::Output where @@ -121,7 +121,7 @@ pub trait Ty>: fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self; - fn new_unsafe_binder(interner: I, ty: ty::Binder>) -> Self; + fn new_unsafe_binder(interner: I, ty: ty::Binder) -> Self; fn tuple_fields(self) -> I::Tys; @@ -158,7 +158,7 @@ pub trait Ty>: self.kind().fn_sig(interner) } - fn discriminant_ty(self, interner: I) -> ty::Ty; + fn discriminant_ty(self, interner: I) -> I::Ty; fn is_known_rigid(self) -> bool { self.kind().is_known_rigid() @@ -198,11 +198,11 @@ pub trait Ty>: } pub trait Tys>: - Copy + Debug + Hash + Eq + SliceLike> + TypeFoldable + Default + Copy + Debug + Hash + Eq + SliceLike + TypeFoldable + Default { fn inputs(self) -> I::FnInputTys; - fn output(self) -> ty::Ty; + fn output(self) -> I::Ty; } pub trait Abi>: Copy + Debug + Hash + Eq { @@ -290,7 +290,7 @@ pub trait Const>: } pub trait ValueConst>: Copy + Debug + Hash + Eq { - fn ty(self) -> ty::Ty; + fn ty(self) -> I::Ty; fn valtree(self) -> I::ValTree; } @@ -310,7 +310,7 @@ pub trait GenericArg>: + IntoKind> + TypeVisitable + Relate - + From> + + From + From + From + From @@ -323,11 +323,11 @@ pub trait GenericArg>: } } - fn as_type(&self) -> Option> { + fn as_type(&self) -> Option { if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> ty::Ty { + fn expect_ty(&self) -> I::Ty { self.as_type().expect("expected a type") } @@ -359,11 +359,11 @@ pub trait GenericArg>: pub trait Term>: Copy + Debug + Hash + Eq + IntoKind> + TypeFoldable + Relate { - fn as_type(&self) -> Option> { + fn as_type(&self) -> Option { if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> ty::Ty { + fn expect_ty(&self) -> I::Ty { self.as_type().expect("expected a type, but found a const") } @@ -413,7 +413,7 @@ pub trait GenericArgs>: target: I::GenericArgs, ) -> I::GenericArgs; - fn type_at(self, i: usize) -> ty::Ty; + fn type_at(self, i: usize) -> I::Ty; fn region_at(self, i: usize) -> I::Region; @@ -459,7 +459,7 @@ pub trait Predicate>: + UpcastFrom> + UpcastFrom>> + UpcastFrom> - + UpcastFrom>> + + UpcastFrom> + UpcastFrom> + IntoKind>> + Elaboratable @@ -578,7 +578,7 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { /// Returns the type of the struct tail. /// /// Expects the `AdtDef` to be a struct. If it is not, then this will panic. - fn struct_tail_ty(self, interner: I) -> Option>>; + fn struct_tail_ty(self, interner: I) -> Option>; fn is_phantom_data(self) -> bool; @@ -591,13 +591,13 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { ) -> Option>; // FIXME: perhaps use `all_fields` and expose `FieldDef`. - fn all_field_tys(self, interner: I) -> ty::EarlyBinder>>; + fn all_field_tys(self, interner: I) -> ty::EarlyBinder>; fn sizedness_constraint( self, interner: I, sizedness: SizedTraitKind, - ) -> Option>>; + ) -> Option>; fn is_fundamental(self) -> bool; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 6c838cf8a48ac..a0b444024ca79 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -31,7 +31,6 @@ pub mod outlives; pub mod relate; pub mod search_graph; pub mod solve; -pub mod sty; pub mod walk; // These modules are not `pub` since they are glob-imported. @@ -79,7 +78,6 @@ pub use predicate_kind::*; pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; use rustc_type_ir_macros::GenericTypeVisitable; -pub use sty::*; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; @@ -445,8 +443,8 @@ impl fmt::Display for ClosureKind { } pub struct FieldInfo { - pub base: Ty, - pub ty: Ty, + pub base: I::Ty, + pub ty: I::Ty, pub variant: Option, pub variant_idx: VariantIdx, pub name: I::Symbol, diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index cc79d6589e6fb..300e5c0b46956 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -8,7 +8,7 @@ use smallvec::{SmallVec, smallvec}; use crate::data_structures::SsoHashSet; use crate::inherent::*; use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor}; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; #[derive_where(Debug; I: Interner)] pub enum Component { @@ -55,7 +55,7 @@ pub enum Component { /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. pub fn push_outlives_components( cx: I, - ty: Ty, + ty: I::Ty, out: &mut SmallVec<[Component; 4]>, ) { ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() }); @@ -64,14 +64,14 @@ pub fn push_outlives_components( struct OutlivesCollector<'a, I: Interner> { cx: I, out: &'a mut SmallVec<[Component; 4]>, - visited: SsoHashSet>, + visited: SsoHashSet, } impl TypeVisitor for OutlivesCollector<'_, I> { #[cfg(not(feature = "nightly"))] type Result = (); - fn visit_ty(&mut self, ty: Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { if !self.visited.insert(ty) { return; } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index f4975f3ad4486..113192cc02eb8 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -101,7 +101,7 @@ impl TraitRef { ) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { TraitRef::new( interner, self.def_id, @@ -110,13 +110,13 @@ impl TraitRef { } #[inline] - pub fn self_ty(&self) -> ty::Ty { + pub fn self_ty(&self) -> I::Ty { self.args.type_at(0) } } impl ty::Binder> { - pub fn self_ty(&self) -> ty::Binder> { + pub fn self_ty(&self) -> ty::Binder { self.map_bound_ref(|tr| tr.self_ty()) } @@ -152,7 +152,7 @@ pub struct TraitPredicate { impl Eq for TraitPredicate {} impl TraitPredicate { - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), polarity: self.polarity, @@ -163,7 +163,7 @@ impl TraitPredicate { self.trait_ref.def_id } - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.trait_ref.self_ty() } } @@ -174,7 +174,7 @@ impl ty::Binder> { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder> { + pub fn self_ty(self) -> ty::Binder { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -307,7 +307,7 @@ impl ty::Binder> { /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq`, in our example). - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> I::Clause { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause { match self.skip_binder() { ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx), ExistentialPredicate::Projection(p) => { @@ -384,7 +384,7 @@ impl ExistentialTraitRef { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(self, interner: I, self_ty: ty::Ty) -> TraitRef { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -401,7 +401,7 @@ impl ty::Binder> { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> ty::Binder> { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder> { self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty)) } } @@ -459,7 +459,7 @@ impl ExistentialProjection { ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args) } - pub fn with_self_ty(&self, interner: I, self_ty: ty::Ty) -> ProjectionPredicate { + pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate { // otherwise the escaping regions would be captured by the binders debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -487,7 +487,7 @@ impl ExistentialProjection { } impl ty::Binder> { - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> ty::Binder> { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder> { self.map_bound(|p| p.with_self_ty(cx, self_ty)) } @@ -683,11 +683,11 @@ impl AliasTerm { /// The following methods work only with (trait) associated term projections. impl AliasTerm { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { AliasTerm::new( interner, self.def_id, @@ -796,11 +796,11 @@ pub struct ProjectionPredicate { impl Eq for ProjectionPredicate {} impl ProjectionPredicate { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.projection_term.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> ProjectionPredicate { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate { Self { projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty), ..self @@ -859,11 +859,11 @@ pub struct NormalizesTo { impl Eq for NormalizesTo {} impl NormalizesTo { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.alias.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> NormalizesTo { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo { Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self } } @@ -896,11 +896,11 @@ pub struct HostEffectPredicate { impl Eq for HostEffectPredicate {} impl HostEffectPredicate { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.trait_ref.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self } } @@ -915,7 +915,7 @@ impl ty::Binder> { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder> { + pub fn self_ty(self) -> ty::Binder { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -936,8 +936,8 @@ impl ty::Binder> { )] pub struct SubtypePredicate { pub a_is_expected: bool, - pub a: ty::Ty, - pub b: ty::Ty, + pub a: I::Ty, + pub b: I::Ty, } impl Eq for SubtypePredicate {} @@ -950,8 +950,8 @@ impl Eq for SubtypePredicate {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub struct CoercePredicate { - pub a: ty::Ty, - pub b: ty::Ty, + pub a: I::Ty, + pub b: I::Ty, } impl Eq for CoercePredicate {} diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index b6ff27fb238e6..445e85a888fca 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -5,7 +5,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. @@ -25,7 +25,7 @@ pub enum ClauseKind { RegionOutlives(ty::OutlivesPredicate), /// `where T: 'r` - TypeOutlives(ty::OutlivesPredicate>), + TypeOutlives(ty::OutlivesPredicate), /// `where ::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. @@ -33,7 +33,7 @@ pub enum ClauseKind { /// Ensures that a const generic argument to a parameter `const N: u8` /// is of type `u8`. - ConstArgHasType(I::Const, Ty), + ConstArgHasType(I::Const, I::Ty), /// No syntax: `T` well-formed. WellFormed(I::Term), diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 31248bea4cf85..d33c6036dadd8 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -44,7 +44,7 @@ pub enum VarianceDiagInfo { Invariant { /// The generic type containing the generic parameter /// that changes the variance (e.g. `*mut T`, `MyStruct`) - ty: ty::Ty, + ty: I::Ty, /// The index of the generic parameter being used /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) param_index: u32, @@ -75,13 +75,13 @@ pub trait TypeRelation: Sized { fn relate_ty_args( &mut self, - a_ty: ty::Ty, - b_ty: ty::Ty, + a_ty: I::Ty, + b_ty: I::Ty, ty_def_id: I::DefId, a_arg: I::GenericArgs, b_arg: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> ty::Ty, - ) -> RelateResult>; + mk: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult; /// Switch variance for the purpose of relating `a` and `b`. fn relate_with_variance>( @@ -98,7 +98,7 @@ pub trait TypeRelation: Sized { // additional hooks for other types in the future if needed // without making older code, which called `relate`, obsolete. - fn tys(&mut self, a: ty::Ty, b: ty::Ty) -> RelateResult>; + fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult; fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult; @@ -332,9 +332,9 @@ impl Relate for ty::ExistentialTraitRef { #[instrument(level = "trace", skip(relation), ret)] pub fn structurally_relate_tys>( relation: &mut R, - a: ty::Ty, - b: ty::Ty, -) -> RelateResult> { + a: I::Ty, + b: I::Ty, +) -> RelateResult { let cx = relation.cx(); match (a.kind(), b.kind()) { (ty::Infer(_), _) | (_, ty::Infer(_)) => { diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 11fbbf89b9c7b..64b87fac77f94 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -39,15 +39,15 @@ where ); /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_alias_relate_predicate(&mut self, a: ty::Ty, b: ty::Ty); + fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); } pub fn super_combine_tys( infcx: &Infcx, relation: &mut R, - a: ty::Ty, - b: ty::Ty, -) -> RelateResult> + a: I::Ty, + b: I::Ty, +) -> RelateResult where Infcx: InferCtxtLike, I: Interner, @@ -226,13 +226,13 @@ where pub fn combine_ty_args( infcx: &Infcx, relation: &mut R, - a_ty: ty::Ty, - b_ty: ty::Ty, + a_ty: I::Ty, + b_ty: I::Ty, variances: I::VariancesOf, a_args: I::GenericArgs, b_args: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> ty::Ty, -) -> RelateResult> + mk: impl FnOnce(I::GenericArgs) -> I::Ty, +) -> RelateResult where Infcx: InferCtxtLike, I: Interner, diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 1494d67d3c603..82ee4f75fcb0a 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -5,7 +5,7 @@ use crate::data_structures::DelayedSet; use crate::relate::combine::combine_ty_args; pub use crate::relate::*; use crate::solve::Goal; -use crate::{self as ty, InferCtxtLike, Interner, Ty}; +use crate::{self as ty, InferCtxtLike, Interner}; pub trait RelateExt: InferCtxtLike { fn relate>( @@ -104,7 +104,7 @@ pub struct SolverRelating<'infcx, Infcx, I: Interner> { /// constrain `?1` to `u32`. When using the cache entry from the /// first time we've related these types, this only happens when /// later proving the `Subtype(?0, ?1)` goal from the first relation. - cache: DelayedSet<(ty::Variance, Ty, Ty)>, + cache: DelayedSet<(ty::Variance, I::Ty, I::Ty)>, } impl<'infcx, Infcx, I> SolverRelating<'infcx, Infcx, I> @@ -142,13 +142,13 @@ where fn relate_ty_args( &mut self, - a_ty: Ty, - b_ty: Ty, + a_ty: I::Ty, + b_ty: I::Ty, def_id: I::DefId, a_args: I::GenericArgs, b_args: I::GenericArgs, - _: impl FnOnce(I::GenericArgs) -> Ty, - ) -> RelateResult> { + _: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult { if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles @@ -178,7 +178,7 @@ where } #[instrument(skip(self), level = "trace")] - fn tys(&mut self, a: Ty, b: Ty) -> RelateResult> { + fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult { if a == b { return Ok(a); } @@ -383,7 +383,7 @@ where self.goals.extend(obligations); } - fn register_alias_relate_predicate(&mut self, a: Ty, b: Ty) { + fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index e0c6c777c09af..535af2718f3ab 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 @@ impl, X: Cx> SearchGraph { /// 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 { NoCycleUsages, + Ambiguity(X::AmbiguityInfo), Overflow, /// We've actually reached a fixpoint. /// @@ -965,7 +966,7 @@ impl, X: Cx> SearchGraph { &mut self, cx: X, stack_entry: &StackEntry, - rebase_reason: RebaseReason, + rebase_reason: RebaseReason, ) { 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 @@ impl, X: Cx> SearchGraph { // 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 @@ impl, X: Cx> SearchGraph { 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/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 23e6075452b18..72b7df22b30d5 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -11,7 +11,7 @@ use rustc_type_ir_macros::{ use crate::lang_items::SolverTraitLangItem; use crate::search_graph::PathKind; -use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Ty, Upcast}; +use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; pub type CanonicalInput::Predicate> = ty::CanonicalQueryInput>; @@ -254,7 +254,7 @@ impl Eq for Response {} #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct ExternalConstraintsData { pub region_constraints: Vec>, - pub opaque_types: Vec<(ty::OpaqueTypeKey, Ty)>, + pub opaque_types: Vec<(ty::OpaqueTypeKey, I::Ty)>, pub normalization_nested_goals: NestedNormalizationGoals, } diff --git a/compiler/rustc_type_ir/src/sty/mod.rs b/compiler/rustc_type_ir/src/sty/mod.rs deleted file mode 100644 index 5b73d372384b8..0000000000000 --- a/compiler/rustc_type_ir/src/sty/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -/// This type is temporary and exists to cut down the bloat of further PR's -/// moving `struct Ty` from `rustc_middle` to `rustc_type_ir`. -pub type Ty = ::Ty; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index ad7a934bb28a5..9afd39e2c7627 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -100,7 +100,7 @@ pub enum TyKind { Str, /// An array with the given length. Written as `[T; N]`. - Array(ty::Ty, I::Const), + Array(I::Ty, I::Const), /// A pattern newtype. /// @@ -109,17 +109,17 @@ pub enum TyKind { /// Only `Copy` and `Clone` will automatically get implemented for pattern types. /// Auto-traits treat this as if it were an aggregate with a single nested type. /// Only supports integer range patterns for now. - Pat(ty::Ty, I::Pat), + Pat(I::Ty, I::Pat), /// The pointee of an array slice. Written as `[T]`. - Slice(ty::Ty), + Slice(I::Ty), /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(ty::Ty, Mutability), + RawPtr(I::Ty, Mutability), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - Ref(I::Region, ty::Ty, Mutability), + Ref(I::Region, I::Ty, Mutability), /// The anonymous type of a function declaration/definition. /// @@ -469,18 +469,18 @@ impl AliasTy { matches!(self.kind(interner), AliasTyKind::Opaque) } - pub fn to_ty(self, interner: I) -> ty::Ty { + pub fn to_ty(self, interner: I) -> I::Ty { Ty::new_alias(interner, self.kind(interner), self) } } /// The following methods work only with (trait) associated type projections. impl AliasTy { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { AliasTy::new( interner, self.def_id, @@ -735,7 +735,7 @@ impl fmt::Debug for InferTy { )] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct TypeAndMut { - pub ty: ty::Ty, + pub ty: I::Ty, pub mutbl: Mutability, } @@ -765,7 +765,7 @@ impl FnSig { self.inputs_and_output.inputs() } - pub fn output(self) -> ty::Ty { + pub fn output(self) -> I::Ty { self.inputs_and_output.output() } @@ -783,7 +783,7 @@ impl ty::Binder> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder> { + pub fn input(self, index: usize) -> ty::Binder { self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap()) } @@ -792,7 +792,7 @@ impl ty::Binder> { } #[inline] - pub fn output(self) -> ty::Binder> { + pub fn output(self) -> ty::Binder { self.map_bound(|fn_sig| fn_sig.output()) } @@ -856,21 +856,21 @@ impl fmt::Debug for FnSig { } // FIXME: this is a distinct type because we need to define `Encode`/`Decode` -// impls in this crate for `Binder>`. +// impls in this crate for `Binder`. #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] -pub struct UnsafeBinderInner(ty::Binder>); +pub struct UnsafeBinderInner(ty::Binder); impl Eq for UnsafeBinderInner {} -impl From>> for UnsafeBinderInner { - fn from(value: ty::Binder>) -> Self { +impl From> for UnsafeBinderInner { + fn from(value: ty::Binder) -> Self { UnsafeBinderInner(value) } } -impl From> for ty::Binder> { +impl From> for ty::Binder { fn from(value: UnsafeBinderInner) -> Self { value.0 } @@ -883,7 +883,7 @@ impl fmt::Debug for UnsafeBinderInner { } impl Deref for UnsafeBinderInner { - type Target = ty::Binder>; + type Target = ty::Binder; fn deref(&self) -> &Self::Target { &self.0 @@ -894,7 +894,7 @@ impl Deref for UnsafeBinderInner { impl rustc_serialize::Encodable for UnsafeBinderInner where - ty::Ty: rustc_serialize::Encodable, + I::Ty: rustc_serialize::Encodable, I::BoundVarKinds: rustc_serialize::Encodable, { fn encode(&self, e: &mut E) { @@ -907,7 +907,7 @@ where impl rustc_serialize::Decodable for UnsafeBinderInner where - ty::Ty: TypeVisitable + rustc_serialize::Decodable, + I::Ty: TypeVisitable + rustc_serialize::Decodable, I::BoundVarKinds: rustc_serialize::Decodable, { fn decode(decoder: &mut D) -> Self { @@ -937,7 +937,7 @@ impl FnSigTys { self.inputs_and_output.inputs() } - pub fn output(self) -> ty::Ty { + pub fn output(self) -> I::Ty { self.inputs_and_output.output() } } @@ -960,7 +960,7 @@ impl ty::Binder> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder> { + pub fn input(self, index: usize) -> ty::Binder { self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap()) } @@ -969,7 +969,7 @@ impl ty::Binder> { } #[inline] - pub fn output(self) -> ty::Binder> { + pub fn output(self) -> ty::Binder { self.map_bound(|sig_tys| sig_tys.output()) } } diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 08c303b8de9c8..e8f94c8e7cc92 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -121,13 +121,13 @@ pub struct ClosureArgsParts { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: ty::Ty, + pub closure_kind_ty: I::Ty, /// Captures the closure's signature. This closure signature is "tupled", and /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`. - pub closure_sig_as_fn_ptr_ty: ty::Ty, + pub closure_sig_as_fn_ptr_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, } impl ClosureArgs { @@ -169,14 +169,14 @@ impl ClosureArgs { /// Returns the tuple type representing the upvars for this closure. #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } /// Returns the closure kind for this closure; may return a type /// variable during inference. To get the closure kind during /// inference, use `infcx.closure_kind(args)`. - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().closure_kind_ty } @@ -185,7 +185,7 @@ impl ClosureArgs { // FIXME(eddyb) this should be unnecessary, as the shallowly resolved // type is known at the time of the creation of `ClosureArgs`, // see `rustc_hir_analysis::check::closure`. - pub fn sig_as_fn_ptr_ty(self) -> ty::Ty { + pub fn sig_as_fn_ptr_ty(self) -> I::Ty { self.split().closure_sig_as_fn_ptr_ty } @@ -223,7 +223,7 @@ pub struct CoroutineClosureArgsParts { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: ty::Ty, + pub closure_kind_ty: I::Ty, /// Represents all of the relevant parts of the coroutine returned by this /// coroutine-closure. This signature parts type will have the general /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where @@ -232,10 +232,10 @@ pub struct CoroutineClosureArgsParts { /// /// Use `coroutine_closure_sig` to break up this type rather than using it /// yourself. - pub signature_parts_ty: ty::Ty, + pub signature_parts_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. /// This allows us to represent the binder of the self-captures of the closure. /// @@ -243,7 +243,7 @@ pub struct CoroutineClosureArgsParts { /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, /// while the `tupled_upvars_ty`, representing the by-move version of the same /// captures, will be `(String,)`. - pub coroutine_captures_by_ref_ty: ty::Ty, + pub coroutine_captures_by_ref_ty: I::Ty, } impl CoroutineClosureArgs { @@ -277,11 +277,11 @@ impl CoroutineClosureArgs { } #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().closure_kind_ty } @@ -289,7 +289,7 @@ impl CoroutineClosureArgs { self.kind_ty().to_opt_closure_kind().unwrap() } - pub fn signature_parts_ty(self) -> ty::Ty { + pub fn signature_parts_ty(self) -> I::Ty { self.split().signature_parts_ty } @@ -314,7 +314,7 @@ impl CoroutineClosureArgs { }) } - pub fn coroutine_captures_by_ref_ty(self) -> ty::Ty { + pub fn coroutine_captures_by_ref_ty(self) -> I::Ty { self.split().coroutine_captures_by_ref_ty } @@ -358,10 +358,10 @@ impl TypeVisitor for HasRegionsBoundAt { #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct CoroutineClosureSignature { - pub tupled_inputs_ty: ty::Ty, - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub tupled_inputs_ty: I::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types // never actually differ. But we save them rather than recreating them @@ -393,10 +393,10 @@ impl CoroutineClosureSignature { self, cx: I, parent_args: I::GenericArgsSlice, - coroutine_kind_ty: ty::Ty, + coroutine_kind_ty: I::Ty, coroutine_def_id: I::CoroutineId, - tupled_upvars_ty: ty::Ty, - ) -> ty::Ty { + tupled_upvars_ty: I::Ty, + ) -> I::Ty { let coroutine_args = ty::CoroutineArgs::new( cx, ty::CoroutineArgsParts { @@ -424,9 +424,9 @@ impl CoroutineClosureSignature { coroutine_def_id: I::CoroutineId, goal_kind: ty::ClosureKind, env_region: I::Region, - closure_tupled_upvars_ty: ty::Ty, - coroutine_captures_by_ref_ty: ty::Ty, - ) -> ty::Ty { + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, + ) -> I::Ty { let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( cx, goal_kind, @@ -457,11 +457,11 @@ impl CoroutineClosureSignature { pub fn tupled_upvars_by_closure_kind( cx: I, kind: ty::ClosureKind, - tupled_inputs_ty: ty::Ty, - closure_tupled_upvars_ty: ty::Ty, - coroutine_captures_by_ref_ty: ty::Ty, + tupled_inputs_ty: I::Ty, + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, env_region: I::Region, - ) -> ty::Ty { + ) -> I::Ty { match kind { ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else { @@ -503,7 +503,7 @@ struct FoldEscapingRegions { // Depends on `debruijn` because we may have types with regions of different // debruijn depths depending on the binders we've entered. - cache: DelayedMap<(ty::DebruijnIndex, ty::Ty), ty::Ty>, + cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>, } impl TypeFolder for FoldEscapingRegions { @@ -511,7 +511,7 @@ impl TypeFolder for FoldEscapingRegions { self.interner } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.has_vars_bound_at_or_above(self.debruijn) { t } else if let Some(&t) = self.cache.get(&(self.debruijn, t)) { @@ -553,9 +553,9 @@ impl TypeFolder for FoldEscapingRegions { #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct GenSig { - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, } impl Eq for GenSig {} @@ -581,15 +581,15 @@ pub struct CoroutineArgsParts { /// kind: `i8`/`i16`/`i32`. /// /// For regular coroutines, this field will always just be `()`. - pub kind_ty: ty::Ty, + pub kind_ty: I::Ty, - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, } impl CoroutineArgs { @@ -619,7 +619,7 @@ impl CoroutineArgs { } // Returns the kind of the coroutine. See docs on the `kind_ty` field. - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().kind_ty } @@ -638,22 +638,22 @@ impl CoroutineArgs { /// Returns the tuple type representing the upvars for this coroutine. #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } /// Returns the type representing the resume type of the coroutine. - pub fn resume_ty(self) -> ty::Ty { + pub fn resume_ty(self) -> I::Ty { self.split().resume_ty } /// Returns the type representing the yield type of the coroutine. - pub fn yield_ty(self) -> ty::Ty { + pub fn yield_ty(self) -> I::Ty { self.split().yield_ty } /// Returns the type representing the return type of the coroutine. - pub fn return_ty(self) -> ty::Ty { + pub fn return_ty(self) -> I::Ty { self.split().return_ty } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 1ee4bff6b7a11..a078b860be774 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, Ty, TypeFlags}; +use crate::{self as ty, Interner, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -98,7 +98,7 @@ pub trait TypeVisitor: Sized { t.super_visit_with(self) } - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { t.super_visit_with(self) } @@ -279,6 +279,8 @@ pub trait TypeVisitableExt: TypeVisitable { 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 @@ pub trait TypeVisitableExt: TypeVisitable { 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> TypeVisitableExt for T { @@ -376,6 +383,18 @@ impl> TypeVisitableExt for T { Ok(()) } } + + fn non_region_error_reported(&self) -> Result<(), I::ErrorGuaranteed> { + if self.has_non_region_error() { + if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) { + Err(guar) + } else { + panic!("type flags said there was an non region error, but now there is not") + } + } else { + Ok(()) + } + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -417,7 +436,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { } #[inline] - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { // Note: no `super_visit_with` call. let flags = t.flags(); if flags.intersects(self.flags) { @@ -522,7 +541,7 @@ impl TypeVisitor for HasEscapingVarsVisitor { } #[inline] - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { // If the outer-exclusive-binder is *strictly greater* than // `outer_index`, that means that `t` contains some content // bound at `outer_index` or above (because diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index bcd9e092a310f..aff10c4320fe1 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 b3e49af868b8c..af1eaf2015e9d 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/lib.rs b/library/core/src/lib.rs index e0750f0784458..312295154dc52 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -236,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 7f35e94d3df30..33397e56b86c5 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1720,7 +1720,7 @@ pub(crate) mod builtin { /// /// 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/prelude/v1.rs b/library/core/src/prelude/v1.rs index f2eb047d342bc..6122ab12ec351 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -120,9 +120,13 @@ pub use crate::trace_macros; // (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 1730742dffe93..70ccd3431a2ff 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -706,6 +706,8 @@ pub use core::cfg_select; 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 ee57e031c959c..aeefec8b9e084 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -115,9 +115,13 @@ pub use core::prelude::v1::trace_macros; // (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/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 847e688d03d0a..fc61103d939fb 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -203,7 +203,7 @@ fn clean_param_env<'tcx>( let mut generics = clean::Generics { params, where_predicates }; simplify::sized_bounds(cx, &mut generics); - generics.where_predicates = simplify::where_clauses(cx, generics.where_predicates); + generics.where_predicates = simplify::where_clauses(cx.tcx, generics.where_predicates); generics } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 09b2bc5dcef1d..96e15eac0a920 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -137,7 +137,7 @@ pub(crate) fn try_inline( }) } Res::Def(DefKind::Macro(kinds), did) => { - let mac = build_macro(cx, did, name, kinds); + let mac = build_macro(cx.tcx, did, name, kinds); // FIXME: handle attributes and derives that aren't proc macros, and macros with // multiple kinds @@ -218,10 +218,10 @@ pub(crate) fn try_inline_glob( } } -pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir::Attribute] { +pub(crate) fn load_attrs<'hir>(tcx: TyCtxt<'hir>, did: DefId) -> &'hir [hir::Attribute] { // FIXME: all uses should use `find_attr`! #[allow(deprecated)] - cx.tcx.get_all_attrs(did) + tcx.get_all_attrs(did) } pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec { @@ -289,7 +289,7 @@ pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { supertrait_bounds.retain(|b| { // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` // is shown and none of the new sizedness traits leak into documentation. - !b.is_meta_sized_bound(cx) + !b.is_meta_sized_bound(cx.tcx) }); clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } @@ -302,7 +302,7 @@ fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { bounds.retain(|b| { // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` // is shown and none of the new sizedness traits leak into documentation. - !b.is_meta_sized_bound(cx) + !b.is_meta_sized_bound(cx.tcx) }); clean::TraitAlias { generics, bounds } @@ -312,7 +312,7 @@ pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box)>, ret: &mut Vec, ) { - let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls"); let tcx = cx.tcx; + let _prof_timer = tcx.sess.prof.generic_activity("build_inherent_impls"); // for each implementation of an item represented by `did`, build the clean::Item for that impl for &did in tcx.inherent_impls(did).iter() { @@ -416,7 +416,7 @@ pub(crate) fn build_impls( } pub(crate) fn merge_attrs( - cx: &mut DocContext<'_>, + tcx: TyCtxt<'_>, old_attrs: &[hir::Attribute], new_attrs: Option<(&[hir::Attribute], Option)>, cfg_info: &mut CfgInfo, @@ -434,13 +434,10 @@ pub(crate) fn merge_attrs( } else { Attributes::from_hir(&both) }, - extract_cfg_from_attrs(both.iter(), cx.tcx, cfg_info), + extract_cfg_from_attrs(both.iter(), tcx, cfg_info), ) } else { - ( - Attributes::from_hir(old_attrs), - extract_cfg_from_attrs(old_attrs.iter(), cx.tcx, cfg_info), - ) + (Attributes::from_hir(old_attrs), extract_cfg_from_attrs(old_attrs.iter(), tcx, cfg_info)) } } @@ -623,7 +620,8 @@ pub(crate) fn build_impl( // doesn't matter at this point. // // We need to pass this empty `CfgInfo` because `merge_attrs` is used when computing the `cfg`. - let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs, &mut CfgInfo::default()); + let (merged_attrs, cfg) = + merge_attrs(cx.tcx, load_attrs(cx.tcx, did), attrs, &mut CfgInfo::default()); trace!("merged_attrs={merged_attrs:?}"); trace!( @@ -771,17 +769,17 @@ fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::St } fn build_macro( - cx: &mut DocContext<'_>, + tcx: TyCtxt<'_>, def_id: DefId, name: Symbol, macro_kinds: MacroKinds, ) -> clean::ItemKind { - match CStore::from_tcx(cx.tcx).load_macro_untracked(cx.tcx, def_id) { + match CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id) { // FIXME: handle attributes and derives that aren't proc macros, and macros with multiple // kinds LoadedMacro::MacroDef { def, .. } => match macro_kinds { MacroKinds::BANG => clean::MacroItem(clean::Macro { - source: utils::display_macro_source(cx, name, &def), + source: utils::display_macro_source(tcx, name, &def), macro_rules: def.macro_rules, }), MacroKinds::DERIVE => clean::ProcMacroItem(clean::ProcMacro { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f54339429fa58..67eee30e99a9f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -184,7 +184,8 @@ fn generate_item_with_correct_attrs( import_ids: &[LocalDefId], renamed: Option, ) -> Item { - let target_attrs = inline::load_attrs(cx, def_id); + let tcx = cx.tcx; + let target_attrs = inline::load_attrs(tcx, def_id); let attrs = if !import_ids.is_empty() { let mut attrs = Vec::with_capacity(import_ids.len()); let mut is_inline = false; @@ -196,11 +197,11 @@ fn generate_item_with_correct_attrs( // cfgs on the path up until the glob can be removed, and only cfgs on the globbed item // itself matter), for non-inlined re-exports see #85043. let import_is_inline = find_attr!( - inline::load_attrs(cx, import_id.to_def_id()), + inline::load_attrs(tcx, import_id.to_def_id()), Doc(d) if d.inline.first().is_some_and(|(inline, _)| *inline == DocInline::Inline) - ) || (is_glob_import(cx.tcx, import_id) - && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); + ) || (is_glob_import(tcx, import_id) + && (cx.document_hidden() || !tcx.is_doc_hidden(def_id))); attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); is_inline = is_inline || import_is_inline; } @@ -272,7 +273,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>( GenericBound::TraitBound( PolyTrait { trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints), - generic_params: clean_bound_vars(poly_trait_ref.bound_vars(), cx), + generic_params: clean_bound_vars(poly_trait_ref.bound_vars(), cx.tcx), }, hir::TraitBoundModifiers::NONE, ) @@ -342,7 +343,6 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind pub(crate) fn clean_middle_const<'tcx>( constant: ty::Binder<'tcx, ty::Const<'tcx>>, - _cx: &mut DocContext<'tcx>, ) -> ConstantKind { // FIXME: instead of storing the stringified expression, store `self` directly instead. ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() } @@ -350,9 +350,9 @@ pub(crate) fn clean_middle_const<'tcx>( pub(crate) fn clean_middle_region<'tcx>( region: ty::Region<'tcx>, - cx: &mut DocContext<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Option { - region.get_name(cx.tcx).map(Lifetime) + region.get_name(tcx).map(Lifetime) } fn clean_where_predicate<'tcx>( @@ -394,7 +394,7 @@ pub(crate) fn clean_predicate<'tcx>( let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx), - ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred, cx)), + ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred, cx.tcx)), ty::ClauseKind::TypeOutlives(pred) => { Some(clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)) } @@ -431,14 +431,14 @@ fn clean_poly_trait_predicate<'tcx>( fn clean_region_outlives_predicate<'tcx>( pred: ty::RegionOutlivesPredicate<'tcx>, - cx: &mut DocContext<'tcx>, + tcx: TyCtxt<'tcx>, ) -> WherePredicate { let ty::OutlivesPredicate(a, b) = pred; WherePredicate::RegionPredicate { - lifetime: clean_middle_region(a, cx).expect("failed to clean lifetime"), + lifetime: clean_middle_region(a, tcx).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives( - clean_middle_region(b, cx).expect("failed to clean bounds"), + clean_middle_region(b, tcx).expect("failed to clean bounds"), )], } } @@ -452,7 +452,7 @@ fn clean_type_outlives_predicate<'tcx>( WherePredicate::BoundPredicate { ty: clean_middle_ty(pred.rebind(ty), cx, None, None), bounds: vec![GenericBound::Outlives( - clean_middle_region(lt, cx).expect("failed to clean lifetimes"), + clean_middle_region(lt, cx.tcx).expect("failed to clean lifetimes"), )], bound_params: Vec::new(), } @@ -464,7 +464,7 @@ fn clean_middle_term<'tcx>( ) -> Term { match term.skip_binder().kind() { ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(term.rebind(ty), cx, None, None)), - ty::TermKind::Const(c) => Term::Constant(clean_middle_const(term.rebind(c), cx)), + ty::TermKind::Const(c) => Term::Constant(clean_middle_const(term.rebind(c))), } } @@ -479,7 +479,7 @@ fn clean_hir_term<'tcx>( // FIXME(generic_const_items): this should instantiate with the alias item's args let ty = cx.tcx.type_of(assoc_item.unwrap()).instantiate_identity(); let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty); - Term::Constant(clean_middle_const(ty::Binder::dummy(ct), cx)) + Term::Constant(clean_middle_const(ty::Binder::dummy(ct))) } } } @@ -898,10 +898,10 @@ fn clean_ty_generics_inner<'tcx>( for (idx, mut bounds) in impl_trait { let mut has_sized = false; bounds.retain(|b| { - if b.is_sized_bound(cx) { + if b.is_sized_bound(cx.tcx) { has_sized = true; false - } else if b.is_meta_sized_bound(cx) { + } else if b.is_meta_sized_bound(cx.tcx) { // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` // is shown and none of the new sizedness traits leak into documentation. false @@ -925,7 +925,7 @@ fn clean_ty_generics_inner<'tcx>( if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { let rhs = clean_middle_term(rhs, cx); - simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); + simplify::merge_bounds(cx.tcx, &mut bounds, trait_did, name, &rhs); } } @@ -939,7 +939,7 @@ fn clean_ty_generics_inner<'tcx>( let mut generics = Generics { params, where_predicates }; simplify::sized_bounds(cx, &mut generics); - generics.where_predicates = simplify::where_clauses(cx, generics.where_predicates); + generics.where_predicates = simplify::where_clauses(cx.tcx, generics.where_predicates); generics } @@ -1001,12 +1001,12 @@ fn clean_proc_macro<'tcx>( item: &hir::Item<'tcx>, name: &mut Symbol, kind: MacroKind, - cx: &mut DocContext<'tcx>, + tcx: TyCtxt<'tcx>, ) -> ItemKind { if kind != MacroKind::Derive { return ProcMacroItem(ProcMacro { kind, helpers: vec![] }); } - let attrs = cx.tcx.hir_attrs(item.hir_id()); + let attrs = tcx.hir_attrs(item.hir_id()); let Some((trait_name, helper_attrs)) = find_attr!(attrs, ProcMacroDerive { trait_name, helper_attrs, ..} => (*trait_name, helper_attrs)) else { return ProcMacroItem(ProcMacro { kind, helpers: vec![] }); @@ -1037,7 +1037,7 @@ fn clean_fn_or_proc_macro<'tcx>( }; match macro_kind { - Some(kind) => clean_proc_macro(item, name, kind, cx), + Some(kind) => clean_proc_macro(item, name, kind, cx.tcx), None => { let mut func = clean_function(cx, sig, generics, ParamsSrc::Body(body_id)); clean_fn_decl_legacy_const_generics(&mut func, attrs); @@ -1248,7 +1248,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext RequiredAssocTypeItem(generics, bounds) } }; - Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) + Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx.tcx) }) } @@ -1289,7 +1289,7 @@ pub(crate) fn clean_impl_item<'tcx>( } }; - Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx) + Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx.tcx) }) } @@ -1459,7 +1459,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo bounds.retain(|b| { // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` // is shown and none of the new sizedness traits leak into documentation. - !b.is_meta_sized_bound(cx) + !b.is_meta_sized_bound(tcx) }); // Our Sized/?Sized bound didn't get handled when creating the generics @@ -1467,7 +1467,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo // (some of them may have come from the trait). If we do have a sized // bound, we remove it, and if we don't then we add the `?Sized` bound // at the end. - match bounds.iter().position(|b| b.is_sized_bound(cx)) { + match bounds.iter().position(|b| b.is_sized_bound(tcx)) { Some(i) => { bounds.remove(i); } @@ -1517,7 +1517,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } }; - Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name()), kind, cx) + Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name()), kind, tcx) } fn first_non_private_clean_path<'tcx>( @@ -1831,7 +1831,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); - print_const(cx, ct) + print_const(cx.tcx, ct) } hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) @@ -1840,7 +1840,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::Array(..) | hir::ConstArgKind::Literal { .. } => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); - print_const(cx, ct) + print_const(cx.tcx, ct) } }; Array(Box::new(clean_ty(ty, cx)), length.into()) @@ -2060,14 +2060,14 @@ pub(crate) fn clean_middle_ty<'tcx>( ), ty::Array(ty, n) => { let n = cx.tcx.normalize_erasing_regions(cx.typing_env(), n); - let n = print_const(cx, n); + let n = print_const(cx.tcx, n); Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), n.into()) } ty::RawPtr(ty, mutbl) => { RawPointer(mutbl, Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None))) } ty::Ref(r, ty, mutbl) => BorrowedRef { - lifetime: clean_middle_region(r, cx), + lifetime: clean_middle_region(r, cx.tcx), mutability: mutbl, type_: Box::new(clean_middle_ty( bound_ty.rebind(ty), @@ -2080,7 +2080,7 @@ pub(crate) fn clean_middle_ty<'tcx>( // FIXME: should we merge the outer and inner binders somehow? let sig = bound_ty.skip_binder().fn_sig(cx.tcx); let decl = clean_poly_fn_sig(cx, None, sig); - let generic_params = clean_bound_vars(sig.bound_vars(), cx); + let generic_params = clean_bound_vars(sig.bound_vars(), cx.tcx); BareFunction(Box::new(BareFunctionDecl { safety: sig.safety(), @@ -2090,7 +2090,7 @@ pub(crate) fn clean_middle_ty<'tcx>( })) } ty::UnsafeBinder(inner) => { - let generic_params = clean_bound_vars(inner.bound_vars(), cx); + let generic_params = clean_bound_vars(inner.bound_vars(), cx.tcx); let ty = clean_middle_ty(inner.into(), cx, None, None); UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, ty })) } @@ -2301,7 +2301,7 @@ fn clean_middle_opaque_bounds<'tcx>( let trait_ref = match bound_predicate.skip_binder() { ty::ClauseKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref), ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { - return clean_middle_region(reg, cx).map(GenericBound::Outlives); + return clean_middle_region(reg, cx.tcx).map(GenericBound::Outlives); } _ => return None, }; @@ -2376,7 +2376,12 @@ fn clean_middle_opaque_bounds<'tcx>( } pub(crate) fn clean_field<'tcx>(field: &hir::FieldDef<'tcx>, cx: &mut DocContext<'tcx>) -> Item { - clean_field_with_def_id(field.def_id.to_def_id(), field.ident.name, clean_ty(field.ty, cx), cx) + clean_field_with_def_id( + field.def_id.to_def_id(), + field.ident.name, + clean_ty(field.ty, cx), + cx.tcx, + ) } pub(crate) fn clean_middle_field(field: &ty::FieldDef, cx: &mut DocContext<'_>) -> Item { @@ -2389,7 +2394,7 @@ pub(crate) fn clean_middle_field(field: &ty::FieldDef, cx: &mut DocContext<'_>) Some(field.did), None, ), - cx, + cx.tcx, ) } @@ -2397,9 +2402,9 @@ pub(crate) fn clean_field_with_def_id( def_id: DefId, name: Symbol, ty: Type, - cx: &mut DocContext<'_>, + tcx: TyCtxt<'_>, ) -> Item { - Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx) + Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), tcx) } pub(crate) fn clean_variant_def(variant: &ty::VariantDef, cx: &mut DocContext<'_>) -> Item { @@ -2422,7 +2427,7 @@ pub(crate) fn clean_variant_def(variant: &ty::VariantDef, cx: &mut DocContext<'_ variant.def_id, Some(variant.name), VariantItem(Variant { kind, discriminant }), - cx, + cx.tcx, ) } @@ -2463,7 +2468,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( field.did, field.name, clean_middle_ty(ty::Binder::dummy(ty), cx, Some(field.did), None), - cx, + cx.tcx, ) }) .collect(), @@ -2488,7 +2493,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( field.did, field.name, clean_middle_ty(ty::Binder::dummy(ty), cx, Some(field.did), None), - cx, + cx.tcx, ) }) .collect(), @@ -2499,7 +2504,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( variant.def_id, Some(variant.name), VariantItem(Variant { kind, discriminant }), - cx, + cx.tcx, ) } @@ -2663,7 +2668,7 @@ fn get_all_import_attributes<'hir>( .iter() .flat_map(|reexport| reexport.id()) { - let import_attrs = inline::load_attrs(cx, def_id); + let import_attrs = inline::load_attrs(cx.tcx, def_id); if first { // This is the "original" reexport so we get all its attributes without filtering them. attrs = import_attrs.iter().map(|attr| (Cow::Borrowed(attr), Some(def_id))).collect(); @@ -2763,12 +2768,8 @@ fn clean_maybe_renamed_item<'tcx>( import_ids: &[LocalDefId], ) -> Vec { use hir::ItemKind; - fn get_name( - cx: &DocContext<'_>, - item: &hir::Item<'_>, - renamed: Option, - ) -> Option { - renamed.or_else(|| cx.tcx.hir_opt_name(item.hir_id())) + fn get_name(tcx: TyCtxt<'_>, item: &hir::Item<'_>, renamed: Option) -> Option { + renamed.or_else(|| tcx.hir_opt_name(item.hir_id())) } let def_id = item.owner_id.to_def_id(); @@ -2785,7 +2786,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Use(path, kind) => { return clean_use_statement( item, - get_name(cx, item, renamed), + get_name(cx.tcx, item, renamed), path, kind, cx, @@ -2795,7 +2796,7 @@ fn clean_maybe_renamed_item<'tcx>( _ => {} } - let mut name = get_name(cx, item, renamed).unwrap(); + let mut name = get_name(cx.tcx, item, renamed).unwrap(); let kind = match item.kind { ItemKind::Static(mutability, _, ty, body_id) => StaticItem(Static { @@ -2861,14 +2862,14 @@ fn clean_maybe_renamed_item<'tcx>( // FIXME: handle attributes and derives that aren't proc macros, and macros with // multiple kinds ItemKind::Macro(_, macro_def, MacroKinds::BANG) => MacroItem(Macro { - source: display_macro_source(cx, name, macro_def), + source: display_macro_source(cx.tcx, name, macro_def), macro_rules: macro_def.macro_rules, }), ItemKind::Macro(_, _, MacroKinds::ATTR) => { - clean_proc_macro(item, &mut name, MacroKind::Attr, cx) + clean_proc_macro(item, &mut name, MacroKind::Attr, cx.tcx) } ItemKind::Macro(_, _, MacroKinds::DERIVE) => { - clean_proc_macro(item, &mut name, MacroKind::Derive, cx) + clean_proc_macro(item, &mut name, MacroKind::Derive, cx.tcx) } ItemKind::Macro(_, _, _) => todo!("Handle macros with multiple kinds"), // proc macros can have a name set by attributes @@ -2907,7 +2908,7 @@ fn clean_maybe_renamed_item<'tcx>( fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item { let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx)); - Item::from_def_id_and_parts(variant.def_id.to_def_id(), Some(variant.ident.name), kind, cx) + Item::from_def_id_and_parts(variant.def_id.to_def_id(), Some(variant.ident.name), kind, cx.tcx) } fn clean_impl<'tcx>( @@ -2928,7 +2929,7 @@ fn clean_impl<'tcx>( def_id.to_def_id(), None, PlaceholderImplItem, - cx, + tcx, )]; } Some(clean_trait_ref(&t.trait_ref, cx)) @@ -2983,7 +2984,7 @@ fn clean_impl<'tcx>( }, is_deprecated, })); - Item::from_def_id_and_parts(def_id.to_def_id(), None, kind, cx) + Item::from_def_id_and_parts(def_id.to_def_id(), None, kind, tcx) }; if let Some(type_alias) = type_alias { ret.push(make_item(trait_.clone(), type_alias, items.clone())); @@ -3031,7 +3032,7 @@ fn clean_extern_crate<'tcx>( krate_owner_def_id.to_def_id(), Some(name), ExternCrateItem { src: orig_name }, - cx, + cx.tcx, )] } @@ -3160,14 +3161,14 @@ fn clean_use_statement_inner<'tcx>( import_def_id.to_def_id(), None, ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)), - cx, + cx.tcx, )); return items; } Import::new_simple(name, resolve_use_source(cx, path), true) }; - vec![Item::from_def_id_and_parts(import_def_id.to_def_id(), None, ImportItem(inner), cx)] + vec![Item::from_def_id_and_parts(import_def_id.to_def_id(), None, ImportItem(inner), cx.tcx)] } fn clean_maybe_renamed_foreign_item<'tcx>( @@ -3233,13 +3234,13 @@ fn clean_assoc_item_constraint<'tcx>( fn clean_bound_vars<'tcx>( bound_vars: &ty::List>, - cx: &mut DocContext<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Vec { bound_vars .into_iter() .filter_map(|var| match var { ty::BoundVariableKind::Region(ty::BoundRegionKind::Named(def_id)) => { - let name = cx.tcx.item_name(def_id); + let name = tcx.item_name(def_id); if name != kw::UnderscoreLifetime { Some(GenericParamDef::lifetime(def_id, name)) } else { @@ -3247,7 +3248,7 @@ fn clean_bound_vars<'tcx>( } } ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id)) => { - let name = cx.tcx.item_name(def_id); + let name = tcx.item_name(def_id); Some(GenericParamDef { name, def_id, diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 6fb878ea54856..154f31e89dbff 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -15,12 +15,13 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::DefId; +use rustc_middle::ty::TyCtxt; use crate::clean; use crate::clean::{GenericArgs as PP, WherePredicate as WP}; use crate::core::DocContext; -pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: ThinVec) -> ThinVec { +pub(crate) fn where_clauses(tcx: TyCtxt<'_>, clauses: ThinVec) -> ThinVec { // First, partition the where clause into its separate components. // // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to @@ -47,7 +48,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: ThinVec) -> ThinVe // general bound predicates. equalities.retain(|(lhs, rhs)| { let Some((bounds, _)) = tybounds.get_mut(&lhs.self_type) else { return true }; - merge_bounds(cx, bounds, lhs.trait_.as_ref().unwrap().def_id(), lhs.assoc.clone(), rhs) + merge_bounds(tcx, bounds, lhs.trait_.as_ref().unwrap().def_id(), lhs.assoc.clone(), rhs) }); // And finally, let's reassemble everything @@ -65,7 +66,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: ThinVec) -> ThinVe } pub(crate) fn merge_bounds( - cx: &clean::DocContext<'_>, + tcx: TyCtxt<'_>, bounds: &mut [clean::GenericBound], trait_did: DefId, assoc: clean::PathSegment, @@ -79,7 +80,7 @@ pub(crate) fn merge_bounds( // If this QPath's trait `trait_did` is the same as, or a supertrait // of, the bound's trait `did` then we can keep going, otherwise // this is just a plain old equality bound. - if !trait_is_same_or_supertrait(cx, trait_ref.trait_.def_id(), trait_did) { + if !trait_is_same_or_supertrait(tcx, trait_ref.trait_.def_id(), trait_did) { return false; } let last = trait_ref.trait_.segments.last_mut().expect("segments were empty"); @@ -108,15 +109,15 @@ pub(crate) fn merge_bounds( }) } -fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) -> bool { +fn trait_is_same_or_supertrait(tcx: TyCtxt<'_>, child: DefId, trait_: DefId) -> bool { if child == trait_ { return true; } - let predicates = cx.tcx.explicit_super_predicates_of(child); + let predicates = tcx.explicit_super_predicates_of(child); predicates .iter_identity_copied() .filter_map(|(pred, _)| Some(pred.as_trait_clause()?.def_id())) - .any(|did| trait_is_same_or_supertrait(cx, did, trait_)) + .any(|did| trait_is_same_or_supertrait(tcx, did, trait_)) } pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generics) { @@ -139,10 +140,10 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi return true; }; - if bounds.iter().any(|b| b.is_sized_bound(cx)) { + if bounds.iter().any(|b| b.is_sized_bound(cx.tcx)) { sized_params.insert(*param); false - } else if bounds.iter().any(|b| b.is_meta_sized_bound(cx)) { + } else if bounds.iter().any(|b| b.is_meta_sized_bound(cx.tcx)) { // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` // is shown and none of the new sizedness traits leak into documentation. false diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ad70fc1096691..04aeb19f242de 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -465,6 +465,15 @@ impl Item { .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 { let kind = match &self.kind { ItemKind::StrippedItem(k) => k, @@ -514,10 +523,10 @@ impl Item { def_id: DefId, name: Option, kind: ItemKind, - cx: &mut DocContext<'_>, + tcx: TyCtxt<'_>, ) -> Item { #[allow(deprecated)] - let hir_attrs = cx.tcx.get_all_attrs(def_id); + let hir_attrs = tcx.get_all_attrs(def_id); Self::from_def_id_and_attrs_and_parts( def_id, @@ -1119,20 +1128,20 @@ impl GenericBound { matches!(self, Self::TraitBound(..)) } - pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { - self.is_bounded_by_lang_item(cx, LangItem::Sized) + pub(crate) fn is_sized_bound(&self, tcx: TyCtxt<'_>) -> bool { + self.is_bounded_by_lang_item(tcx, LangItem::Sized) } - pub(crate) fn is_meta_sized_bound(&self, cx: &DocContext<'_>) -> bool { - self.is_bounded_by_lang_item(cx, LangItem::MetaSized) + pub(crate) fn is_meta_sized_bound(&self, tcx: TyCtxt<'_>) -> bool { + self.is_bounded_by_lang_item(tcx, LangItem::MetaSized) } - fn is_bounded_by_lang_item(&self, cx: &DocContext<'_>, lang_item: LangItem) -> bool { + fn is_bounded_by_lang_item(&self, tcx: TyCtxt<'_>, lang_item: LangItem) -> bool { if let GenericBound::TraitBound( PolyTrait { ref trait_, .. }, rustc_hir::TraitBoundModifiers::NONE, ) = *self - && cx.tcx.is_lang_item(trait_.def_id(), lang_item) + && tcx.is_lang_item(trait_.def_id(), lang_item) { return true; } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 834b73997c959..2284b815a09a9 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -72,14 +72,14 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { def_id, Some(prim.as_sym()), ItemKind::PrimitiveItem(prim), - cx, + cx.tcx, ) })); m.items.extend(keywords.map(|(def_id, kw)| { - Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem, cx) + Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem, cx.tcx) })); m.items.extend(documented_attributes.into_iter().map(|(def_id, kw)| { - Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::AttributeItem, cx) + Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::AttributeItem, cx.tcx) })); } @@ -135,7 +135,7 @@ pub(crate) fn clean_middle_generic_args<'tcx>( match arg.skip_binder().kind() { GenericArgKind::Lifetime(lt) => Some(GenericArg::Lifetime( - clean_middle_region(lt, cx).unwrap_or(Lifetime::elided()), + clean_middle_region(lt, cx.tcx).unwrap_or(Lifetime::elided()), )), GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty( arg.rebind(ty), @@ -148,7 +148,7 @@ pub(crate) fn clean_middle_generic_args<'tcx>( }), ))), GenericArgKind::Const(ct) => { - Some(GenericArg::Const(Box::new(clean_middle_const(arg.rebind(ct), cx)))) + Some(GenericArg::Const(Box::new(clean_middle_const(arg.rebind(ct))))) } } }; @@ -347,13 +347,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { }) } -pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { +pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { if let Some(def) = def.as_local() { - rendered_const(cx.tcx, cx.tcx.hir_body_owned_by(def), def) + rendered_const(tcx, tcx.hir_body_owned_by(def), def) } else { - inline::print_inlined_const(cx.tcx, def) + inline::print_inlined_const(tcx, def) } } // array lengths are obviously usize @@ -602,26 +602,21 @@ fn render_macro_arms<'a>( out } -pub(super) fn display_macro_source( - cx: &mut DocContext<'_>, - name: Symbol, - def: &ast::MacroDef, -) -> String { +pub(super) fn display_macro_source(tcx: TyCtxt<'_>, name: Symbol, def: &ast::MacroDef) -> String { // Extract the spans of all matchers. They represent the "interface" of the macro. let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]); if def.macro_rules { - format!("macro_rules! {name} {{\n{arms}}}", arms = render_macro_arms(cx.tcx, matchers, ";")) + format!("macro_rules! {name} {{\n{arms}}}", arms = render_macro_arms(tcx, matchers, ";")) } else { if matchers.len() <= 1 { format!( "macro {name}{matchers} {{\n ...\n}}", - matchers = matchers - .map(|matcher| render_macro_matcher(cx.tcx, matcher)) - .collect::(), + matchers = + matchers.map(|matcher| render_macro_matcher(tcx, matcher)).collect::(), ) } else { - format!("macro {name} {{\n{arms}}}", arms = render_macro_arms(cx.tcx, matchers, ",")) + format!("macro {name} {{\n{arms}}}", arms = render_macro_arms(tcx, matchers, ",")) } } } diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index a4535792ac3ce..d40c9501cabc1 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::>() + }) .collect::>(); 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, url: String) -> String { format!("{url}-{add}") } +enum GetMethodsMode<'r, 'l> { + Deref { deref_mut: bool }, + AlsoCollectAssocFns { assoc_fns: &'r mut Vec> }, +} + fn get_methods<'a>( i: &'a clean::Impl, - for_deref: bool, + mut mode: GetMethodsMode<'_, 'a>, used_links: &mut FxHashSet, - deref_mut: bool, tcx: TyCtxt<'_>, -) -> Vec> { - 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> { + 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, -) -> Vec> { - 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> { + 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, -) -> Vec> { - 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> { + 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 49153d58fe98c..4d4222a34956a 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -60,11 +60,6 @@

{# #} Note: Encountered an error during type layout; {#+ #} the type failed to be normalized. {# #}

- {% when Err(LayoutError::Cycle(_)) %} -

{# #} - Note: Encountered an error during type layout; {#+ #} - the type's layout depended on the type's layout itself. {# #} -

{% when Err(LayoutError::InvalidSimd {..}) %}

{# #} Note: Encountered an error during type layout; {#+ #} diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index f73db253af062..92798bb9bb011 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -64,14 +64,14 @@ impl CfgPropagator<'_, '_> { && let Some(mut next_def_id) = item.item_id.as_local_def_id() { while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) { - let x = load_attrs(self.cx, parent_def_id.to_def_id()); + let x = load_attrs(self.cx.tcx, parent_def_id.to_def_id()); add_only_cfg_attributes(&mut attrs, x); next_def_id = parent_def_id; } } let (_, cfg) = merge_attrs( - self.cx, + self.cx.tcx, item.attrs.other_attrs.as_slice(), Some((&attrs, None)), &mut self.cfg_info, diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 1e75df7d278fb..cf4f7d689ac22 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -10,6 +10,7 @@ use std::{iter, thread}; 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> = 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::() { + 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 3e0dd881db84e..8d5f1914d0c32 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 dae6934931228..f8d555e5a10b8 100644 --- a/src/tools/miri/tests/fail/layout_cycle.stderr +++ b/src/tools/miri/tests/fail/layout_cycle.stderr @@ -9,13 +9,6 @@ LL | const SIZE: usize = intrinsics::size_of::(); | ^^^^^^^^^^^^^^^^^ = 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::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `> as std::mem::SizedTypeProperties>::SIZE` failed here - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -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 4ef1775d4bed9..77cbdcbd37aa2 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 c1192986e63f2..96dad53fa359f 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 = (None, parse_opt_bool, [TRACKED], diff --git a/tests/rustdoc-gui/hash-item-expansion.goml b/tests/rustdoc-gui/hash-item-expansion.goml index a7a5c3cb48345..8661641206685 100644 --- a/tests/rustdoc-gui/hash-item-expansion.goml +++ b/tests/rustdoc-gui/hash-item-expansion.goml @@ -5,7 +5,7 @@ assert-attribute: ("#blanket-implementations-list > details:nth-child(2)", {"ope // 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 3183650b555a8..61c1555fbc0e3 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -48,7 +48,7 @@ assert-property: ("rustdoc-topbar", {"clientHeight": "45"}) // 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 6e13457796e5e..bd0893dac3e36 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 3fdc2788bcacf..4eae3c7258213 100644 --- a/tests/rustdoc-html/typedef.rs +++ b/tests/rustdoc-html/typedef.rs @@ -13,7 +13,7 @@ impl 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/auto-traits/ungated-impl.rs b/tests/ui/auto-traits/ungated-impl.rs deleted file mode 100644 index d46b4b01af9c7..0000000000000 --- 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 !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 9d10d46a90283..0000000000000 --- 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 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 !MyTrait for *mut T {} - | ^^^^^^^^ - | - = note: see issue #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/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 e3db3dea3735e..d96c718617d24 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: usize = const { N + 1 }; @@ -11,8 +13,6 @@ type const ONE: usize = ADD1::<0>; 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 e736484b5c3c9..e80540d621de5 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: 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 0000000000000..1b181d792d362 --- /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: usize = const { N + 1 }; +type const BAR: 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: 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: usize = const { N + 1 }; +type const SUB1: 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 0000000000000..e8122c1b832f1 --- /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 0000000000000..447f25bfdc36b --- /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: 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 a62b509190bd6..ed4467d6f0039 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() {} 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 bb6c6b667e1d0..6c0337dbbd470 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: usize = ID::; //~^ ERROR generic parameters in const blocks are only allowed as the direct value of a `type const` type const ID: 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/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index f1d5e5c674756..0060c94875b5c 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 @@ error: generic parameters may not be used in const operations LL | foo::<{ Some:: { 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 e0804158952d1..b25199bca2e28 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 @@ error: generic parameters may not be used in const operations LL | T: Trait | ^^ | - = 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 1c72afce52c7d..f634ec1cf12e4 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 @@ error: generic parameters may not be used in const operations LL | type const ITEM3: 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 @@ error: generic parameters may not be used in const operations LL | T3: Trait, | ^ | - = 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 @@ error: generic parameters may not be used in const operations LL | struct Default3; | ^ | - = 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 @@ error: generic parameters may not be used in const operations 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 @@ error: generic parameters may not be used in const operations 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 @@ error: generic parameters may not be used in const operations LL | type Adt3 = Foo; | ^ | - = 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 @@ error: generic parameters may not be used in const operations LL | type Arr3 = [(); 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 1c841e39e6739..cf5974fd83df9 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 @@ note: not a concrete type | LL | impl S { | ^^^^ - = 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 c3e0770fb978e..74d8f083ee09e 100644 --- a/tests/ui/const-generics/mgca/selftyparam.stderr +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations 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 61e934380c360..694d4c8ebabd4 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 @@ error: generic parameters may not be used in const operations 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 2961c714d1415..3a873ec33fb19 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 @@ error: generic parameters may not be used in const operations 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 95a98d857b1d4..a9d412964da29 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 @@ error: generic parameters may not be used in const operations 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 0000000000000..74c945b0881a4 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs @@ -0,0 +1,15 @@ +//! Regression test for +//! +//@ 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 0000000000000..b09ac22240325 --- /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 475d2cf312d64..0c88fbfb8578c 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 @@ error: generic parameters may not be used in const operations LL | type const FREE1: usize = const { std::mem::size_of::() }; | ^ | - = 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 @@ error: generic parameters may not be used in const operations LL | type const FREE2: 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 e13d6fbcdd82f..78e38d800524e 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 @@ error: generic parameters may not be used in const operations LL | type const N1: usize = const { std::mem::size_of::() }; | ^ | - = 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 @@ error: generic parameters may not be used in const operations LL | type const N2: 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 @@ error: generic parameters may not be used in const operations 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 b1808deacd27f..0000000000000 --- 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 bb20c0457c03d..0000000000000 --- 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: usize = const { N + 1 }; - -type const BAR: 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 919a0c8d70e94..0000000000000 --- 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/consts/ice-extra-args-fn-abi-issue-127423.rs b/tests/ui/consts/ice-extra-args-fn-abi-issue-127423.rs new file mode 100644 index 0000000000000..67aed9122e89f --- /dev/null +++ b/tests/ui/consts/ice-extra-args-fn-abi-issue-127423.rs @@ -0,0 +1,15 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/127423 + +#![allow(dead_code)] + +const fn add(a: &'self isize) -> usize { + //~^ ERROR use of undeclared lifetime name `'self` + //~| ERROR lifetimes cannot use keyword names + Qux + y + //~^ ERROR cannot find value `Qux` in this scope + //~| ERROR cannot find value `y` in this scope +} + +const ARR: [i32; add(1, 2)] = [5, 6, 7]; + +pub fn main() {} diff --git a/tests/ui/consts/ice-extra-args-fn-abi-issue-127423.stderr b/tests/ui/consts/ice-extra-args-fn-abi-issue-127423.stderr new file mode 100644 index 0000000000000..f01e9bd51357d --- /dev/null +++ b/tests/ui/consts/ice-extra-args-fn-abi-issue-127423.stderr @@ -0,0 +1,39 @@ +error: lifetimes cannot use keyword names + --> $DIR/ice-extra-args-fn-abi-issue-127423.rs:5:18 + | +LL | const fn add(a: &'self isize) -> usize { + | ^^^^^ + +error[E0261]: use of undeclared lifetime name `'self` + --> $DIR/ice-extra-args-fn-abi-issue-127423.rs:5:18 + | +LL | const fn add(a: &'self isize) -> usize { + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'self` here + | +LL | const fn add<'self>(a: &'self isize) -> usize { + | +++++++ + +error[E0425]: cannot find value `Qux` in this scope + --> $DIR/ice-extra-args-fn-abi-issue-127423.rs:8:5 + | +LL | Qux + y + | ^^^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/ice-extra-args-fn-abi-issue-127423.rs:8:11 + | +LL | Qux + y + | ^ + | +help: a local variable with a similar name exists + | +LL - Qux + y +LL + Qux + a + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0261, E0425. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.rs b/tests/ui/dropck/dropck-after-failed-type-lowering.rs index 2441e26fec96c..ee55e0dcaa491 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() -> F { + //~^ ERROR: the trait bound `E: B` is not satisfied todo!() } } struct F { - h: Option<::C>, + h: Option<::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 56ea72de0c5f2..0922d2e4340e8 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<::C>, | ^ expected 1 lifetime argument @@ -14,6 +14,24 @@ help: add missing lifetime argument LL | h: Option<::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<::C>, + | ^^^^^^^^^^^^^^^^^^^ the trait `B` is not implemented for `G` + | +help: consider restricting type parameter `G` with trait `B` + | +LL | struct F { + | +++ + +error[E0277]: the trait bound `E: B` is not satisfied + --> $DIR/dropck-after-failed-type-lowering.rs:5:18 + | +LL | fn d() -> F { + | ^^^^ the trait `B` is not implemented for `E` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0107`. +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 0000000000000..f61d42cd2bf01 --- /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/extern/bad-external-async-fn-issue-146754.rs b/tests/ui/extern/bad-external-async-fn-issue-146754.rs new file mode 100644 index 0000000000000..394341c129654 --- /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 0000000000000..2a04b23630430 --- /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 aab9e784fe9d7..e900fb84a02d9 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 8fa5168b2d041..d476b4fecbe58 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 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 for more information - = help: add `#![feature(negative_impls)]` to the crate attributes to enable + = note: see issue #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 f18f59cf60bd1..b62e7fb08099a 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: 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-opaque-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr similarity index 57% rename from tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr rename to tests/ui/feature-gates/feature-gate-generic-const-args.stderr index ef771e77f6923..27794b43966cd 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr @@ -1,10 +1,10 @@ error: generic parameters may not be used in const operations - --> $DIR/feature-gate-opaque-generic-const-args.rs:4:49 + --> $DIR/feature-gate-generic-const-args.rs:4:49 | LL | type const INC: usize = 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 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 e7b2eca6f858a..6382af32efb2a 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 d58603883f158..bc0db8b81aefc 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 @@ error: expected attribute, found macro `rustc::unknown` 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 0ccbaf1e476a9..01f44df0d7621 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 8ab0e80e6be31..9fdaa7a0ec08c 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 7d2d48503797a..dbc0b940265fc 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 0000000000000..0071ce6350b16 --- /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 0000000000000..35e125cb2d24c --- /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 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 + +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 553e88375a2a7..7f929f5198a70 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 aa51e60d56b4a..3f439d0c26893 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 deab31c251f83..4a0532284c176 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 @@ error[E0405]: cannot find trait `r#use` in this scope 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 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 @@ LL | fn asyncness() -> impl Sized + async use<> {} = 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 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 0000000000000..5f0a6bb86bf30 --- /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/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs deleted file mode 100644 index 54ed408e74881..0000000000000 --- 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 { - data: T::Bar, -} - -fn foo(a: &ArrayPeano) -> &[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 1242a9e2b5c01..0000000000000 --- 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 c8f7c8ea32fe7..0000000000000 --- 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 b38bd52c6ade9..846ce0882cad1 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 e05ff614567c4..28c35d431226e 100644 --- a/tests/ui/layout/layout-cycle.stderr +++ b/tests/ui/layout/layout-cycle.stderr @@ -6,18 +6,6 @@ note: cycle used when const-evaluating + checking `core::mem::SizedTypePropertie --> $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 `> as std::mem::SizedTypeProperties>::SIZE` failed here - -note: the above error was encountered while instantiating `fn std::mem::size_of::>>` - --> $DIR/layout-cycle.rs:26:5 - | -LL | mem::size_of::>() - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -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 0000000000000..10e54c633ae03 --- /dev/null +++ b/tests/ui/layout/opt-repr-i32-min.rs @@ -0,0 +1,14 @@ +//@ run-pass +// Tests that Option 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 7f246b3d409ad..b9b1b988499e6 100644 --- a/tests/ui/layout/post-mono-layout-cycle.stderr +++ b/tests/ui/layout/post-mono-layout-cycle.stderr @@ -5,12 +5,6 @@ error[E0391]: cycle detected when computing layout of `Wrapper<()>` = note: cycle used when computing layout of `core::option::Option>` = 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::(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 0395aea63ee97..e2a110ffd09c6 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 af2ba7a809ad0..46f50593c4e95 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 8700c78508476..6016850838d3c 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 @@ impl ThreadPool { } 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 47d6fd6cbad3b..462eb274ce5af 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>>`, 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 | pool.execute(move || { 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 9c957a4e01b41..eea9858532d4c 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 6d4a867fa88d0..e0fce32ba7fc0 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>`, 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)[3], 4); 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` 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 a5dac8cc14bf2..c9094cb78a391 100644 --- a/tests/ui/moves/no-reuse-move-arc.fixed +++ b/tests/ui/moves/no-reuse-move-arc.fixed @@ -11,7 +11,7 @@ fn main() { 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 0d67aa56489ce..29452220aebcc 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 aff979af905e4..8f56b32f96a89 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>`, 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)[3], 4); 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` help: consider cloning the value before moving it into the closure | diff --git a/tests/ui/parser/trait-item-with-defaultness-pass.rs b/tests/ui/parser/trait-item-with-defaultness-pass.rs index 164d0b13b539c..e8452fcbd5f99 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/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr deleted file mode 100644 index d097b809b5698..0000000000000 --- 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.rs b/tests/ui/sized/stack-overflow-trait-infer-98842.rs index 1c9f6c593f447..d6522e3cfb643 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 @@ struct Foo(<&'static Foo as ::core::ops::Deref>::Target); // 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.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr similarity index 55% rename from tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr rename to tests/ui/sized/stack-overflow-trait-infer-98842.stderr index d097b809b5698..5557a6fc45b89 100644 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr @@ -3,19 +3,12 @@ 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 + --> $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[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 +error: aborting due to 1 previous error -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/specialization/feature-gate-specialization.rs b/tests/ui/specialization/feature-gate-specialization.rs new file mode 100644 index 0000000000000..82e467ad98d32 --- /dev/null +++ b/tests/ui/specialization/feature-gate-specialization.rs @@ -0,0 +1,21 @@ +trait Trait { + type Ty; + const CT: (); + fn fn_(&self); +} + +impl 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 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 0000000000000..2efc0faa7c23e --- /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 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 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 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 OtherTrait for T { +LL | | fn fn_() {} +LL | | } + | |_^ + | + = note: see issue #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 0000000000000..f5961090947ed --- /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 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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:24:5 + | +LL | default const CT: () = (); + | ^^^^^^^ + | + = note: see issue #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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:40:1 + | +LL | default impl Trait for () {} + | ^^^^^^^ + | + = note: see issue #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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:27:5 + | +LL | default fn fn_(); + | ^^^^^^^ + | + = note: see issue #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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:35:1 + | +LL | default fn fn_() {} + | ^^^^^^^ + | + = note: see issue #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 + +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 0000000000000..aa4ce0cc58be2 --- /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 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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:24:5 + | +LL | default const CT: () = (); + | ^^^^^^^ + | + = note: see issue #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 + +warning: specialization is experimental + --> $DIR/soft-feature-gate-specialization.rs:40:1 + | +LL | default impl Trait for () {} + | ^^^^^^^ + | + = note: see issue #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 + +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 0000000000000..46e4b28e61d23 --- /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 8bad3ac0a1fb3..0000000000000 --- 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 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 3e651b6ee4f37..0000000000000 --- 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 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/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index aa75c5691e5f9..38d34f46270a4 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -12,7 +12,7 @@ pub trait Foo { impl 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 a61f7855e3231..30d518a69cadd 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/traits/negative-impls/feature-gate-negative_impls.rs b/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs index 8d3f6ff6d78c7..1b3c5abe10918 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 1777dfcc993f1..36bc5bb4be2bc 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 @@ LL | impl !MyTrait for u32 {} = note: see issue #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 e57fbf378a0d2..0000000000000 --- 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 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 {} - -struct MyField; -impl Field for MyField {} - -trait IdReqField { - type This; -} -impl IdReqField for F { - type This = F; -} - -fn foo() -where - ::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 0000000000000..0ad8e3444600b --- /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(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 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 0000000000000..f16a17833368d --- /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(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 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 0000000000000..c3f8bc75d6cce --- /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 Id for T { + type This = T; +} + +fn foo(x: <(*const T,) as Id>::This) -> (*const T,) +where + (): Id, + (<() 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 f5fd9ce9864ce..47d38365e970e 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 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` LL | ::Assoc: Trait, | ^^^^^ -error: aborting due to 1 previous error +error[E0275]: overflow evaluating whether `::Assoc` is well-formed + --> $DIR/normalize-param-env-4.rs:19:26 + | +LL | ::Assoc: Trait, + | ^^^^^ + +error[E0275]: overflow evaluating the requirement `T: Trait` + --> $DIR/normalize-param-env-4.rs:32:19 + | +LL | impls_trait::(); + | ^ + | +note: required by a bound in `impls_trait` + --> $DIR/normalize-param-env-4.rs:15:19 + | +LL | fn impls_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 0000000000000..9521a944391cc --- /dev/null +++ b/tests/ui/transmute/transmute-associated-type-to-slice.rs @@ -0,0 +1,23 @@ +//! regression test for +//@ normalize-stderr: "\d+ bits" -> "N bits" + +trait MyTrait { + type MyType; +} + +struct ArrayPeano { + data: T::MyType, +} + +fn foo(a: &ArrayPeano) -> &[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 87% rename from tests/ui/issues/issue-28625.stderr rename to tests/ui/transmute/transmute-associated-type-to-slice.stderr index 3600622a45424..ada3153165e57 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 77% rename from tests/ui/issues/issue-23477.rs rename to tests/ui/transmute/transmute-slice-to-dst.rs index fa69a1d762682..c1f77bee284dd 100644 --- a/tests/ui/issues/issue-23477.rs +++ b/tests/ui/transmute/transmute-slice-to-dst.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass //@ compile-flags: -g 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 0000000000000..79918e6a0722d --- /dev/null +++ b/tests/ui/unsized/thin-ptr-to-unsized-projection.rs @@ -0,0 +1,6 @@ +// This is a regression test for +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 0000000000000..256523c4a47ec --- /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`.