diff options
| author | bors <bors@rust-lang.org> | 2024-06-25 22:33:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-25 22:33:35 +0000 |
| commit | fc94ce216ede9f89a1032b13e2563ddba0ae4194 (patch) | |
| tree | e520b53ebf7d874cc6dfdc2aa17257bb9ff8dac8 /compiler | |
| parent | 8a8b357bf11ed4f7ba28916c5975f74dde55f0ea (diff) | |
| parent | 8f688d2634b10da6c6a91a57bf8f39557c333b31 (diff) | |
| download | rust-fc94ce216ede9f89a1032b13e2563ddba0ae4194.tar.gz rust-fc94ce216ede9f89a1032b13e2563ddba0ae4194.zip | |
Auto merge of #3711 - saethlin:rustup, r=saethlin
Manual Rustup This bumps us to a rustc commit that doesn't have the chatty `./miri fmt` reported in https://rust-lang.zulipchat.com/#narrow/stream/269128-miri/topic/.22rewriting.20static.22.20printed.20during.20.2E.2Fmiri.20build
Diffstat (limited to 'compiler')
121 files changed, 1221 insertions, 798 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a6662d4e0e4..31c66a56bea 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -427,11 +427,13 @@ pub struct Size { raw: u64, } -// Safety: Ord is implement as just comparing numerical values and numerical values -// are not changed by (de-)serialization. #[cfg(feature = "nightly")] -unsafe impl StableOrd for Size { +impl StableOrd for Size { const CAN_USE_UNSTABLE_SORT: bool = true; + + // `Ord` is implemented as just comparing numerical values and numerical values + // are not changed by (de-)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } // This is debug-printed a lot in larger structs, don't waste too much space there diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index c9d2f5c779b..ed8bf58eb23 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -429,10 +429,10 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>( ) -> SmallVec<[PatField; 1]> { let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; vis.visit_id(id); + visit_attrs(attrs, vis); vis.visit_ident(ident); vis.visit_pat(pat); vis.visit_span(span); - visit_attrs(attrs, vis); smallvec![fp] } @@ -443,8 +443,8 @@ fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), UseTreeKind::Nested { items, .. } => { for (tree, id) in items { - vis.visit_use_tree(tree); vis.visit_id(id); + vis.visit_use_tree(tree); } } UseTreeKind::Glob => {} @@ -454,8 +454,8 @@ fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; - visit_attrs(attrs, vis); vis.visit_id(id); + visit_attrs(attrs, vis); vis.visit_pat(pat); visit_opt(guard, |guard| vis.visit_expr(guard)); visit_opt(body, |body| vis.visit_expr(body)); @@ -548,10 +548,10 @@ pub fn noop_flat_map_variant<T: MutVisitor>( visitor: &mut T, ) -> SmallVec<[Variant; 1]> { let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; + visitor.visit_id(id); + visit_attrs(attrs, visitor); visitor.visit_ident(ident); visitor.visit_vis(vis); - visit_attrs(attrs, visitor); - visitor.visit_id(id); visitor.visit_variant_data(data); visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); visitor.visit_span(span); @@ -565,8 +565,8 @@ fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mu fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) { vis.visit_span(span); for PathSegment { ident, id, args } in segments { - vis.visit_ident(ident); vis.visit_id(id); + vis.visit_ident(ident); visit_opt(args, |args| vis.visit_generic_args(args)); } visit_lazy_tts(tokens, vis); @@ -620,6 +620,7 @@ fn noop_visit_parenthesized_parameter_data<T: MutVisitor>( fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); vis.visit_id(id); + visit_attrs(attrs, vis); vis.visit_pat(pat); visit_opt(ty, |ty| vis.visit_ty(ty)); match kind { @@ -634,7 +635,6 @@ fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { } vis.visit_span(span); visit_opt(colon_sp, |sp| vis.visit_span(sp)); - visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } @@ -894,9 +894,9 @@ fn noop_visit_coroutine_kind<T: MutVisitor>(coroutine_kind: &mut CoroutineKind, CoroutineKind::Async { span, closure_id, return_impl_trait_id } | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => { - vis.visit_span(span); vis.visit_id(closure_id); vis.visit_id(return_impl_trait_id); + vis.visit_span(span); } } } @@ -932,8 +932,8 @@ fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturingArg vis.visit_lifetime(lt); } PreciseCapturingArg::Arg(path, id) => { - vis.visit_path(path); vis.visit_id(id); + vis.visit_path(path); } } } @@ -944,11 +944,11 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>( ) -> SmallVec<[GenericParam; 1]> { let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; vis.visit_id(id); + visit_attrs(attrs, vis); vis.visit_ident(ident); if let Some(colon_span) = colon_span { vis.visit_span(colon_span); } - visit_attrs(attrs, vis); visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); match kind { GenericParamKind::Lifetime => {} @@ -1015,16 +1015,16 @@ fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); } VariantData::Tuple(fields, id) => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); vis.visit_id(id); + fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); } VariantData::Unit(id) => vis.visit_id(id), } } fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { - vis.visit_path(path); vis.visit_id(ref_id); + vis.visit_path(path); } fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) { @@ -1039,12 +1039,12 @@ pub fn noop_flat_map_field_def<T: MutVisitor>( visitor: &mut T, ) -> SmallVec<[FieldDef; 1]> { let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; + visitor.visit_id(id); + visit_attrs(attrs, visitor); visitor.visit_span(span); visit_opt(ident, |ident| visitor.visit_ident(ident)); visitor.visit_vis(vis); - visitor.visit_id(id); visitor.visit_ty(ty); - visit_attrs(attrs, visitor); smallvec![fd] } @@ -1053,11 +1053,11 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>( vis: &mut T, ) -> SmallVec<[ExprField; 1]> { let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; + vis.visit_id(id); + visit_attrs(attrs, vis); vis.visit_ident(ident); vis.visit_expr(expr); - vis.visit_id(id); vis.visit_span(span); - visit_attrs(attrs, vis); smallvec![f] } @@ -1429,6 +1429,8 @@ pub fn noop_visit_expr<T: MutVisitor>( Expr { kind, id, span, attrs, tokens }: &mut Expr, vis: &mut T, ) { + vis.visit_id(id); + visit_attrs(attrs, vis); match kind { ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis), ExprKind::ConstBlock(anon_const) => { @@ -1449,8 +1451,8 @@ pub fn noop_visit_expr<T: MutVisitor>( args: call_args, span, }) => { - vis.visit_ident(ident); vis.visit_id(id); + vis.visit_ident(ident); visit_opt(seg_args, |args| vis.visit_generic_args(args)); vis.visit_method_receiver_expr(receiver); visit_thin_exprs(call_args, vis); @@ -1601,9 +1603,7 @@ pub fn noop_visit_expr<T: MutVisitor>( ExprKind::TryBlock(body) => vis.visit_block(body), ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {} } - vis.visit_id(id); vis.visit_span(span); - visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } @@ -1645,8 +1645,8 @@ fn noop_flat_map_stmt_kind<T: MutVisitor>(kind: StmtKind, vis: &mut T) -> SmallV StmtKind::Empty => smallvec![StmtKind::Empty], StmtKind::MacCall(mut mac) => { let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); - vis.visit_mac_call(mac_); visit_attrs(attrs, vis); + vis.visit_mac_call(mac_); visit_lazy_tts(tokens, vis); smallvec![StmtKind::MacCall(mac)] } @@ -1657,8 +1657,8 @@ fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) { match &mut visibility.kind { VisibilityKind::Public | VisibilityKind::Inherited => {} VisibilityKind::Restricted { path, id, shorthand: _ } => { - vis.visit_path(path); vis.visit_id(id); + vis.visit_path(path); } } vis.visit_span(&mut visibility.span); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ce38a67ea69..e2ef0542bf9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -298,8 +298,8 @@ pub trait Visitor<'ast>: Sized { } pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { - walk_list!(visitor, visit_item, &krate.items); walk_list!(visitor, visit_attribute, &krate.attrs); + walk_list!(visitor, visit_item, &krate.items); V::Result::output() } @@ -462,25 +462,25 @@ pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) - where V: Visitor<'a>, { + walk_list!(visitor, visit_attribute, &variant.attrs); try_visit!(visitor.visit_ident(variant.ident)); try_visit!(visitor.visit_vis(&variant.vis)); try_visit!(visitor.visit_variant_data(&variant.data)); visit_opt!(visitor, visit_variant_discr, &variant.disr_expr); - walk_list!(visitor, visit_attribute, &variant.attrs); V::Result::output() } pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result { + walk_list!(visitor, visit_attribute, &f.attrs); try_visit!(visitor.visit_expr(&f.expr)); try_visit!(visitor.visit_ident(f.ident)); - walk_list!(visitor, visit_attribute, &f.attrs); V::Result::output() } pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { + walk_list!(visitor, visit_attribute, &fp.attrs); try_visit!(visitor.visit_ident(fp.ident)); try_visit!(visitor.visit_pat(&fp.pat)); - walk_list!(visitor, visit_attribute, &fp.attrs); V::Result::output() } @@ -722,8 +722,8 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>( visitor: &mut V, param: &'a GenericParam, ) -> V::Result { - try_visit!(visitor.visit_ident(param.ident)); walk_list!(visitor, visit_attribute, ¶m.attrs); + try_visit!(visitor.visit_ident(param.ident)); walk_list!(visitor, visit_param_bound, ¶m.bounds, BoundKind::Bound); match ¶m.kind { GenericParamKind::Lifetime => (), @@ -882,10 +882,10 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>( ctxt: AssocCtxt, ) -> V::Result { let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); try_visit!(kind.walk(item, ctxt, visitor)); - walk_list!(visitor, visit_attribute, attrs); V::Result::output() } @@ -898,10 +898,10 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>( } pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { + walk_list!(visitor, visit_attribute, &field.attrs); try_visit!(visitor.visit_vis(&field.vis)); visit_opt!(visitor, visit_ident, field.ident); try_visit!(visitor.visit_ty(&field.ty)); - walk_list!(visitor, visit_attribute, &field.attrs); V::Result::output() } @@ -918,8 +918,8 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V: StmtKind::Empty => {} StmtKind::MacCall(mac) => { let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; - try_visit!(visitor.visit_mac_call(mac)); walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_mac_call(mac)); } } V::Result::output() @@ -1141,10 +1141,10 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::R } pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { + walk_list!(visitor, visit_attribute, &arm.attrs); try_visit!(visitor.visit_pat(&arm.pat)); visit_opt!(visitor, visit_expr, &arm.guard); visit_opt!(visitor, visit_expr, &arm.body); - walk_list!(visitor, visit_attribute, &arm.attrs); V::Result::output() } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 8a2936c2657..f26f8711dd4 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,7 +6,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { self.infcx.dcx() } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 5e10f14f31b..d46febffba8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> { pub(crate) fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option<ty::Region<'tcx>>, @@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> { #[instrument(level = "debug", skip(self, mbcx))] fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option<ty::Region<'tcx>>, @@ -270,7 +270,7 @@ where fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option<ty::Region<'tcx>>, @@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option<ty::Region<'tcx>>, @@ -336,7 +336,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option<ty::Region<'tcx>>, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 197da3eb641..1cc7fee718e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -4243,7 +4243,11 @@ enum AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { /// Annotate the provided diagnostic with information about borrow from the fn signature that /// helps explain. - pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, 'tcx>, diag: &mut Diag<'_>) -> String { + pub(crate) fn emit( + &self, + cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>, + diag: &mut Diag<'_>, + ) -> String { match self { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { diag.span_label( diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index e3ad92a5b2b..6165a718a30 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -389,7 +389,7 @@ impl<'tcx> BorrowExplanation<'tcx> { } } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn free_region_constraint_info( &self, borrow_region: RegionVid, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 5b4269caccb..842ed38f1e2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -771,7 +771,7 @@ struct CapturedMessageOpt { maybe_reinitialized_locations_is_empty: bool, } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 5a7bca9ab03..12fa4c4f5ee 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e0b18536dd5..93fac3181ba 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 1a42e551597..082111a642c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -75,7 +75,7 @@ impl OutlivesSuggestionBuilder { /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`. fn region_vid_to_name( &self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, region: RegionVid, ) -> Option<RegionName> { mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) @@ -84,7 +84,7 @@ impl OutlivesSuggestionBuilder { /// Compiles a list of all suggestions to be printed in the final big suggestion. fn compile_all_suggestions( &self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -160,7 +160,7 @@ impl OutlivesSuggestionBuilder { /// Emit an intermediate note on the given `Diag` if the involved regions are suggestable. pub(crate) fn intermediate_suggestion( &mut self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, errci: &ErrorConstraintInfo<'_>, diag: &mut Diag<'_>, ) { @@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { + pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index c214c52880a..245ce790e49 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 25a0d40218b..356416d1a75 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -198,7 +198,7 @@ impl rustc_errors::IntoDiagArg for RegionName { } } -impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId { self.body.source.def_id().expect_local() } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b3b53e9cb79..69efee2fbdc 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -310,11 +310,11 @@ fn do_mir_borrowck<'tcx>( promoted_mbcx.report_move_errors(); diags = promoted_mbcx.diags; - struct MoveVisitor<'a, 'cx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'cx, 'tcx>, + struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>, } - impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> { + impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { if let Operand::Move(place) = operand { self.ctxt.check_movable_place(location, *place); @@ -528,15 +528,15 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -struct MirBorrowckCtxt<'cx, 'tcx> { +struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { infcx: &'cx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, - body: &'cx Body<'tcx>, - move_data: &'cx MoveData<'tcx>, + body: &'mir Body<'tcx>, + move_data: &'a MoveData<'tcx>, /// Map from MIR `Location` to `LocationIndex`; created /// when MIR borrowck begins. - location_table: &'cx LocationTable, + location_table: &'a LocationTable, movable_coroutine: bool, /// This keeps track of whether local variables are free-ed when the function @@ -605,14 +605,16 @@ struct MirBorrowckCtxt<'cx, 'tcx> { // 2. loans made in overlapping scopes do not conflict // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorrowckCtxt<'cx, 'tcx> { - type FlowState = Flows<'cx, 'tcx>; +impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> + for MirBorrowckCtxt<'_, 'mir, '_, 'tcx> +{ + type FlowState = Flows<'mir, 'tcx>; fn visit_statement_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - stmt: &'cx Statement<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + stmt: &'mir Statement<'tcx>, location: Location, ) { debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state); @@ -681,8 +683,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro fn visit_terminator_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - term: &'cx Terminator<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + term: &'mir Terminator<'tcx>, loc: Location, ) { debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state); @@ -792,8 +794,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro fn visit_terminator_after_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - term: &'cx Terminator<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + term: &'mir Terminator<'tcx>, loc: Location, ) { let span = term.source_info.span; @@ -969,8 +971,8 @@ impl InitializationRequiringAction { } } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { - fn body(&self) -> &'cx Body<'tcx> { +impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { + fn body(&self) -> &'mir Body<'tcx> { self.body } @@ -986,7 +988,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let (sd, rw) = kind; @@ -1036,7 +1038,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) -> bool { let mut error_reported = false; let borrow_set = Rc::clone(&self.borrow_set); @@ -1177,7 +1179,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, place_span: (Place<'tcx>, Span), kind: AccessDepth, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { // Write of P[i] or *P requires P init'd. self.check_if_assigned_path_is_moved(location, place_span, flow_state); @@ -1194,8 +1196,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn consume_rvalue( &mut self, location: Location, - (rvalue, span): (&'cx Rvalue<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + (rvalue, span): (&'mir Rvalue<'tcx>, Span), + flow_state: &Flows<'mir, 'tcx>, ) { match rvalue { &Rvalue::Ref(_ /*rgn*/, bk, place) => { @@ -1452,8 +1454,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn consume_operand( &mut self, location: Location, - (operand, span): (&'cx Operand<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + (operand, span): (&'mir Operand<'tcx>, Span), + flow_state: &Flows<'mir, 'tcx>, ) { match *operand { Operand::Copy(place) => { @@ -1573,7 +1575,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'cx, 'tcx>) { + fn check_activations( + &mut self, + location: Location, + span: Span, + flow_state: &Flows<'mir, 'tcx>, + ) { // Two-phase borrow support: For each activation that is newly // generated at this statement, check if it interferes with // another borrow. @@ -1736,7 +1743,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1841,7 +1848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1940,7 +1947,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, (place, span): (Place<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); @@ -2001,12 +2008,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn check_parent_of_field<'cx, 'tcx>( - this: &mut MirBorrowckCtxt<'cx, 'tcx>, + fn check_parent_of_field<'mir, 'tcx>( + this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>, location: Location, base: PlaceRef<'tcx>, span: Span, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { // rust-lang/rust#21232: Until Rust allows reads from the // initialized parts of partially initialized structs, we @@ -2097,7 +2104,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, location: Location, ) -> bool { debug!( @@ -2213,7 +2220,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn is_local_ever_initialized( &self, local: Local, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) -> Option<InitIndex> { let mpi = self.move_data.rev_lookup.find_local(local)?; let ii = &self.move_data.init_path_map[mpi]; @@ -2221,7 +2228,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// Adds the place into the used mutable variables set - fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'cx, 'tcx>) { + fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) { match root_place { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being @@ -2476,7 +2483,7 @@ mod diags { } } - impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { + impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub fn buffer_error(&mut self, diag: Diag<'tcx>) { self.diags.buffer_error(diag); } diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 8a3a089d0ee..5d3ac1c409a 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -34,7 +34,7 @@ pub(super) enum PrefixSet { Shallow, } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Returns an iterator over the prefixes of `place` /// (inclusive) from longest to smallest, potentially /// terminating the iteration early based on `kind`. diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index dea1c7823a5..25e1f6268e0 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::{ use crate::MirBorrowckCtxt; -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes /// of the `unused_mut` lint. /// @@ -45,13 +45,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { +struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> { temporary_used_locals: FxIndexSet<Local>, never_initialized_mut_locals: &'visit mut FxIndexSet<Local>, - mbcx: &'visit mut MirBorrowckCtxt<'cx, 'tcx>, + mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>, } -impl GatherUsedMutsVisitor<'_, '_, '_> { +impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) { // Remove any locals that we found were initialized from the // `never_initialized_mut_locals` set. At the end, the only remaining locals will @@ -63,7 +63,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { } } -impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { +impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { debug!("visit_terminator: terminator={:?}", terminator); match &terminator.kind { diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index e3a93ae13e4..32936ac183d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -27,6 +27,7 @@ pub(crate) mod decodable; pub(crate) mod default; pub(crate) mod encodable; pub(crate) mod hash; +pub(crate) mod smart_ptr; #[path = "cmp/eq.rs"] pub(crate) mod eq; diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs new file mode 100644 index 00000000000..ea054a7e355 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -0,0 +1,140 @@ +use std::mem::swap; + +use ast::HasAttrs; +use rustc_ast::{ + self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem, + TraitBoundModifiers, +}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::symbol::{sym, Ident}; +use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; +use thin_vec::{thin_vec, ThinVec}; + +macro_rules! path { + ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] } +} + +pub fn expand_deriving_smart_ptr( + cx: &ExtCtxt<'_>, + span: Span, + _mitem: &MetaItem, + item: &Annotatable, + push: &mut dyn FnMut(Annotatable), + _is_const: bool, +) { + let (name_ident, generics) = if let Annotatable::Item(aitem) = item + && let ItemKind::Struct(_, g) = &aitem.kind + { + (aitem.ident, g) + } else { + cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit(); + return; + }; + + // Convert generic parameters (from the struct) into generic args. + let mut pointee_param = None; + let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![]; + let self_params = generics + .params + .iter() + .enumerate() + .map(|(idx, p)| match p.kind { + GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)), + GenericParamKind::Type { .. } => { + if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) { + if pointee_param.is_some() { + multiple_pointee_diag.push(cx.dcx().struct_span_err( + p.span(), + "`SmartPointer` can only admit one type as pointee", + )); + } else { + pointee_param = Some(idx); + } + } + GenericArg::Type(cx.ty_ident(p.span(), p.ident)) + } + GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)), + }) + .collect::<Vec<_>>(); + let Some(pointee_param_idx) = pointee_param else { + cx.dcx().struct_span_err( + span, + "At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits", + ).emit(); + return; + }; + if !multiple_pointee_diag.is_empty() { + for diag in multiple_pointee_diag { + diag.emit(); + } + return; + } + + // Create the type of `self`. + let path = cx.path_all(span, false, vec![name_ident], self_params.clone()); + let self_type = cx.ty_path(path); + + // Declare helper function that adds implementation blocks. + // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls + let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),]; + let mut add_impl_block = |generics, trait_symbol, trait_args| { + let mut parts = path!(span, core::ops); + parts.push(Ident::new(trait_symbol, span)); + let trait_path = cx.path_all(span, true, parts, trait_args); + let trait_ref = cx.trait_ref(trait_path); + let item = cx.item( + span, + Ident::empty(), + attrs.clone(), + ast::ItemKind::Impl(Box::new(ast::Impl { + safety: ast::Safety::Default, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + constness: ast::Const::No, + generics, + of_trait: Some(trait_ref), + self_ty: self_type.clone(), + items: ThinVec::new(), + })), + ); + push(Annotatable::Item(item)); + }; + + // Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For + // example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`. + let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span)); + let mut alt_self_params = self_params; + alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone()); + let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params)); + + // Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it. + let mut impl_generics = generics.clone(); + { + let p = &mut impl_generics.params[pointee_param_idx]; + let arg = GenericArg::Type(s_ty.clone()); + let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]); + p.bounds.push(cx.trait_bound(unsize, false)); + let mut attrs = thin_vec![]; + swap(&mut p.attrs, &mut attrs); + p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect(); + } + + // Add the `__S: ?Sized` extra parameter to the impl block. + let sized = cx.path_global(span, path!(span, core::marker::Sized)); + let bound = GenericBound::Trait( + cx.poly_trait_ref(span, sized), + TraitBoundModifiers { + polarity: ast::BoundPolarity::Maybe(span), + constness: ast::BoundConstness::Never, + asyncness: ast::BoundAsyncness::Normal, + }, + ); + let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None); + impl_generics.params.push(extra_param); + + // Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`. + let gen_args = vec![GenericArg::Type(alt_self_type.clone())]; + add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone()); + add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone()); +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 35b0f43d8af..8ac59605bc1 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -127,6 +127,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { PartialOrd: partial_ord::expand_deriving_partial_ord, RustcDecodable: decodable::expand_deriving_rustc_decodable, RustcEncodable: encodable::expand_deriving_rustc_encodable, + SmartPointer: smart_ptr::expand_deriving_smart_ptr, } let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bbfc697407b..5e481eb98f5 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -564,9 +564,6 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); - // FIXME: NewPM doesn't provide a facility to pass custom InlineParams. - // We would have to add upstream support for this first, before we can support - // config.inline_threshold and our more aggressive default thresholds. let result = llvm::LLVMRustOptimize( module.module_llvm.llmod(), &*module.module_llvm.tm, diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 1a851ad04a1..000fe2e3ce0 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -27,8 +27,6 @@ codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} -codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)` - codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 064be4988bd..0e48eee3dd5 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -120,7 +120,6 @@ pub struct ModuleConfig { pub vectorize_loop: bool, pub vectorize_slp: bool, pub merge_functions: bool, - pub inline_threshold: Option<u32>, pub emit_lifetime_markers: bool, pub llvm_plugins: Vec<String>, } @@ -280,7 +279,6 @@ impl ModuleConfig { } }, - inline_threshold: sess.opts.cg.inline_threshold, emit_lifetime_markers: sess.emit_lifetime_markers(), llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]), } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 15955170e87..fb71cdaa8ff 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -15,11 +15,7 @@ use rustc_span::{sym, Span}; use rustc_target::spec::{abi, SanitizerSet}; use crate::errors; -use crate::target_features::from_target_feature; -use crate::{ - errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol}, - target_features::check_target_feature_trait_unsafe, -}; +use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature}; fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage { use rustc_middle::mir::mono::Linkage::*; @@ -139,7 +135,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // coverage on a smaller scope within an excluded larger scope. } Some(_) | None => { - tcx.dcx().emit_err(ExpectedCoverageSymbol { span: attr.span }); + tcx.dcx() + .span_delayed_bug(attr.span, "unexpected value of coverage attribute"); } } } @@ -174,7 +171,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } Some(_) => { - tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span }); + tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span }); } None => { // Unfortunately, unconditionally using `llvm.used` causes diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index e6ba31c5165..e9d31db9254 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -565,13 +565,6 @@ pub struct UnknownArchiveKind<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_expected_coverage_symbol)] -pub struct ExpectedCoverageSymbol { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(codegen_ssa_expected_used_symbol)] pub struct ExpectedUsedSymbol { #[primary_span] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 9781aae22eb..cddc67d1578 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -27,7 +27,6 @@ #![feature(lint_reasons)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] -#![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index 4c9acfe0f71..fed23df10dc 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -188,7 +188,7 @@ impl SipHasher128 { pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 { let mut hasher = SipHasher128 { nbuf: 0, - buf: MaybeUninit::uninit_array(), + buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY], state: State { v0: key0 ^ 0x736f6d6570736575, // The XOR with 0xee is only done on 128-bit algorithm version. diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index b5bdf2e1790..a57f5067dd8 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -238,12 +238,21 @@ pub trait ToStableHashKey<HCX> { /// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether /// unstable sorting can be used for this type. Set to true if and /// only if `a == b` implies `a` and `b` are fully indistinguishable. -pub unsafe trait StableOrd: Ord { +pub trait StableOrd: Ord { const CAN_USE_UNSTABLE_SORT: bool; + + /// Marker to ensure that implementors have carefully considered + /// whether their `Ord` implementation obeys this trait's contract. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: (); } -unsafe impl<T: StableOrd> StableOrd for &T { +impl<T: StableOrd> StableOrd for &T { const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT; + + // Ordering of a reference is exactly that of the referent, and since + // the ordering of the referet is stable so must be the ordering of the + // reference. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } /// This is a companion trait to `StableOrd`. Some types like `Symbol` can be @@ -290,8 +299,12 @@ macro_rules! impl_stable_traits_for_trivial_type { } } - unsafe impl $crate::stable_hasher::StableOrd for $t { + impl $crate::stable_hasher::StableOrd for $t { const CAN_USE_UNSTABLE_SORT: bool = true; + + // Encoding and decoding doesn't change the bytes of trivial types + // and `Ord::cmp` depends only on those bytes. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } }; } @@ -327,8 +340,12 @@ impl<CTX> HashStable<CTX> for Hash128 { } } -unsafe impl StableOrd for Hash128 { +impl StableOrd for Hash128 { const CAN_USE_UNSTABLE_SORT: bool = true; + + // Encoding and decoding doesn't change the bytes of `Hash128` + // and `Ord::cmp` depends only on those bytes. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<CTX> HashStable<CTX> for ! { @@ -392,8 +409,12 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2) } } -unsafe impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) { +impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) { const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT; + + // Ordering of tuples is a pure function of their elements' ordering, and since + // the ordering of each element is stable so must be the ordering of the tuple. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3) @@ -410,9 +431,13 @@ where } } -unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) { +impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) { const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT; + + // Ordering of tuples is a pure function of their elements' ordering, and since + // the ordering of each element is stable so must be the ordering of the tuple. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4) @@ -431,13 +456,15 @@ where } } -unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd - for (T1, T2, T3, T4) -{ +impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (T1, T2, T3, T4) { const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT && T4::CAN_USE_UNSTABLE_SORT; + + // Ordering of tuples is a pure function of their elements' ordering, and since + // the ordering of each element is stable so must be the ordering of the tuple. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] { @@ -530,8 +557,12 @@ impl<CTX> HashStable<CTX> for str { } } -unsafe impl StableOrd for &str { +impl StableOrd for &str { const CAN_USE_UNSTABLE_SORT: bool = true; + + // Encoding and decoding doesn't change the bytes of string slices + // and `Ord::cmp` depends only on those bytes. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<CTX> HashStable<CTX> for String { @@ -541,10 +572,12 @@ impl<CTX> HashStable<CTX> for String { } } -// Safety: String comparison only depends on their contents and the -// contents are not changed by (de-)serialization. -unsafe impl StableOrd for String { +impl StableOrd for String { const CAN_USE_UNSTABLE_SORT: bool = true; + + // String comparison only depends on their contents and the + // contents are not changed by (de-)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<HCX> ToStableHashKey<HCX> for String { @@ -570,9 +603,11 @@ impl<CTX> HashStable<CTX> for bool { } } -// Safety: sort order of bools is not changed by (de-)serialization. -unsafe impl StableOrd for bool { +impl StableOrd for bool { const CAN_USE_UNSTABLE_SORT: bool = true; + + // sort order of bools is not changed by (de-)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<T, CTX> HashStable<CTX> for Option<T> @@ -590,9 +625,11 @@ where } } -// Safety: the Option wrapper does not add instability to comparison. -unsafe impl<T: StableOrd> StableOrd for Option<T> { +impl<T: StableOrd> StableOrd for Option<T> { const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT; + + // the Option wrapper does not add instability to comparison. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2> diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5ffa3a6099c..bbe9741bf44 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -30,7 +30,7 @@ use rustc_errors::{ }; use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, get_codegen_backend}; -use rustc_interface::{interface, Queries}; +use rustc_interface::{interface, passes, Queries}; use rustc_lint::unerased_lint_store; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; @@ -367,18 +367,17 @@ fn run_compiler( return early_exit(); } - let early_dcx = EarlyDiagCtxt::new(sess.opts.error_format); - - if print_crate_info(&early_dcx, codegen_backend, sess, has_input) == Compilation::Stop { + if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop { return early_exit(); } if !has_input { - early_dcx.early_fatal("no input filename given"); // this is fatal + #[allow(rustc::diagnostic_outside_of_impl)] + sess.dcx().fatal("no input filename given"); // this is fatal } if !sess.opts.unstable_opts.ls.is_empty() { - list_metadata(&early_dcx, sess, &*codegen_backend.metadata_loader()); + list_metadata(sess, &*codegen_backend.metadata_loader()); return early_exit(); } @@ -399,7 +398,9 @@ fn run_compiler( Ok(()) })?; - queries.write_dep_info()?; + queries.global_ctxt()?.enter(|tcx| { + passes::write_dep_info(tcx); + }); } else { let krate = queries.parse()?; pretty::print( @@ -427,7 +428,9 @@ fn run_compiler( return early_exit(); } - queries.write_dep_info()?; + queries.global_ctxt()?.enter(|tcx| { + passes::write_dep_info(tcx); + }); if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 @@ -670,7 +673,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { } } -fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dyn MetadataLoader) { +fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) { match sess.io.input { Input::File(ref ifile) => { let path = &(*ifile); @@ -687,13 +690,13 @@ fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dy safe_println!("{}", String::from_utf8(v).unwrap()); } Input::Str { .. } => { - early_dcx.early_fatal("cannot list metadata for stdin"); + #[allow(rustc::diagnostic_outside_of_impl)] + sess.dcx().fatal("cannot list metadata for stdin"); } } } fn print_crate_info( - early_dcx: &EarlyDiagCtxt, codegen_backend: &dyn CodegenBackend, sess: &Session, parse_attrs: bool, @@ -877,8 +880,8 @@ fn print_crate_info( .expect("unknown Apple target OS"); println_info!("deployment_target={}", format!("{major}.{minor}")) } else { - early_dcx - .early_fatal("only Apple targets currently support deployment version info") + #[allow(rustc::diagnostic_outside_of_impl)] + sess.dcx().fatal("only Apple targets currently support deployment version info") } } } @@ -1133,7 +1136,11 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> } if cg_flags.iter().any(|x| *x == "no-stack-check") { - early_dcx.early_warn("the --no-stack-check flag is deprecated and does nothing"); + early_dcx.early_warn("the `-Cno-stack-check` flag is deprecated and does nothing"); + } + + if cg_flags.iter().any(|x| x.starts_with("inline-threshold")) { + early_dcx.early_warn("the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)"); } if cg_flags.iter().any(|x| *x == "passes=list") { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 7405705dd33..45118bcc58a 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -902,7 +902,7 @@ impl HumanEmitter { // <EMPTY LINE> // let mut annotations_position = vec![]; - let mut line_len = 0; + let mut line_len: usize = 0; let mut p = 0; for (i, annotation) in annotations.iter().enumerate() { for (j, next) in annotations.iter().enumerate() { @@ -973,6 +973,31 @@ impl HumanEmitter { return vec![]; } + if annotations_position + .iter() + .all(|(_, ann)| matches!(ann.annotation_type, AnnotationType::MultilineStart(_))) + && let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max() + { + // Special case the following, so that we minimize overlapping multiline spans. + // + // 3 │ X0 Y0 Z0 + // │ ┏━━━━━┛ │ │ < We are writing these lines + // │ ┃┌───────┘ │ < by reverting the "depth" of + // │ ┃│┌─────────┘ < their multilne spans. + // 4 │ ┃││ X1 Y1 Z1 + // 5 │ ┃││ X2 Y2 Z2 + // │ ┃│└────╿──│──┘ `Z` label + // │ ┃└─────│──┤ + // │ ┗━━━━━━┥ `Y` is a good letter too + // ╰╴ `X` is a good letter + for (pos, _) in &mut annotations_position { + *pos = max_pos - *pos; + } + // We know then that we don't need an additional line for the span label, saving us + // one line of vertical space. + line_len = line_len.saturating_sub(1); + } + // Write the column separator. // // After this we will have: diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5e83e0d27e1..c53bf965139 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -105,6 +105,9 @@ pub struct AttributeTemplate { pub word: bool, /// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`. pub list: Option<&'static str>, + /// If non-empty, the attribute is allowed to take a list containing exactly + /// one of the listed words, like `#[coverage(off)]`. + pub one_of: &'static [Symbol], /// If `Some`, the attribute is allowed to be a name/value pair where the /// value is a string, like `#[must_use = "reason"]`. pub name_value_str: Option<&'static str>, @@ -165,19 +168,20 @@ pub enum AttributeDuplicates { /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. macro_rules! template { - (Word) => { template!(@ true, None, None) }; - (List: $descr: expr) => { template!(@ false, Some($descr), None) }; - (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; - (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; - (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; + (Word) => { template!(@ true, None, &[], None) }; + (List: $descr: expr) => { template!(@ false, Some($descr), &[], None) }; + (OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) }; + (NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) }; + (Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) }; + (Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) }; (List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ false, Some($descr1), Some($descr2)) + template!(@ false, Some($descr1), &[], Some($descr2)) }; (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ true, Some($descr1), Some($descr2)) + template!(@ true, Some($descr1), &[], Some($descr2)) }; - (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { - word: $word, list: $list, name_value_str: $name_value_str + (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate { + word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str } }; } @@ -478,8 +482,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, experimental!(no_sanitize) ), gated!( - coverage, Normal, template!(Word, List: "on|off"), - WarnFollowing, EncodeCrossCrate::No, + coverage, Normal, template!(OneOf: &[sym::off, sym::on]), + ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), @@ -575,6 +579,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, coroutines, experimental!(coroutines) ), + // `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro + gated!( + pointee, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f66c9604cbe..2dfaac8f6e7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -436,6 +436,8 @@ declare_features! ( (unstable, deprecated_suggestion, "1.61.0", Some(94785)), /// Allows deref patterns. (incomplete, deref_patterns, "1.79.0", Some(87121)), + /// Allows deriving `SmartPointer` traits + (unstable, derive_smart_pointer, "1.79.0", Some(123430)), /// Controls errors in trait implementations. (unstable, do_not_recommend, "1.67.0", Some(51992)), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index ac487469507..c0ca1a8017e 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -165,10 +165,12 @@ impl ItemLocalId { pub const INVALID: ItemLocalId = ItemLocalId::MAX; } -// Safety: Ord is implement as just comparing the ItemLocalId's numerical -// values and these are not changed by (de-)serialization. -unsafe impl StableOrd for ItemLocalId { +impl StableOrd for ItemLocalId { const CAN_USE_UNSTABLE_SORT: bool = true; + + // `Ord` is implemented as just comparing the ItemLocalId's numerical + // values and these are not changed by (de-)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 3b53c253195..e13ea1a1935 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -719,7 +719,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx, assoc_item, assoc_item, - ty::TraitRef::new(tcx, def_id.to_def_id(), trait_args), + ty::TraitRef::new_from_args(tcx, def_id.to_def_id(), trait_args), ); } _ => {} 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 550f38af8b5..7fa5c96bc9a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2032,7 +2032,7 @@ pub(super) fn check_type_bounds<'tcx>( // to its definition type. This should be the param-env we use to *prove* the // predicate too, but we don't do that because of performance issues. // See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>. - let trait_projection_ty = Ty::new_projection(tcx, trait_ty.def_id, rebased_args); + let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args); let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity(); let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); for mut obligation in util::elaborate(tcx, obligations) { @@ -2230,7 +2230,11 @@ fn param_env_with_gat_bounds<'tcx>( _ => predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, trait_ty.def_id, rebased_args), + projection_term: ty::AliasTerm::new_from_args( + tcx, + trait_ty.def_id, + rebased_args, + ), term: normalize_impl_ty.into(), }, bound_vars, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 683709f43f2..f21aeb4c0b9 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -504,7 +504,11 @@ pub fn check_intrinsic_type( ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0), )], - Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])), + Ty::new_projection_from_args( + tcx, + discriminant_def_id, + tcx.mk_args(&[param(0).into()]), + ), ) } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e5bd147352d..e7892f17660 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -423,7 +423,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { item_segment, trait_ref.args, ); - Ty::new_projection(self.tcx(), item_def_id, item_args) + Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) } else { // There are no late-bound regions; we can just ignore the binder. let (mut mpart_sugg, mut inferred_sugg) = (None, None); @@ -1607,7 +1607,7 @@ pub fn suggest_impl_trait<'tcx>( let item_ty = ocx.normalize( &ObligationCause::dummy(), param_env, - Ty::new_projection(infcx.tcx, assoc_item_def_id, args), + Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args), ); // FIXME(compiler-errors): We may benefit from resolving regions here. if ocx.select_where_possible().is_empty() diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 9f198933dee..d084d3aefeb 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -23,7 +23,7 @@ fn associated_type_bounds<'tcx>( span: Span, filter: PredicateFilter, ) -> &'tcx [(ty::Clause<'tcx>, Span)] { - let item_ty = Ty::new_projection( + let item_ty = Ty::new_projection_from_args( tcx, assoc_item_def_id.to_def_id(), GenericArgs::identity_for_item(tcx, assoc_item_def_id), @@ -108,7 +108,7 @@ pub(super) fn explicit_item_bounds_with_filter( tcx, opaque_def_id.expect_local(), opaque_ty.bounds, - Ty::new_projection( + Ty::new_projection_from_args( tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index c7699b0b310..802215b2843 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -409,7 +409,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?alias_args); - ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args) + ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args) }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. 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 5911d5bb4e1..24ea328889c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -693,7 +693,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?bound_vars); let poly_trait_ref = ty::Binder::bind_with_vars( - ty::TraitRef::new(tcx, trait_def_id, generic_args), + ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args), bound_vars, ); @@ -759,7 +759,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some((trait_def_id, trait_segment, span)), ); } - ty::TraitRef::new(self.tcx(), trait_def_id, generic_args) + ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args) } fn probe_trait_that_defines_assoc_item( @@ -789,7 +789,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Type aliases defined in crates that have the // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. - let alias_ty = ty::AliasTy::new(tcx, did, args); + let alias_ty = ty::AliasTy::new_from_args(tcx, did, args); Ty::new_alias(tcx, ty::Weak, alias_ty) } else { tcx.at(span).type_of(did).instantiate(tcx, args) @@ -1267,7 +1267,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .chain(args.into_iter().skip(parent_args.len())), ); - let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args)); + let ty = + Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new_from_args(tcx, assoc_item, args)); Ok(Some((ty, assoc_item))) } @@ -1534,7 +1535,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let item_args = self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args); - Ty::new_projection(tcx, item_def_id, item_args) + Ty::new_projection_from_args(tcx, item_def_id, item_args) } pub fn prohibit_generic_args<'a>( @@ -2302,7 +2303,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?args); if in_trait { - Ty::new_projection(tcx, def_id, args) + Ty::new_projection_from_args(tcx, def_id, args) } else { Ty::new_opaque(tcx, def_id, args) } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 31f85e21d71..0551b9bc1f0 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1245,11 +1245,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr, ); - return self + return Err(self .commit_if_ok(|_| { - self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty) + self.at(cause, self.param_env).lub(DefineOpaqueTypes::Yes, prev_ty, new_ty) }) - .map(|ok| self.register_infer_ok_obligations(ok)); + .unwrap_err()); } } @@ -1259,10 +1259,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(e) = first_error { Err(e) } else { - self.commit_if_ok(|_| { - self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty) - }) - .map(|ok| self.register_infer_ok_obligations(ok)) + Err(self + .commit_if_ok(|_| { + self.at(cause, self.param_env).lub( + DefineOpaqueTypes::Yes, + prev_ty, + new_ty, + ) + }) + .unwrap_err()) } } Ok(ok) => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 233dc2afa9b..f4e1e461953 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3108,7 +3108,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let element_ty = ocx.normalize( &cause, self.param_env, - Ty::new_projection(self.tcx, index_trait_output_def_id, impl_trait_ref.args), + Ty::new_projection_from_args( + self.tcx, + index_trait_output_def_id, + impl_trait_ref.args, + ), ); let true_errors = ocx.select_where_possible(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 4edc11d7ab1..f7abba35706 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of // that struct type. let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_or_alias_def_id) { - ty::TraitRef::new( + ty::TraitRef::new_from_args( self.tcx, obligation.impl_or_alias_def_id, ty::GenericArgs::identity_for_item(self.tcx, obligation.impl_or_alias_def_id), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 1713d75092e..c0d60477967 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -297,7 +297,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { trait_ref.args, ); - Ty::new_projection(self.tcx(), item_def_id, item_args) + Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) } fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> { diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index fb8863c143f..5eafc60a04e 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -73,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Special-case transmuting from `typeof(function)` and // `Option<typeof(function)>` to present a clearer error. let from = unpack_option_like(tcx, from); - if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) + if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") @@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to display a sensible error with as much information as possible. let skeleton_string = |ty: Ty<'tcx>, sk: Result<_, &_>| match sk { Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), - Ok(SizeSkeleton::Known(size)) => { + Ok(SizeSkeleton::Known(size, _)) => { if let Some(v) = u128::from(size.bytes()).checked_mul(8) { format!("{v} bits") } else { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 1f90d5e4c88..e1223307b53 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -333,7 +333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.var_for_def(cause.span, param) }); - let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, args); + let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, args); // Construct an obligation let poly_trait_ref = ty::Binder::dummy(trait_ref); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 47ea221d1a1..9747a91ccbf 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -870,7 +870,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { trait_def_id: DefId, ) { let trait_args = self.fresh_args_for_item(self.span, trait_def_id); - let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_args); + let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args); if self.tcx.is_trait_alias(trait_def_id) { // For trait aliases, recursively assume all explicitly named traits are relevant diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index ec0cb7a67ba..a385bc70e35 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1978,7 +1978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err, self_source, args, - ty::TraitRef::new( + ty::TraitRef::new_from_args( self.tcx, trait_did, self.fresh_args_for_item(sugg_span, trait_did), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index e125f1858dd..80b7e3b4fa5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -256,12 +256,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { (false, None, None, Some(span), String::new()) }; - let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( + let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args( self.cx.tcx, trait_def_id, expected_args, )); - let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( + let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args( self.cx.tcx, trait_def_id, actual_args, diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 41c8b941717..dba20e4a335 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -495,9 +495,8 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se let res = { // If `f` panics, `finish_diagnostics` will run during // unwinding because of the `defer`. - let mut guar = None; let sess_abort_guard = defer(|| { - guar = compiler.sess.finish_diagnostics(&config.registry); + compiler.sess.finish_diagnostics(&config.registry); }); let res = f(&compiler); @@ -506,16 +505,14 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se // normally when `sess_abort_guard` is dropped. drop(sess_abort_guard); - // If `finish_diagnostics` emits errors (e.g. stashed - // errors) we can't return an error directly, because the - // return type of this function is `R`, not `Result<R, E>`. - // But we need to communicate the errors' existence to the - // caller, otherwise the caller might mistakenly think that - // no errors occurred and return a zero exit code. So we - // abort (panic) instead, similar to if `f` had panicked. - if guar.is_some() { - compiler.sess.dcx().abort_if_errors(); - } + // If error diagnostics have been emitted, we can't return an + // error directly, because the return type of this function + // is `R`, not `Result<R, E>`. But we need to communicate the + // errors' existence to the caller, otherwise the caller might + // mistakenly think that no errors occurred and return a zero + // exit code. So we abort (panic) instead, similar to if `f` + // had panicked. + compiler.sess.dcx().abort_if_errors(); res }; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 0c3d4e19ef8..38f64ebb04e 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -8,7 +8,7 @@ mod callbacks; mod errors; pub mod interface; -mod passes; +pub mod passes; mod proc_macro_decls; mod queries; pub mod util; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f881d53858a..2951f50b1f5 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -7,16 +7,16 @@ use rustc_ast::{self as ast, visit}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::parallel; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{Lrc, OnceLock, WorkerLocal}; -use rustc_errors::PResult; +use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal}; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; -use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE}; +use rustc_hir::def_id::{StableCrateId, StableCrateIdMap, LOCAL_CRATE}; +use rustc_hir::definitions::Definitions; +use rustc_incremental::setup_dep_graph; use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore}; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; -use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt}; use rustc_middle::util::Providers; use rustc_parse::{ @@ -28,6 +28,7 @@ use rustc_session::code_stats::VTableSizeInfo; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; use rustc_session::output::filename_for_input; +use rustc_session::output::{collect_crate_types, find_crate_name}; use rustc_session::search_paths::PathKind; use rustc_session::{Limit, Session}; use rustc_span::symbol::{sym, Symbol}; @@ -39,20 +40,22 @@ use std::any::Any; use std::ffi::OsString; use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; -use std::sync::LazyLock; +use std::sync::{Arc, LazyLock}; use std::{env, fs, iter}; use tracing::{info, instrument}; -pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> { - let krate = sess.time("parse_crate", || { - let mut parser = unwrap_or_emit_fatal(match &sess.io.input { - Input::File(file) => new_parser_from_file(&sess.psess, file, None), - Input::Str { input, name } => { - new_parser_from_source_str(&sess.psess, name.clone(), input.clone()) - } - }); - parser.parse_crate_mod() - })?; +pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> { + let krate = sess + .time("parse_crate", || { + let mut parser = unwrap_or_emit_fatal(match &sess.io.input { + Input::File(file) => new_parser_from_file(&sess.psess, file, None), + Input::Str { input, name } => { + new_parser_from_source_str(&sess.psess, name.clone(), input.clone()) + } + }); + parser.parse_crate_mod() + }) + .map_err(|parse_error| parse_error.emit())?; if sess.opts.unstable_opts.input_stats { eprintln!("Lines of code: {}", sess.source_map().count_lines()); @@ -559,7 +562,7 @@ fn resolver_for_lowering_raw<'tcx>( (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate)))), resolutions) } -pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) { +pub fn write_dep_info(tcx: TyCtxt<'_>) { // Make sure name resolution and macro expansion is run for // the side-effect of providing a complete set of all // accessed files and env vars. @@ -640,22 +643,48 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| { *providers }); -pub fn create_global_ctxt<'tcx>( +pub(crate) fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, - crate_types: Vec<CrateType>, - stable_crate_id: StableCrateId, - dep_graph: DepGraph, - untracked: Untracked, + mut krate: rustc_ast::Crate, gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>, arena: &'tcx WorkerLocal<Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>, -) -> &'tcx GlobalCtxt<'tcx> { +) -> Result<&'tcx GlobalCtxt<'tcx>> { + let sess = &compiler.sess; + + rustc_builtin_macros::cmdline_attrs::inject( + &mut krate, + &sess.psess, + &sess.opts.unstable_opts.crate_attr, + ); + + let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); + + // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. + let crate_name = find_crate_name(sess, &pre_configured_attrs); + let crate_types = collect_crate_types(sess, &pre_configured_attrs); + let stable_crate_id = StableCrateId::new( + crate_name, + crate_types.contains(&CrateType::Executable), + sess.opts.cg.metadata.clone(), + sess.cfg_version, + ); + let outputs = util::build_output_filenames(&pre_configured_attrs, sess); + let dep_graph = setup_dep_graph(sess)?; + + let cstore = + FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); + let definitions = FreezeLock::new(Definitions::new(stable_crate_id)); + + let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default()); + let untracked = + Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids }; + // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to // incr. comp. yet. dep_graph.assert_ignored(); - let sess = &compiler.sess; let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); let codegen_backend = &compiler.codegen_backend; @@ -669,7 +698,7 @@ pub fn create_global_ctxt<'tcx>( let incremental = dep_graph.is_fully_enabled(); sess.time("setup_global_ctxt", || { - gcx_cell.get_or_init(move || { + let qcx = gcx_cell.get_or_init(move || { TyCtxt::create_global_ctxt( sess, crate_types, @@ -688,7 +717,23 @@ pub fn create_global_ctxt<'tcx>( providers.hooks, compiler.current_gcx.clone(), ) - }) + }); + + qcx.enter(|tcx| { + let feed = tcx.create_crate_num(stable_crate_id).unwrap(); + assert_eq!(feed.key(), LOCAL_CRATE); + feed.crate_name(crate_name); + + let feed = tcx.feed_unit_query(); + feed.features_query(tcx.arena.alloc(rustc_expand::config::features( + sess, + &pre_configured_attrs, + crate_name, + ))); + feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); + feed.output_filenames(Arc::new(outputs)); + }); + Ok(qcx) }) } @@ -924,12 +969,56 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { Ok(()) } +/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used +/// to write UI tests that actually test that compilation succeeds without reporting +/// an error. +fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { + let Some((def_id, _)) = tcx.entry_fn(()) else { return }; + for attr in tcx.get_attrs(def_id, sym::rustc_error) { + match attr.meta_item_list() { + // Check if there is a `#[rustc_error(delayed_bug_from_inside_query)]`. + Some(list) + if list.iter().any(|list_item| { + matches!( + list_item.ident().map(|i| i.name), + Some(sym::delayed_bug_from_inside_query) + ) + }) => + { + tcx.ensure().trigger_delayed_bug(def_id); + } + + // Bare `#[rustc_error]`. + None => { + tcx.dcx().emit_fatal(errors::RustcErrorFatal { span: tcx.def_span(def_id) }); + } + + // Some other attribute. + Some(_) => { + tcx.dcx().emit_warn(errors::RustcErrorUnexpectedAnnotation { + span: tcx.def_span(def_id), + }); + } + } + } +} + /// Runs the codegen backend, after which the AST and analysis can /// be discarded. -pub fn start_codegen<'tcx>( +pub(crate) fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, -) -> Box<dyn Any> { +) -> Result<Box<dyn Any>> { + // Don't do code generation if there were any errors. Likewise if + // there were any delayed bugs, because codegen will likely cause + // more ICEs, obscuring the original problem. + if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() { + return Err(guar); + } + + // Hook for UI tests. + check_for_rustc_errors_attr(tcx); + info!("Pre-codegen\n{:?}", tcx.debug_stats()); let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx); @@ -952,7 +1041,7 @@ pub fn start_codegen<'tcx>( } } - codegen + Ok(codegen) } fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 1b9165342d4..cfd4304e893 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,26 +1,20 @@ -use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation}; +use crate::errors::FailedWritingFile; use crate::interface::{Compiler, Result}; -use crate::{errors, passes, util}; +use crate::{errors, passes}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::CodegenResults; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal}; -use rustc_hir::def_id::{StableCrateId, StableCrateIdMap, LOCAL_CRATE}; -use rustc_hir::definitions::Definitions; -use rustc_incremental::setup_dep_graph; -use rustc_metadata::creader::CStore; +use rustc_data_structures::sync::{OnceLock, WorkerLocal}; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{GlobalCtxt, TyCtxt}; use rustc_serialize::opaque::FileEncodeResult; -use rustc_session::config::{self, CrateType, OutputFilenames, OutputType}; -use rustc_session::cstore::Untracked; -use rustc_session::output::{collect_crate_types, find_crate_name}; +use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::Session; -use rustc_span::symbol::sym; use std::any::Any; use std::cell::{RefCell, RefMut}; use std::sync::Arc; @@ -106,133 +100,26 @@ impl<'tcx> Queries<'tcx> { } pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> { - self.parse.compute(|| { - passes::parse(&self.compiler.sess).map_err(|parse_error| parse_error.emit()) - }) + self.parse.compute(|| passes::parse(&self.compiler.sess)) } pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> { self.gcx.compute(|| { - let sess = &self.compiler.sess; - - let mut krate = self.parse()?.steal(); - - rustc_builtin_macros::cmdline_attrs::inject( - &mut krate, - &sess.psess, - &sess.opts.unstable_opts.crate_attr, - ); - - let pre_configured_attrs = - rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); - - // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. - let crate_name = find_crate_name(sess, &pre_configured_attrs); - let crate_types = collect_crate_types(sess, &pre_configured_attrs); - let stable_crate_id = StableCrateId::new( - crate_name, - crate_types.contains(&CrateType::Executable), - sess.opts.cg.metadata.clone(), - sess.cfg_version, - ); - let outputs = util::build_output_filenames(&pre_configured_attrs, sess); - let dep_graph = setup_dep_graph(sess)?; - - let cstore = FreezeLock::new(Box::new(CStore::new( - self.compiler.codegen_backend.metadata_loader(), - )) as _); - let definitions = FreezeLock::new(Definitions::new(stable_crate_id)); - - let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default()); - let untracked = Untracked { - cstore, - source_span: AppendOnlyIndexVec::new(), - definitions, - stable_crate_ids, - }; - - let qcx = passes::create_global_ctxt( + let krate = self.parse()?.steal(); + + passes::create_global_ctxt( self.compiler, - crate_types, - stable_crate_id, - dep_graph, - untracked, + krate, &self.gcx_cell, &self.arena, &self.hir_arena, - ); - - qcx.enter(|tcx| { - let feed = tcx.create_crate_num(stable_crate_id).unwrap(); - assert_eq!(feed.key(), LOCAL_CRATE); - feed.crate_name(crate_name); - - let feed = tcx.feed_unit_query(); - feed.features_query(tcx.arena.alloc(rustc_expand::config::features( - sess, - &pre_configured_attrs, - crate_name, - ))); - feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); - feed.output_filenames(Arc::new(outputs)); - }); - Ok(qcx) + ) }) } - pub fn write_dep_info(&'tcx self) -> Result<()> { - self.global_ctxt()?.enter(|tcx| { - passes::write_dep_info(tcx); - }); - Ok(()) - } - - /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used - /// to write UI tests that actually test that compilation succeeds without reporting - /// an error. - fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { - let Some((def_id, _)) = tcx.entry_fn(()) else { return }; - for attr in tcx.get_attrs(def_id, sym::rustc_error) { - match attr.meta_item_list() { - // Check if there is a `#[rustc_error(delayed_bug_from_inside_query)]`. - Some(list) - if list.iter().any(|list_item| { - matches!( - list_item.ident().map(|i| i.name), - Some(sym::delayed_bug_from_inside_query) - ) - }) => - { - tcx.ensure().trigger_delayed_bug(def_id); - } - - // Bare `#[rustc_error]`. - None => { - tcx.dcx().emit_fatal(RustcErrorFatal { span: tcx.def_span(def_id) }); - } - - // Some other attribute. - Some(_) => { - tcx.dcx() - .emit_warn(RustcErrorUnexpectedAnnotation { span: tcx.def_span(def_id) }); - } - } - } - } - pub fn codegen_and_build_linker(&'tcx self) -> Result<Linker> { self.global_ctxt()?.enter(|tcx| { - // Don't do code generation if there were any errors. Likewise if - // there were any delayed bugs, because codegen will likely cause - // more ICEs, obscuring the original problem. - if let Some(guar) = self.compiler.sess.dcx().has_errors_or_delayed_bugs() { - return Err(guar); - } - - // Hook for UI tests. - Self::check_for_rustc_errors_attr(tcx); - - let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx); + let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx)?; Ok(Linker { dep_graph: tcx.dep_graph.clone(), diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index eac5083ffbf..46cf87d1e3c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -604,6 +604,9 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro .suggestion = use pat_param to preserve semantics +lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope + .help = import `macro_rules` with `use` to make it callable above its definition + lint_overflowing_bin_hex = literal out of range for `{$ty}` .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}` diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index adb2a3275c0..05e075205c4 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -434,5 +434,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::InnerAttributeUnstable::CustomInnerAttribute } .decorate_lint(diag), + BuiltinLintDiag::OutOfScopeMacroCalls { path } => { + lints::OutOfScopeMacroCalls { path }.decorate_lint(diag) + } } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 6df3a11deb0..14084405d0e 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2911,3 +2911,10 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion { #[suggestion_part(code = ")")] pub right: Span, } + +#[derive(LintDiagnostic)] +#[diag(lint_out_of_scope_macro_calls)] +#[help] +pub struct OutOfScopeMacroCalls { + pub path: String, +} diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 7aef6321eeb..8b669bcc13f 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { return; } - let proj_ty = Ty::new_projection( + let proj_ty = Ty::new_projection_from_args( cx.tcx, proj.projection_term.def_id, proj.projection_term.args, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 265779c9374..a023d6161df 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4945,3 +4945,42 @@ declare_lint! { reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>", }; } + +declare_lint! { + /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope, + /// above their definition, which may happen in key-value attributes. + /// + /// ### Example + /// + /// ```rust + /// #![doc = in_root!()] + /// + /// macro_rules! in_root { () => { "" } } + /// + /// fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The scope in which a `macro_rules` item is visible starts at that item and continues + /// below it. This is more similar to `let` than to other items, which are in scope both above + /// and below their definition. + /// Due to a bug `macro_rules` were accidentally in scope inside some key-value attributes + /// above their definition. The lint catches such cases. + /// To address the issue turn the `macro_rules` into a regularly scoped item by importing it + /// with `use`. + /// + /// This is a [future-incompatible] lint to transition this to a + /// hard error in the future. + /// + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub OUT_OF_SCOPE_MACRO_CALLS, + Warn, + "detects out of scope calls to `macro_rules` in key-value attributes", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reference: "issue #124535 <https://github.com/rust-lang/rust/issues/124535>", + }; +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index f33aadfbbc8..b44eb252167 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -744,6 +744,9 @@ pub enum BuiltinLintDiag { InnerAttributeUnstable { is_macro: bool, }, + OutOfScopeMacroCalls { + path: String, + }, } /// Lints that are buffered up early on in the `Session` before the diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 01cefc75194..ef88b253864 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1817,11 +1817,11 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // tidy-alphabetical-start - static_assert_size!(BasicBlockData<'_>, 144); + static_assert_size!(BasicBlockData<'_>, 128); static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); static_assert_size!(Statement<'_>, 32); - static_assert_size!(Terminator<'_>, 112); + static_assert_size!(Terminator<'_>, 96); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 0fc84ea5c62..2c2884f1897 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -730,7 +730,7 @@ pub enum TerminatorKind<'tcx> { /// reused across function calls without duplicating the contents. /// The span for each arg is also included /// (e.g. `a` and `b` in `x.foo(a, b)`). - args: Vec<Spanned<Operand<'tcx>>>, + args: Box<[Spanned<Operand<'tcx>>]>, /// Where the returned value will be written destination: Place<'tcx>, /// Where to go after this call returns. If none, the call necessarily diverges. @@ -837,7 +837,7 @@ pub enum TerminatorKind<'tcx> { template: &'tcx [InlineAsmTemplatePiece], /// The operands for the inline assembly, as `Operand`s or `Place`s. - operands: Vec<InlineAsmOperand<'tcx>>, + operands: Box<[InlineAsmOperand<'tcx>]>, /// Miscellaneous options for the inline assembly. options: InlineAsmOptions, @@ -849,7 +849,7 @@ pub enum TerminatorKind<'tcx> { /// Valid targets for the inline assembly. /// The first element is the fallthrough destination, unless /// InlineAsmOptions::NORETURN is set. - targets: Vec<BasicBlock>, + targets: Box<[BasicBlock]>, /// Action to be taken if the inline assembly unwinds. This is present /// if and only if InlineAsmOptions::MAY_UNWIND is set. @@ -1561,6 +1561,6 @@ mod size_asserts { static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(Rvalue<'_>, 40); static_assert_size!(StatementKind<'_>, 16); - static_assert_size!(TerminatorKind<'_>, 96); + static_assert_size!(TerminatorKind<'_>, 80); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7848aa21eac..4bac9396e59 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -240,7 +240,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); let trait_generics = self.generics_of(trait_def_id); ( - ty::TraitRef::new(self, trait_def_id, args.truncate_to(self, trait_generics)), + ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)), &args[trait_generics.count()..], ) } @@ -261,12 +261,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.check_args_compatible(def_id, args) } - fn check_and_mk_args( - self, - def_id: DefId, - args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, - ) -> ty::GenericArgsRef<'tcx> { - self.check_and_mk_args(def_id, args) + fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) { + self.debug_assert_args_compatible(def_id, args); } fn intern_canonical_goal_evaluation_step( diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f608b02f42c..eb25aecd9ce 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -309,7 +309,8 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> { #[derive(Copy, Clone, Debug)] pub enum SizeSkeleton<'tcx> { /// Any statically computable Layout. - Known(Size), + /// Alignment can be `None` if unknown. + Known(Size, Option<Align>), /// This is a generic const expression (i.e. N * 2), which may contain some parameters. /// It must be of type usize, and represents the size of a type in bytes. @@ -339,7 +340,12 @@ impl<'tcx> SizeSkeleton<'tcx> { // First try computing a static layout. let err = match tcx.layout_of(param_env.and(ty)) { Ok(layout) => { - return Ok(SizeSkeleton::Known(layout.size)); + if layout.abi.is_sized() { + return Ok(SizeSkeleton::Known(layout.size, Some(layout.align.abi))); + } else { + // Just to be safe, don't claim a known layout for unsized types. + return Err(tcx.arena.alloc(LayoutError::Unknown(ty))); + } } Err(err @ LayoutError::Unknown(_)) => err, // We can't extract SizeSkeleton info from other layout errors @@ -389,19 +395,20 @@ impl<'tcx> SizeSkeleton<'tcx> { ty::Array(inner, len) if tcx.features().transmute_generic_consts => { let len_eval = len.try_eval_target_usize(tcx, param_env); if len_eval == Some(0) { - return Ok(SizeSkeleton::Known(Size::from_bytes(0))); + return Ok(SizeSkeleton::Known(Size::from_bytes(0), None)); } match SizeSkeleton::compute(inner, tcx, param_env)? { // This may succeed because the multiplication of two types may overflow // but a single size of a nested array will not. - SizeSkeleton::Known(s) => { + SizeSkeleton::Known(s, a) => { if let Some(c) = len_eval { let size = s .bytes() .checked_mul(c) .ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?; - return Ok(SizeSkeleton::Known(Size::from_bytes(size))); + // Alignment is unchanged by arrays. + return Ok(SizeSkeleton::Known(Size::from_bytes(size), a)); } Err(tcx.arena.alloc(LayoutError::Unknown(ty))) } @@ -427,8 +434,10 @@ impl<'tcx> SizeSkeleton<'tcx> { for field in fields { let field = field?; match field { - SizeSkeleton::Known(size) => { - if size.bytes() > 0 { + SizeSkeleton::Known(size, align) => { + let is_1zst = size.bytes() == 0 + && align.is_some_and(|align| align.bytes() == 1); + if !is_1zst { return Err(err); } } @@ -492,7 +501,7 @@ impl<'tcx> SizeSkeleton<'tcx> { pub fn same_size(self, other: SizeSkeleton<'tcx>) -> bool { match (self, other) { - (SizeSkeleton::Known(a), SizeSkeleton::Known(b)) => a == b, + (SizeSkeleton::Known(a, _), SizeSkeleton::Known(b, _)) => a == b, (SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => { a == b } diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 71a93cc520d..73eba93194e 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -133,6 +133,20 @@ impl<H, T> RawList<H, T> { } } +impl<'a, H, T: Copy> rustc_type_ir::inherent::SliceLike for &'a RawList<H, T> { + type Item = T; + + type IntoIter = iter::Copied<<&'a [T] as IntoIterator>::IntoIter>; + + fn iter(self) -> Self::IntoIter { + (*self).iter() + } + + fn as_slice(&self) -> &[Self::Item] { + (*self).as_slice() + } +} + macro_rules! impl_list_empty { ($header_ty:ty, $header_init:expr) => { impl<T> RawList<$header_ty, T> { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 709c5fe2305..ff40a726fbc 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -499,7 +499,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> { - Ty::new_alias(tcx, ty::Opaque, AliasTy::new(tcx, def_id, args)) + Ty::new_alias(tcx, ty::Opaque, AliasTy::new_from_args(tcx, def_id, args)) } /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` @@ -670,6 +670,15 @@ impl<'tcx> Ty<'tcx> { } #[inline] + pub fn new_projection_from_args( + tcx: TyCtxt<'tcx>, + item_def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> Ty<'tcx> { + Ty::new_alias(tcx, ty::Projection, AliasTy::new_from_args(tcx, item_def_id, args)) + } + + #[inline] pub fn new_projection( tcx: TyCtxt<'tcx>, item_def_id: DefId, @@ -1409,7 +1418,7 @@ impl<'tcx> Ty<'tcx> { let assoc_items = tcx.associated_item_def_ids( tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), ); - Ty::new_projection(tcx, assoc_items[0], tcx.mk_args(&[self.into()])) + Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()])) } ty::Pat(ty, _) => ty.discriminant_ty(tcx), diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 7549481c1b3..94ab2fb4581 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -170,7 +170,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { .map(|arg| Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span } ) ) - .collect::<PResult<Vec<_>>>()?; + .collect::<PResult<Box<[_]>>>()?; Ok(TerminatorKind::Call { func: fun, args, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 9f9b566bb8f..c5ee6db5999 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -152,10 +152,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, TerminatorKind::Call { func: exchange_malloc, - args: vec![ + args: [ Spanned { node: Operand::Move(size), span: DUMMY_SP }, Spanned { node: Operand::Move(align), span: DUMMY_SP }, - ], + ] + .into(), destination: storage, target: Some(success), unwind: UnwindAction::Continue, diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 6b4dd8b64a4..76bdc26a501 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Call { ty: _, fun, ref args, from_hir_call, fn_span } => { let fun = unpack!(block = this.as_local_operand(block, fun)); - let args: Vec<_> = args + let args: Box<[_]> = args .into_iter() .copied() .map(|arg| Spanned { @@ -485,7 +485,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { operands, options, line_spans, - targets, + targets: targets.into_boxed_slice(), unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) { UnwindAction::Continue } else { diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 11d3e2a8180..d29874a5ad4 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -324,7 +324,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { user_ty: None, const_: method, })), - args: vec![Spanned { node: Operand::Move(ref_src), span }], + args: [Spanned { node: Operand::Move(ref_src), span }].into(), destination: temp, target: Some(target_block), unwind: UnwindAction::Continue, @@ -486,10 +486,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { const_: method, })), - args: vec![ + args: [ Spanned { node: Operand::Copy(val), span: DUMMY_SP }, Spanned { node: expect, span: DUMMY_SP }, - ], + ] + .into(), destination: eq_result, target: Some(eq_block), unwind: UnwindAction::Continue, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index dda6c88008b..8c6c9e10cdf 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -220,7 +220,7 @@ impl<'tcx> ConstToPat<'tcx> { tcx, ObligationCause::dummy(), self.param_env, - ty::TraitRef::new( + ty::TraitRef::new_from_args( tcx, partial_eq_trait_id, tcx.with_opt_host_effect_param( diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 654020164db..e0da9600ae3 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -650,10 +650,8 @@ where [ty.into()], self.source_info.span, ), - args: vec![Spanned { - node: Operand::Move(Place::from(ref_place)), - span: DUMMY_SP, - }], + args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }] + .into(), destination: unit_temp, target: Some(succ), unwind: unwind.into_action(), diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 6b338efd569..52db931b68e 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -34,7 +34,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { 2, mir::TerminatorKind::Call { func: mir::Operand::Copy(dummy_place.clone()), - args: vec![], + args: [].into(), destination: dummy_place.clone(), target: Some(mir::START_BLOCK), unwind: mir::UnwindAction::Continue, @@ -48,7 +48,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { 4, mir::TerminatorKind::Call { func: mir::Operand::Copy(dummy_place.clone()), - args: vec![], + args: [].into(), destination: dummy_place.clone(), target: Some(mir::START_BLOCK), unwind: mir::UnwindAction::Continue, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index bf79b4e133a..05674792426 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -677,8 +677,8 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { let terminator = bb_data.terminator.take().unwrap(); - if let TerminatorKind::Call { mut args, destination, target, .. } = terminator.kind { - let arg = args.pop().unwrap(); + if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind { + let [arg] = *Box::try_from(args).unwrap(); let local = arg.node.place().unwrap().local; let arg = Rvalue::Use(arg.node); diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 048547dc9f5..63a9f303b85 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -134,7 +134,7 @@ impl<'tcx> MockBlocks<'tcx> { some_from_block, TerminatorKind::Call { func: Operand::Copy(self.dummy_place.clone()), - args: vec![], + args: [].into(), destination: self.dummy_place.clone(), target: Some(TEMP_BLOCK), unwind: UnwindAction::Continue, diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 32b5d812025..0a5fc697d03 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -624,8 +624,7 @@ impl<'tcx> Inliner<'tcx> { }; // Copy the arguments if needed. - let args: Vec<_> = - self.make_call_args(args, &callsite, caller_body, &callee_body, return_block); + let args = self.make_call_args(args, &callsite, caller_body, &callee_body, return_block); let mut integrator = Integrator { args: &args, @@ -736,12 +735,12 @@ impl<'tcx> Inliner<'tcx> { fn make_call_args( &self, - args: Vec<Spanned<Operand<'tcx>>>, + args: Box<[Spanned<Operand<'tcx>>]>, callsite: &CallSite<'tcx>, caller_body: &mut Body<'tcx>, callee_body: &Body<'tcx>, return_block: Option<BasicBlock>, - ) -> Vec<Local> { + ) -> Box<[Local]> { let tcx = self.tcx; // There is a bit of a mismatch between the *caller* of a closure and the *callee*. @@ -768,7 +767,8 @@ impl<'tcx> Inliner<'tcx> { // // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() { - let mut args = args.into_iter(); + // FIXME(edition_2024): switch back to a normal method call. + let mut args = <_>::into_iter(args); let self_ = self.create_temp_if_necessary( args.next().unwrap().node, callsite, @@ -802,7 +802,8 @@ impl<'tcx> Inliner<'tcx> { closure_ref_arg.chain(tuple_tmp_args).collect() } else { - args.into_iter() + // FIXME(edition_2024): switch back to a normal method call. + <_>::into_iter(args) .map(|a| self.create_temp_if_necessary(a.node, callsite, caller_body, return_block)) .collect() } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 6806c517c17..8209e5e2711 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -1,6 +1,7 @@ //! Performs various peephole optimizations. use crate::simplify::simplify_duplicate_switch_targets; +use crate::take_array; use rustc_ast::attr; use rustc_middle::bug; use rustc_middle::mir::*; @@ -285,7 +286,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { return; } - let Some(arg_place) = args.pop().unwrap().node.place() else { return }; + let Ok([arg]) = take_array(args) else { return }; + let Some(arg_place) = arg.node.place() else { return }; statements.push(Statement { source_info: terminator.source_info, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index fe195f0112f..f7056702cb4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -160,8 +160,9 @@ fn remap_mir_for_const_eval_select<'tcx>( } if let ty::FnDef(def_id, _) = *const_.ty().kind() && tcx.is_intrinsic(def_id, sym::const_eval_select) => { - let [tupled_args, called_in_const, called_at_rt]: [_; 3] = - std::mem::take(args).try_into().unwrap(); + let Ok([tupled_args, called_in_const, called_at_rt]) = take_array(args) else { + unreachable!() + }; let ty = tupled_args.node.ty(&body.local_decls, tcx); let fields = ty.tuple_fields(); let num_args = fields.len(); @@ -211,6 +212,11 @@ fn remap_mir_for_const_eval_select<'tcx>( body } +fn take_array<T, const N: usize>(b: &mut Box<[T]>) -> Result<[T; N], Box<[T]>> { + let b: Box<[T; N]> = std::mem::take(b).try_into()?; + Ok(*b) +} + fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { tcx.mir_keys(()).contains(&def_id) } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 3ffc447217d..6aa90394355 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -1,5 +1,6 @@ //! Lowers intrinsic calls +use crate::take_array; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -50,42 +51,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } sym::copy_nonoverlapping => { let target = target.unwrap(); - let mut args = args.drain(..); + let Ok([src, dst, count]) = take_array(args) else { + bug!("Wrong arguments for copy_non_overlapping intrinsic"); + }; block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Intrinsic(Box::new( NonDivergingIntrinsic::CopyNonOverlapping( rustc_middle::mir::CopyNonOverlapping { - src: args.next().unwrap().node, - dst: args.next().unwrap().node, - count: args.next().unwrap().node, + src: src.node, + dst: dst.node, + count: count.node, }, ), )), }); - assert_eq!( - args.next(), - None, - "Extra argument for copy_non_overlapping intrinsic" - ); - drop(args); terminator.kind = TerminatorKind::Goto { target }; } sym::assume => { let target = target.unwrap(); - let mut args = args.drain(..); + let Ok([arg]) = take_array(args) else { + bug!("Wrong arguments for assume intrinsic"); + }; block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Intrinsic(Box::new( - NonDivergingIntrinsic::Assume(args.next().unwrap().node), + NonDivergingIntrinsic::Assume(arg.node), )), }); - assert_eq!( - args.next(), - None, - "Extra argument for copy_non_overlapping intrinsic" - ); - drop(args); terminator.kind = TerminatorKind::Goto { target }; } sym::wrapping_add @@ -100,13 +93,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { | sym::unchecked_shl | sym::unchecked_shr => { let target = target.unwrap(); - let lhs; - let rhs; - { - let mut args = args.drain(..); - lhs = args.next().unwrap(); - rhs = args.next().unwrap(); - } + let Ok([lhs, rhs]) = take_array(args) else { + bug!("Wrong arguments for {} intrinsic", intrinsic.name); + }; let bin_op = match intrinsic.name { sym::wrapping_add => BinOp::Add, sym::wrapping_sub => BinOp::Sub, @@ -132,13 +121,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { if let Some(target) = *target { - let lhs; - let rhs; - { - let mut args = args.drain(..); - lhs = args.next().unwrap(); - rhs = args.next().unwrap(); - } + let Ok([lhs, rhs]) = take_array(args) else { + bug!("Wrong arguments for {} intrinsic", intrinsic.name); + }; let bin_op = match intrinsic.name { sym::add_with_overflow => BinOp::AddWithOverflow, sym::sub_with_overflow => BinOp::SubWithOverflow, @@ -174,7 +159,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } sym::read_via_copy => { - let [arg] = args.as_slice() else { + let Ok([arg]) = take_array(args) else { span_bug!(terminator.source_info.span, "Wrong number of arguments"); }; let derefed_place = if let Some(place) = arg.node.place() @@ -207,7 +192,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } sym::write_via_move => { let target = target.unwrap(); - let Ok([ptr, val]) = <[_; 2]>::try_from(std::mem::take(args)) else { + let Ok([ptr, val]) = take_array(args) else { span_bug!( terminator.source_info.span, "Wrong number of arguments for write_via_move intrinsic", @@ -247,7 +232,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } sym::offset => { let target = target.unwrap(); - let Ok([ptr, delta]) = <[_; 2]>::try_from(std::mem::take(args)) else { + let Ok([ptr, delta]) = take_array(args) else { span_bug!( terminator.source_info.span, "Wrong number of arguments for offset intrinsic", @@ -264,7 +249,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; - let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { + let Ok([arg]) = take_array(args) else { span_bug!( terminator.source_info.span, "Wrong number of arguments for transmute intrinsic", @@ -289,7 +274,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } sym::aggregate_raw_ptr => { - let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else { + let Ok([data, meta]) = take_array(args) else { span_bug!( terminator.source_info.span, "Wrong number of arguments for aggregate_raw_ptr intrinsic", @@ -317,7 +302,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } sym::ptr_metadata => { - let Ok([ptr]) = <[_; 1]>::try_from(std::mem::take(args)) else { + let Ok([ptr]) = take_array(args) else { span_bug!( terminator.source_info.span, "Wrong number of arguments for ptr_metadata intrinsic", diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 825f8957187..25577e88e28 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -562,7 +562,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { vec![statement], TerminatorKind::Call { func, - args: vec![Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }], + args: [Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }].into(), destination: dest, target: Some(next), unwind: UnwindAction::Cleanup(cleanup), @@ -843,7 +843,7 @@ fn build_call_shim<'tcx>( }; // BB #0 - let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect::<Vec<_>>(); + let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect(); block( &mut blocks, statements, 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 cae9c5c8567..ee7279a43b2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -527,7 +527,7 @@ where }; for assumption in - self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), &alias_ty.args) + self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -603,7 +603,7 @@ where // Consider all of the auto-trait and projection bounds, which don't // need to be recorded as a `BuiltinImplSource::Object` since they don't // really have a vtable base... - for bound in bounds { + for bound in bounds.iter() { match bound.skip_binder() { ty::ExistentialPredicate::Trait(_) => { // Skip principal diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index b10be5a9ba7..2df039c766c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -58,7 +58,7 @@ where ty::Tuple(tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - Ok(tys.into_iter().map(ty::Binder::dummy).collect()) + Ok(tys.iter().map(ty::Binder::dummy).collect()) } ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), @@ -79,23 +79,21 @@ where .cx() .bound_coroutine_hidden_types(def_id) .into_iter() - .map(|bty| bty.instantiate(tcx, &args)) + .map(|bty| bty.instantiate(tcx, args)) .collect()), // For `PhantomData<T>`, we pass `T`. ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]), - ty::Adt(def, args) => Ok(def - .all_field_tys(tcx) - .iter_instantiated(tcx, &args) - .map(ty::Binder::dummy) - .collect()), + ty::Adt(def, args) => { + Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect()) + } ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, &args))]) + Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))]) } } } @@ -147,7 +145,7 @@ where // impl Sized for () // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 - ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |&ty| vec![ty::Binder::dummy(ty)])), + ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])), // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized // `sized_constraint(Adt)` is the deepest struct trail that can be determined @@ -160,7 +158,7 @@ where // if the ADT is sized for all possible args. ty::Adt(def, args) => { if let Some(sized_crit) = def.sized_constraint(ecx.cx()) { - Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), &args))]) + Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))]) } else { Ok(vec![]) } @@ -213,7 +211,7 @@ where } // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone - ty::Tuple(tys) => Ok(tys.into_iter().map(ty::Binder::dummy).collect()), + ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()), // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), @@ -242,7 +240,7 @@ where .cx() .bound_coroutine_hidden_types(def_id) .into_iter() - .map(|bty| bty.instantiate(ecx.cx(), &args)) + .map(|bty| bty.instantiate(ecx.cx(), args)) .collect()), } } @@ -259,8 +257,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern let sig = tcx.fn_sig(def_id); if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) { Ok(Some( - sig.instantiate(tcx, &args) - .map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())), + sig.instantiate(tcx, args) + .map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())), )) } else { Err(NoSolution) @@ -269,7 +267,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. ty::FnPtr(sig) => { if sig.is_fn_trait_compatible() { - Ok(Some(sig.map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())))) + Ok(Some( + sig.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())), + )) } else { Err(NoSolution) } @@ -292,7 +292,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern } } } - Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output())))) + Ok(Some( + closure_args.sig().map_bound(|sig| (sig.inputs().get(0).unwrap(), sig.output())), + )) } // Coroutine-closures don't implement `Fn` traits the normal way. @@ -470,7 +472,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); Ok(( bound_sig.rebind(AsyncCallableRelevantTypes { - tupled_inputs_ty: Ty::new_tup(tcx, &sig.inputs()), + tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs().as_slice()), output_coroutine_ty: sig.output(), coroutine_return_ty: future_output_ty, }), @@ -521,7 +523,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); Ok(( bound_sig.rebind(AsyncCallableRelevantTypes { - tupled_inputs_ty: sig.inputs()[0], + tupled_inputs_ty: sig.inputs().get(0).unwrap(), output_coroutine_ty: sig.output(), coroutine_return_ty: future_output_ty, }), @@ -669,7 +671,7 @@ where let tcx = ecx.cx(); let mut requirements = vec![]; requirements - .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args)); + .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args)); // FIXME(associated_const_equality): Also add associated consts to // the requirements here. @@ -680,13 +682,12 @@ where continue; } - requirements.extend( - tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args), - ); + requirements + .extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args)); } let mut replace_projection_with = HashMap::default(); - for bound in object_bounds { + for bound in object_bounds.iter() { if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() { let proj = proj.with_self_ty(tcx, trait_ref.self_ty()); let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj)); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index f1d4864a84b..0a313c6a951 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -267,7 +267,9 @@ where // We therefore instantiate the existential variable in the canonical response with the // inference variable of the input right away, which is more performant. let mut opt_values = IndexVec::from_elem_n(None, response.variables.len()); - for (original_value, result_value) in iter::zip(original_values, var_values.var_values) { + for (original_value, result_value) in + iter::zip(original_values, var_values.var_values.iter()) + { match result_value.kind() { ty::GenericArgKind::Type(t) => { if let ty::Bound(debruijn, b) = t.kind() { @@ -291,7 +293,7 @@ where } let var_values = delegate.cx().mk_args_from_iter( - response.variables.into_iter().enumerate().map(|(index, info)| { + response.variables.iter().enumerate().map(|(index, info)| { if info.universe() != ty::UniverseIndex::ROOT { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all (see the FIXME at the start of this method), we have to deal with @@ -344,7 +346,7 @@ where ) { assert_eq!(original_values.len(), var_values.len()); - for (&orig, response) in iter::zip(original_values, var_values.var_values) { + for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) { let goals = delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap(); assert!(goals.is_empty()); @@ -413,7 +415,8 @@ where // In case any fresh inference variables have been created between `state` // and the previous instantiation, extend `orig_values` for it. assert!(orig_values.len() <= state.value.var_values.len()); - for &arg in &state.value.var_values.var_values[orig_values.len()..state.value.var_values.len()] + for &arg in &state.value.var_values.var_values.as_slice() + [orig_values.len()..state.value.var_values.len()] { // FIXME: This is so ugly. let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span); 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 6644fff2140..04dce2780b0 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 @@ -787,7 +787,7 @@ where // Alternatively we could modify `Equate` for this case by adding another // variant to `StructurallyRelateAliases`. let identity_args = self.fresh_args_for_item(alias.def_id); - let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args); + let rigid_ctor = ty::AliasTerm::new_from_args(tcx, alias.def_id, identity_args); let ctor_term = rigid_ctor.to_term(tcx); let obligations = self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?; @@ -875,7 +875,7 @@ where pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs { let args = self.delegate.fresh_args_for_item(def_id); - for arg in args { + for arg in args.iter() { self.inspect.add_var_value(arg); } args @@ -979,7 +979,7 @@ where result: *result, }) .enter(|ecx| { - for (a, b) in std::iter::zip(candidate_key.args, key.args) { + for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) { ecx.eq(param_env, a, b)?; } ecx.eq(param_env, candidate_ty, ty)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs index ae59f0c5e95..4fc58e06d67 100644 --- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs +++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs @@ -7,6 +7,7 @@ use std::marker::PhantomData; use std::mem; +use rustc_type_ir::inherent::*; use rustc_type_ir::{self as ty, Interner}; use crate::delegate::SolverDelegate; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index b76b4c09852..e29ae7ac0a2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -182,7 +182,7 @@ where return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } ty::ConstKind::Unevaluated(uv) => { - self.cx().type_of(uv.def).instantiate(self.cx(), &uv.args) + self.cx().type_of(uv.def).instantiate(self.cx(), uv.args) } ty::ConstKind::Expr(_) => unimplemented!( "`feature(generic_const_exprs)` is not supported in the new trait solver" 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 827fe5f2ca4..004ecf2d2c4 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 @@ -29,7 +29,7 @@ where self.eq( goal.param_env, inherent.self_ty(), - tcx.type_of(impl_def_id).instantiate(tcx, &impl_args), + tcx.type_of(impl_def_id).instantiate(tcx, impl_args), )?; // Equate IAT with the RHS of the project goal @@ -44,11 +44,11 @@ where self.add_goals( GoalSource::Misc, tcx.predicates_of(inherent.def_id) - .iter_instantiated(tcx, &inherent_args) + .iter_instantiated(tcx, inherent_args) .map(|pred| goal.with(tcx, pred)), ); - let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, &inherent_args); + let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args); self.instantiate_normalizes_to_term(goal, normalized.into()); 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 f58384d86cd..bc5233c4887 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 @@ -121,7 +121,7 @@ where ecx.add_goals( GoalSource::Misc, tcx.own_predicates_of(goal.predicate.def_id()) - .iter_instantiated(tcx, &goal.predicate.alias.args) + .iter_instantiated(tcx, goal.predicate.alias.args) .map(|pred| goal.with(tcx, pred)), ); @@ -163,13 +163,13 @@ where ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id); - let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args); ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; let where_clause_bounds = tcx .predicates_of(impl_def_id) - .iter_instantiated(tcx, &impl_args) + .iter_instantiated(tcx, impl_args) .map(|pred| goal.with(tcx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); @@ -177,7 +177,7 @@ where ecx.add_goals( GoalSource::Misc, tcx.own_predicates_of(goal.predicate.def_id()) - .iter_instantiated(tcx, &goal.predicate.alias.args) + .iter_instantiated(tcx, goal.predicate.alias.args) .map(|pred| goal.with(tcx, pred)), ); @@ -254,7 +254,7 @@ where kind => panic!("expected projection, found {kind:?}"), }; - ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, &target_args)); + ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, target_args)); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -467,7 +467,7 @@ where tupled_inputs_ty, tupled_upvars_ty, coroutine_captures_by_ref_ty, - ] = **goal.predicate.alias.args + ] = *goal.predicate.alias.args.as_slice() else { panic!(); }; @@ -567,14 +567,14 @@ where ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) { None => Ty::new_unit(tcx), Some(tail_ty) => { - Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, &args)]) + Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, args)]) } }, ty::Adt(_, _) => Ty::new_unit(tcx), ty::Tuple(elements) => match elements.last() { None => Ty::new_unit(tcx), - Some(&tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]), + Some(tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]), }, ty::Infer( @@ -895,7 +895,7 @@ where } else { let target_args = self.fresh_args_for_item(target_container_def_id); let target_trait_ref = - tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, &target_args); + tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, target_args); // Relate source impl to target impl by equating trait refs. self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?; // Also add predicates since they may be needed to constrain the @@ -903,7 +903,7 @@ where self.add_goals( GoalSource::Misc, tcx.predicates_of(target_container_def_id) - .iter_instantiated(tcx, &target_args) + .iter_instantiated(tcx, target_args) .map(|pred| goal.with(tcx, pred)), ); goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index f3494328d9e..a16f9e64f2f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -86,7 +86,7 @@ where } (Reveal::All, _) => { // FIXME: Add an assertion that opaque type storage is empty. - let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, &opaque_ty.args); + let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args); self.eq(goal.param_env, expected, actual)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -102,7 +102,7 @@ pub fn uses_unique_placeholders_ignoring_regions<I: Interner>( args: I::GenericArgs, ) -> Result<(), NotUniqueParam<I>> { let mut seen = GrowableBitSet::default(); - for arg in args { + for arg in args.iter() { match arg.kind() { // Ignore regions, since we can't resolve those in a canonicalized // query in the trait solver. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs index 27d5ae07729..ca90bc17cc7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs @@ -25,11 +25,11 @@ where self.add_goals( GoalSource::Misc, tcx.predicates_of(weak_ty.def_id) - .iter_instantiated(tcx, &weak_ty.args) + .iter_instantiated(tcx, weak_ty.args) .map(|pred| goal.with(tcx, pred)), ); - let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, &weak_ty.args); + let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args); self.instantiate_normalizes_to_term(goal, actual.into()); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 2ddb3c981db..9746c836aff 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -77,12 +77,12 @@ where ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id); ecx.record_impl_args(impl_args); - let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args); ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; let where_clause_bounds = tcx .predicates_of(impl_def_id) - .iter_instantiated(tcx, &impl_args) + .iter_instantiated(tcx, impl_args) .map(|pred| goal.with(tcx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); @@ -186,7 +186,7 @@ where ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { let nested_obligations = tcx .predicates_of(goal.predicate.def_id()) - .iter_instantiated(tcx, &goal.predicate.trait_ref.args) + .iter_instantiated(tcx, goal.predicate.trait_ref.args) .map(|p| goal.with(tcx, p)); // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? ecx.add_goals(GoalSource::Misc, nested_obligations); @@ -373,7 +373,7 @@ where ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution> { - let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else { + let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else { panic!(); }; @@ -783,7 +783,7 @@ where // (i.e. the principal, all of the associated types match, and any auto traits) ecx.add_goals( GoalSource::ImplWhereBound, - b_data.into_iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), + b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), ); // The type must be `Sized` to be unsized. @@ -851,7 +851,7 @@ where }; self.probe_trait_candidate(source).enter(|ecx| { - for bound in b_data { + for bound in b_data.iter() { match bound.skip_binder() { // Check that a's supertrait (upcast_principal) is compatible // with the target (b_ty). @@ -953,18 +953,15 @@ where let tail_field_ty = def.struct_tail_ty(tcx).unwrap(); - let a_tail_ty = tail_field_ty.instantiate(tcx, &a_args); - let b_tail_ty = tail_field_ty.instantiate(tcx, &b_args); + let a_tail_ty = tail_field_ty.instantiate(tcx, a_args); + let b_tail_ty = tail_field_ty.instantiate(tcx, b_args); // Instantiate just the unsizing params from B into A. The type after // this instantiation must be equal to B. This is so we don't unsize // unrelated type parameters. - let new_a_args = tcx.mk_args_from_iter( - a_args - .iter() - .enumerate() - .map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { *a }), - ); + let new_a_args = tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| { + if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a } + })); let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args); // Finally, we require that `TailA: Unsize<TailB>` for the tail field @@ -1005,7 +1002,7 @@ where let Goal { predicate: (_a_ty, b_ty), .. } = goal; let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); - let &b_last_ty = b_tys.last().unwrap(); + let b_last_ty = b_tys.last().unwrap(); // Instantiate just the tail field of B., and require that they're equal. let unsized_a_ty = diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 3a4690670af..42392ad2163 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -322,9 +322,8 @@ error: foo --> test.rs:3:3 | 3 | X0 Y0 - | ___^__- - | |___| - | || + | ____^ - + | | ______| 4 | || X1 Y1 5 | || X2 Y2 | ||____^__- `Y` is a good letter too @@ -361,9 +360,8 @@ error: foo --> test.rs:3:3 | 3 | X0 Y0 - | ___^__- - | |___| - | || + | ____^ - + | | ______| 4 | || Y1 X1 | ||____-__^ `X` is a good letter | |____| @@ -445,10 +443,9 @@ error: foo --> test.rs:3:3 | 3 | X0 Y0 Z0 - | ___^__-__- - | |___|__| - | ||___| - | ||| + | _____^ - - + | | _______| | + | || _________| 4 | ||| X1 Y1 Z1 5 | ||| X2 Y2 Z2 | |||____^__-__- `Z` label diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bcb1131cc19..3d5e6371f4c 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -4,8 +4,10 @@ use crate::{errors, parse_in}; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::MetaItemKind; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety}; +use rustc_ast::{ + self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind, + NestedMetaItem, Safety, +}; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{ AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP, @@ -184,9 +186,13 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim /// Checks that the given meta-item is compatible with this `AttributeTemplate`. fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool { + let is_one_allowed_subword = |items: &[NestedMetaItem]| match items { + [item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)), + _ => false, + }; match meta { MetaItemKind::Word => template.word, - MetaItemKind::List(..) => template.list.is_some(), + MetaItemKind::List(items) => template.list.is_some() || is_one_allowed_subword(items), MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(), MetaItemKind::NameValue(..) => false, } @@ -230,6 +236,7 @@ fn emit_malformed_attribute( if let Some(descr) = template.list { suggestions.push(format!("#{inner}[{name}({descr})]")); } + suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]"))); if let Some(descr) = template.name_value_str { suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 9a830b0f49b..5a560325ab9 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -103,18 +103,9 @@ passes_continue_labeled_block = .label = labeled blocks cannot be `continue`'d .block_label = labeled block the `continue` points to -passes_coverage_fn_defn = - `#[coverage]` may only be applied to function definitions - -passes_coverage_ignored_function_prototype = - `#[coverage]` is ignored on function prototypes - -passes_coverage_not_coverable = - `#[coverage]` must be applied to coverable code - .label = not coverable code - -passes_coverage_propagate = - `#[coverage]` does not propagate into items and must be applied to the contained functions directly +passes_coverage_not_fn_or_closure = + attribute should be applied to a function definition or closure + .label = not a function or closure passes_dead_codes = { $multiple -> diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2ed5bba85c6..d33f12a973f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) } [sym::inline] => self.check_inline(hir_id, attr, span, target), - [sym::coverage] => self.check_coverage(hir_id, attr, span, target), + [sym::coverage] => self.check_coverage(attr, span, target), [sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target), [sym::marker] => self.check_marker(hir_id, attr, span, target), [sym::target_feature] => { @@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if a `#[coverage]` is applied directly to a function - fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks that `#[coverage(..)]` is applied to a function or closure. + fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool { match target { - // #[coverage] on function is fine + // #[coverage(..)] on function is fine Target::Fn | Target::Closure | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, - - // function prototypes can't be covered - Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnProto, - ); - true - } - - Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoveragePropagate, - ); - true - } - - Target::Expression | Target::Statement | Target::Arm => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnDefn, - ); - true - } - _ => { - self.dcx().emit_err(errors::IgnoredCoverageNotCoverable { + self.dcx().emit_err(errors::CoverageNotFnOrClosure { attr_span: attr.span, defn_span: span, }); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 69386c0fbdb..7c7700dd859 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1010,6 +1010,22 @@ impl<'tcx> DeadVisitor<'tcx> { parent_item: Option<LocalDefId>, report_on: ReportOn, ) { + fn get_parent_if_enum_variant<'tcx>( + tcx: TyCtxt<'tcx>, + may_variant: LocalDefId, + ) -> LocalDefId { + if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant) + && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id()) + && let Some(enum_local_id) = enum_did.as_local() + && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id) + && let ItemKind::Enum(_, _) = item.kind + { + enum_local_id + } else { + may_variant + } + } + let Some(&first_item) = dead_codes.first() else { return; }; @@ -1053,6 +1069,9 @@ impl<'tcx> DeadVisitor<'tcx> { }; let encl_def_id = parent_item.unwrap_or(first_item.def_id); + // If parent of encl_def_id is an enum, use the parent ID intead. + let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id); + let ignored_derived_impls = if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { let trait_list = ign_traits diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f0596568092..7734dba3670 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure { pub defn_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_coverage_ignored_function_prototype)] -pub struct IgnoredCoverageFnProto; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_propagate)] -pub struct IgnoredCoveragePropagate; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_fn_defn)] -pub struct IgnoredCoverageFnDefn; - #[derive(Diagnostic)] -#[diag(passes_coverage_not_coverable, code = E0788)] -pub struct IgnoredCoverageNotCoverable { +#[diag(passes_coverage_not_fn_or_closure, code = E0788)] +pub struct CoverageNotFnOrClosure { #[primary_span] pub attr_span: Span, #[label] diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 5f1a03502a7..f2a68e35671 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -301,9 +301,12 @@ impl<HCX> ToStableHashKey<HCX> for WorkProductId { self.hash } } -unsafe impl StableOrd for WorkProductId { +impl StableOrd for WorkProductId { // Fingerprint can use unstable (just a tuple of `u64`s), so WorkProductId can as well const CAN_USE_UNSTABLE_SORT: bool = true; + + // `WorkProductId` sort order is not affected by (de)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } // Some types are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e035749fc39..4e0f2792d97 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -14,7 +14,7 @@ use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, Modul use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError}; use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError}; -use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind}; use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId}; use rustc_attr as attr; @@ -1313,7 +1313,17 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { _ => { let orig_macro_rules_scope = self.parent_scope.macro_rules; self.build_reduced_graph_for_item(item); - visit::walk_item(self, item); + match item.kind { + ItemKind::Mod(..) => { + // Visit attributes after items for backward compatibility. + // This way they can use `macro_rules` defined later. + self.visit_vis(&item.vis); + self.visit_ident(item.ident); + item.kind.walk(item, AssocCtxt::Trait, self); + visit::walk_list!(self, visit_attribute, &item.attrs); + } + _ => visit::walk_item(self, item), + } match item.kind { ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => { self.parent_scope.macro_rules @@ -1514,7 +1524,10 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { if krate.is_placeholder { self.visit_invoc_in_module(krate.id); } else { - visit::walk_crate(self, krate); + // Visit attributes after items for backward compatibility. + // This way they can use `macro_rules` defined later. + visit::walk_list!(self, visit_item, &krate.items); + visit::walk_list!(self, visit_attribute, &krate.attrs); self.contains_macro_use(&krate.attrs); } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 87794d11cea..026a2ca1412 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -5,7 +5,7 @@ use crate::errors::CannotDetermineMacroResolution; use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope}; use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive}; use crate::Namespace::*; -use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, Used}; +use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, NameBindingKind, Used}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::expand::StrippedCfgItem; @@ -18,15 +18,18 @@ use rustc_errors::{Applicability, StashKey}; use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; -use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; +use rustc_expand::expand::{ + AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion, +}; use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::middle::stability; use rustc_middle::ty::RegisteredTools; use rustc_middle::ty::{TyCtxt, Visibility}; -use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; -use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE}; -use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES}; +use rustc_session::lint::builtin::{ + LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, SOFT_UNSTABLE, + UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACROS, UNUSED_MACRO_RULES, +}; use rustc_session::lint::BuiltinLintDiag; use rustc_session::parse::feature_err; use rustc_span::edit_distance::edit_distance; @@ -140,9 +143,10 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { } } } - // We implicitly add `rustfmt`, `clippy`, `diagnostic` to known tools, - // but it's not an error to register them explicitly. - let predefined_tools = [sym::clippy, sym::rustfmt, sym::diagnostic, sym::miri]; + // We implicitly add `rustfmt`, `clippy`, `diagnostic`, `miri` and `rust_analyzer` to known + // tools, but it's not an error to register them explicitly. + let predefined_tools = + [sym::clippy, sym::rustfmt, sym::diagnostic, sym::miri, sym::rust_analyzer]; registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span)); registered_tools } @@ -288,6 +292,16 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { let parent_scope = &ParentScope { derives, ..parent_scope }; let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion(); let node_id = invoc.expansion_data.lint_node_id; + // This is a heuristic, but it's good enough for the lint. + let looks_like_invoc_in_mod_inert_attr = self + .invocation_parents + .get(&invoc_id) + .or_else(|| self.invocation_parents.get(&eager_expansion_root)) + .map(|&(mod_def_id, _)| mod_def_id) + .filter(|&mod_def_id| { + invoc.fragment_kind == AstFragmentKind::Expr + && self.tcx.def_kind(mod_def_id) == DefKind::Mod + }); let (ext, res) = self.smart_resolve_macro_path( path, kind, @@ -298,6 +312,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { force, soft_custom_inner_attributes_gate(path, invoc), deleg_impl, + looks_like_invoc_in_mod_inert_attr, )?; let span = invoc.span(); @@ -520,6 +535,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { force: bool, soft_custom_inner_attributes_gate: bool, deleg_impl: Option<LocalDefId>, + invoc_in_mod_inert_attr: Option<LocalDefId>, ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> { let (ext, res) = match self.resolve_macro_or_delegation_path( path, @@ -528,6 +544,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { true, force, deleg_impl, + invoc_in_mod_inert_attr.map(|def_id| (def_id, node_id)), ) { Ok((Some(ext), res)) => (ext, res), Ok((None, res)) => (self.dummy_ext(kind), res), @@ -682,20 +699,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { trace: bool, force: bool, ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { - self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None) + self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None, None) } fn resolve_macro_or_delegation_path( &mut self, - path: &ast::Path, + ast_path: &ast::Path, kind: Option<MacroKind>, parent_scope: &ParentScope<'a>, trace: bool, force: bool, deleg_impl: Option<LocalDefId>, + invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { - let path_span = path.span; - let mut path = Segment::from_path(path); + let path_span = ast_path.span; + let mut path = Segment::from_path(ast_path); // Possibly apply the macro helper hack if deleg_impl.is_none() @@ -761,6 +779,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let res = binding.map(|binding| binding.res()); self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span); + self.report_out_of_scope_macro_calls( + ast_path, + parent_scope, + invoc_in_mod_inert_attr, + binding.ok(), + ); res }; @@ -1013,6 +1037,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } + fn report_out_of_scope_macro_calls( + &mut self, + path: &ast::Path, + parent_scope: &ParentScope<'a>, + invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, + binding: Option<NameBinding<'a>>, + ) { + if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr + && let Some(binding) = binding + // This is a `macro_rules` itself, not some import. + && let NameBindingKind::Res(res) = binding.kind + && let Res::Def(DefKind::Macro(MacroKind::Bang), def_id) = res + // And the `macro_rules` is defined inside the attribute's module, + // so it cannot be in scope unless imported. + && self.tcx.is_descendant_of(def_id, mod_def_id.to_def_id()) + { + // Try to resolve our ident ignoring `macro_rules` scopes. + // If such resolution is successful and gives the same result + // (e.g. if the macro is re-imported), then silence the lint. + let no_macro_rules = self.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty); + let fallback_binding = self.early_resolve_ident_in_lexical_scope( + path.segments[0].ident, + ScopeSet::Macro(MacroKind::Bang), + &ParentScope { macro_rules: no_macro_rules, ..*parent_scope }, + None, + false, + None, + ); + if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) { + self.tcx.sess.psess.buffer_lint( + OUT_OF_SCOPE_MACRO_CALLS, + path.span, + node_id, + BuiltinLintDiag::OutOfScopeMacroCalls { path: pprust::path_to_string(path) }, + ); + } + } + } + pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) { // Reserve some names that are not quite covered by the general check // performed on `Resolver::builtin_attrs`. diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 44b31f2659c..f0f2d1fefd2 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -232,7 +232,8 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc .filter(|item| item.kind == ty::AssocKind::Type) .map(move |assoc_ty| { super_poly_trait_ref.map_bound(|super_trait_ref| { - let alias_ty = ty::AliasTy::new(tcx, assoc_ty.def_id, super_trait_ref.args); + let alias_ty = + ty::AliasTy::new_from_args(tcx, assoc_ty.def_id, super_trait_ref.args); let resolved = tcx.normalize_erasing_regions( ty::ParamEnv::reveal_all(), alias_ty.to_ty(tcx), @@ -351,7 +352,7 @@ pub fn transform_instance<'tcx>( // Adjust the type ids of VTableShims to the type id expected in the call sites for the // entry in the vtable (i.e., by using the signature of the closure passed as an argument // to the shim, or by just removing self). - let trait_ref = ty::TraitRef::new(tcx, trait_id, instance.args); + let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, instance.args); let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1)); } @@ -432,7 +433,7 @@ pub fn transform_instance<'tcx>( x => bug!("Unexpected type kind for closure-like: {x:?}"), }; let concrete_args = tcx.mk_args_trait(closure_ty, inputs.map(Into::into)); - let trait_ref = ty::TraitRef::new(tcx, trait_id, concrete_args); + let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, concrete_args); let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1)); // There should be exactly one method on this trait, and it should be the one we're diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 839cc51efce..2d38ad37133 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -498,9 +498,11 @@ pub enum OutputType { DepInfo, } -// Safety: Trivial C-Style enums have a stable sort order across compilation sessions. -unsafe impl StableOrd for OutputType { +impl StableOrd for OutputType { const CAN_USE_UNSTABLE_SORT: bool = true; + + // Trivial C-Style enums have a stable sort order across compilation sessions. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f068d093889..9a10adeb6d1 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1499,7 +1499,8 @@ options! { incremental: Option<String> = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation"), inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED], - "set the threshold for inlining a function"), + "this option is deprecated and does nothing \ + (consider using `-Cllvm-args=--inline-threshold=...`)"), #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")] instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED], "instrument the generated code to support LLVM source-based code coverage reports \ diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index c33a52f4a7a..c9c1570a29a 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -408,7 +408,7 @@ impl RustcInternal for TraitRef { type T<'tcx> = rustc_ty::TraitRef<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::TraitRef::new( + rustc_ty::TraitRef::new_from_args( tcx, self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx), diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 1ac3a817bba..5456303b36f 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -120,9 +120,11 @@ impl Default for DefPathHash { } } -// Safety: `DefPathHash` sort order is not affected (de)serialization. -unsafe impl StableOrd for DefPathHash { +impl StableOrd for DefPathHash { const CAN_USE_UNSTABLE_SORT: bool = true; + + // `DefPathHash` sort order is not affected by (de)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } /// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8d8f4927e99..6d4a8c29bc9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -174,6 +174,7 @@ symbols! { Center, Cleanup, Clone, + CoerceUnsized, Command, ConstParamTy, Context, @@ -189,6 +190,7 @@ symbols! { DiagMessage, Diagnostic, DirBuilder, + DispatchFromDyn, Display, DoubleEndedIterator, Duration, @@ -299,8 +301,10 @@ symbols! { Saturating, Send, SeqCst, + Sized, SliceIndex, SliceIter, + SmartPointer, Some, SpanCtxt, String, @@ -323,6 +327,7 @@ symbols! { TyCtxt, TyKind, Unknown, + Unsize, Upvars, Vec, VecDeque, @@ -707,6 +712,7 @@ symbols! { derive, derive_const, derive_default_enum, + derive_smart_pointer, destruct, destructuring_assignment, diagnostic, @@ -1315,6 +1321,7 @@ symbols! { on, on_unimplemented, opaque, + ops, opt_out_copy, optimize, optimize_attribute, @@ -1389,6 +1396,7 @@ symbols! { plugin, plugin_registrar, plugins, + pointee, pointee_trait, pointer, pointer_like, @@ -1559,6 +1567,7 @@ symbols! { rust_2018_preview, rust_2021, rust_2024, + rust_analyzer, rust_begin_unwind, rust_cold_cc, rust_eh_catch_typeinfo, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b2fa3489dda..f4a026c0367 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -630,7 +630,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let trait_pred_and_ty = trait_pred.map_bound(|inner| { ( ty::TraitPredicate { - trait_ref: ty::TraitRef::new( + trait_ref: ty::TraitRef::new_from_args( self.tcx, inner.trait_ref.def_id, self.tcx.mk_args( @@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::RepeatElementCopy { is_constable, - elt_type, + elt_type: _, elt_span, - elt_stmt_span, + elt_stmt_span: _, } => { err.note( "the `Copy` trait is required because this value will be copied for each element of the array", ); - let value_kind = match is_constable { - IsConstable::Fn => Some("the result of the function call"), - IsConstable::Ctor => Some("the result of the constructor"), - _ => None, - }; let sm = tcx.sess.source_map(); - if let Some(value_kind) = value_kind + if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) && let Ok(snip) = sm.span_to_snippet(elt_span) { - let help_msg = format!( - "consider creating a new `const` item and initializing it with {value_kind} \ - to be used in the repeat position" - ); - let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default(); - err.multipart_suggestion( - help_msg, - vec![ - ( - elt_stmt_span.shrink_to_lo(), - format!( - "const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}" - ), - ), - (elt_span, "ARRAY_REPEAT_VALUE".to_string()), - ], + err.span_suggestion( + elt_span, + "create an inline `const` block", + format!("const {{ {snip} }}"), Applicability::MachineApplicable, ); } else { @@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("consider using `core::array::from_fn` to initialize the array"); err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information"); } - - if tcx.sess.is_nightly_build() - && matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) - { - err.help( - "create an inline `const` block, see RFC #2920 \ - <https://github.com/rust-lang/rfcs/pull/2920> for more information", - ); - } } ObligationCauseCode::VariableType(hir_id) => { if let Some(typeck_results) = &self.typeck_results @@ -3955,7 +3929,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Extract `<U as Deref>::Target` assoc type and check that it is `T` && let Some(deref_target_did) = tcx.lang_items().deref_target() - && let projection = Ty::new_projection(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)])) + && let projection = Ty::new_projection_from_args(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)])) && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection) && obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation)) && infcx.can_eq(param_env, deref_target, target_ty) @@ -4290,7 +4264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // This corresponds to `<ExprTy as Iterator>::Item = _`. let projection = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(self.tcx, proj.def_id, args), + projection_term: ty::AliasTerm::new_from_args(self.tcx, proj.def_id, args), term: ty.into(), }), )); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index fc5a2875b67..4d10d33fa6e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -689,7 +689,7 @@ fn receiver_is_dispatchable<'tcx>( if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) } }); - ty::TraitRef::new(tcx, trait_def_id, args).upcast(tcx) + ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx) }; let caller_bounds = diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 8ab324e6601..1d7a0515044 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -727,10 +727,12 @@ fn project<'cx, 'tcx>( ProjectionCandidateSet::None => { let tcx = selcx.tcx(); let term = match tcx.def_kind(obligation.predicate.def_id) { - DefKind::AssocTy => { - Ty::new_projection(tcx, obligation.predicate.def_id, obligation.predicate.args) - .into() - } + DefKind::AssocTy => Ty::new_projection_from_args( + tcx, + obligation.predicate.def_id, + obligation.predicate.args, + ) + .into(), DefKind::AssocConst => ty::Const::new_unevaluated( tcx, ty::UnevaluatedConst::new( @@ -1387,7 +1389,11 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new_from_args( + tcx, + obligation.predicate.def_id, + trait_ref.args, + ), term: ty.into(), }; @@ -1431,7 +1437,11 @@ fn confirm_future_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output); let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new_from_args( + tcx, + obligation.predicate.def_id, + trait_ref.args, + ), term: return_ty.into(), }; @@ -1473,7 +1483,11 @@ fn confirm_iterator_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item); let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new_from_args( + tcx, + obligation.predicate.def_id, + trait_ref.args, + ), term: yield_ty.into(), }; @@ -1523,7 +1537,11 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( let item_ty = args.type_at(0); let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new_from_args( + tcx, + obligation.predicate.def_id, + trait_ref.args, + ), term: item_ty.into(), }; @@ -1592,7 +1610,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, item_def_id, args), + projection_term: ty::AliasTerm::new_from_args(tcx, item_def_id, args), term, }; @@ -1753,7 +1771,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn_host_effect, ) .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(tcx, fn_once_output_def_id, trait_ref.args), + projection_term: ty::AliasTerm::new_from_args(tcx, fn_once_output_def_id, trait_ref.args), term: ret_type.into(), }); @@ -1937,7 +1955,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new( + projection_term: ty::AliasTerm::new_from_args( selcx.tcx(), obligation.predicate.def_id, obligation.predicate.args, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index c53939bfe60..e36a9ca8bd1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -940,7 +940,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let ty = traits::normalize_projection_ty( self, param_env, - ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args), + ty::AliasTy::new_from_args(tcx, tcx.lang_items().deref_target()?, trait_ref.args), cause.clone(), 0, // We're *intentionally* throwing these away, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index b50f6260ab3..8c5dc88184c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1162,7 +1162,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { mut obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, target, source_trait) + .sup(DefineOpaqueTypes::Yes, target, source_trait) .map_err(|_| Unimplemented)?; // Register one obligation for 'a: 'b. @@ -1229,7 +1229,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, b, a) + .eq(DefineOpaqueTypes::Yes, b, a) .map_err(|_| Unimplemented)?; ImplSource::Builtin(BuiltinImplSource::Misc, obligations) @@ -1277,7 +1277,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, target, new_struct) + .eq(DefineOpaqueTypes::Yes, target, new_struct) .map_err(|_| Unimplemented)?; nested.extend(obligations); @@ -1310,7 +1310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { mut obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, target, new_tuple) + .eq(DefineOpaqueTypes::Yes, target, new_tuple) .map_err(|_| Unimplemented)?; // Add a nested `T: Unsize<U>` predicate. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fe047f9966f..68cc04bc8e6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2487,7 +2487,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { trait_def_id, &[normalized_ty.into()], ); - ty::TraitRef::new(tcx, trait_def_id, err_args) + ty::TraitRef::new_from_args(tcx, trait_def_id, err_args) }; let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 18b34f8d99b..491ef34430c 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -320,7 +320,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> { if self.bound_vars.len() <= idx { panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); } - bound_ty.assert_eq(self.bound_vars[idx]); + bound_ty.assert_eq(self.bound_vars.get(idx).unwrap()); } _ => {} }; @@ -335,7 +335,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> { if self.bound_vars.len() <= idx { panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars); } - br.assert_eq(self.bound_vars[idx]); + br.assert_eq(self.bound_vars.get(idx).unwrap()); } _ => (), @@ -435,15 +435,14 @@ impl<I: Interner, T> EarlyBinder<I, Option<T>> { } } -impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter> +impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter> where Iter::Item: TypeFoldable<I>, { - pub fn iter_instantiated( - self, - tcx: I, - args: &'s [I::GenericArg], - ) -> IterInstantiated<'s, I, Iter> { + pub fn iter_instantiated<A>(self, tcx: I, args: A) -> IterInstantiated<I, Iter, A> + where + A: SliceLike<Item = I::GenericArg>, + { IterInstantiated { it: self.value.into_iter(), tcx, args } } @@ -454,15 +453,16 @@ where } } -pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> { +pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> { it: Iter::IntoIter, tcx: I, - args: &'s [I::GenericArg], + args: A, } -impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiated<'_, I, Iter> +impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A> where Iter::Item: TypeFoldable<I>, + A: SliceLike<Item = I::GenericArg>, { type Item = Iter::Item; @@ -478,10 +478,11 @@ where } } -impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, I, Iter> +impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A> where Iter::IntoIter: DoubleEndedIterator, Iter::Item: TypeFoldable<I>, + A: SliceLike<Item = I::GenericArg>, { fn next_back(&mut self) -> Option<Self::Item> { Some( @@ -491,10 +492,11 @@ where } } -impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiated<'_, I, Iter> +impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A> where Iter::IntoIter: ExactSizeIterator, Iter::Item: TypeFoldable<I>, + A: SliceLike<Item = I::GenericArg>, { } @@ -589,8 +591,11 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> { } impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> { - pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T { - let mut folder = ArgFolder { tcx, args, binders_passed: 0 }; + pub fn instantiate<A>(self, tcx: I, args: A) -> T + where + A: SliceLike<Item = I::GenericArg>, + { + let mut folder = ArgFolder { tcx, args: args.as_slice(), binders_passed: 0 }; self.value.fold_with(&mut folder) } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 61ae36265ec..7b114f565f2 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -283,7 +283,7 @@ pub struct CanonicalVarValues<I: Interner> { impl<I: Interner> CanonicalVarValues<I> { pub fn is_identity(&self) -> bool { - self.var_values.into_iter().enumerate().all(|(bv, arg)| match arg.kind() { + self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() { ty::GenericArgKind::Lifetime(r) => { matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv) } @@ -298,7 +298,7 @@ impl<I: Interner> CanonicalVarValues<I> { pub fn is_identity_modulo_regions(&self) -> bool { let mut var = ty::BoundVar::ZERO; - for arg in self.var_values { + for arg in self.var_values.iter() { match arg.kind() { ty::GenericArgKind::Lifetime(r) => { if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) { @@ -332,7 +332,7 @@ impl<I: Interner> CanonicalVarValues<I> { // the identity response. pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> { CanonicalVarValues { - var_values: tcx.mk_args_from_iter(infos.into_iter().enumerate().map( + var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map( |(i, info)| -> I::GenericArg { match info.kind { CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { @@ -371,10 +371,10 @@ impl<I: Interner> CanonicalVarValues<I> { impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> { type Item = I::GenericArg; - type IntoIter = <I::GenericArgs as IntoIterator>::IntoIter; + type IntoIter = <I::GenericArgs as SliceLike>::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.var_values.into_iter() + self.var_values.iter() } } @@ -382,6 +382,6 @@ impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> { type Output = I::GenericArg; fn index(&self, value: ty::BoundVar) -> &I::GenericArg { - &self.var_values[value.as_usize()] + &self.var_values.as_slice()[value.as_usize()] } } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 953a438cb14..09ee12d1cc3 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -323,6 +323,12 @@ impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Vec<T> { } } +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<[T]> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice) + } +} + impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> { fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { self.raw.try_fold_with(folder).map(IndexVec::from_raw) diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index be6deee011b..a4e1a97d505 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -5,7 +5,6 @@ use std::fmt::Debug; use std::hash::Hash; -use std::ops::Deref; use rustc_ast_ir::Mutability; @@ -47,6 +46,14 @@ pub trait Ty<I: Interner<Ty = Self>>: fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self; + fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self { + Ty::new_alias( + interner, + ty::AliasTyKind::Projection, + ty::AliasTy::new_from_args(interner, def_id, args), + ) + } + fn new_projection( interner: I, def_id: I::DefId, @@ -120,7 +127,7 @@ pub trait Ty<I: Interner<Ty = Self>>: fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> { match self.kind() { ty::FnPtr(sig) => sig, - ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, &args), + ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args), ty::Error(_) => { // ignore errors (#54954) ty::Binder::dummy(ty::FnSig { @@ -182,14 +189,7 @@ pub trait Ty<I: Interner<Ty = Self>>: } pub trait Tys<I: Interner<Tys = Self>>: - Copy - + Debug - + Hash - + Eq - + IntoIterator<Item = I::Ty> - + Deref<Target: Deref<Target = [I::Ty]>> - + TypeFoldable<I> - + Default + Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default { fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty); } @@ -354,14 +354,7 @@ pub trait Term<I: Interner<Term = Self>>: } pub trait GenericArgs<I: Interner<GenericArgs = Self>>: - Copy - + Debug - + Hash - + Eq - + IntoIterator<Item = I::GenericArg> - + Deref<Target: Deref<Target = [I::GenericArg]>> - + Default - + Relate<I> + Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I> { fn rebase_onto( self, @@ -553,12 +546,7 @@ pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> { } pub trait BoundExistentialPredicates<I: Interner>: - Copy - + Debug - + Hash - + Eq - + Relate<I> - + IntoIterator<Item = ty::Binder<I, ty::ExistentialPredicate<I>>> + Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>> { fn principal_def_id(self) -> Option<I::DefId>; @@ -570,3 +558,82 @@ pub trait BoundExistentialPredicates<I: Interner>: self, ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>; } + +pub trait SliceLike: Sized + Copy { + type Item: Copy; + type IntoIter: Iterator<Item = Self::Item>; + + fn iter(self) -> Self::IntoIter; + + fn as_slice(&self) -> &[Self::Item]; + + fn get(self, idx: usize) -> Option<Self::Item> { + self.as_slice().get(idx).copied() + } + + fn len(self) -> usize { + self.as_slice().len() + } + + fn is_empty(self) -> bool { + self.len() == 0 + } + + fn contains(self, t: &Self::Item) -> bool + where + Self::Item: PartialEq, + { + self.as_slice().contains(t) + } + + fn to_vec(self) -> Vec<Self::Item> { + self.as_slice().to_vec() + } + + fn last(self) -> Option<Self::Item> { + self.as_slice().last().copied() + } + + fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> { + self.as_slice().split_last() + } +} + +impl<'a, T: Copy> SliceLike for &'a [T] { + type Item = T; + type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>; + + fn iter(self) -> Self::IntoIter { + self.iter().copied() + } + + fn as_slice(&self) -> &[Self::Item] { + *self + } +} + +impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] { + type Item = T; + type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>; + + fn iter(self) -> Self::IntoIter { + self.into_iter().copied() + } + + fn as_slice(&self) -> &[Self::Item] { + *self + } +} + +impl<'a, S: SliceLike> SliceLike for &'a S { + type Item = S::Item; + type IntoIter = S::IntoIter; + + fn iter(self) -> Self::IntoIter { + (*self).iter() + } + + fn as_slice(&self) -> &[Self::Item] { + (*self).as_slice() + } +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 59ca95c09cd..b89ea30fc34 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -34,16 +34,11 @@ pub trait Interner: type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>; type GenericArgs: GenericArgs<Self>; - type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref<Target = [Self::GenericArg]>; + type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>; type GenericArg: GenericArg<Self>; type Term: Term<Self>; - type BoundVarKinds: Copy - + Debug - + Hash - + Eq - + Deref<Target: Deref<Target = [Self::BoundVarKind]>> - + Default; + type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike<Item = Self::BoundVarKind> + Default; type BoundVarKind: Copy + Debug + Hash + Eq; type PredefinedOpaques: Copy @@ -63,7 +58,7 @@ pub trait Interner: + Default + Eq + TypeVisitable<Self> - + Deref<Target: Deref<Target = [Self::LocalDefId]>>; + + SliceLike<Item = Self::LocalDefId>; type CanonicalGoalEvaluationStepRef: Copy + Debug + Hash @@ -74,8 +69,7 @@ pub trait Interner: + Debug + Hash + Eq - + IntoIterator<Item = ty::CanonicalVarInfo<Self>> - + Deref<Target: Deref<Target = [ty::CanonicalVarInfo<Self>]>> + + SliceLike<Item = ty::CanonicalVarInfo<Self>> + Default; fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars; @@ -96,7 +90,7 @@ pub trait Interner: // Kinds of tys type Ty: Ty<Self>; type Tys: Tys<Self>; - type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]> + TypeVisitable<Self>; + type FnInputTys: Copy + Debug + Hash + Eq + SliceLike<Item = Self::Ty> + TypeVisitable<Self>; type ParamTy: Copy + Debug + Hash + Eq + ParamLike; type BoundTy: Copy + Debug + Hash + Eq + BoundVarLike<Self>; type PlaceholderTy: PlaceholderLike; @@ -138,11 +132,7 @@ pub trait Interner: type GenericsOf: GenericsOf<Self>; fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf; - type VariancesOf: Copy - + Debug - + Deref<Target = [ty::Variance]> - // FIXME: This is terrible! - + IntoIterator<Item: Deref<Target = ty::Variance>>; + type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>; fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf; fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>; @@ -169,11 +159,7 @@ pub trait Interner: fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool; - fn check_and_mk_args( - self, - def_id: Self::DefId, - args: impl IntoIterator<Item: Into<Self::GenericArg>>, - ) -> Self::GenericArgs; + fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs); fn intern_canonical_goal_evaluation_step( self, diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index 738350f1b34..d8ed4770e2d 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -24,13 +24,13 @@ pub struct OpaqueTypeKey<I: Interner> { impl<I: Interner> OpaqueTypeKey<I> { pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> { let variances = tcx.variances_of(self.def_id.into()); - std::iter::zip(self.args, variances.into_iter()).enumerate().filter_map(|(i, (arg, v))| { - match (arg.kind(), *v) { + std::iter::zip(self.args.iter(), variances.iter()).enumerate().filter_map( + |(i, (arg, v))| match (arg.kind(), v) { (_, ty::Invariant) => Some((i, arg)), (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None, _ => panic!("unexpected opaque type arg variance"), - } - }) + }, + ) } pub fn fold_captured_lifetime_args( @@ -41,7 +41,7 @@ impl<I: Interner> OpaqueTypeKey<I> { let Self { def_id, args } = self; let variances = tcx.variances_of(def_id.into()); let args = - std::iter::zip(args, variances.into_iter()).map(|(arg, v)| match (arg.kind(), *v) { + std::iter::zip(args.iter(), variances.iter()).map(|(arg, v)| match (arg.kind(), v) { (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(), _ => arg, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 7a3376c7218..e5bcbc67f94 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -64,36 +64,45 @@ pub struct TraitRef<I: Interner> { pub def_id: I::DefId, pub args: I::GenericArgs, /// This field exists to prevent the creation of `TraitRef` without - /// calling [`TraitRef::new`]. + /// calling [`TraitRef::new_from_args`]. _use_trait_ref_new_instead: (), } impl<I: Interner> TraitRef<I> { + pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self { + interner.debug_assert_args_compatible(trait_def_id, args); + Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } + } + pub fn new( interner: I, trait_def_id: I::DefId, args: impl IntoIterator<Item: Into<I::GenericArg>>, ) -> Self { - let args = interner.check_and_mk_args(trait_def_id, args); - Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } + let args = interner.mk_args_from_iter(args.into_iter().map(Into::into)); + Self::new_from_args(interner, trait_def_id, args) } pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> { let generics = interner.generics_of(trait_id); - TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) + TraitRef::new(interner, trait_id, args.iter().take(generics.count())) } /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` /// are the parameters defined on trait. pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> { - TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id)) + TraitRef::new_from_args( + interner, + def_id, + I::GenericArgs::identity_for_item(interner, def_id), + ) } pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { TraitRef::new( interner, self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), + [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), ) } @@ -274,7 +283,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> { // If this is an ill-formed auto trait, then synthesize // new error args for the missing generics. let err_args = GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); - ty::TraitRef::new(tcx, did, err_args) + ty::TraitRef::new_from_args(tcx, did, err_args) }; self.rebind(trait_ref).upcast(tcx) } @@ -311,7 +320,7 @@ impl<I: Interner> ExistentialTraitRef<I> { ExistentialTraitRef { def_id: trait_ref.def_id, - args: interner.mk_args(&trait_ref.args[1..]), + args: interner.mk_args(&trait_ref.args.as_slice()[1..]), } } @@ -323,11 +332,7 @@ impl<I: Interner> ExistentialTraitRef<I> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - TraitRef::new( - interner, - self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter()), - ) + TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter())) } } @@ -370,7 +375,7 @@ impl<I: Interner> ExistentialProjection<I> { pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> { let def_id = interner.parent(self.def_id); let args_count = interner.generics_of(def_id).count() - 1; - let args = interner.mk_args(&self.args[..args_count]); + let args = interner.mk_args(&self.args.as_slice()[..args_count]); ExistentialTraitRef { def_id, args } } @@ -382,7 +387,7 @@ impl<I: Interner> ExistentialProjection<I> { projection_term: AliasTerm::new( interner, self.def_id, - [self_ty.into()].into_iter().chain(self.args), + [self_ty.into()].iter().chain(self.args.iter()), ), term: self.term, } @@ -394,7 +399,7 @@ impl<I: Interner> ExistentialProjection<I> { Self { def_id: projection_predicate.projection_term.def_id, - args: interner.mk_args(&projection_predicate.projection_term.args[1..]), + args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]), term: projection_predicate.term, } } @@ -485,19 +490,24 @@ pub struct AliasTerm<I: Interner> { /// aka. `interner.parent(def_id)`. pub def_id: I::DefId, - /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new`]. + /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`]. #[derivative(Debug = "ignore")] _use_alias_term_new_instead: (), } impl<I: Interner> AliasTerm<I> { + pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> { + interner.debug_assert_args_compatible(def_id, args); + AliasTerm { def_id, args, _use_alias_term_new_instead: () } + } + pub fn new( interner: I, def_id: I::DefId, args: impl IntoIterator<Item: Into<I::GenericArg>>, ) -> AliasTerm<I> { - let args = interner.check_and_mk_args(def_id, args); - AliasTerm { def_id, args, _use_alias_term_new_instead: () } + let args = interner.mk_args_from_iter(args.into_iter().map(Into::into)); + Self::new_from_args(interner, def_id, args) } pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> { @@ -564,7 +574,7 @@ impl<I: Interner> AliasTerm<I> { AliasTerm::new( interner, self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), + [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), ) } diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index efe270ed608..b1d0f8d19b3 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -127,7 +127,6 @@ impl std::fmt::Display for AliasRelationDirection { } } -// FIXME: Convert to DebugWithInfcx impl impl<I: Interner> fmt::Debug for ClauseKind<I> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -144,7 +143,6 @@ impl<I: Interner> fmt::Debug for ClauseKind<I> { } } -// FIXME: Convert to DebugWithInfcx impl impl<I: Interner> fmt::Debug for PredicateKind<I> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 429bc3197d4..0439e7f857f 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -82,7 +82,7 @@ pub trait TypeRelation<I: Interner>: Sized { let tcx = self.tcx(); let opt_variances = tcx.variances_of(item_def_id); - relate_args_with_variances(self, item_def_id, &opt_variances, a_arg, b_arg, true) + relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true) } /// Switch variance for the purpose of relating `a` and `b`. @@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>( a_arg: I::GenericArgs, b_arg: I::GenericArgs, ) -> RelateResult<I, I::GenericArgs> { - relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| { + relation.tcx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| { relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b) })) } @@ -136,7 +136,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>( pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( relation: &mut R, ty_def_id: I::DefId, - variances: &[ty::Variance], + variances: I::VariancesOf, a_arg: I::GenericArgs, b_arg: I::GenericArgs, fetch_ty_for_diag: bool, @@ -144,11 +144,11 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( let tcx = relation.tcx(); let mut cached_ty = None; - let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| { - let variance = variances[i]; + let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| { + let variance = variances.get(i).unwrap(); let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { let ty = - *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg)); + *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg)); VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } } else { VarianceDiagInfo::default() @@ -185,7 +185,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> { } let inputs_and_output = iter::zip(a_inputs.iter(), b_inputs.iter()) - .map(|(&a, &b)| ((a, b), false)) + .map(|(a, b)| ((a, b), false)) .chain(iter::once(((a.output(), b.output()), true))) .map(|((a, b), is_output)| { if is_output { @@ -249,7 +249,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> { ty::Opaque => relate_args_with_variances( relation, a.def_id, - &relation.tcx().variances_of(a.def_id), + relation.tcx().variances_of(a.def_id), a.args, b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle @@ -258,7 +258,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> { relate_args_invariantly(relation, a.args, b.args)? } }; - Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args)) + Ok(ty::AliasTy::new_from_args(relation.tcx(), a.def_id, args)) } } } @@ -280,7 +280,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> { ty::AliasTermKind::OpaqueTy => relate_args_with_variances( relation, a.def_id, - &relation.tcx().variances_of(a.def_id), + relation.tcx().variances_of(a.def_id), a.args, b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle @@ -293,7 +293,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> { relate_args_invariantly(relation, a.args, b.args)? } }; - Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args)) + Ok(ty::AliasTerm::new_from_args(relation.tcx(), a.def_id, args)) } } } @@ -343,7 +343,7 @@ impl<I: Interner> Relate<I> for ty::TraitRef<I> { })) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; - Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args)) + Ok(ty::TraitRef::new_from_args(relation.tcx(), a.def_id, args)) } } } @@ -525,7 +525,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( if as_.len() == bs.len() { Ok(Ty::new_tup_from_iter( tcx, - iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)), + iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)), )?) } else if !(as_.is_empty() || bs.is_empty()) { Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len()))) @@ -607,8 +607,8 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>( // be stabilized. (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { if cfg!(debug_assertions) { - let a_ty = tcx.type_of(au.def).instantiate(tcx, &au.args); - let b_ty = tcx.type_of(bu.def).instantiate(tcx, &bu.args); + let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args); + let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args); assert_eq!(a_ty, b_ty); } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 915888ab59b..4ffebef9f1f 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -352,7 +352,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> { Float(float) => write!(f, "{float:?}"), Adt(d, s) => { write!(f, "{d:?}")?; - let mut s = s.into_iter(); + let mut s = s.iter(); let first = s.next(); match first { Some(first) => write!(f, "<{:?}", first)?, @@ -388,7 +388,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> { Tuple(t) => { write!(f, "(")?; let mut count = 0; - for ty in *t { + for ty in t.iter() { if count > 0 { write!(f, ", ")?; } @@ -452,19 +452,24 @@ pub struct AliasTy<I: Interner> { /// aka. `interner.parent(def_id)`. pub def_id: I::DefId, - /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new`]. + /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`]. #[derivative(Debug = "ignore")] pub(crate) _use_alias_ty_new_instead: (), } impl<I: Interner> AliasTy<I> { + pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> { + interner.debug_assert_args_compatible(def_id, args); + AliasTy { def_id, args, _use_alias_ty_new_instead: () } + } + pub fn new( interner: I, def_id: I::DefId, args: impl IntoIterator<Item: Into<I::GenericArg>>, ) -> AliasTy<I> { - let args = interner.check_and_mk_args(def_id, args); - AliasTy { def_id, args, _use_alias_ty_new_instead: () } + let args = interner.mk_args_from_iter(args.into_iter().map(Into::into)); + Self::new_from_args(interner, def_id, args) } pub fn kind(self, interner: I) -> AliasTyKind { @@ -491,7 +496,7 @@ impl<I: Interner> AliasTy<I> { AliasTy::new( interner, self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), + [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), ) } @@ -539,7 +544,7 @@ impl<I: Interner> AliasTy<I> { interner: I, ) -> I::GenericArgs { debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent); - interner.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1))) + interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) } } @@ -1000,7 +1005,7 @@ impl<I: Interner> ty::Binder<I, FnSig<I>> { #[inline] #[track_caller] pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> { - self.map_bound(|fn_sig| fn_sig.inputs()[index]) + self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap()) } pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> { diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 3a17a27bd03..24a7c0c67e9 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -138,7 +138,7 @@ impl<I: Interner> ClosureArgs<I> { /// for the closure parent, alongside additional closure-specific components. pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> { ClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.closure_kind_ty.into(), parts.closure_sig_as_fn_ptr_ty.into(), parts.tupled_upvars_ty.into(), @@ -260,7 +260,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> { impl<I: Interner> CoroutineClosureArgs<I> { pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> { CoroutineClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.closure_kind_ty.into(), parts.signature_parts_ty.into(), parts.tupled_upvars_ty.into(), @@ -309,10 +309,10 @@ impl<I: Interner> CoroutineClosureArgs<I> { let interior = self.coroutine_witness_ty(); let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { panic!() }; sig.map_bound(|sig| { - let [resume_ty, tupled_inputs_ty] = *sig.inputs() else { + let [resume_ty, tupled_inputs_ty] = *sig.inputs().as_slice() else { panic!(); }; - let [yield_ty, return_ty] = **sig.output().tuple_fields() else { panic!() }; + let [yield_ty, return_ty] = *sig.output().tuple_fields().as_slice() else { panic!() }; CoroutineClosureSignature { interior, tupled_inputs_ty, @@ -496,16 +496,16 @@ impl<I: Interner> CoroutineClosureSignature<I> { tcx, tupled_inputs_ty .tuple_fields() - .into_iter() - .chain(coroutine_captures_by_ref_ty.tuple_fields()), + .iter() + .chain(coroutine_captures_by_ref_ty.tuple_fields().iter()), ) } ty::ClosureKind::FnOnce => Ty::new_tup_from_iter( tcx, tupled_inputs_ty .tuple_fields() - .into_iter() - .chain(closure_tupled_upvars_ty.tuple_fields()), + .iter() + .chain(closure_tupled_upvars_ty.tuple_fields().iter()), ), } } @@ -617,7 +617,7 @@ impl<I: Interner> CoroutineArgs<I> { /// for the coroutine parent, alongside additional coroutine-specific components. pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> { CoroutineArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.kind_ty.into(), parts.resume_ty.into(), parts.yield_ty.into(), |
