|
1 | 1 | use std::str::FromStr;
|
2 | 2 |
|
3 |
| -use rustc_abi::ExternAbi; |
| 3 | +use rustc_abi::{Align, ExternAbi}; |
4 | 4 | use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
|
5 | 5 | use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
|
6 | 6 | use rustc_attr_data_structures::{
|
@@ -402,6 +402,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
402 | 402 | codegen_fn_attrs.alignment =
|
403 | 403 | Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
|
404 | 404 |
|
| 405 | + // On trait methods, inherit the `#[align]` of the trait's method prototype. |
| 406 | + codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did)); |
| 407 | + |
405 | 408 | let inline_span;
|
406 | 409 | (codegen_fn_attrs.inline, inline_span) = if let Some((inline_attr, span)) =
|
407 | 410 | find_attr!(attrs, AttributeKind::Inline(i, span) => (*i, *span))
|
@@ -556,17 +559,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
556 | 559 | codegen_fn_attrs
|
557 | 560 | }
|
558 | 561 |
|
| 562 | +/// If the provided DefId is a method in a trait impl, return the DefId of the method prototype. |
| 563 | +fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { |
| 564 | + let impl_item = tcx.opt_associated_item(def_id)?; |
| 565 | + match impl_item.container { |
| 566 | + ty::AssocItemContainer::Impl => impl_item.trait_item_def_id, |
| 567 | + _ => None, |
| 568 | + } |
| 569 | +} |
| 570 | + |
559 | 571 | /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
|
560 | 572 | /// applied to the method prototype.
|
561 | 573 | fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
562 |
| - if let Some(impl_item) = tcx.opt_associated_item(def_id) |
563 |
| - && let ty::AssocItemContainer::Impl = impl_item.container |
564 |
| - && let Some(trait_item) = impl_item.trait_item_def_id |
565 |
| - { |
566 |
| - return tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER); |
567 |
| - } |
| 574 | + let Some(trait_item) = opt_trait_item(tcx, def_id) else { return false }; |
| 575 | + tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER) |
| 576 | +} |
568 | 577 |
|
569 |
| - false |
| 578 | +/// If the provided DefId is a method in a trait impl, return the value of the `#[align]` |
| 579 | +/// attribute on the method prototype (if any). |
| 580 | +fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> { |
| 581 | + tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment |
570 | 582 | }
|
571 | 583 |
|
572 | 584 | fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
|
@@ -734,5 +746,6 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
734 | 746 | }
|
735 | 747 |
|
736 | 748 | pub(crate) fn provide(providers: &mut Providers) {
|
737 |
| - *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers }; |
| 749 | + *providers = |
| 750 | + Providers { codegen_fn_attrs, should_inherit_track_caller, inherited_align, ..*providers }; |
738 | 751 | }
|
0 commit comments