diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b105a97cdf98d..0be00f4d00be7 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4087,18 +4087,18 @@ impl ItemKind { pub fn ident(&self) -> Option { match *self { ItemKind::ExternCrate(_, ident) - | ItemKind::Static(box StaticItem { ident, .. }) - | ItemKind::Const(box ConstItem { ident, .. }) - | ItemKind::Fn(box Fn { ident, .. }) + | ItemKind::Static(StaticItem { ident, .. }) + | ItemKind::Const(ConstItem { ident, .. }) + | ItemKind::Fn(Fn { ident, .. }) | ItemKind::Mod(_, ident, _) - | ItemKind::TyAlias(box TyAlias { ident, .. }) + | ItemKind::TyAlias(TyAlias { ident, .. }) | ItemKind::Enum(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Union(ident, ..) - | ItemKind::Trait(box Trait { ident, .. }) - | ItemKind::TraitAlias(box TraitAlias { ident, .. }) + | ItemKind::Trait(Trait { ident, .. }) + | ItemKind::TraitAlias(TraitAlias { ident, .. }) | ItemKind::MacroDef(ident, _) - | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident), + | ItemKind::Delegation(Delegation { ident, .. }) => Some(ident), ItemKind::ConstBlock(_) => Some(ConstBlockItem::IDENT), @@ -4149,14 +4149,14 @@ impl ItemKind { pub fn generics(&self) -> Option<&Generics> { match self { - Self::Fn(box Fn { generics, .. }) - | Self::TyAlias(box TyAlias { generics, .. }) - | Self::Const(box ConstItem { generics, .. }) + Self::Fn(Fn { generics, .. }) + | Self::TyAlias(TyAlias { generics, .. }) + | Self::Const(ConstItem { generics, .. }) | Self::Enum(_, generics, _) | Self::Struct(_, generics, _) | Self::Union(_, generics, _) - | Self::Trait(box Trait { generics, .. }) - | Self::TraitAlias(box TraitAlias { generics, .. }) + | Self::Trait(Trait { generics, .. }) + | Self::TraitAlias(TraitAlias { generics, .. }) | Self::Impl(Impl { generics, .. }) => Some(generics), Self::ExternCrate(..) @@ -4205,10 +4205,10 @@ pub enum AssocItemKind { impl AssocItemKind { pub fn ident(&self) -> Option { match *self { - AssocItemKind::Const(box ConstItem { ident, .. }) - | AssocItemKind::Fn(box Fn { ident, .. }) - | AssocItemKind::Type(box TyAlias { ident, .. }) - | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident), + AssocItemKind::Const(ConstItem { ident, .. }) + | AssocItemKind::Fn(Fn { ident, .. }) + | AssocItemKind::Type(TyAlias { ident, .. }) + | AssocItemKind::Delegation(Delegation { ident, .. }) => Some(ident), AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None, } @@ -4216,9 +4216,9 @@ impl AssocItemKind { pub fn defaultness(&self) -> Defaultness { match *self { - Self::Const(box ConstItem { defaultness, .. }) - | Self::Fn(box Fn { defaultness, .. }) - | Self::Type(box TyAlias { defaultness, .. }) => defaultness, + Self::Const(ConstItem { defaultness, .. }) + | Self::Fn(Fn { defaultness, .. }) + | Self::Type(TyAlias { defaultness, .. }) => defaultness, Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => { Defaultness::Implicit } @@ -4271,9 +4271,9 @@ pub enum ForeignItemKind { impl ForeignItemKind { pub fn ident(&self) -> Option { match *self { - ForeignItemKind::Static(box StaticItem { ident, .. }) - | ForeignItemKind::Fn(box Fn { ident, .. }) - | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident), + ForeignItemKind::Static(StaticItem { ident, .. }) + | ForeignItemKind::Fn(Fn { ident, .. }) + | ForeignItemKind::TyAlias(TyAlias { ident, .. }) => Some(ident), ForeignItemKind::MacCall(_) => None, } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 4178db1bfb09d..3b01eb6eefa7d 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -7,7 +7,7 @@ // tidy-alphabetical-start #![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(associated_type_defaults)] -#![feature(box_patterns)] +#![feature(deref_patterns)] #![feature(iter_order_by)] #![feature(macro_metavar_expr)] #![recursion_limit = "256"] diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 1e5f414fae1c7..1430d04dcca6a 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -210,7 +210,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { contains_exterior_struct_lit(x) } - ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => { + ast::ExprKind::MethodCall(ast::MethodCall { receiver, .. }) => { // X { y: 1 }.bar(...) contains_exterior_struct_lit(receiver) } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ee4b1d1354300..cbd7cb3ee8c6f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -851,7 +851,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, impl_), ItemKind::Trait(trait_) => visit_visitable!($($mut)? vis, trait_), - ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => { + ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds}) => { visit_visitable!($($mut)? vis, constness, ident, generics); visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound) } @@ -949,7 +949,7 @@ macro_rules! common_visitor_and_walkers { impl_walkable!(|&$($mut)? $($lt)? self: Impl, vis: &mut V| { let Impl { generics, of_trait, self_ty, items, constness: _ } = self; try_visit!(vis.visit_generics(generics)); - if let Some(box of_trait) = of_trait { + if let Some(of_trait) = of_trait { let TraitImplHeader { defaultness, safety, polarity, trait_ref } = of_trait; visit_visitable!($($mut)? vis, defaultness, safety, polarity, trait_ref); } @@ -1004,7 +1004,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, block, opt_label, span), ExprKind::Match(subexpression, arms, kind) => visit_visitable!($($mut)? vis, subexpression, arms, kind), - ExprKind::Closure(box Closure { + ExprKind::Closure(Closure { binder, capture_clause, coroutine_kind, diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index d390934f3b172..adde518af0f41 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -626,7 +626,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let callee_path = this.arena.alloc(this.mk_expr(hir::ExprKind::Path(path), span)); - let args = if let Some(box block) = delegation.body.as_ref() { + let args = if let Some(block) = delegation.body.as_ref() { this.arena.alloc_slice(&[this.lower_target_expr(block)]) } else { &mut [] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index d017c29a22f7f..eaa22e071af4b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -118,7 +118,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => { + ExprKind::MethodCall(MethodCall { seg, receiver, args, span }) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -212,7 +212,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ), ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr), ExprKind::Use(expr, use_kw_span) => self.lower_expr_use(*use_kw_span, expr), - ExprKind::Closure(box Closure { + ExprKind::Closure(Closure { binder, capture_clause, constness, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3e0bc072a8d04..249f8e579eee9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -211,14 +211,12 @@ impl<'hir> LoweringContext<'_, 'hir> { i: &ItemKind, ) -> Vec { match i { - ItemKind::Fn(box Fn { eii_impls, .. }) - | ItemKind::Static(box StaticItem { eii_impls, .. }) + ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. }) if eii_impls.is_empty() => { Vec::new() } - ItemKind::Fn(box Fn { eii_impls, .. }) - | ItemKind::Static(box StaticItem { eii_impls, .. }) => { + ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. }) => { vec![hir::Attribute::Parsed(AttributeKind::EiiImpls( eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(), ))] @@ -298,7 +296,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs) } - ItemKind::Static(box ast::StaticItem { + ItemKind::Static(ast::StaticItem { ident, ty, safety: _, @@ -314,7 +312,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_define_opaque(hir_id, define_opaque); hir::ItemKind::Static(*m, ident, ty, body_id) } - ItemKind::Const(box ConstItem { + ItemKind::Const(ConstItem { defaultness: _, ident, generics, @@ -352,7 +350,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.record_body(&[], body) }), ), - ItemKind::Fn(box Fn { + ItemKind::Fn(Fn { sig: FnSig { decl, header, span: fn_sig_span }, ident, generics, @@ -419,7 +417,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); hir::ItemKind::GlobalAsm { asm, fake_body } } - ItemKind::TyAlias(box TyAlias { ident, generics, after_where_clause, ty, .. }) => { + ItemKind::TyAlias(TyAlias { ident, generics, after_where_clause, ty, .. }) => { // We lower // // type Foo = impl Trait @@ -539,7 +537,7 @@ impl<'hir> LoweringContext<'_, 'hir> { constness, }) } - ItemKind::Trait(box Trait { + ItemKind::Trait(Trait { impl_restriction, constness, is_auto, @@ -580,7 +578,7 @@ impl<'hir> LoweringContext<'_, 'hir> { items, } } - ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => { + ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => { let constness = self.lower_constness(*constness); let ident = self.lower_ident(*ident); let (generics, bounds) = self.lower_generics( @@ -615,7 +613,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }); hir::ItemKind::Macro(ident, macro_def, macro_kinds) } - ItemKind::Delegation(box delegation) => { + ItemKind::Delegation(delegation) => { let delegation_results = self.lower_delegation(delegation, id); hir::ItemKind::Fn { sig: delegation_results.sig, @@ -794,7 +792,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind)); let (ident, kind) = match &i.kind { - ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => { + ForeignItemKind::Fn(Fn { sig, ident, generics, define_opaque, .. }) => { let fdec = &sig.decl; let itctx = ImplTraitContext::Universal; let (generics, (decl, fn_args)) = @@ -822,7 +820,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ), ) } - ForeignItemKind::Static(box StaticItem { + ForeignItemKind::Static(StaticItem { ident, ty, mutability, @@ -839,9 +837,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } (ident, hir::ForeignItemKind::Static(ty, *mutability, safety)) } - ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => { - (ident, hir::ForeignItemKind::Type) - } + ForeignItemKind::TyAlias(TyAlias { ident, .. }) => (ident, hir::ForeignItemKind::Type), ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), }; @@ -980,7 +976,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let trait_item_def_id = hir_id.expect_owner(); let (ident, generics, kind, has_value) = match &i.kind { - AssocItemKind::Const(box ConstItem { + AssocItemKind::Const(ConstItem { ident, generics, ty, @@ -1020,9 +1016,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (*ident, generics, kind, rhs_kind.has_expr()) } - AssocItemKind::Fn(box Fn { - sig, ident, generics, body: None, define_opaque, .. - }) => { + AssocItemKind::Fn(Fn { sig, ident, generics, body: None, define_opaque, .. }) => { // FIXME(contracts): Deny contract here since it won't apply to // any impl method or callees. let idents = self.lower_fn_params_to_idents(&sig.decl); @@ -1047,7 +1041,7 @@ impl<'hir> LoweringContext<'_, 'hir> { false, ) } - AssocItemKind::Fn(box Fn { + AssocItemKind::Fn(Fn { sig, ident, generics, @@ -1082,7 +1076,7 @@ impl<'hir> LoweringContext<'_, 'hir> { true, ) } - AssocItemKind::Type(box TyAlias { + AssocItemKind::Type(TyAlias { ident, generics, after_where_clause, @@ -1115,7 +1109,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (*ident, generics, kind, ty.is_some()) } - AssocItemKind::Delegation(box delegation) => { + AssocItemKind::Delegation(delegation) => { let delegation_results = self.lower_delegation(delegation, i.id); let item_kind = hir::TraitItemKind::Fn( delegation_results.sig, @@ -1216,7 +1210,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let (ident, (generics, kind)) = match &i.kind { - AssocItemKind::Const(box ConstItem { + AssocItemKind::Const(ConstItem { ident, generics, ty, @@ -1240,14 +1234,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }, ), ), - AssocItemKind::Fn(box Fn { - sig, - ident, - generics, - body, - contract, - define_opaque, - .. + AssocItemKind::Fn(Fn { + sig, ident, generics, body, contract, define_opaque, .. }) => { let body_id = self.lower_maybe_coroutine_body( sig.span, @@ -1271,9 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id))) } - AssocItemKind::Type(box TyAlias { - ident, generics, after_where_clause, ty, .. - }) => { + AssocItemKind::Type(TyAlias { ident, generics, after_where_clause, ty, .. }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, after_where_clause, false); ( @@ -1307,7 +1293,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ), ) } - AssocItemKind::Delegation(box delegation) => { + AssocItemKind::Delegation(delegation) => { let delegation_results = self.lower_delegation(delegation, i.id); ( delegation.ident, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0c0763aeb59fd..1ce4478c09e8b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,7 +31,7 @@ //! in the HIR, especially for multiple identifiers. // tidy-alphabetical-start -#![feature(box_patterns)] +#![feature(deref_patterns)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d9f03342e1047..5725c65518845 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -607,7 +607,7 @@ impl<'a> AstValidator<'a> { } fn check_final_has_body(&self, item: &Item, defaultness: Defaultness) { - if let AssocItemKind::Fn(box Fn { body: None, .. }) = &item.kind + if let AssocItemKind::Fn(Fn { body: None, .. }) = &item.kind && let Defaultness::Final(def_span) = defaultness { let span = self.sess.source_map().guess_head_span(item.span); @@ -1163,8 +1163,7 @@ impl Visitor<'_> for AstValidator<'_> { ItemKind::Impl(Impl { generics, constness, - of_trait: - Some(box TraitImplHeader { safety, polarity, defaultness: _, trait_ref: t }), + of_trait: Some(TraitImplHeader { safety, polarity, defaultness: _, trait_ref: t }), self_ty, items, }) => { @@ -1234,7 +1233,7 @@ impl Visitor<'_> for AstValidator<'_> { ); } ItemKind::Fn( - func @ box Fn { + func @ Fn { defaultness, ident, generics: _, @@ -1328,14 +1327,8 @@ impl Visitor<'_> for AstValidator<'_> { visit::walk_item(this, item) }); } - ItemKind::Trait(box Trait { - constness, - is_auto, - generics, - ident, - bounds, - items, - .. + ItemKind::Trait(Trait { + constness, is_auto, generics, ident, bounds, items, .. }) => { self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident); if *is_auto == IsAuto::Yes { @@ -1360,7 +1353,7 @@ impl Visitor<'_> for AstValidator<'_> { walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait); }); } - ItemKind::TraitAlias(box TraitAlias { constness, generics, bounds, .. }) => { + ItemKind::TraitAlias(TraitAlias { constness, generics, bounds, .. }) => { let disallowed = matches!(constness, ast::Const::No) .then(|| TildeConstReason::Trait { span: item.span }); self.with_tilde_const(disallowed, |this| { @@ -1422,7 +1415,7 @@ impl Visitor<'_> for AstValidator<'_> { } }); } - ItemKind::Const(box ConstItem { defaultness, ident, rhs_kind, .. }) => { + ItemKind::Const(ConstItem { defaultness, ident, rhs_kind, .. }) => { self.check_defaultness(item.span, *defaultness, AllowDefault::No, AllowFinal::No); if !rhs_kind.has_expr() { self.dcx().emit_err(errors::ConstWithoutBody { @@ -1444,7 +1437,7 @@ impl Visitor<'_> for AstValidator<'_> { visit::walk_item(self, item); } - ItemKind::Static(box StaticItem { expr, safety, .. }) => { + ItemKind::Static(StaticItem { expr, safety, .. }) => { self.check_item_safety(item.span, *safety); if matches!(safety, Safety::Unsafe(_)) { self.dcx().emit_err(errors::UnsafeStatic { span: item.span }); @@ -1459,7 +1452,7 @@ impl Visitor<'_> for AstValidator<'_> { visit::walk_item(self, item); } ItemKind::TyAlias( - ty_alias @ box TyAlias { defaultness, bounds, after_where_clause, ty, .. }, + ty_alias @ TyAlias { defaultness, bounds, after_where_clause, ty, .. }, ) => { self.check_defaultness(item.span, *defaultness, AllowDefault::No, AllowFinal::No); if ty.is_none() { @@ -1490,7 +1483,7 @@ impl Visitor<'_> for AstValidator<'_> { fn visit_foreign_item(&mut self, fi: &ForeignItem) { match &fi.kind { - ForeignItemKind::Fn(box Fn { defaultness, ident, sig, body, .. }) => { + ForeignItemKind::Fn(Fn { defaultness, ident, sig, body, .. }) => { self.check_defaultness(fi.span, *defaultness, AllowDefault::No, AllowFinal::No); self.check_foreign_fn_bodyless(*ident, body.as_deref()); self.check_foreign_fn_headerless(sig.header); @@ -1511,7 +1504,7 @@ impl Visitor<'_> for AstValidator<'_> { }); } } - ForeignItemKind::TyAlias(box TyAlias { + ForeignItemKind::TyAlias(TyAlias { defaultness, ident, generics, @@ -1526,7 +1519,7 @@ impl Visitor<'_> for AstValidator<'_> { self.check_foreign_ty_genericless(generics, after_where_clause); self.check_foreign_item_ascii_only(*ident); } - ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => { + ForeignItemKind::Static(StaticItem { ident, safety, expr, .. }) => { self.check_item_safety(fi.span, *safety); self.check_foreign_kind_bodyless(*ident, "static", expr.as_ref().map(|b| b.span)); self.check_foreign_item_ascii_only(*ident); @@ -1818,7 +1811,7 @@ impl Visitor<'_> for AstValidator<'_> { if let AssocCtxt::Impl { .. } = ctxt { match &item.kind { - AssocItemKind::Const(box ConstItem { rhs_kind, .. }) => { + AssocItemKind::Const(ConstItem { rhs_kind, .. }) => { if !rhs_kind.has_expr() { self.dcx().emit_err(errors::AssocConstWithoutBody { span: item.span, @@ -1826,7 +1819,7 @@ impl Visitor<'_> for AstValidator<'_> { }); } } - AssocItemKind::Fn(box Fn { body, .. }) => { + AssocItemKind::Fn(Fn { body, .. }) => { if body.is_none() && !self.is_sdylib_interface { self.dcx().emit_err(errors::AssocFnWithoutBody { span: item.span, @@ -1834,7 +1827,7 @@ impl Visitor<'_> for AstValidator<'_> { }); } } - AssocItemKind::Type(box TyAlias { bounds, ty, .. }) => { + AssocItemKind::Type(TyAlias { bounds, ty, .. }) => { if ty.is_none() { self.dcx().emit_err(errors::AssocTypeWithoutBody { span: item.span, @@ -1889,13 +1882,13 @@ impl Visitor<'_> for AstValidator<'_> { &item.vis, errors::VisibilityNotPermittedNote::TraitImpl, ); - if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { + if let AssocItemKind::Fn(Fn { sig, .. }) = &item.kind { self.check_trait_fn_not_const(sig.header.constness, parent); self.check_async_fn_in_const_trait_or_impl(sig, parent); } } Some(parent @ TraitOrImpl::Impl { constness }) => { - if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { + if let AssocItemKind::Fn(Fn { sig, .. }) = &item.kind { self.check_impl_fn_not_const(sig.header.constness, *constness); self.check_async_fn_in_const_trait_or_impl(sig, parent); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 2b08906a77434..e38716cbb7fb7 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -228,7 +228,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Trait(box ast::Trait { is_auto: ast::IsAuto::Yes, .. }) => { + ast::ItemKind::Trait(ast::Trait { is_auto: ast::IsAuto::Yes, .. }) => { gate!(self, auto_traits, i.span, "auto traits are experimental and possibly buggy"); } @@ -241,10 +241,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate!(self, decl_macro, i.span, msg); } - ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { + ast::ItemKind::TyAlias(ast::TyAlias { ty: Some(ty), .. }) => { self.check_impl_trait(ty, false) } - ast::ItemKind::Const(box ast::ConstItem { + ast::ItemKind::Const(ast::ConstItem { rhs_kind: ast::ConstItemRhsKind::TypeConst { .. }, .. }) => { @@ -407,7 +407,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { let is_fn = match &i.kind { ast::AssocItemKind::Fn(_) => true, - ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => { + ast::AssocItemKind::Type(ast::TyAlias { ty, .. }) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate!( self, @@ -421,7 +421,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } false } - ast::AssocItemKind::Const(box ast::ConstItem { + ast::AssocItemKind::Const(ast::ConstItem { rhs_kind: ast::ConstItemRhsKind::TypeConst { rhs }, .. }) => { @@ -464,6 +464,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { check_incompatible_features(sess, features); check_dependent_features(sess, features); check_new_solver_banned_features(sess, features); + check_features_requiring_new_solver(sess, features); let mut visitor = PostExpansionVisitor { sess, features }; @@ -739,3 +740,25 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) { }); } } + +fn check_features_requiring_new_solver(sess: &Session, features: &Features) { + if sess.opts.unstable_opts.next_solver.globally { + return; + } + + // Require the new solver with GCA, because the old solver can't implement GCA correctly as it + // does not support normalization obligations for free and inherent consts. + if let Some(gca_span) = features + .enabled_lang_features() + .iter() + .find(|feat| feat.gate_name == sym::generic_const_args) + .map(|feat| feat.attr_sp) + { + #[allow(rustc::symbol_intern_string_literal)] + sess.dcx().emit_err(errors::MissingDependentFeatures { + parent_span: gca_span, + parent: sym::generic_const_args, + missing: String::from("-Znext-solver=globally"), + }); + } +} diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 677e44a79ac4b..8bf51dd10a844 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -3,7 +3,7 @@ //! by `rustc_ast_lowering`. // tidy-alphabetical-start -#![feature(box_patterns)] +#![feature(deref_patterns)] #![feature(iter_intersperse)] #![feature(iter_is_partitioned)] // tidy-alphabetical-end diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index bfc1d387b7009..694e2229830fe 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![feature(box_patterns)] +#![feature(deref_patterns)] #![feature(negative_impls)] // tidy-alphabetical-end diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 701152e9f9529..a20ef210da973 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -464,7 +464,7 @@ impl<'a> State<'a> { ast::ExprKind::Call(func, args) => { self.print_expr_call(func, args, fixup); } - ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => { + ast::ExprKind::MethodCall(ast::MethodCall { seg, receiver, args, .. }) => { self.print_expr_method_call(seg, receiver, args, fixup); } ast::ExprKind::Binary(op, lhs, rhs) => { @@ -582,7 +582,7 @@ impl<'a> State<'a> { let empty = attrs.is_empty() && arms.is_empty(); self.bclose(expr.span, empty, cb); } - ast::ExprKind::Closure(box ast::Closure { + ast::ExprKind::Closure(ast::Closure { binder, capture_clause, constness, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 5154e5dc005cd..b3a8f5d8cac30 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -36,7 +36,7 @@ impl<'a> State<'a> { ast::ForeignItemKind::Fn(func) => { self.print_fn_full(vis, attrs, &*func); } - ast::ForeignItemKind::Static(box ast::StaticItem { + ast::ForeignItemKind::Static(ast::StaticItem { ident, ty, mutability, @@ -56,7 +56,7 @@ impl<'a> State<'a> { define_opaque.as_deref(), eii_impls, ), - ast::ForeignItemKind::TyAlias(box ast::TyAlias { + ast::ForeignItemKind::TyAlias(ast::TyAlias { defaultness, ident, generics, @@ -190,7 +190,7 @@ impl<'a> State<'a> { self.print_use_tree(tree); self.word(";"); } - ast::ItemKind::Static(box StaticItem { + ast::ItemKind::Static(StaticItem { ident, ty, safety, @@ -224,7 +224,7 @@ impl<'a> State<'a> { } self.end(ib); } - ast::ItemKind::Const(box ast::ConstItem { + ast::ItemKind::Const(ast::ConstItem { defaultness, ident, generics, @@ -296,7 +296,7 @@ impl<'a> State<'a> { self.end(ib); self.end(cb); } - ast::ItemKind::TyAlias(box ast::TyAlias { + ast::ItemKind::TyAlias(ast::TyAlias { defaultness, ident, generics, @@ -340,7 +340,7 @@ impl<'a> State<'a> { } }; - if let Some(box of_trait) = of_trait { + if let Some(of_trait) = of_trait { let ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } = *of_trait; self.print_defaultness(defaultness); @@ -370,7 +370,7 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && items.is_empty(); self.bclose(item.span, empty, cb); } - ast::ItemKind::Trait(box ast::Trait { + ast::ItemKind::Trait(ast::Trait { impl_restriction, constness, safety, @@ -403,7 +403,7 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && items.is_empty(); self.bclose(item.span, empty, cb); } - ast::ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => { + ast::ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => { let (cb, ib) = self.head(""); self.print_visibility(&item.vis); self.print_constness(*constness); @@ -596,7 +596,7 @@ impl<'a> State<'a> { ast::AssocItemKind::Fn(func) => { self.print_fn_full(vis, attrs, &*func); } - ast::AssocItemKind::Const(box ast::ConstItem { + ast::AssocItemKind::Const(ast::ConstItem { defaultness, ident, generics, @@ -617,7 +617,7 @@ impl<'a> State<'a> { &[], ); } - ast::AssocItemKind::Type(box ast::TyAlias { + ast::AssocItemKind::Type(ast::TyAlias { defaultness, ident, generics, diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 76aecb3b9e54e..2155f94a7cfd3 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1464,14 +1464,6 @@ impl<'a> Linker for WasmLd<'a> { for (sym, _) in symbols { self.link_args(&["--export", sym]); } - - // LLD will hide these otherwise-internal symbols since it only exports - // symbols explicitly passed via the `--export` flags above and hides all - // others. Various bits and pieces of wasm32-unknown-unknown tooling use - // this, so be sure these symbols make their way out of the linker as well. - if matches!(self.sess.target.os, Os::Unknown | Os::None) { - self.link_args(&["--export=__heap_base", "--export=__data_end"]); - } } fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {} diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 5ec0344592da5..edbb668024455 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -81,7 +81,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> TyAndLayout<'tcx> { match layout.ty.kind() { ty::Adt(adt_def, _) if adt_def.repr().transparent() && may_unfold(*adt_def) => { - assert!(!adt_def.is_enum()); + assert_matches!(layout.variants, rustc_abi::Variants::Single { .. }); // Find the non-1-ZST field, and recurse. let (_, field) = layout.non_1zst_field(self).unwrap(); self.unfold_transparent(field, may_unfold) 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 473a32bac03a9..5a86e8186a5aa 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -3064,7 +3064,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - if tcx.is_type_const(def_id) { + // FIXME(gca): Intentionally disallowing paths to inherent associated non-type constants + // until a refactoring for how generic args for IACs are represented has been landed. + let is_inherent_assoc_const = tcx.def_kind(def_id) + == DefKind::AssocConst { is_type_const: false } + && tcx.def_kind(tcx.parent(def_id)) == DefKind::Impl { of_trait: false }; + if tcx.is_type_const(def_id) + || tcx.features().generic_const_args() && !is_inherent_assoc_const + { Ok(()) } else { let mut err = self.dcx().struct_span_err( diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 38c16fb1cd6d5..ed1b75bea29d9 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -273,6 +273,15 @@ fn main() { cfg.flag(&*flag); } + // Remap ci-llvm include paths in debug info for reproducible builds. + if let Some(maps) = tracked_env_var_os("RUSTC_DEBUGINFO_MAP") + && let Some(maps_str) = maps.to_str() + { + for map in maps_str.split('\t') { + cfg.flag_if_supported(&format!("-ffile-prefix-map={map}")); + } + } + for component in &components { let mut flag = String::from("LLVM_COMPONENT_"); flag.push_str(&component.to_uppercase()); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c7e8f99465e18..b03a07538ccd8 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -91,8 +91,12 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char *FileName) { extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, const char *Feature) { TargetMachine *Target = unwrap(TM); - const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - return MCInfo->checkFeatures(std::string("+") + Feature); +#if LLVM_VERSION_GE(23, 0) + const MCSubtargetInfo &MCInfo = Target->getMCSubtargetInfo(); +#else + const MCSubtargetInfo &MCInfo = *Target->getMCSubtargetInfo(); +#endif + return MCInfo.checkFeatures(std::string("+") + Feature); } /// Check whether the target has a specific assembly mnemonic like `ret` or @@ -274,7 +278,11 @@ static llvm::DebugCompressionType fromRust(LLVMRustCompressionKind Kind) { extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, RustStringRef OutStr) { ArrayRef CPUTable = +#if LLVM_VERSION_GE(23, 0) + unwrap(TM)->getMCSubtargetInfo().getAllProcessorDescriptions(); +#else unwrap(TM)->getMCSubtargetInfo()->getAllProcessorDescriptions(); +#endif auto OS = RawRustStringOstream(OutStr); // Just print a bare list of target CPU names, and let Rust-side code handle @@ -286,9 +294,13 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) { const TargetMachine *Target = unwrap(TM); - const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); +#if LLVM_VERSION_GE(23, 0) + const MCSubtargetInfo &MCInfo = Target->getMCSubtargetInfo(); +#else + const MCSubtargetInfo &MCInfo = *Target->getMCSubtargetInfo(); +#endif const ArrayRef FeatTable = - MCInfo->getAllProcessorFeatures(); + MCInfo.getAllProcessorFeatures(); return FeatTable.size(); } @@ -296,9 +308,13 @@ extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index, const char **Feature, const char **Desc) { const TargetMachine *Target = unwrap(TM); - const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); +#if LLVM_VERSION_GE(23, 0) + const MCSubtargetInfo &MCInfo = Target->getMCSubtargetInfo(); +#else + const MCSubtargetInfo &MCInfo = *Target->getMCSubtargetInfo(); +#endif const ArrayRef FeatTable = - MCInfo->getAllProcessorFeatures(); + MCInfo.getAllProcessorFeatures(); const SubtargetFeatureKV Feat = FeatTable[Index]; *Feature = Feat.Key; *Desc = Feat.Desc; diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 37273928d7d1f..bda9b3a47849e 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -317,11 +317,9 @@ impl<'tcx> TyCtxt<'tcx> { BodyOwnerKind::Static(mutability) => ConstContext::Static(mutability), BodyOwnerKind::Fn if self.is_constructor(def_id) => return None, - // Const closures use their parent's const context - BodyOwnerKind::Closure if self.is_const_fn(def_id) => { - return self.hir_body_const_context(self.local_parent(local_def_id)); + BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.is_const_fn(def_id) => { + ConstContext::ConstFn } - BodyOwnerKind::Fn if self.is_const_fn(def_id) => ConstContext::ConstFn, BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None, }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2d7cefd137d91..1c7bba82d3a7b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -106,6 +106,10 @@ impl<'tcx> rustc_type_ir::inherent::Features> for &'tcx rustc_featu self.generic_const_exprs() } + fn generic_const_args(self) -> bool { + self.generic_const_args() + } + fn coroutine_clone(self) -> bool { self.coroutine_clone() } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 6f6317d53d97b..bacddb6808290 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -172,6 +172,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { self.type_of_opaque_hir_typeck(def_id) } + fn is_type_const(self, def_id: DefId) -> bool { + self.is_type_const(def_id) + } fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { self.const_of_item(def_id) } 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 b9e1758be0fd4..4af2743b0a273 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 @@ -1200,6 +1200,44 @@ where self.delegate.evaluate_const(param_env, uv) } + pub(super) fn evaluate_const_and_instantiate_normalizes_to_term( + &mut self, + goal: Goal>, + uv: ty::UnevaluatedConst, + ) -> QueryResult { + match self.evaluate_const(goal.param_env, uv) { + Some(evaluated) => { + self.instantiate_normalizes_to_term(goal, evaluated.into()); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + None if self.cx().features().generic_const_args() => { + // HACK(khyperia): calling `resolve_vars_if_possible` here shouldn't be necessary, + // `try_evaluate_const` calls `resolve_vars_if_possible` already. However, we want + // to check `has_non_region_infer` against the type with vars resolved (i.e. check + // if there are vars we failed to resolve), so we need to call it again here. + // Perhaps we could split EvaluateConstErr::HasGenericsOrInfers into HasGenerics and + // HasInfers or something, make evaluate_const return that, and make this branch be + // based on that, rather than checking `has_non_region_infer`. + if self.resolve_vars_if_possible(uv).has_non_region_infer() { + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } else { + // We do not instantiate to the `uv` passed in, but rather + // `goal.predicate.alias`. The `uv` passed in might correspond to the `impl` + // form of a constant (with generic arguments corresponding to the impl block), + // however, we want to structurally instantiate to the original, non-rebased, + // trait `Self` form of the constant (with generic arguments being the trait + // `Self` type). + self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + } + None => { + // Legacy behavior: always treat as ambiguous + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } + } + } + pub(super) fn is_transmutable( &mut self, src: I::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 b3703639d99ef..72e8d1be5915e 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 @@ -2,7 +2,7 @@ use rustc_type_ir::{self as ty, Interner}; use tracing::instrument; use crate::delegate::SolverDelegate; -use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult}; +use crate::solve::{EvalCtxt, Goal, QueryResult}; impl EvalCtxt<'_, D> where @@ -14,17 +14,7 @@ where &mut self, goal: Goal>, ) -> QueryResult { - if let Some(normalized_const) = self.evaluate_const( - goal.param_env, - ty::UnevaluatedConst::new( - goal.predicate.alias.def_id().try_into().unwrap(), - goal.predicate.alias.args, - ), - ) { - self.instantiate_normalizes_to_term(goal, normalized_const.into()); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } else { - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } + let uv = goal.predicate.alias.expect_ct(self.cx()); + self.evaluate_const_and_instantiate_normalizes_to_term(goal, uv) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs index f3004e4c8105b..44fe2913b73de 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -30,13 +30,20 @@ where .map(|pred| goal.with(cx, pred)), ); - let actual = if free_alias.kind(cx).is_type() { - cx.type_of(free_alias.def_id()).instantiate(cx, free_alias.args).skip_norm_wip().into() - } else { - cx.const_of_item(free_alias.def_id()) - .instantiate(cx, free_alias.args) - .skip_norm_wip() - .into() + let actual = match free_alias.kind(cx) { + ty::AliasTermKind::FreeTy { def_id } => { + cx.type_of(def_id).instantiate(cx, free_alias.args).skip_norm_wip().into() + } + ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id) => { + cx.const_of_item(def_id).instantiate(cx, free_alias.args).skip_norm_wip().into() + } + ty::AliasTermKind::FreeConst { .. } => { + return self.evaluate_const_and_instantiate_normalizes_to_term( + goal, + free_alias.expect_ct(cx), + ); + } + kind => panic!("expected free alias, found {kind:?}"), }; self.instantiate_normalizes_to_term(goal, actual); diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 4d62407fe2995..00b5fd7fdcbce 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -52,13 +52,23 @@ where .map(|pred| goal.with(cx, pred)), ); - let normalized = if inherent.kind(cx).is_type() { - cx.type_of(inherent.def_id()).instantiate(cx, inherent_args).skip_norm_wip().into() - } else { - cx.const_of_item(inherent.def_id()) - .instantiate(cx, inherent_args) - .skip_norm_wip() - .into() + let normalized = match inherent.kind(cx) { + ty::AliasTermKind::InherentTy { def_id } => { + cx.type_of(def_id).instantiate(cx, inherent_args).skip_norm_wip().into() + } + ty::AliasTermKind::InherentConst { def_id } if cx.is_type_const(def_id) => { + cx.const_of_item(def_id).instantiate(cx, inherent_args).skip_norm_wip().into() + } + ty::AliasTermKind::InherentConst { .. } => { + // FIXME(gca): This is dead code at the moment. It should eventually call + // self.evaluate_const like projected consts do in consider_impl_candidate in + // normalizes_to/mod.rs. However, how generic args are represented for IACs is up in + // the air right now. + // Will self.evaluate_const eventually take the inherent_args or the impl_args form + // of args? It might be either. + panic!("References to inherent associated consts should have been blocked"); + } + kind => panic!("expected inherent alias, found {kind:?}"), }; self.instantiate_normalizes_to_term(goal, normalized); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) 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 d93b7843b2251..688c7fb2c2370 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 @@ -383,19 +383,30 @@ where // Finally we construct the actual value of the associated type. let term = match goal.predicate.alias.kind(cx) { - ty::AliasTermKind::ProjectionTy { .. } => { - cx.type_of(target_item_def_id).map_bound(|ty| ty.into()) + ty::AliasTermKind::ProjectionTy { .. } => cx + .type_of(target_item_def_id) + .instantiate(cx, target_args) + .skip_norm_wip() + .into(), + ty::AliasTermKind::ProjectionConst { .. } + if cx.is_type_const(target_item_def_id) => + { + cx.const_of_item(target_item_def_id) + .instantiate(cx, target_args) + .skip_norm_wip() + .into() } ty::AliasTermKind::ProjectionConst { .. } => { - cx.const_of_item(target_item_def_id).map_bound(|ct| ct.into()) + let uv = ty::UnevaluatedConst::new( + target_item_def_id.try_into().unwrap(), + target_args, + ); + return ecx.evaluate_const_and_instantiate_normalizes_to_term(goal, uv); } kind => panic!("expected projection, found {kind:?}"), }; - ecx.instantiate_normalizes_to_term( - goal, - term.instantiate(cx, target_args).skip_norm_wip(), - ); + ecx.instantiate_normalizes_to_term(goal, term); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs index 469f8272e1ccf..5ab81aa55787e 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs @@ -5,7 +5,13 @@ pub(crate) fn target() -> Target { base.max_atomic_width = Some(64); base.add_pre_link_args( LinkerFlavor::Unix(Cc::No), - &["-b64", "-bpT:0x100000000", "-bpD:0x110000000", "-bcdtors:mbr:0:s"], + &[ + "-b64", + "-bpT:0x100000000", + "-bpD:0x110000000", + "-bcdtors:mbr:0:s", + "-bdbg:namedsects:ss", // PGO and ifunc support depends on the named sections linker feature + ], ); Target { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 148f1471b1b66..b442faad70ef4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3642,27 +3642,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { already implement it", with_no_trimmed_paths!(tcx.def_path_str(def_id)), )); - let impls_of = tcx.trait_impls_of(def_id); - let impls = impls_of - .non_blanket_impls() - .values() - .flatten() - .chain(impls_of.blanket_impls().iter()) + let mut types = tcx + .all_impls(def_id) + .map(|t| { + with_no_trimmed_paths!(format!( + " {}", + tcx.type_of(t).instantiate_identity().skip_norm_wip(), + )) + }) .collect::>(); - if !impls.is_empty() { - let len = impls.len(); - let mut types = impls - .iter() - .map(|&&t| { - with_no_trimmed_paths!(format!( - " {}", - tcx.type_of(t) - .instantiate_identity() - .skip_norm_wip(), - )) - }) - .collect::>(); - let post = if types.len() > 9 { + if !types.is_empty() { + let len = types.len(); + let post = if len > 9 { types.truncate(8); format!("\nand {} others", len - 8) } else { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index e0eeca23c6d46..a834dbd1604f8 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -701,7 +701,10 @@ pub fn try_evaluate_const<'tcx>( // logic does not go through type system normalization. If it did this would // be a backwards compatibility problem as we do not enforce "syntactic" non- // usage of generic parameters like we do here. - if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { + if uv.args.has_non_region_param() + || uv.args.has_non_region_infer() + || uv.args.has_non_region_placeholders() + { return Err(EvaluateConstErr::HasGenericsOrInfers); } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 51173500f4718..fdf32d32e9058 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1065,7 +1065,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { ty::ConstKind::Unevaluated(uv) => { if !c.has_escaping_bound_vars() { // Skip type consts as mGCA doesn't support evaluatable clauses - if !tcx.is_type_const(uv.def) { + if !tcx.is_type_const(uv.def) && !tcx.features().generic_const_args() { let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::ConstEvaluatable(c), )); diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 3539215072ad9..f63361f5968d2 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -629,6 +629,8 @@ pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { pub trait Features: Copy { fn generic_const_exprs(self) -> bool; + fn generic_const_args(self) -> bool; + fn coroutine_clone(self) -> bool; fn feature_bound_holds_in_crate(self, symbol: I::Symbol) -> bool; diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index fba43b9cffbe2..03573012177d7 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -203,6 +203,7 @@ pub trait Interner: fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder; fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> ty::EarlyBinder; + fn is_type_const(self, def_id: Self::DefId) -> bool; fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder; fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 90240e241bc90..7b815e61cf09e 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -726,16 +726,32 @@ impl AliasTerm { AliasTermKind::InherentTy { def_id } => AliasTyKind::Inherent { def_id }, AliasTermKind::OpaqueTy { def_id } => AliasTyKind::Opaque { def_id }, AliasTermKind::FreeTy { def_id } => AliasTyKind::Free { def_id }, - AliasTermKind::InherentConst { .. } + kind @ (AliasTermKind::InherentConst { .. } | AliasTermKind::FreeConst { .. } | AliasTermKind::UnevaluatedConst { .. } - | AliasTermKind::ProjectionConst { .. } => { - panic!("Cannot turn `UnevaluatedConst` into `AliasTy`") + | AliasTermKind::ProjectionConst { .. }) => { + panic!("Cannot turn `{}` into `AliasTy`", kind.descr()) } }; ty::AliasTy { kind, args: self.args, _use_alias_ty_new_instead: () } } + pub fn expect_ct(self, interner: I) -> ty::UnevaluatedConst { + let def_id = match self.kind(interner) { + AliasTermKind::InherentConst { def_id } + | AliasTermKind::FreeConst { def_id } + | AliasTermKind::UnevaluatedConst { def_id } + | AliasTermKind::ProjectionConst { def_id } => def_id, + kind @ (AliasTermKind::ProjectionTy { .. } + | AliasTermKind::InherentTy { .. } + | AliasTermKind::OpaqueTy { .. } + | AliasTermKind::FreeTy { .. }) => { + panic!("Cannot turn `{}` into `UnevaluatedConst`", kind.descr()) + } + }; + ty::UnevaluatedConst { def: def_id.try_into().unwrap(), args: self.args } + } + // FIXME: remove this function (access the field instead) pub fn kind(self, _interner: I) -> AliasTermKind { self.kind diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index 6483f0861139b..6f2da15a98d69 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -31,7 +31,6 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; target_arch = "powerpc", target_arch = "sparc", target_arch = "arm", - target_arch = "wasm32" ))] mod arch { use crate::os::raw::{c_long, c_short, c_uint}; @@ -311,7 +310,9 @@ mod arch { } } -#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + // `wasm32-wali-linux-musl` uses ABI similar to x86_64 + target_arch = "wasm32"))] mod arch { use crate::os::raw::{c_int, c_long}; diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index fd5562a520b71..2659750f49eff 100644 --- a/library/std/src/sys/args/mod.rs +++ b/library/std/src/sys/args/mod.rs @@ -15,7 +15,7 @@ mod common; cfg_select! { any( - all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), + all(target_family = "unix", not(any(all(target_family = "wasm", target_os = "linux"), target_os = "espidf", target_os = "vita"))), target_os = "hermit", ) => { mod unix; @@ -45,6 +45,10 @@ cfg_select! { mod wasi; pub use wasi::*; } + all(target_family = "wasm", target_os = "linux") => { + mod wali; + pub use wali::*; + } target_os = "xous" => { mod xous; pub use xous::*; diff --git a/library/std/src/sys/args/wali.rs b/library/std/src/sys/args/wali.rs new file mode 100644 index 0000000000000..dc6295a483334 --- /dev/null +++ b/library/std/src/sys/args/wali.rs @@ -0,0 +1,54 @@ +pub use super::common::Args; + +/// One-time global initialization. +pub unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe { imp::init(argc, argv) } +} + +/// Returns the command line arguments +pub fn args() -> Args { + imp::args() +} + +mod imp { + use super::Args; + use crate::ffi::{CString, OsString}; + use crate::os::raw::{c_uint as WaliArgIdx, c_uint}; + use crate::os::unix::prelude::*; + use crate::sync::OnceLock; + + #[link(wasm_import_module = "wali")] + unsafe extern "C" { + pub fn __cl_get_argc() -> WaliArgIdx; + pub fn __cl_get_argv_len(offset: WaliArgIdx) -> c_uint; + pub fn __cl_copy_argv(buf: *mut i8, offset: WaliArgIdx) -> c_uint; + } + + static ARGS: OnceLock> = OnceLock::new(); + + pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + // Uses the WALI arguments API + ARGS.set(argc_argv()).ok(); + } + + unsafe fn load_arg(idx: c_uint) -> OsString { + let arg_len = unsafe { __cl_get_argv_len(idx) }; + let arg_buf = CString::new(vec![b'x'; arg_len as usize]).unwrap(); + let ptr = arg_buf.into_raw(); + let arg_buf = unsafe { + __cl_copy_argv(ptr, idx); + CString::from_raw(ptr) + }; + OsStringExt::from_vec(arg_buf.into_bytes()) + } + + fn argc_argv() -> Vec { + let argc = unsafe { __cl_get_argc() }; + (0..argc).map(|x| unsafe { load_arg(x) }).collect() + } + + pub fn args() -> Args { + let cached = ARGS.get().cloned().unwrap_or_default(); + Args::new(cached) + } +} diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm3.sh b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh index 17eb2cea59ac1..6ea6082b4ea0e 100755 --- a/src/ci/docker/scripts/x86_64-gnu-llvm3.sh +++ b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh @@ -14,10 +14,6 @@ set -ex # despite having different output on 32-bit vs 64-bit targets. ../x.py --stage 1 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu -# Run `ui-fulldeps` in `--stage=1`, which actually uses the stage0 -# compiler, and is sensitive to the addition of new flags. -../x.py --stage 1 test tests/ui-fulldeps - # Rebuild the stdlib with the size optimizations enabled and run tests again. RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \ library/std library/alloc library/core diff --git a/src/doc/rustc-dev-guide/src/feature-gate-check.md b/src/doc/rustc-dev-guide/src/feature-gate-check.md index 038a14ac070e1..0b4fc0cd680c0 100644 --- a/src/doc/rustc-dev-guide/src/feature-gate-check.md +++ b/src/doc/rustc-dev-guide/src/feature-gate-check.md @@ -69,6 +69,8 @@ in `check_crate` and its AST visitor. (declared in `rustc_feature::INCOMPATIBLE_FEATURES`) are not used together. - `check_new_solver_banned_features`: Bans features incompatible with compiler mode for the next trait solver. +- `check_features_requiring_new_solver`: Requires the new trait solver for + features incompatible with the old solver. - **Parser-gated spans**: Processes the `GatedSpans` recorded during parsing (see [Checking `GatedSpans`](#checking-gatedspans)). diff --git a/src/doc/unstable-book/src/language-features/generic-const-args.md b/src/doc/unstable-book/src/language-features/generic-const-args.md index b9870e60d0f91..c496c50bf0400 100644 --- a/src/doc/unstable-book/src/language-features/generic-const-args.md +++ b/src/doc/unstable-book/src/language-features/generic-const-args.md @@ -23,7 +23,8 @@ See also: [generic_const_items] ## Examples -```rust + +```rust,ignore (requires-Z-next-solver) #![feature(generic_const_items)] #![feature(min_generic_const_args)] #![feature(generic_const_args)] diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs index cd48bd2accb27..ca76897faea86 100644 --- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs +++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs @@ -63,13 +63,20 @@ fn test_abi_newtype() { #[repr(transparent)] #[derive(Copy, Clone)] struct Wrapper3(Zst, T, [u8; 0]); + #[repr(transparent)] + #[derive(Copy, Clone)] + enum Wrapper4 { + V(Zst, T, [u8; 0]) + } let t = T::default(); test_abi_compat(t, Wrapper(t)); test_abi_compat(t, Wrapper2(t, ())); test_abi_compat(t, Wrapper2a((), t)); test_abi_compat(t, Wrapper3(Zst, t, [])); - test_abi_compat(t, mem::MaybeUninit::new(t)); // MaybeUninit is `repr(transparent)` + test_abi_compat(t, Wrapper4::V(Zst, t, [])); + // MaybeUninit is `repr(transparent)`; that covers the `union` case. + test_abi_compat(t, mem::MaybeUninit::new(t)); } fn main() { diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr new file mode 100644 index 0000000000000..f609dcab752af --- /dev/null +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr @@ -0,0 +1,48 @@ +error[E0284]: type annotations needed for `([(); _], [(); 10])` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:29:9 + | +LL | let (mut arr, mut arr_with_weird_len) = free(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ type must be known at this point + | +note: required by a const generic parameter in `free` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:24:9 + | +LL | fn free() -> ([(); N], [(); FREE::]) { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `free` +help: consider giving this pattern a type, where the value of const parameter `N` is specified + | +LL | let (mut arr, mut arr_with_weird_len): ([_; N], _) = free(); + | +++++++++++++ + +error[E0271]: type mismatch resolving `10 == 2` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:35:45 + | +LL | let (mut arr, mut arr_with_weird_len) = free(); + | ^^^^^^ types differ + +error[E0284]: type annotations needed for `([(); _], [(); 10])` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:46:9 + | +LL | let (mut arr, mut arr_with_weird_len) = proj(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ type must be known at this point + | +note: required by a const generic parameter in `proj` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:41:9 + | +LL | fn proj() -> ([(); N], [(); ::PROJ::]) { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `proj` +help: consider giving this pattern a type, where the value of const parameter `N` is specified + | +LL | let (mut arr, mut arr_with_weird_len): ([_; N], _) = proj(); + | +++++++++++++ + +error[E0271]: type mismatch resolving `10 == 2` + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:52:45 + | +LL | let (mut arr, mut arr_with_weird_len) = proj(); + | ^^^^^^ types differ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0271, E0284. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr new file mode 100644 index 0000000000000..f27badafa2ca7 --- /dev/null +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr @@ -0,0 +1,10 @@ +error: `generic_const_args` requires -Znext-solver=globally to be enabled + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:9:12 + | +LL | #![feature(generic_const_args)] + | ^^^^^^^^^^^^^^^^^^ + | + = help: enable all of these features + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs new file mode 100644 index 0000000000000..72952940b1c12 --- /dev/null +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs @@ -0,0 +1,61 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +// (`test_free_mismatch` is quite difficult to implement in the old solver, so make sure this test +// runs on the old solver, just in case someone attempts to implement GCA for the old solver and +// removes the restriction that -Znext-solver must be enabled) + +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +//[old]~^ ERROR next-solver +#![expect(incomplete_features)] + +const FREE: usize = 10; + +trait Trait { + const PROJ: usize; +} +struct S; + +impl Trait for S { + const PROJ: usize = 10; +} + +fn free() -> ([(); N], [(); FREE::]) { + loop {} +} + +fn test_free() { + let (mut arr, mut arr_with_weird_len) = free(); + //[next]~^ ERROR type annotations needed + arr_with_weird_len = [(); 10]; +} + +fn test_free_mismatch() { + let (mut arr, mut arr_with_weird_len) = free(); + //[next]~^ ERROR type mismatch resolving `10 == 2` + arr_with_weird_len = [(); 2]; + arr = [(); 10]; +} + +fn proj() -> ([(); N], [(); ::PROJ::]) { + loop {} +} + +fn test_proj() { + let (mut arr, mut arr_with_weird_len) = proj(); + //[next]~^ ERROR type annotations needed + arr_with_weird_len = [(); 10]; +} + +fn test_proj_mismatch() { + let (mut arr, mut arr_with_weird_len) = proj(); + //[next]~^ ERROR type mismatch resolving `10 == 2` + arr_with_weird_len = [(); 2]; + arr = [(); 10]; +} + +fn main() { + test_free(); + test_proj(); +} diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars.rs b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars.rs new file mode 100644 index 0000000000000..4be1b036d6946 --- /dev/null +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars.rs @@ -0,0 +1,43 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +const FREE: usize = 10; + +trait Trait { + const PROJ: usize; +} +struct S; + +impl Trait for S { + const PROJ: usize = 10; +} + +fn free() -> ([(); N], [(); FREE::]) { + loop {} +} + +fn test_free() { + let (mut arr, mut arr_with_weird_len) = free(); + arr_with_weird_len = [(); 10]; + arr = [(); 10]; +} + +fn proj() -> ([(); N], [(); ::PROJ::]) { + loop {} +} + +fn test_proj() { + let (mut arr, mut arr_with_weird_len) = proj(); + arr_with_weird_len = [(); 10]; + arr = [(); 10]; +} + +fn main() { + test_free(); + test_proj(); +} diff --git a/tests/ui/const-generics/gca/basic-different-definitions.rs b/tests/ui/const-generics/gca/basic-different-definitions.rs index d96c718617d24..ec26f26630a57 100644 --- a/tests/ui/const-generics/gca/basic-different-definitions.rs +++ b/tests/ui/const-generics/gca/basic-different-definitions.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![feature(generic_const_items)] #![feature(min_generic_const_args)] diff --git a/tests/ui/const-generics/gca/basic.rs b/tests/ui/const-generics/gca/basic.rs index e80540d621de5..40c28c3d38c0e 100644 --- a/tests/ui/const-generics/gca/basic.rs +++ b/tests/ui/const-generics/gca/basic.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![feature(generic_const_items)] #![feature(min_generic_const_args)] diff --git a/tests/ui/const-generics/gca/coherence-fail.rs b/tests/ui/const-generics/gca/coherence-fail.rs index 1b181d792d362..079c8cf63e144 100644 --- a/tests/ui/const-generics/gca/coherence-fail.rs +++ b/tests/ui/const-generics/gca/coherence-fail.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![feature(generic_const_items, min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] diff --git a/tests/ui/const-generics/gca/coherence-fail.stderr b/tests/ui/const-generics/gca/coherence-fail.stderr index e8122c1b832f1..d180654cc84a6 100644 --- a/tests/ui/const-generics/gca/coherence-fail.stderr +++ b/tests/ui/const-generics/gca/coherence-fail.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait1` for type `[(); 2]` - --> $DIR/coherence-fail.rs:9:1 + --> $DIR/coherence-fail.rs:10:1 | LL | impl Trait1 for [(); FOO::<1>] {} | ------------------------------ first implementation here @@ -7,7 +7,7 @@ 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 + --> $DIR/coherence-fail.rs:17:1 | LL | impl Trait2 for [(); DIV2::<2>] {} | ------------------------------- first implementation here @@ -15,7 +15,7 @@ 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 + --> $DIR/coherence-fail.rs:26:1 | LL | impl Trait3 for [(); ADD1::<1>] {} | ------------------------------- first implementation here diff --git a/tests/ui/const-generics/gca/coherence-ok.rs b/tests/ui/const-generics/gca/coherence-ok.rs index 447f25bfdc36b..38899badf5f03 100644 --- a/tests/ui/const-generics/gca/coherence-ok.rs +++ b/tests/ui/const-generics/gca/coherence-ok.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![feature(generic_const_items, min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] diff --git a/tests/ui/const-generics/gca/generic-free-const.rs b/tests/ui/const-generics/gca/generic-free-const.rs new file mode 100644 index 0000000000000..e7816728d461e --- /dev/null +++ b/tests/ui/const-generics/gca/generic-free-const.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![feature(generic_const_items)] +#![expect(incomplete_features)] + +const ADD1: usize = N + 1; + +fn a() -> [usize; ADD1::] { + [ADD1::; ADD1::] +} + +fn main() { + let _: [(); ADD1::<1>] = [(); ADD1::<1>]; + let _: [(); ADD1::<{ ADD1::<1> }>] = [(); ADD1::<2>]; + a::<2>(); +} diff --git a/tests/ui/const-generics/gca/generic-param-rhs.rs b/tests/ui/const-generics/gca/generic-param-rhs.rs index ed4467d6f0039..ea6e2d7398b57 100644 --- a/tests/ui/const-generics/gca/generic-param-rhs.rs +++ b/tests/ui/const-generics/gca/generic-param-rhs.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![feature(min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] diff --git a/tests/ui/const-generics/gca/generic-param-rhs.stderr b/tests/ui/const-generics/gca/generic-param-rhs.stderr index acf3a5b21a855..ca0ce899b8b0d 100644 --- a/tests/ui/const-generics/gca/generic-param-rhs.stderr +++ b/tests/ui/const-generics/gca/generic-param-rhs.stderr @@ -1,5 +1,5 @@ error: generic parameters in const blocks are only allowed as the direct value of a `type const` - --> $DIR/generic-param-rhs.rs:6:19 + --> $DIR/generic-param-rhs.rs:7:19 | LL | foo::(); | ^ diff --git a/tests/ui/const-generics/gca/non-type-equality-fail.rs b/tests/ui/const-generics/gca/non-type-equality-fail.rs new file mode 100644 index 0000000000000..235ab37f8b570 --- /dev/null +++ b/tests/ui/const-generics/gca/non-type-equality-fail.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -Znext-solver + +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + const PROJECTED_A: usize; + const PROJECTED_B: usize; +} + +struct StructImpl; +struct GenericStructImpl; + +impl Trait for StructImpl { + const PROJECTED_A: usize = 1; + const PROJECTED_B: usize = 1; +} + +impl Trait for GenericStructImpl { + const PROJECTED_A: usize = N; + const PROJECTED_B: usize = N; +} + +const FREE_A: usize = 1; +const FREE_B: usize = 1; + +struct Struct; + +fn f() { + let _: Struct<{ as Trait>::PROJECTED_A }> = + Struct::<{ as Trait>::PROJECTED_B }>; + //~^ ERROR mismatched types +} + +fn g() { + let _: Struct<{ T::PROJECTED_A }> = Struct::<{ T::PROJECTED_B }>; + //~^ ERROR mismatched types +} + +fn main() { + f::<2>(); + g::(); +} diff --git a/tests/ui/const-generics/gca/non-type-equality-fail.stderr b/tests/ui/const-generics/gca/non-type-equality-fail.stderr new file mode 100644 index 0000000000000..796efdcea93cc --- /dev/null +++ b/tests/ui/const-generics/gca/non-type-equality-fail.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/non-type-equality-fail.rs:32:9 + | +LL | let _: Struct<{ as Trait>::PROJECTED_A }> = + | -------------------------------------------------------- expected due to this +LL | Struct::<{ as Trait>::PROJECTED_B }>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | + = note: expected struct `Struct< as Trait>::PROJECTED_A>` + found struct `Struct< as Trait>::PROJECTED_B>` + +error[E0308]: mismatched types + --> $DIR/non-type-equality-fail.rs:37:41 + | +LL | let _: Struct<{ T::PROJECTED_A }> = Struct::<{ T::PROJECTED_B }>; + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | | + | expected due to this + | + = note: expected struct `Struct<::PROJECTED_A>` + found struct `Struct<::PROJECTED_B>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/gca/non-type-equality-ok.rs b/tests/ui/const-generics/gca/non-type-equality-ok.rs new file mode 100644 index 0000000000000..443fbc46bd8a0 --- /dev/null +++ b/tests/ui/const-generics/gca/non-type-equality-ok.rs @@ -0,0 +1,47 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![feature(generic_const_items)] +#![expect(incomplete_features)] + +trait Trait { + const PROJECTED_A: usize; + const PROJECTED_B: usize; +} + +struct StructImpl; +struct GenericStructImpl; + +impl Trait for StructImpl { + const PROJECTED_A: usize = 1; + const PROJECTED_B: usize = 1; +} + +impl Trait for GenericStructImpl { + const PROJECTED_A: usize = N; + const PROJECTED_B: usize = N; +} + +const FREE_A: usize = 1; +const FREE_B: usize = 1; + +struct Struct; + +fn f() { + let _: Struct<{ as Trait>::PROJECTED_A }> = + Struct::<{ as Trait>::PROJECTED_A }>; +} + +fn g() { + let _: Struct<{ T::PROJECTED_A }> = Struct::<{ T::PROJECTED_A }>; +} + +fn main() { + let _: Struct = Struct::; + let _: Struct<{ ::PROJECTED_A }> = + Struct::<{ ::PROJECTED_B }>; + let _: Struct<{ as Trait>::PROJECTED_A }> = + Struct::<{ as Trait>::PROJECTED_B }>; +} diff --git a/tests/ui/const-generics/gca/path-to-non-type-const.rs b/tests/ui/const-generics/gca/path-to-non-type-const.rs new file mode 100644 index 0000000000000..c36dbbcc578fa --- /dev/null +++ b/tests/ui/const-generics/gca/path-to-non-type-const.rs @@ -0,0 +1,35 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + const PROJECTED: usize; +} + +struct StructImpl; +struct GenericStructImpl; + +const FREE: usize = 1; + +impl Trait for StructImpl { + const PROJECTED: usize = 1; +} + +impl Trait for GenericStructImpl { + const PROJECTED: usize = A; +} + +struct Struct; + +fn f() { + let _ = Struct::<{ T::PROJECTED }>; +} + +fn main() { + let _ = Struct::; + let _ = Struct::<{ ::PROJECTED }>; + let _ = Struct::<{ as Trait>::PROJECTED }>; +} diff --git a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs new file mode 100644 index 0000000000000..1b9164d4a2300 --- /dev/null +++ b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs @@ -0,0 +1,28 @@ +//! This test should be part of path-to-non-type-const.rs, and should pass. However, we are holding +//! off on implementing paths to IACs until a refactoring of how IAC generics are represented. +//@ compile-flags: -Znext-solver + +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![feature(inherent_associated_types)] +#![expect(incomplete_features)] + +struct StructImpl; +struct GenericStructImpl; + +impl StructImpl { + const INHERENT: usize = 1; +} + +impl GenericStructImpl { + const INHERENT: usize = A; +} + +struct Struct; + +fn main() { + let _ = Struct::<{ StructImpl::INHERENT }>; + //~^ ERROR use of `const` in the type system not defined as `type const` + let _ = Struct::<{ GenericStructImpl::<2>::INHERENT }>; + //~^ ERROR use of `const` in the type system not defined as `type const` +} diff --git a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr new file mode 100644 index 0000000000000..b5da53f0f1c8e --- /dev/null +++ b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr @@ -0,0 +1,24 @@ +error: use of `const` in the type system not defined as `type const` + --> $DIR/path-to-non-type-inherent-associated-const.rs:24:24 + | +LL | let _ = Struct::<{ StructImpl::INHERENT }>; + | ^^^^^^^^^^^^^^^^^^^^ + | +help: add `type` before `const` for `StructImpl::INHERENT` + | +LL | type const INHERENT: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/path-to-non-type-inherent-associated-const.rs:26:24 + | +LL | let _ = Struct::<{ GenericStructImpl::<2>::INHERENT }>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: add `type` before `const` for `GenericStructImpl::::INHERENT` + | +LL | type const INHERENT: usize = A; + | ++++ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/gca/require-next-solver.rs b/tests/ui/const-generics/gca/require-next-solver.rs new file mode 100644 index 0000000000000..ffe3141b0f28a --- /dev/null +++ b/tests/ui/const-generics/gca/require-next-solver.rs @@ -0,0 +1,4 @@ +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +//~^ ERROR next-solver +fn main() {} diff --git a/tests/ui/const-generics/gca/require-next-solver.stderr b/tests/ui/const-generics/gca/require-next-solver.stderr new file mode 100644 index 0000000000000..677c37610d842 --- /dev/null +++ b/tests/ui/const-generics/gca/require-next-solver.stderr @@ -0,0 +1,10 @@ +error: `generic_const_args` requires -Znext-solver=globally to be enabled + --> $DIR/require-next-solver.rs:2:12 + | +LL | #![feature(generic_const_args)] + | ^^^^^^^^^^^^^^^^^^ + | + = help: enable all of these features + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/gca/rhs-but-not-root.rs b/tests/ui/const-generics/gca/rhs-but-not-root.rs index 6c0337dbbd470..61762a2851356 100644 --- a/tests/ui/const-generics/gca/rhs-but-not-root.rs +++ b/tests/ui/const-generics/gca/rhs-but-not-root.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![feature(generic_const_items)] #![feature(min_generic_const_args)] #![feature(generic_const_args)] diff --git a/tests/ui/const-generics/gca/rhs-but-not-root.stderr b/tests/ui/const-generics/gca/rhs-but-not-root.stderr index 6481407eedc42..06f5ae248ac14 100644 --- a/tests/ui/const-generics/gca/rhs-but-not-root.stderr +++ b/tests/ui/const-generics/gca/rhs-but-not-root.stderr @@ -1,5 +1,5 @@ error: generic parameters in const blocks are only allowed as the direct value of a `type const` - --> $DIR/rhs-but-not-root.rs:7:54 + --> $DIR/rhs-but-not-root.rs:8:54 | LL | type const FOO: usize = ID::; | ^ diff --git a/tests/ui/traits/const-traits/call-const-closure.next.stderr b/tests/ui/traits/const-traits/call-const-closure.next.stderr index 16b936d58aaf6..9a851a97f186a 100644 --- a/tests/ui/traits/const-traits/call-const-closure.next.stderr +++ b/tests/ui/traits/const-traits/call-const-closure.next.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): const Bar` is not satisfied +error[E0277]: the trait bound `(): [const] Bar` is not satisfied --> $DIR/call-const-closure.rs:16:18 | LL | (const || ().foo())(); diff --git a/tests/ui/traits/const-traits/call-const-closure.old.stderr b/tests/ui/traits/const-traits/call-const-closure.old.stderr index 16b936d58aaf6..9a851a97f186a 100644 --- a/tests/ui/traits/const-traits/call-const-closure.old.stderr +++ b/tests/ui/traits/const-traits/call-const-closure.old.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): const Bar` is not satisfied +error[E0277]: the trait bound `(): [const] Bar` is not satisfied --> $DIR/call-const-closure.rs:16:18 | LL | (const || ().foo())(); diff --git a/tests/ui/traits/const-traits/call-const-closure.rs b/tests/ui/traits/const-traits/call-const-closure.rs index 2cf561ae6db14..5a5369a075358 100644 --- a/tests/ui/traits/const-traits/call-const-closure.rs +++ b/tests/ui/traits/const-traits/call-const-closure.rs @@ -14,7 +14,7 @@ impl Bar for () { const FOO: () = { (const || ().foo())(); - //~^ ERROR the trait bound `(): const Bar` is not satisfied + //~^ ERROR the trait bound `(): [const] Bar` is not satisfied }; fn main() {} diff --git a/tests/ui/traits/const-traits/const-closure-fn-ptr-const-item.rs b/tests/ui/traits/const-traits/const-closure-fn-ptr-const-item.rs new file mode 100644 index 0000000000000..1c24112883708 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-fn-ptr-const-item.rs @@ -0,0 +1,11 @@ +//@ run-pass + +// Regression test for https://github.com/rust-lang/rust/issues/155803 + +#![feature(const_closures, const_trait_impl)] + +const F: fn() -> i32 = const || 42; + +fn main() { + assert_eq!(F(), 42); +} diff --git a/tests/ui/traits/const-traits/const-closure-link-dead-code.rs b/tests/ui/traits/const-traits/const-closure-link-dead-code.rs new file mode 100644 index 0000000000000..b28234c355eec --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-link-dead-code.rs @@ -0,0 +1,12 @@ +//@ build-pass +//@ compile-flags: -Clink-dead-code=true + +// Regression test for https://github.com/rust-lang/rust/issues/155803 + +#![feature(const_closures, const_trait_impl)] + +const _: () = { + assert!((const || true)()); +}; + +fn main() {} diff --git a/tests/ui/traits/next-solver/self-referential-closure-sig-4.rs b/tests/ui/traits/next-solver/generalize/alias-with-bound-vars-incomplete-generalization.rs similarity index 75% rename from tests/ui/traits/next-solver/self-referential-closure-sig-4.rs rename to tests/ui/traits/next-solver/generalize/alias-with-bound-vars-incomplete-generalization.rs index fb6297869356c..bf2276e4967b0 100644 --- a/tests/ui/traits/next-solver/self-referential-closure-sig-4.rs +++ b/tests/ui/traits/next-solver/generalize/alias-with-bound-vars-incomplete-generalization.rs @@ -2,7 +2,9 @@ //@[next] compile-flags: -Znext-solver //@ check-pass -// Regression test for the fourth variant of trait-system-refactor-initiative#191 +// Regression test for the fourth variant of trait-system-refactor-initiative#191. +// We previously didn't normalize `<() as Trait>::Assoc<'a>` before generalizing +// here, resulting in an error. trait Trait { type Assoc<'a>;