Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
177dc5a
Clearer security warnings in std::env::current_exe docs
sourcefrog Jan 8, 2026
8a021d9
rustc_public: rewrite `bridge_impl` to reduce boilerplate
makai410 Feb 15, 2026
945caf3
rustc_public: remove the `CrateDefItems` trait
makai410 Feb 15, 2026
4b7a05e
Stop using `LinkedGraph` in `lexical_region_resolve`
Zalathar Feb 23, 2026
a226650
Remove mutation from macro path URL construction in generate_macro_de…
arferreira Feb 26, 2026
d79efc5
Recover feature lang_items for emscripten
mu001999 Feb 26, 2026
dfd18b7
Print path root when printing path
mu001999 Feb 26, 2026
b12629f
Add new unstable attribute: `#[export_visibility = ...]`.
anforowicz May 29, 2025
9092262
fix: mem::conjure_zst panic message to use any::type_name instead of …
mehdiakiki Feb 25, 2026
882ae15
Work around a false `err.emit();` type error in rust-analyzer
Zalathar Feb 27, 2026
1bf9831
Rollup merge of #151431 - anforowicz:export-visibility, r=anforowicz
JonathanBrouwer Feb 27, 2026
0c27f93
Rollup merge of #153012 - Zalathar:lexical, r=petrochenkov
JonathanBrouwer Feb 27, 2026
2fd2bd9
Rollup merge of #150828 - sourcefrog:doc-exe-security, r=cuviper
JonathanBrouwer Feb 27, 2026
2381397
Rollup merge of #152673 - makai410:rpub/bridge-impl, r=celinval
JonathanBrouwer Feb 27, 2026
36fe953
Rollup merge of #152674 - makai410:rpub/sus-trait, r=celinval
JonathanBrouwer Feb 27, 2026
9e1ec70
Rollup merge of #153073 - mehdiakiki:fix/conjure-zst-panic-message, r…
JonathanBrouwer Feb 27, 2026
1e678b9
Rollup merge of #153117 - arferreira:cleanup-macro-path-iter, r=Guill…
JonathanBrouwer Feb 27, 2026
44427f2
Rollup merge of #153128 - mu001999-contrib:fix/features, r=joboet
JonathanBrouwer Feb 27, 2026
40d7e7f
Rollup merge of #153138 - mu001999-contrib:print-path-root, r=petroch…
JonathanBrouwer Feb 27, 2026
b70cf15
Rollup merge of #153159 - Zalathar:emit-workaround, r=nnethercote
JonathanBrouwer Feb 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
use rustc_hir::attrs::{
CoverageAttrKind, ExportVisibilityAttrValue, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy,
};
use rustc_session::parse::feature_err;

use super::prelude::*;
Expand Down Expand Up @@ -153,6 +155,43 @@ impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
}
}

pub(crate) struct ExportVisibilityParser;

impl<S: Stage> SingleAttributeParser<S> for ExportVisibilityParser {
const PATH: &[rustc_span::Symbol] = &[sym::export_visibility];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::Static)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "visibility");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(nv) = args.name_value() else {
cx.expected_name_value(cx.attr_span, None);
return None;
};
let Some(sv) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};

let str_to_visibility = [("target_default", ExportVisibilityAttrValue::TargetDefault)];
for &(s, visibility) in str_to_visibility.iter() {
if s == sv.as_str() {
return Some(AttributeKind::ExportVisibility { visibility, span: cx.attr_span });
}
}

let allowed_str_values = str_to_visibility
.into_iter()
.map(|(s, _visibility)| s)
.map(Symbol::intern)
.collect::<Vec<_>>();
cx.expected_specific_argument_strings(nv.value_span, &allowed_str_values);
None
}
}

pub(crate) struct RustcObjcClassParser;

impl<S: Stage> SingleAttributeParser<S> for RustcObjcClassParser {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ attribute_parsers!(
Single<DeprecatedParser>,
Single<DoNotRecommendParser>,
Single<ExportNameParser>,
Single<ExportVisibilityParser>,
Single<IgnoreParser>,
Single<InlineParser>,
Single<InstructionSetParser>,
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::{Align, ExternAbi};
use rustc_hir::attrs::{
AttributeKind, EiiImplResolution, InlineAttr, Linkage, RtsanSetting, UsedBy,
AttributeKind, EiiImplResolution, ExportVisibilityAttrValue, InlineAttr, Linkage, RtsanSetting,
UsedBy,
};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
Expand Down Expand Up @@ -70,6 +71,13 @@ fn process_builtin_attrs(
match attr {
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
AttributeKind::ExportName { name, .. } => codegen_fn_attrs.symbol_name = Some(*name),
AttributeKind::ExportVisibility { visibility, .. } => {
codegen_fn_attrs.export_visibility = Some(match visibility {
ExportVisibilityAttrValue::TargetDefault => {
tcx.sess.default_visibility().into()
}
});
}
AttributeKind::Inline(inline, span) => {
codegen_fn_attrs.inline = *inline;
interesting_spans.inline = Some(*span);
Expand Down Expand Up @@ -533,6 +541,16 @@ fn handle_lang_items(
}
err.emit();
}

if codegen_fn_attrs.export_visibility.is_some() {
let span = find_attr!(attrs, ExportVisibility{span, ..} => *span).unwrap_or_default();
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
tcx.dcx().emit_err(errors::ExportVisibilityWithRustcStdInternalSymbol { span });
}
if !codegen_fn_attrs.contains_extern_indicator() {
tcx.dcx().emit_err(errors::ExportVisibilityWithoutNoMangleNorExportName { span });
}
}
}

/// Generate the [`CodegenFnAttrs`] for an item (identified by the [`LocalDefId`]).
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,3 +1268,20 @@ pub(crate) struct LtoProcMacro;
#[diag("cannot prefer dynamic linking when performing LTO")]
#[note("only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO")]
pub(crate) struct DynamicLinkingWithLTO;

#[derive(Diagnostic)]
#[diag("`#[export_visibility = ...]` cannot be used on internal language items")]
pub(crate) struct ExportVisibilityWithRustcStdInternalSymbol {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(
"`#[export_visibility = ...]` will be ignored \
without `export_name`, `no_mangle`, or similar attribute"
)]
pub(crate) struct ExportVisibilityWithoutNoMangleNorExportName {
#[primary_span]
pub span: Span,
}
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"),
FutureWarnPreceding, EncodeCrossCrate::No
),
gated!(export_visibility, Normal, template!(NameValueStr: "visibility"), ErrorPreceding, EncodeCrossCrate::No, experimental!(export_visibility)),
ungated!(
unsafe(Edition2024) link_section, Normal,
template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute"),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ declare_features! (
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
/// Allows using `#[export_stable]` which indicates that an item is exportable.
(incomplete, export_stable, "1.88.0", Some(139939)),
/// Allows `#[export_visibility]` on definitions of statics and/or functions.
(unstable, export_visibility, "CURRENT_RUSTC_VERSION", Some(151425)),
/// Externally implementable items
(unstable, extern_item_impls, "1.94.0", Some(125418)),
/// Allows defining `extern type`s.
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ impl Deprecation {
}
}

/// Pre-parsed value of `#[export_visibility = ...]` attribute.
///
/// In a future RFC we may consider adding support for `Hidden`, `Protected`, and/or
/// `Interposable`.
#[derive(Clone, Copy, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub enum ExportVisibilityAttrValue {
TargetDefault,
}

/// There are three valid forms of the attribute:
/// `#[used]`, which is equivalent to `#[used(linker)]` on targets that support it, but `#[used(compiler)]` if not.
/// `#[used(compiler)]`
Expand Down Expand Up @@ -1045,6 +1054,12 @@ pub enum AttributeKind {
/// Represents `#[export_stable]`.
ExportStable,

/// Represents [`#[export_visibility = ...]`](https://github.com/rust-lang/rust/issues/151425)
ExportVisibility {
visibility: ExportVisibilityAttrValue,
span: Span,
},

/// Represents `#[feature(...)]`
Feature(ThinVec<Ident>, Span),

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl AttributeKind {
EiiImpls(..) => No,
ExportName { .. } => Yes,
ExportStable => No,
ExportVisibility { .. } => Yes,
Feature(..) => No,
FfiConst(..) => No,
FfiPure(..) => No,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use rustc_index::IndexVec;
use rustc_type_ir::RegionVid;

use crate::infer::SubregionOrigin;
use crate::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};

/// Selects either out-edges or in-edges for [`IndexedConstraintEdges::adjacent_edges`].
#[derive(Clone, Copy, Debug)]
pub(super) enum EdgeDirection {
Out,
In,
}

/// Type alias for the pairs stored in [`RegionConstraintData::constraints`],
/// which we are indexing.
type ConstraintPair<'tcx> = (Constraint<'tcx>, SubregionOrigin<'tcx>);

/// An index from region variables to their corresponding constraint edges,
/// used on some error paths.
pub(super) struct IndexedConstraintEdges<'data, 'tcx> {
out_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
in_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
}

impl<'data, 'tcx> IndexedConstraintEdges<'data, 'tcx> {
pub(super) fn build_index(num_vars: usize, data: &'data RegionConstraintData<'tcx>) -> Self {
let mut out_edges = IndexVec::from_fn_n(|_| vec![], num_vars);
let mut in_edges = IndexVec::from_fn_n(|_| vec![], num_vars);

for pair @ (c, _) in &data.constraints {
// Only push a var out-edge for `VarSub...` constraints.
match c.kind {
ConstraintKind::VarSubVar | ConstraintKind::VarSubReg => {
out_edges[c.sub.as_var()].push(pair)
}
ConstraintKind::RegSubVar | ConstraintKind::RegSubReg => {}
}
}

// Index in-edges in reverse order, to match what current tests expect.
// (It's unclear whether this is important or not.)
for pair @ (c, _) in data.constraints.iter().rev() {
// Only push a var in-edge for `...SubVar` constraints.
match c.kind {
ConstraintKind::VarSubVar | ConstraintKind::RegSubVar => {
in_edges[c.sup.as_var()].push(pair)
}
ConstraintKind::VarSubReg | ConstraintKind::RegSubReg => {}
}
}

IndexedConstraintEdges { out_edges, in_edges }
}

/// Returns either the out-edges or in-edges of the specified region var,
/// as selected by `dir`.
pub(super) fn adjacent_edges(
&self,
region_vid: RegionVid,
dir: EdgeDirection,
) -> &[&'data ConstraintPair<'tcx>] {
let edges = match dir {
EdgeDirection::Out => &self.out_edges,
EdgeDirection::In => &self.in_edges,
};
&edges[region_vid]
}
}
Loading
Loading