Skip to content

Commit b6bed6f

Browse files
committed
Auto merge of #152839 - JonathanBrouwer:rollup-iPaprtK, r=JonathanBrouwer
Rollup of 9 pull requests Successful merges: - #151733 (Use function shims to make sure EII works on apple targets) - #152558 (rustc_expand: improve diagnostics for non-repeatable metavars in repetition) - #152596 (Make all multipart suggestions verbose) - #152815 (Add CURRENT_RUSTC_VERSION support for Clippy) - #152733 (Port #[rustc_doc_primitive] to the new attribute parser) - #152817 (Update enzyme submodule to match upstream) - #152819 (explicitly show behavior of <_>::assoc_fn) - #152823 (fix stale comments left over from ed3711e) - #152824 (Enable "View all comments" link feature in `triagebot.toml`)
2 parents 41198cb + cad5b1a commit b6bed6f

File tree

152 files changed

+2401
-843
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

152 files changed

+2401
-843
lines changed

‎compiler/rustc_ast/src/attr/mod.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ impl AttributeExt for Attribute {
296296
}
297297
false
298298
}
299+
300+
fn is_rustc_doc_primitive(&self) -> bool {
301+
self.has_name(sym::rustc_doc_primitive)
302+
}
299303
}
300304

301305
impl Attribute {
@@ -935,6 +939,9 @@ pub trait AttributeExt: Debug {
935939

936940
/// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`.
937941
fn is_doc_keyword_or_attribute(&self) -> bool;
942+
943+
/// Returns `true` if this is a `#[rustc_doc_primitive]` attribute.
944+
fn is_rustc_doc_primitive(&self) -> bool;
938945
}
939946

940947
// FIXME(fn_delegation): use function delegation instead of manually forwarding

‎compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,3 +1319,27 @@ impl<S: Stage> NoArgsAttributeParser<S> for PreludeImportParser {
13191319
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]);
13201320
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport;
13211321
}
1322+
1323+
pub(crate) struct RustcDocPrimitiveParser;
1324+
1325+
impl<S: Stage> SingleAttributeParser<S> for RustcDocPrimitiveParser {
1326+
const PATH: &[Symbol] = &[sym::rustc_doc_primitive];
1327+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
1328+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
1329+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]);
1330+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
1331+
1332+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
1333+
let Some(nv) = args.name_value() else {
1334+
cx.expected_name_value(args.span().unwrap_or(cx.attr_span), None);
1335+
return None;
1336+
};
1337+
1338+
let Some(value_str) = nv.value_as_str() else {
1339+
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
1340+
return None;
1341+
};
1342+
1343+
Some(AttributeKind::RustcDocPrimitive(cx.attr_span, value_str))
1344+
}
1345+
}

‎compiler/rustc_attr_parsing/src/context.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ attribute_parsers!(
205205
Single<RustcDefPath>,
206206
Single<RustcDeprecatedSafe2024Parser>,
207207
Single<RustcDiagnosticItemParser>,
208+
Single<RustcDocPrimitiveParser>,
208209
Single<RustcForceInlineParser>,
209210
Single<RustcIfThisChangedParser>,
210211
Single<RustcLayoutScalarValidRangeEndParser>,

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
535535
if let Some(pat) = finder.parent_pat {
536536
sugg.insert(0, (pat.span.shrink_to_lo(), "ref ".to_string()));
537537
}
538-
err.multipart_suggestion_verbose(
538+
err.multipart_suggestion(
539539
"borrow this binding in the pattern to avoid moving the value",
540540
sugg,
541541
Applicability::MachineApplicable,
@@ -1509,7 +1509,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
15091509
} else {
15101510
"consider cloning the value if the performance cost is acceptable"
15111511
};
1512-
err.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable);
1512+
err.multipart_suggestion(msg, sugg, Applicability::MachineApplicable);
15131513
true
15141514
}
15151515

@@ -2759,7 +2759,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
27592759
.chain(finder.closure_call_changes)
27602760
.collect();
27612761

2762-
err.multipart_suggestion_verbose(
2762+
err.multipart_suggestion(
27632763
"try explicitly passing `&Self` into the closure as an argument",
27642764
sugg,
27652765
Applicability::MachineApplicable,
@@ -3347,7 +3347,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
33473347

33483348
let addition =
33493349
format!("let {}binding = {};\n{}", mutability, s, " ".repeat(p));
3350-
err.multipart_suggestion_verbose(
3350+
err.multipart_suggestion(
33513351
msg,
33523352
vec![
33533353
(stmt.span.shrink_to_lo(), addition),

‎compiler/rustc_borrowck/src/diagnostics/mod.rs‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,11 +1511,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
15111511
)
15121512
}
15131513
};
1514-
err.multipart_suggestion_verbose(
1515-
msg,
1516-
sugg,
1517-
Applicability::MaybeIncorrect,
1518-
);
1514+
err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
15191515
for error in errors {
15201516
if let FulfillmentErrorCode::Select(
15211517
SelectionError::Unimplemented,

‎compiler/rustc_borrowck/src/diagnostics/move_errors.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
375375
.source_map()
376376
.indentation_before(stmt.span)
377377
.unwrap_or_else(|| " ".to_string());
378-
err.multipart_suggestion_verbose(
378+
err.multipart_suggestion(
379379
"consider cloning the value before moving it into the closure",
380380
vec![
381381
(
@@ -405,7 +405,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
405405
.source_map()
406406
.indentation_before(closure_expr.span)
407407
.unwrap_or_else(|| " ".to_string());
408-
err.multipart_suggestion_verbose(
408+
err.multipart_suggestion(
409409
"consider cloning the value before moving it into the closure",
410410
vec![
411411
(

‎compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
13401340
return;
13411341
}
13421342

1343-
err.multipart_suggestion_verbose(
1343+
err.multipart_suggestion(
13441344
format!(
13451345
"consider changing this to be a mutable {pointer_desc}{}{extra}",
13461346
if is_trait_sig {
@@ -1365,7 +1365,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
13651365
if self.infcx.tcx.sess.source_map().is_imported(span) {
13661366
return;
13671367
}
1368-
err.multipart_suggestion_verbose(
1368+
err.multipart_suggestion(
13691369
"consider using `get_mut`",
13701370
vec![(span, suggestion)],
13711371
Applicability::MaybeIncorrect,

‎compiler/rustc_borrowck/src/diagnostics/region_errors.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
290290
});
291291
if suggestions.len() > 0 {
292292
suggestions.dedup();
293-
diag.multipart_suggestion_verbose(
293+
diag.multipart_suggestion(
294294
msg!("consider restricting the type parameter to the `'static` lifetime"),
295295
suggestions,
296296
Applicability::MaybeIncorrect,
@@ -902,7 +902,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
902902
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
903903
}
904904

905-
diag.multipart_suggestion_verbose(
905+
diag.multipart_suggestion(
906906
format!(
907907
"to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
908908
),

‎compiler/rustc_codegen_llvm/src/llvm/mod.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ pub(crate) fn set_comdat(llmod: &Module, llglobal: &Value, name: &CStr) {
284284
}
285285
}
286286

287+
pub(crate) fn count_params(llfn: &Value) -> c_uint {
288+
LLVMCountParams(llfn)
289+
}
290+
287291
/// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
288292
pub(crate) fn get_param(llfn: &Value, index: c_uint) -> &Value {
289293
unsafe {

‎compiler/rustc_codegen_llvm/src/mono_item.rs‎

Lines changed: 115 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Cow;
12
use std::ffi::CString;
23

34
use rustc_abi::AddressSpace;
@@ -6,13 +7,17 @@ use rustc_hir::attrs::Linkage;
67
use rustc_hir::def::DefKind;
78
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
89
use rustc_middle::bug;
10+
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
911
use rustc_middle::mir::mono::Visibility;
1012
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
11-
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
13+
use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt};
1214
use rustc_session::config::CrateType;
15+
use rustc_target::callconv::{FnAbi, PassMode};
1316
use rustc_target::spec::{Arch, RelocModel};
1417
use tracing::debug;
1518

19+
use crate::abi::FnAbiLlvmExt;
20+
use crate::builder::Builder;
1621
use crate::context::CodegenCx;
1722
use crate::errors::SymbolAlreadyDefined;
1823
use crate::type_of::LayoutLlvmExt;
@@ -46,7 +51,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
4651
self.assume_dso_local(g, false);
4752

4853
let attrs = self.tcx.codegen_instance_attrs(instance.def);
49-
self.add_aliases(g, &attrs.foreign_item_symbol_aliases);
54+
self.add_static_aliases(g, &attrs.foreign_item_symbol_aliases);
5055

5156
self.instances.borrow_mut().insert(instance, g);
5257
}
@@ -60,11 +65,29 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
6065
) {
6166
assert!(!instance.args.has_infer());
6267

63-
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
68+
let attrs = self.tcx.codegen_instance_attrs(instance.def);
69+
70+
let lldecl =
71+
self.predefine_without_aliases(instance, &attrs, linkage, visibility, symbol_name);
72+
self.add_function_aliases(instance, lldecl, &attrs, &attrs.foreign_item_symbol_aliases);
73+
74+
self.instances.borrow_mut().insert(instance, lldecl);
75+
}
76+
}
77+
78+
impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
79+
fn predefine_without_aliases(
80+
&self,
81+
instance: Instance<'tcx>,
82+
attrs: &Cow<'_, CodegenFnAttrs>,
83+
linkage: Linkage,
84+
visibility: Visibility,
85+
symbol_name: &str,
86+
) -> &'ll llvm::Value {
87+
let fn_abi: &FnAbi<'tcx, Ty<'tcx>> = self.fn_abi_of_instance(instance, ty::List::empty());
6488
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
6589
llvm::set_linkage(lldecl, base::linkage_to_llvm(linkage));
66-
let attrs = self.tcx.codegen_instance_attrs(instance.def);
67-
base::set_link_section(lldecl, &attrs);
90+
base::set_link_section(lldecl, attrs);
6891
if (linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR)
6992
&& self.tcx.sess.target.supports_comdat()
7093
{
@@ -76,20 +99,45 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
7699

77100
self.assume_dso_local(lldecl, false);
78101

79-
self.add_aliases(lldecl, &attrs.foreign_item_symbol_aliases);
80-
81-
self.instances.borrow_mut().insert(instance, lldecl);
102+
lldecl
82103
}
83-
}
84104

85-
impl CodegenCx<'_, '_> {
86-
fn add_aliases(&self, aliasee: &llvm::Value, aliases: &[(DefId, Linkage, Visibility)]) {
105+
/// LLVM has the concept of an `alias`.
106+
/// We need this for the "externally implementable items" feature,
107+
/// though it's generally useful.
108+
///
109+
/// On macos, though this might be a more general problem, function symbols
110+
/// have a fixed target architecture. This is necessary, since macos binaries
111+
/// may contain code for both ARM and x86 macs.
112+
///
113+
/// LLVM *can* add attributes for target architecture to function symbols,
114+
/// cannot do so for statics, but importantly, also cannot for aliases
115+
/// *even* when aliases may refer to a function symbol.
116+
///
117+
/// This is not a problem: instead of using LLVM aliases, we can just generate
118+
/// a new function symbol (with target architecture!) which effectively comes down to:
119+
///
120+
/// ```ignore (illustrative example)
121+
/// fn alias_name(...args) {
122+
/// original_name(...args)
123+
/// }
124+
/// ```
125+
///
126+
/// That's also an alias.
127+
///
128+
/// This does mean that the alias symbol has a different address than the original symbol
129+
/// (assuming no optimizations by LLVM occur). This is unacceptable for statics.
130+
/// So for statics we do want to use LLVM aliases, which is fine,
131+
/// since for those we don't care about target architecture anyway.
132+
///
133+
/// So, this function is for static aliases. See [`add_function_aliases`](Self::add_function_aliases) for the alternative.
134+
fn add_static_aliases(&self, aliasee: &llvm::Value, aliases: &[(DefId, Linkage, Visibility)]) {
87135
let ty = self.get_type_of_global(aliasee);
88136

89137
for (alias, linkage, visibility) in aliases {
90138
let symbol_name = self.tcx.symbol_name(Instance::mono(self.tcx, *alias));
139+
tracing::debug!("STATIC ALIAS: {alias:?} {linkage:?} {visibility:?}");
91140

92-
tracing::debug!("ALIAS: {alias:?} {linkage:?} {visibility:?}");
93141
let lldecl = llvm::add_alias(
94142
self.llmod,
95143
ty,
@@ -103,6 +151,61 @@ impl CodegenCx<'_, '_> {
103151
}
104152
}
105153

154+
/// See [`add_static_aliases`](Self::add_static_aliases) for docs.
155+
fn add_function_aliases(
156+
&self,
157+
aliasee_instance: Instance<'tcx>,
158+
aliasee: &'ll llvm::Value,
159+
attrs: &Cow<'_, CodegenFnAttrs>,
160+
aliases: &[(DefId, Linkage, Visibility)],
161+
) {
162+
for (alias, linkage, visibility) in aliases {
163+
let symbol_name = self.tcx.symbol_name(Instance::mono(self.tcx, *alias));
164+
tracing::debug!("FUNCTION ALIAS: {alias:?} {linkage:?} {visibility:?}");
165+
166+
// predefine another copy of the original instance
167+
// with a new symbol name
168+
let alias_lldecl = self.predefine_without_aliases(
169+
aliasee_instance,
170+
attrs,
171+
*linkage,
172+
*visibility,
173+
symbol_name.name,
174+
);
175+
176+
let fn_abi: &FnAbi<'tcx, Ty<'tcx>> =
177+
self.fn_abi_of_instance(aliasee_instance, ty::List::empty());
178+
179+
// both the alias and the aliasee have the same ty
180+
let fn_ty = fn_abi.llvm_type(self);
181+
let start_llbb = Builder::append_block(self, alias_lldecl, "start");
182+
let mut start_bx = Builder::build(self, start_llbb);
183+
184+
let num_params = llvm::count_params(alias_lldecl);
185+
let mut args = Vec::with_capacity(num_params as usize);
186+
for index in 0..num_params {
187+
args.push(llvm::get_param(alias_lldecl, index));
188+
}
189+
190+
let call = start_bx.call(
191+
fn_ty,
192+
Some(attrs),
193+
Some(fn_abi),
194+
aliasee,
195+
&args,
196+
None,
197+
Some(aliasee_instance),
198+
);
199+
200+
match &fn_abi.ret.mode {
201+
PassMode::Ignore | PassMode::Indirect { .. } => start_bx.ret_void(),
202+
PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => {
203+
start_bx.ret(call)
204+
}
205+
}
206+
}
207+
}
208+
106209
/// A definition or declaration can be assumed to be local to a group of
107210
/// libraries that form a single DSO or executable.
108211
/// Marks the local as DSO if so.

0 commit comments

Comments
 (0)