From b071f6405cd7622b12bd45c4d6d77c7663a97816 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 15 Oct 2024 14:40:59 +0200 Subject: [PATCH 01/17] Emscripten: link with -sWASM_BIGINT When linking an executable without dynamic linking, this is a pure improvement. It significantly reduces code size and avoids a lot of buggy behaviors. It is supported in all browsers for many years and in all maintained versions of Node. It does change the ABI, so people who are dynamically linking with a library or executable that uses the old ABI may need to turn it off. It can be disabled if needed by passing `-Clink-arg -sWASM_BIGINT=0` to `rustc`. But few people will want to turn it off. --- .../src/spec/targets/wasm32_unknown_emscripten.rs | 3 ++- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs index a213adadbea78..a70cebbd9c883 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs @@ -5,7 +5,8 @@ use crate::spec::{ pub(crate) fn target() -> Target { // Reset flags for non-Em flavors back to empty to satisfy sanity checking tests. let pre_link_args = LinkArgs::new(); - let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]); + let post_link_args = + TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-sWASM_BIGINT"]); let opts = TargetOptions { os: "emscripten".into(), diff --git a/library/Cargo.lock b/library/Cargo.lock index 772f9b1969565..84c20ec6f876f 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index b732fdf16968e..c1ab70b714a4c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -34,7 +34,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false } addr2line = { version = "0.22.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.161", default-features = false, features = [ +libc = { version = "0.2.162", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } From f2f7d329485d966fd5b2d207fca5e94c315a362f Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:32:16 -0300 Subject: [PATCH 02/17] FieldDef --- compiler/rustc_ast/src/mut_visit.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a09aa9ee66516..578b9bbe199fb 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -116,6 +116,10 @@ pub trait MutVisitor: Sized { walk_fn_header(self, header); } + fn visit_field_def(&mut self, fd: &mut FieldDef) { + walk_field_def(self, fd); + } + fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { walk_flat_map_field_def(self, fd) } @@ -1050,17 +1054,21 @@ fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { vis.visit_span(span); } -pub fn walk_flat_map_field_def( - visitor: &mut T, - mut fd: FieldDef, -) -> SmallVec<[FieldDef; 1]> { - let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; +pub fn walk_field_def(visitor: &mut T, fd: &mut FieldDef) { + let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd; visitor.visit_id(id); visit_attrs(visitor, attrs); visitor.visit_vis(vis); visit_opt(ident, |ident| visitor.visit_ident(ident)); visitor.visit_ty(ty); visitor.visit_span(span); +} + +pub fn walk_flat_map_field_def( + vis: &mut T, + mut fd: FieldDef, +) -> SmallVec<[FieldDef; 1]> { + vis.visit_field_def(&mut fd); smallvec![fd] } From b96758bb71cfb71b3e335b07d86389f53414f1c0 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:37:48 -0300 Subject: [PATCH 03/17] Arm --- compiler/rustc_ast/src/mut_visit.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 578b9bbe199fb..5ff65e9d44d7b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -157,6 +157,10 @@ pub trait MutVisitor: Sized { walk_flat_map_stmt(self, s) } + fn visit_arm(&mut self, arm: &mut Arm) { + walk_arm(self, arm); + } + fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { walk_flat_map_arm(self, arm) } @@ -459,14 +463,18 @@ fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { vis.visit_span(span); } -pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { - let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; +pub fn walk_arm(vis: &mut T, arm: &mut Arm) { + let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_pat(pat); visit_opt(guard, |guard| vis.visit_expr(guard)); visit_opt(body, |body| vis.visit_expr(body)); vis.visit_span(span); +} + +pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { + vis.visit_arm(&mut arm); smallvec![arm] } From e52cef19a4b2a83e803ce8d2d5b1189e2b848d0d Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:41:16 -0300 Subject: [PATCH 04/17] Variant --- compiler/rustc_ast/src/mut_visit.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 5ff65e9d44d7b..735002e25a507 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -207,6 +207,10 @@ pub trait MutVisitor: Sized { walk_foreign_mod(self, nm); } + fn visit_variant(&mut self, v: &mut Variant) { + walk_variant(self, v); + } + fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { walk_flat_map_variant(self, v) } @@ -551,11 +555,8 @@ fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); } -pub fn walk_flat_map_variant( - visitor: &mut T, - mut variant: Variant, -) -> SmallVec<[Variant; 1]> { - let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; +pub fn walk_variant(visitor: &mut T, variant: &mut Variant) { + let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant; visitor.visit_id(id); visit_attrs(visitor, attrs); visitor.visit_vis(vis); @@ -563,6 +564,13 @@ pub fn walk_flat_map_variant( visitor.visit_variant_data(data); visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); visitor.visit_span(span); +} + +pub fn walk_flat_map_variant( + vis: &mut T, + mut variant: Variant, +) -> SmallVec<[Variant; 1]> { + vis.visit_variant(&mut variant); smallvec![variant] } From f4fbe88a4d8e34e34112bb7d16d274cca396ec77 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:43:40 -0300 Subject: [PATCH 05/17] Param --- compiler/rustc_ast/src/mut_visit.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 735002e25a507..c5c26b0bbc17d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -263,6 +263,10 @@ pub trait MutVisitor: Sized { walk_attribute(self, at); } + fn visit_param(&mut self, param: &mut Param) { + walk_param(self, param); + } + fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { walk_flat_map_param(self, param) } @@ -701,13 +705,17 @@ fn walk_meta_item(vis: &mut T, mi: &mut MetaItem) { vis.visit_span(span); } -pub fn walk_flat_map_param(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> { - let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; +pub fn walk_param(vis: &mut T, param: &mut Param) { + let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_pat(pat); vis.visit_ty(ty); vis.visit_span(span); +} + +pub fn walk_flat_map_param(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> { + vis.visit_param(&mut param); smallvec![param] } From 8b0284afd3735a94878a73ecb6d84be8d3842247 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:45:19 -0300 Subject: [PATCH 06/17] GenericParam --- compiler/rustc_ast/src/mut_visit.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index c5c26b0bbc17d..731e5b601ea55 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -287,6 +287,10 @@ pub trait MutVisitor: Sized { walk_variant_data(self, vdata); } + fn visit_generic_param(&mut self, param: &mut GenericParam) { + walk_generic_param(self, param) + } + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { walk_flat_map_generic_param(self, param) } @@ -974,11 +978,8 @@ fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCaptu } } -pub fn walk_flat_map_generic_param( - vis: &mut T, - mut param: GenericParam, -) -> SmallVec<[GenericParam; 1]> { - let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; +pub fn walk_generic_param(vis: &mut T, param: &mut GenericParam) { + let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_ident(ident); @@ -996,6 +997,13 @@ pub fn walk_flat_map_generic_param( if let Some(colon_span) = colon_span { vis.visit_span(colon_span); } +} + +pub fn walk_flat_map_generic_param( + vis: &mut T, + mut param: GenericParam, +) -> SmallVec<[GenericParam; 1]> { + vis.visit_generic_param(&mut param); smallvec![param] } From eb2f1c85b32e591293c8242230ad9bdca9d3c69b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:48:03 -0300 Subject: [PATCH 07/17] ExprField --- compiler/rustc_ast/src/mut_visit.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 731e5b601ea55..4987e218933ad 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -307,6 +307,10 @@ pub trait MutVisitor: Sized { walk_mt(self, mt); } + fn visit_expr_field(&mut self, f: &mut ExprField) { + walk_expr_field(self, f); + } + fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { walk_flat_map_expr_field(self, f) } @@ -1104,16 +1108,20 @@ pub fn walk_flat_map_field_def( smallvec![fd] } -pub fn walk_flat_map_expr_field( - vis: &mut T, - mut f: ExprField, -) -> SmallVec<[ExprField; 1]> { - let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; +pub fn walk_expr_field(vis: &mut T, f: &mut ExprField) { + let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_ident(ident); vis.visit_expr(expr); vis.visit_span(span); +} + +pub fn walk_flat_map_expr_field( + vis: &mut T, + mut f: ExprField, +) -> SmallVec<[ExprField; 1]> { + vis.visit_expr_field(&mut f); smallvec![f] } From 5c2de73700d351b5ec4182f9ea13ce4e702686b3 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 19:49:29 -0300 Subject: [PATCH 08/17] PatField --- compiler/rustc_ast/src/mut_visit.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 4987e218933ad..2158ed33e6e3d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -335,6 +335,10 @@ pub trait MutVisitor: Sized { // Do nothing. } + fn visit_pat_field(&mut self, fp: &mut PatField) { + walk_pat_field(self, fp) + } + fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { walk_flat_map_pat_field(self, fp) } @@ -449,16 +453,20 @@ pub fn visit_delim_span(vis: &mut T, DelimSpan { open, close }: & vis.visit_span(close); } -pub fn walk_flat_map_pat_field( - vis: &mut T, - mut fp: PatField, -) -> SmallVec<[PatField; 1]> { - let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; +pub fn walk_pat_field(vis: &mut T, fp: &mut PatField) { + let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_ident(ident); vis.visit_pat(pat); vis.visit_span(span); +} + +pub fn walk_flat_map_pat_field( + vis: &mut T, + mut fp: PatField, +) -> SmallVec<[PatField; 1]> { + vis.visit_pat_field(&mut fp); smallvec![fp] } From 588c4c45d55556ec7dcaad746ff1af3ca991b64a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 19 Nov 2024 20:30:58 +0000 Subject: [PATCH 09/17] Rename implied_const_bounds to explicit_implied_const_bounds --- .../rustc_hir_analysis/src/check/compare_impl_item.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 4 ++-- compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++++---- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 ++-- .../rustc_next_trait_solver/src/solve/assembly/mod.rs | 2 +- .../rustc_next_trait_solver/src/solve/effect_goals.rs | 5 +---- compiler/rustc_type_ir/src/elaborate.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 2 +- 12 files changed, 17 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 77c324183c357..c004a37137b8b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2083,7 +2083,7 @@ pub(super) fn check_type_bounds<'tcx>( // Only in a const implementation do we need to check that the `~const` item bounds hold. if tcx.is_conditionally_const(impl_ty_def_id) { obligations.extend( - tcx.implied_const_bounds(trait_ty.def_id) + tcx.explicit_implied_const_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) .map(|(c, span)| { traits::Obligation::new( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 63a0e7d31c3b0..001118eb8d32f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) { predicates_of::explicit_supertraits_containing_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, const_conditions: predicates_of::const_conditions, - implied_const_bounds: predicates_of::implied_const_bounds, + explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, adt_def, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 7ce12d48160aa..a675a7fc76839 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1017,7 +1017,7 @@ pub(super) fn const_conditions<'tcx>( } } -pub(super) fn implied_const_bounds<'tcx>( +pub(super) fn explicit_implied_const_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { @@ -1036,7 +1036,7 @@ pub(super) fn implied_const_bounds<'tcx>( Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => { explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) } - _ => bug!("implied_const_bounds called on wrong item: {def_id:?}"), + _ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"), }; bounds.map_bound(|bounds| { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 045fd0565ba0d..a89096beb8c31 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -275,7 +275,7 @@ provide! { tcx, def_id, other, cdata, defaultness => { table_direct } constness => { table_direct } const_conditions => { table } - implied_const_bounds => { table_defaulted_array } + explicit_implied_const_bounds => { table_defaulted_array } coerce_unsized_info => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b5391247cea54..1ac5f1401d6ee 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1463,8 +1463,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|child| child.res.def_id().index)); if self.tcx.is_const_trait(def_id) { - record_defaulted_array!(self.tables.implied_const_bounds[def_id] - <- self.tcx.implied_const_bounds(def_id).skip_binder()); + record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] + <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); } } if let DefKind::TraitAlias = def_kind { @@ -1654,8 +1654,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_super_predicates(def_id); if tcx.is_conditionally_const(def_id) { - record_defaulted_array!(self.tables.implied_const_bounds[def_id] - <- self.tcx.implied_const_bounds(def_id).skip_binder()); + record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] + <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); } } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 58f58efb116fe..4a8f8521b4ff7 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -391,7 +391,7 @@ define_tables! { inferred_outlives_of: Table, Span)>>, explicit_super_predicates_of: Table, Span)>>, explicit_implied_predicates_of: Table, Span)>>, - implied_const_bounds: Table, Span)>>, + explicit_implied_const_bounds: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, opt_rpitit_info: Table>>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 684d5b6c2a778..bb6175cc2cee0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -697,7 +697,7 @@ rustc_queries! { separate_provide_extern } - query implied_const_bounds( + query explicit_implied_const_bounds( key: DefId ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { desc { |tcx| "computing the implied `~const` bounds for `{}`", diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2ba1bf2822fbb..9ccfd8e1117c2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -387,12 +387,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) } - fn implied_const_bounds( + fn explicit_implied_const_bounds( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { ty::EarlyBinder::bind( - self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), + self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), ) } 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 ebf7372926f8a..9f01acb2f6d11 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -102,7 +102,7 @@ where /// Assemble additional assumptions for an alias that are not included /// in the item bounds of the alias. For now, this is limited to the - /// `implied_const_bounds` for an associated type. + /// `explicit_implied_const_bounds` for an associated type. fn consider_additional_alias_assumptions( ecx: &mut EvalCtxt<'_, D>, goal: Goal, 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 0912e5effa63d..bb082a0eb5a34 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -84,12 +84,9 @@ where let cx = ecx.cx(); let mut candidates = vec![]; - // FIXME(const_trait_impl): We elaborate here because the implied const bounds - // aren't necessarily elaborated. We probably should prefix this query - // with `explicit_`... for clause in elaborate::elaborate( cx, - cx.implied_const_bounds(alias_ty.def_id) + cx.explicit_implied_const_bounds(alias_ty.def_id) .iter_instantiated(cx, alias_ty.args) .map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)), ) { diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 3fbce7886edcb..2c1ad9de9aa8b 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -157,7 +157,7 @@ impl> Elaborator { } // `T: ~const Trait` implies `T: ~const Supertrait`. ty::ClauseKind::HostEffect(data) => self.extend_deduped( - cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { + cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { elaboratable.child( trait_ref .to_host_effect_clause(cx, data.constness) diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index f988f003c0f95..d5f5ccce9c50b 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -228,7 +228,7 @@ pub trait Interner: self, def_id: Self::DefId, ) -> ty::EarlyBinder>>>; - fn implied_const_bounds( + fn explicit_implied_const_bounds( self, def_id: Self::DefId, ) -> ty::EarlyBinder>>>; From 5eeaf2ec3310b6b10d0567890a52eb0293585e7a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 19 Nov 2024 20:29:01 +0000 Subject: [PATCH 10/17] Implement ~const opaques --- .../rustc_hir_analysis/src/check/check.rs | 2 + compiler/rustc_hir_analysis/src/collect.rs | 8 ++++ .../src/collect/predicates_of.rs | 9 ++++- .../rustc_infer/src/infer/opaque_types/mod.rs | 27 +++++++++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 ++ compiler/rustc_middle/src/ty/mod.rs | 8 +++- .../const-closure-parse-not-item.stderr | 10 ++++- .../const-traits/const-opaque.no.stderr | 15 ++++++++ tests/ui/traits/const-traits/const-opaque.rs | 38 +++++++++++++++++++ .../ice-112822-expected-type-for-param.rs | 1 + .../ice-112822-expected-type-for-param.stderr | 16 ++++++-- 11 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 tests/ui/traits/const-traits/const-opaque.no.stderr create mode 100644 tests/ui/traits/const-traits/const-opaque.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index cf8c81c0b0890..275100411d391 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -339,6 +339,8 @@ fn check_opaque_meets_bounds<'tcx>( let misc_cause = ObligationCause::misc(span, def_id); // FIXME: We should just register the item bounds here, rather than equating. + // FIXME(const_trait_impl): When we do that, please make sure to also register + // the `~const` bounds. match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) { Ok(()) => {} Err(ty_err) => { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 001118eb8d32f..63e9080190463 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -339,6 +339,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { self.tcx.ensure().explicit_item_super_predicates(def_id); self.tcx.ensure().item_bounds(def_id); self.tcx.ensure().item_super_predicates(def_id); + if self.tcx.is_conditionally_const(def_id) { + self.tcx.ensure().explicit_implied_const_bounds(def_id); + self.tcx.ensure().const_conditions(def_id); + } intravisit::walk_opaque_ty(self, opaque); } @@ -681,6 +685,10 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure().generics_of(item.owner_id); tcx.ensure().type_of(item.owner_id); tcx.ensure().predicates_of(item.owner_id); + if tcx.is_conditionally_const(def_id) { + tcx.ensure().explicit_implied_const_bounds(def_id); + tcx.ensure().const_conditions(def_id); + } match item.kind { hir::ForeignItemKind::Fn(..) => { tcx.ensure().codegen_fn_attrs(item.owner_id); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index a675a7fc76839..65a419adaa1e6 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -958,6 +958,12 @@ pub(super) fn const_conditions<'tcx>( hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false), _ => bug!("const_conditions called on wrong item: {def_id:?}"), }, + Node::OpaqueTy(opaque) => match opaque.origin { + hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent), + hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => { + unreachable!() + } + }, // N.B. Tuple ctors are unconditionally constant. Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(), _ => bug!("const_conditions called on wrong item: {def_id:?}"), @@ -1033,7 +1039,8 @@ pub(super) fn explicit_implied_const_bounds<'tcx>( PredicateFilter::SelfConstIfConst, ) } - Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => { + Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) + | Node::OpaqueTy(_) => { explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) } _ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"), diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index d65ed72a8e84b..0aff46203144a 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -574,9 +574,8 @@ impl<'tcx> InferCtxt<'tcx> { // unexpected region errors. goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into()))); - let item_bounds = tcx.explicit_item_bounds(def_id); - for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { - let predicate = predicate.fold_with(&mut BottomUpFolder { + let replace_opaques_in = |clause: ty::Clause<'tcx>, goals: &mut Vec<_>| { + clause.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| match *ty.kind() { // We can't normalize associated types from `rustc_infer`, @@ -612,11 +611,31 @@ impl<'tcx> InferCtxt<'tcx> { }, lt_op: |lt| lt, ct_op: |ct| ct, - }); + }) + }; + + let item_bounds = tcx.explicit_item_bounds(def_id); + for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { + let predicate = replace_opaques_in(predicate, goals); // Require that the predicate holds for the concrete type. debug!(?predicate); goals.push(Goal::new(self.tcx, param_env, predicate)); } + + // If this opaque is being defined and it's conditionally const, + if self.tcx.is_conditionally_const(def_id) { + let item_bounds = tcx.explicit_implied_const_bounds(def_id); + for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { + let predicate = replace_opaques_in( + predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe), + goals, + ); + + // Require that the predicate holds for the concrete type. + debug!(?predicate); + goals.push(Goal::new(self.tcx, param_env, predicate)); + } + } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1ac5f1401d6ee..8378e7c6e9b99 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1532,6 +1532,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_explicit_item_super_predicates(def_id); record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(def_id); + if tcx.is_conditionally_const(def_id) { + record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] + <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); + } } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cddd6110c23c2..13ea3b6802689 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2117,7 +2117,13 @@ impl<'tcx> TyCtxt<'tcx> { _ => bug!("unexpected parent item of associated item: {parent_def_id:?}"), } } - DefKind::Closure | DefKind::OpaqueTy => { + DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) { + hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent), + hir::OpaqueTyOrigin::AsyncFn { .. } => false, + // FIXME(const_trait_impl): ATPITs could be conditionally const? + hir::OpaqueTyOrigin::TyAlias { .. } => false, + }, + DefKind::Closure => { // Closures and RPITs will eventually have const conditions // for `~const` bounds. false diff --git a/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr index 25c81ff900f27..0970cd5225fba 100644 --- a/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr +++ b/tests/ui/traits/const-traits/const-closure-parse-not-item.stderr @@ -12,5 +12,13 @@ LL | const fn test() -> impl ~const Fn() { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-parse-not-item.rs:7:25 + | +LL | const fn test() -> impl ~const Fn() { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr new file mode 100644 index 0000000000000..e43a6b603fda1 --- /dev/null +++ b/tests/ui/traits/const-traits/const-opaque.no.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): const Foo` is not satisfied + --> $DIR/const-opaque.rs:31:18 + | +LL | let opaque = bar(()); + | ^^^^^^^ + +error[E0277]: the trait bound `(): const Foo` is not satisfied + --> $DIR/const-opaque.rs:33:5 + | +LL | opaque.method(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-opaque.rs b/tests/ui/traits/const-traits/const-opaque.rs new file mode 100644 index 0000000000000..96cdd7d9f2619 --- /dev/null +++ b/tests/ui/traits/const-traits/const-opaque.rs @@ -0,0 +1,38 @@ +//@ revisions: yes no +//@ compile-flags: -Znext-solver +//@[yes] check-pass + +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn method(&self); +} + +impl const Foo for (T,) { + fn method(&self) {} +} + +#[cfg(yes)] +impl const Foo for () { + fn method(&self) {} +} + +#[cfg(no)] +impl Foo for () { + fn method(&self) {} +} + +const fn bar(t: T) -> impl ~const Foo { + (t,) +} + +const _: () = { + let opaque = bar(()); + //[no]~^ ERROR the trait bound `(): const Foo` is not satisfied + opaque.method(); + //[no]~^ ERROR the trait bound `(): const Foo` is not satisfied + std::mem::forget(opaque); +}; + +fn main() {} diff --git a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs index c467088ab3d3c..8ff15dd09cc0a 100644 --- a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs +++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.rs @@ -3,6 +3,7 @@ const fn test() -> impl ~const Fn() { //~^ ERROR `~const` can only be applied to `#[const_trait]` traits //~| ERROR `~const` can only be applied to `#[const_trait]` traits + //~| ERROR `~const` can only be applied to `#[const_trait]` traits const move || { //~ ERROR const closures are experimental let sl: &[u8] = b"foo"; diff --git a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr index 6d7edaf19f267..879d966b1f97b 100644 --- a/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr +++ b/tests/ui/traits/const-traits/effects/ice-112822-expected-type-for-param.stderr @@ -1,5 +1,5 @@ error[E0658]: const closures are experimental - --> $DIR/ice-112822-expected-type-for-param.rs:6:5 + --> $DIR/ice-112822-expected-type-for-param.rs:7:5 | LL | const move || { | ^^^^^ @@ -22,8 +22,16 @@ LL | const fn test() -> impl ~const Fn() { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-112822-expected-type-for-param.rs:3:25 + | +LL | const fn test() -> impl ~const Fn() { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const operator in constant functions - --> $DIR/ice-112822-expected-type-for-param.rs:11:17 + --> $DIR/ice-112822-expected-type-for-param.rs:12:17 | LL | assert_eq!(first, &b'f'); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +40,7 @@ LL | assert_eq!(first, &b'f'); = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions - --> $DIR/ice-112822-expected-type-for-param.rs:11:17 + --> $DIR/ice-112822-expected-type-for-param.rs:12:17 | LL | assert_eq!(first, &b'f'); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +48,7 @@ LL | assert_eq!(first, &b'f'); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. From 19b528b8a0770d55ba3c7b3cc5b91d6466e6ff2d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 27 Oct 2024 00:16:44 +0000 Subject: [PATCH 11/17] Store resolution for self and crate root module segments --- compiler/rustc_resolve/src/ident.rs | 14 +++++--- .../generics/generics-on-self-mod-segment.rs | 18 +++++++++++ .../generics-on-self-mod-segment.stderr | 32 +++++++++++++++++++ .../trait-bounds/maybe-bound-has-path-args.rs | 2 +- .../maybe-bound-has-path-args.stderr | 4 +-- 5 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 tests/ui/generics/generics-on-self-mod-segment.rs create mode 100644 tests/ui/generics/generics-on-self-mod-segment.stderr diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index ad825d7813d6d..466e190028ac9 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1478,9 +1478,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if segment_idx == 0 { if name == kw::SelfLower { let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0(); - module = Some(ModuleOrUniformRoot::Module( - self.resolve_self(&mut ctxt, parent_scope.module), - )); + let self_mod = self.resolve_self(&mut ctxt, parent_scope.module); + if let Some(res) = self_mod.res() { + record_segment_res(self, res); + } + module = Some(ModuleOrUniformRoot::Module(self_mod)); continue; } if name == kw::PathRoot && ident.span.at_least_rust_2018() { @@ -1497,7 +1499,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate { // `::a::b`, `crate::a::b` or `$crate::a::b` - module = Some(ModuleOrUniformRoot::Module(self.resolve_crate_root(ident))); + let crate_root = self.resolve_crate_root(ident); + if let Some(res) = crate_root.res() { + record_segment_res(self, res); + } + module = Some(ModuleOrUniformRoot::Module(crate_root)); continue; } } diff --git a/tests/ui/generics/generics-on-self-mod-segment.rs b/tests/ui/generics/generics-on-self-mod-segment.rs new file mode 100644 index 0000000000000..ef229eeba5306 --- /dev/null +++ b/tests/ui/generics/generics-on-self-mod-segment.rs @@ -0,0 +1,18 @@ +struct Ty; + +fn self_(_: self::::Ty) {} +//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment` + +fn crate_(_: crate::::Ty) {} +//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment` + +macro_rules! dollar_crate { + () => { + fn dollar_crate_(_: $crate::::Ty) {} + //~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment` + } +} + +dollar_crate!(); + +fn main() {} diff --git a/tests/ui/generics/generics-on-self-mod-segment.stderr b/tests/ui/generics/generics-on-self-mod-segment.stderr new file mode 100644 index 0000000000000..4a2d5939a3ec8 --- /dev/null +++ b/tests/ui/generics/generics-on-self-mod-segment.stderr @@ -0,0 +1,32 @@ +error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment` + --> $DIR/generics-on-self-mod-segment.rs:3:20 + | +LL | fn self_(_: self::::Ty) {} + | ---- ^^^ type argument not allowed + | | + | not allowed on module `generics_on_self_mod_segment` + +error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment` + --> $DIR/generics-on-self-mod-segment.rs:6:22 + | +LL | fn crate_(_: crate::::Ty) {} + | ----- ^^^ type argument not allowed + | | + | not allowed on module `generics_on_self_mod_segment` + +error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment` + --> $DIR/generics-on-self-mod-segment.rs:11:38 + | +LL | fn dollar_crate_(_: $crate::::Ty) {} + | ------ ^^^ type argument not allowed + | | + | not allowed on module `generics_on_self_mod_segment` +... +LL | dollar_crate!(); + | --------------- in this macro invocation + | + = note: this error originates in the macro `dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs index 2cb63f25d063d..fd0e96917004d 100644 --- a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs @@ -1,7 +1,7 @@ trait Trait {} fn test::Trait>() {} -//~^ ERROR type arguments are not allowed on this type +//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args` //~| WARN relaxing a default bound only does something for `?Sized` fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr index 701e493f5a527..0c167fff94012 100644 --- a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr @@ -4,13 +4,13 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr LL | fn test::Trait>() {} | ^^^^^^^^^^^^^^^^^^^ -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on module `maybe_bound_has_path_args` --> $DIR/maybe-bound-has-path-args.rs:3:20 | LL | fn test::Trait>() {} | ---- ^^^ type argument not allowed | | - | not allowed on this type + | not allowed on module `maybe_bound_has_path_args` error: aborting due to 1 previous error; 1 warning emitted From b33a0d329236833ecafcd84978f51d6ccb0dd5ad Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 26 Oct 2024 23:57:36 +0000 Subject: [PATCH 12/17] we should not be reporting generic error if there is not a segment to deny --- compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index dd0f250a8e28b..4e5a8271e9ec7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1106,7 +1106,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .collect::() ), [(only, _)] => only.to_string(), - [] => "this type".to_string(), + [] => bug!("expected one segment to deny"), }; let arg_spans: Vec = segments @@ -1136,7 +1136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { "s", ), [only] => (only.to_string(), ""), - [] => unreachable!("expected at least one generic to prohibit"), + [] => bug!("expected at least one generic to prohibit"), }; let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); From 1dc12367b9a0c3317caaad4ec1f5a8af7484cc19 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 20:11:49 -0300 Subject: [PATCH 13/17] Items --- compiler/rustc_ast/src/mut_visit.rs | 52 +++++++++++++++---- compiler/rustc_ast/src/visit.rs | 24 ++++++--- compiler/rustc_builtin_macros/src/cfg_eval.rs | 2 +- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_expand/src/placeholders.rs | 2 +- compiler/rustc_lint/src/early.rs | 17 +++--- 6 files changed, 71 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2158ed33e6e3d..cb38a16db35f8 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -104,8 +104,16 @@ pub trait MutVisitor: Sized { walk_use_tree(self, use_tree); } + fn visit_foreign_item(&mut self, ni: &mut P) { + walk_item(self, ni); + } + fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, ni) + walk_flat_map_foreign_item(self, ni) + } + + fn visit_item(&mut self, i: &mut P) { + walk_item(self, i); } fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { @@ -124,6 +132,10 @@ pub trait MutVisitor: Sized { walk_flat_map_field_def(self, fd) } + fn visit_assoc_item(&mut self, i: &mut P, ctxt: AssocCtxt) { + walk_assoc_item(self, i, ctxt) + } + fn flat_map_assoc_item( &mut self, i: P, @@ -1383,18 +1395,19 @@ pub fn walk_crate(vis: &mut T, krate: &mut Crate) { vis.visit_span(inject_use_span); } -pub fn walk_flat_map_item>( - visitor: &mut impl MutVisitor, - item: P>, -) -> SmallVec<[P>; 1]> { - walk_flat_map_assoc_item(visitor, item, ()) +pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P>>) { + walk_item_ctxt(visitor, item, ()) } -pub fn walk_flat_map_assoc_item( +pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P, ctxt: AssocCtxt) { + walk_item_ctxt(visitor, item, ctxt) +} + +fn walk_item_ctxt( visitor: &mut impl MutVisitor, - mut item: P>, + item: &mut P>, ctxt: K::Ctxt, -) -> SmallVec<[P>; 1]> { +) { let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_id(id); visit_attrs(visitor, attrs); @@ -1403,6 +1416,27 @@ pub fn walk_flat_map_assoc_item( kind.walk(*span, *id, ident, vis, ctxt, visitor); visit_lazy_tts(visitor, tokens); visitor.visit_span(span); +} + +pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P) -> SmallVec<[P; 1]> { + vis.visit_item(&mut item); + smallvec![item] +} + +pub fn walk_flat_map_foreign_item( + vis: &mut impl MutVisitor, + mut item: P, +) -> SmallVec<[P; 1]> { + vis.visit_foreign_item(&mut item); + smallvec![item] +} + +pub fn walk_flat_map_assoc_item( + vis: &mut impl MutVisitor, + mut item: P, + ctxt: AssocCtxt, +) -> SmallVec<[P; 1]> { + vis.visit_assoc_item(&mut item, ctxt); smallvec![item] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3500c2153765d..fafef4169f49b 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -457,13 +457,6 @@ impl WalkItemKind for ItemKind { } } -pub fn walk_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a Item>, -) -> V::Result { - walk_assoc_item(visitor, item, ()) -} - pub fn walk_enum_def<'a, V: Visitor<'a>>( visitor: &mut V, EnumDef { variants }: &'a EnumDef, @@ -925,7 +918,22 @@ impl WalkItemKind for AssocItemKind { } } -pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>( +pub fn walk_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a Item>, +) -> V::Result { + walk_item_ctxt(visitor, item, ()) +} + +pub fn walk_assoc_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a AssocItem, + ctxt: AssocCtxt, +) -> V::Result { + walk_item_ctxt(visitor, item, ctxt) +} + +fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>( visitor: &mut V, item: &'a Item, ctxt: K::Ctxt, diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index e7ee6b43e27a6..d46a1bd3d3139 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -215,7 +215,7 @@ impl MutVisitor for CfgEval<'_> { foreign_item: P, ) -> SmallVec<[P; 1]> { let foreign_item = configure!(self, foreign_item); - mut_visit::walk_flat_map_item(self, foreign_item) + mut_visit::walk_flat_map_foreign_item(self, foreign_item) } fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 91786462b4046..19c2d466f7ca6 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1382,7 +1382,7 @@ impl InvocationCollectorNode for P { fragment.make_foreign_items() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_item(visitor, self) + walk_flat_map_foreign_item(visitor, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ForeignItemKind::MacCall(..)) diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 90206b19bd587..bae16a18bcbfd 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -296,7 +296,7 @@ impl MutVisitor for PlaceholderExpander { ) -> SmallVec<[P; 1]> { match item.kind { ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(), - _ => walk_flat_map_item(self, item), + _ => walk_flat_map_foreign_item(self, item), } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index ef9b3dbd13b81..4f3184f1d7cff 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -230,15 +230,16 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) { - self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt { - ast_visit::AssocCtxt::Trait => { - lint_callback!(cx, check_trait_item, item); - ast_visit::walk_assoc_item(cx, item, ctxt); - } - ast_visit::AssocCtxt::Impl => { - lint_callback!(cx, check_impl_item, item); - ast_visit::walk_assoc_item(cx, item, ctxt); + self.with_lint_attrs(item.id, &item.attrs, |cx| { + match ctxt { + ast_visit::AssocCtxt::Trait => { + lint_callback!(cx, check_trait_item, item); + } + ast_visit::AssocCtxt::Impl => { + lint_callback!(cx, check_impl_item, item); + } } + ast_visit::walk_assoc_item(cx, item, ctxt); }); } From 01b26e61987ae2308b62b28bac435605ea021f27 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 17 Nov 2024 23:01:01 -0300 Subject: [PATCH 14/17] Use visit_item instead of flat_map_item in test_harness.rs --- .../rustc_builtin_macros/src/test_harness.rs | 52 ++++++++----------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index ba5d34359aa2f..b2048c534a48a 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -1,6 +1,6 @@ // Code that generates a test runner to run all the tests in a crate -use std::{iter, mem}; +use std::mem; use rustc_ast as ast; use rustc_ast::entry::EntryPointType; @@ -19,7 +19,7 @@ use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; use rustc_span::symbol::{Ident, Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::PanicStrategy; -use smallvec::{SmallVec, smallvec}; +use smallvec::smallvec; use thin_vec::{ThinVec, thin_vec}; use tracing::debug; @@ -129,8 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { c.items.push(mk_main(&mut self.cx)); } - fn flat_map_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { - let item = &mut *i; + fn visit_item(&mut self, item: &mut P) { + let item = &mut **item; + if let Some(name) = get_test_name(&item) { debug!("this is a test item"); @@ -158,7 +159,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // But in those cases, we emit a lint to warn the user of these missing tests. walk_item(&mut InnerItemLinter { sess: self.cx.ext_cx.sess }, &item); } - smallvec![i] } } @@ -198,40 +198,30 @@ struct EntryPointCleaner<'a> { } impl<'a> MutVisitor for EntryPointCleaner<'a> { - fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { + fn visit_item(&mut self, item: &mut P) { self.depth += 1; - let item = walk_flat_map_item(self, i).expect_one("noop did something"); + ast::mut_visit::walk_item(self, item); self.depth -= 1; // Remove any #[rustc_main] or #[start] from the AST so it doesn't // clash with the one we're going to add, but mark it as // #[allow(dead_code)] to avoid printing warnings. - let item = match entry_point_type(&item, self.depth == 0) { + match entry_point_type(&item, self.depth == 0) { EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => { - item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { - let allow_dead_code = attr::mk_attr_nested_word( - &self.sess.psess.attr_id_generator, - ast::AttrStyle::Outer, - ast::Safety::Default, - sym::allow, - sym::dead_code, - self.def_site, - ); - let attrs = attrs - .into_iter() - .filter(|attr| { - !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start) - }) - .chain(iter::once(allow_dead_code)) - .collect(); - - ast::Item { id, ident, attrs, kind, vis, span, tokens } - }) + let allow_dead_code = attr::mk_attr_nested_word( + &self.sess.psess.attr_id_generator, + ast::AttrStyle::Outer, + ast::Safety::Default, + sym::allow, + sym::dead_code, + self.def_site, + ); + item.attrs + .retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)); + item.attrs.push(allow_dead_code); } - EntryPointType::None | EntryPointType::OtherMain => item, + EntryPointType::None | EntryPointType::OtherMain => {} }; - - smallvec![item] } } @@ -292,7 +282,7 @@ fn generate_test_harness( /// Most of the Ident have the usual def-site hygiene for the AST pass. The /// exception is the `test_const`s. These have a syntax context that has two /// opaque marks: one from the expansion of `test` or `test_case`, and one -/// generated in `TestHarnessGenerator::flat_map_item`. When resolving this +/// generated in `TestHarnessGenerator::visit_item`. When resolving this /// identifier after failing to find a matching identifier in the root module /// we remove the outer mark, and try resolving at its def-site, which will /// then resolve to `test_const`. From 15528b2d6c2d7d83d007440ab84d859bc60ab40d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 20 Nov 2024 10:34:42 +1100 Subject: [PATCH 15/17] Fix `catbat` pager typo. `bat` is known as `batcat` on Ubuntu and Debian, not `catbat`. --- compiler/rustc_driver_impl/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8dd043be6ad3c..038a0d6c2883d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -580,7 +580,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { cmd.arg("-R"); true } else { - ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name) + ["bat", "batcat", "delta"].iter().any(|v| *v == pager_name) }; if color == ColorConfig::Never { From 91164957ec18aa65aa00412f703f2270e47779c1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 20 Nov 2024 14:10:44 +1100 Subject: [PATCH 16/17] Remove redundant `is_terminal` check. It's not necessary because `show_md_content_with_pager` is only ever called if `is_terminal` is true. --- compiler/rustc_driver_impl/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 038a0d6c2883d..6198f40e83d95 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -620,8 +620,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { // to standard output if fallback_to_println { let fmt_success = match color { - ColorConfig::Auto => io::stdout().is_terminal() && bufwtr.print(&mdbuf).is_ok(), - ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(), + ColorConfig::Auto | ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(), ColorConfig::Never => false, }; From 525e1919f730e921f8cc6f917c064c7d083c7048 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 20 Nov 2024 14:15:59 +1100 Subject: [PATCH 17/17] Rewrite `show_md_content_with_pager`. I think the control flow in this function is complicated and confusing, largely due to the use of two booleans `print_formatted` and `fallback_to_println` that are set in multiple places and then used to guide proceedings. As well as hurting readability, this leads to at least one bug: if the `write_termcolor_buf` call fails and the pager also fails, the function will try to print color output to stdout, but that output will be empty because `write_termcolor_buf` failed. I.e. the `if fallback_to_println` body fails to check `print_formatted`. This commit rewrites the function to be neater and more Rust-y, e.g. by putting the result of `write_termcolor_buf` into an `Option` so it can only be used on success, and by using `?` more. It also changes terminology a little, using "pretty" to mean "formatted and colorized". The result is a little shorter, more readable, and less buggy. --- compiler/rustc_driver_impl/src/lib.rs | 92 +++++++++++++-------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 6198f40e83d95..d2333454f289c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -15,6 +15,7 @@ #![feature(panic_update_hook)] #![feature(result_flattening)] #![feature(rustdoc_internals)] +#![feature(try_blocks)] #![warn(unreachable_pub)] // tidy-alphabetical-end @@ -564,70 +565,63 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col } } -/// If color is always or auto, print formatted & colorized markdown. If color is never or -/// if formatted printing fails, print the raw text. +/// If `color` is `always` or `auto`, try to print pretty (formatted & colorized) markdown. If +/// that fails or `color` is `never`, print the raw markdown. /// -/// Prefers a pager, falls back standard print +/// Uses a pager if possible, falls back to stdout. fn show_md_content_with_pager(content: &str, color: ColorConfig) { - let mut fallback_to_println = false; let pager_name = env::var_os("PAGER").unwrap_or_else(|| { if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") } }); let mut cmd = Command::new(&pager_name); - // FIXME: find if other pagers accept color options - let mut print_formatted = if pager_name == "less" { - cmd.arg("-R"); - true - } else { - ["bat", "batcat", "delta"].iter().any(|v| *v == pager_name) - }; - - if color == ColorConfig::Never { - print_formatted = false; - } else if color == ColorConfig::Always { - print_formatted = true; + if pager_name == "less" { + cmd.arg("-R"); // allows color escape sequences } - let mdstream = markdown::MdStream::parse_str(content); - let bufwtr = markdown::create_stdout_bufwtr(); - let mut mdbuf = bufwtr.buffer(); - if mdstream.write_termcolor_buf(&mut mdbuf).is_err() { - print_formatted = false; - } - - if let Ok(mut pager) = cmd.stdin(Stdio::piped()).spawn() { - if let Some(pipe) = pager.stdin.as_mut() { - let res = if print_formatted { - pipe.write_all(mdbuf.as_slice()) - } else { - pipe.write_all(content.as_bytes()) - }; - - if res.is_err() { - fallback_to_println = true; - } + let pretty_on_pager = match color { + ColorConfig::Auto => { + // Add other pagers that accept color escape sequences here. + ["less", "bat", "batcat", "delta"].iter().any(|v| *v == pager_name) } + ColorConfig::Always => true, + ColorConfig::Never => false, + }; - if pager.wait().is_err() { - fallback_to_println = true; - } - } else { - fallback_to_println = true; - } + // Try to prettify the raw markdown text. The result can be used by the pager or on stdout. + let pretty_data = { + let mdstream = markdown::MdStream::parse_str(content); + let bufwtr = markdown::create_stdout_bufwtr(); + let mut mdbuf = bufwtr.buffer(); + if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None } + }; - // If pager fails for whatever reason, we should still print the content - // to standard output - if fallback_to_println { - let fmt_success = match color { - ColorConfig::Auto | ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(), - ColorConfig::Never => false, + // Try to print via the pager, pretty output if possible. + let pager_res: Option<()> = try { + let mut pager = cmd.stdin(Stdio::piped()).spawn().ok()?; + + let pager_stdin = pager.stdin.as_mut()?; + if pretty_on_pager && let Some((_, mdbuf)) = &pretty_data { + pager_stdin.write_all(mdbuf.as_slice()).ok()?; + } else { + pager_stdin.write_all(content.as_bytes()).ok()?; }; - if !fmt_success { - safe_print!("{content}"); - } + pager.wait().ok()?; + }; + if pager_res.is_some() { + return; } + + // The pager failed. Try to print pretty output to stdout. + if let Some((bufwtr, mdbuf)) = &pretty_data + && bufwtr.print(&mdbuf).is_ok() + { + return; + } + + // Everything failed. Print the raw markdown text. + safe_print!("{content}"); } fn process_rlink(sess: &Session, compiler: &interface::Compiler) {