Auto merge of #143645 - matthiaskrgr:rollup-d2a3leo, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang/rust#143402 (Port several linking (linkage?) related attributes the new attribute system ) - rust-lang/rust#143555 (Don't mark `#[target_feature]` safe fns as unsafe in rustdoc JSON.) - rust-lang/rust#143593 (Port #[rustc_dummy]) - rust-lang/rust#143600 (Update intro blurb in `wasm32-wasip1` docs) - rust-lang/rust#143603 (Clarify the meaning of `AttributeOrder::KeepFirst` and `AttributeOrder::KeepLast`) - rust-lang/rust#143620 (fix: Remove newline from multiple crate versions note) - rust-lang/rust#143622 (Add target maintainer information for mips64-unknown-linux-muslabi64) Failed merges: - rust-lang/rust#143403 (Port several trait/coherence-related attributes the new attribute system) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ab68b0fb26
18 changed files with 266 additions and 68 deletions
|
|
@ -240,6 +240,9 @@ pub enum AttributeKind {
|
|||
/// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
|
||||
DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
|
||||
|
||||
/// Represents `#[rustc_dummy]`.
|
||||
Dummy,
|
||||
|
||||
/// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute).
|
||||
ExportName {
|
||||
/// The name to export this item with.
|
||||
|
|
@ -248,6 +251,15 @@ pub enum AttributeKind {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[export_stable]`.
|
||||
ExportStable,
|
||||
|
||||
/// Represents `#[ffi_const]`.
|
||||
FfiConst(Span),
|
||||
|
||||
/// Represents `#[ffi_pure]`.
|
||||
FfiPure(Span),
|
||||
|
||||
/// Represents `#[ignore]`
|
||||
Ignore {
|
||||
span: Span,
|
||||
|
|
@ -326,6 +338,9 @@ pub enum AttributeKind {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[rustc_std_internal_symbol]`.
|
||||
StdInternalSymbol(Span),
|
||||
|
||||
/// Represents `#[target_feature(enable = "...")]`
|
||||
TargetFeature(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,11 @@ impl AttributeKind {
|
|||
ConstStabilityIndirect => No,
|
||||
Deprecation { .. } => Yes,
|
||||
DocComment { .. } => Yes,
|
||||
Dummy => No,
|
||||
ExportName { .. } => Yes,
|
||||
ExportStable => No,
|
||||
FfiConst(..) => No,
|
||||
FfiPure(..) => No,
|
||||
Ignore { .. } => No,
|
||||
Inline(..) => No,
|
||||
LinkName { .. } => Yes,
|
||||
|
|
@ -48,6 +52,7 @@ impl AttributeKind {
|
|||
RustcObjectLifetimeDefault => No,
|
||||
SkipDuringMethodDispatch { .. } => No,
|
||||
Stability { .. } => Yes,
|
||||
StdInternalSymbol(..) => No,
|
||||
TargetFeature(..) => No,
|
||||
TrackCaller(..) => Yes,
|
||||
Used { .. } => No,
|
||||
|
|
|
|||
19
compiler/rustc_attr_parsing/src/attributes/dummy.rs
Normal file
19
compiler/rustc_attr_parsing/src/attributes/dummy.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
|
||||
pub(crate) struct DummyParser;
|
||||
impl<S: Stage> SingleAttributeParser<S> for DummyParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_dummy];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
|
||||
const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
|
||||
|
||||
fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
Some(AttributeKind::Dummy)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Symbol, sym};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
|
||||
use crate::attributes::{
|
||||
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
|
||||
};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
use crate::session_diagnostics::NullOnLinkSection;
|
||||
|
|
@ -57,3 +59,31 @@ impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
|
|||
Some(LinkSection { name, span: cx.attr_span })
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ExportStableParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
|
||||
const PATH: &[Symbol] = &[sym::export_stable];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
|
||||
}
|
||||
|
||||
pub(crate) struct FfiConstParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for FfiConstParser {
|
||||
const PATH: &[Symbol] = &[sym::ffi_const];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst;
|
||||
}
|
||||
|
||||
pub(crate) struct FfiPureParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for FfiPureParser {
|
||||
const PATH: &[Symbol] = &[sym::ffi_pure];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
|
||||
}
|
||||
|
||||
pub(crate) struct StdInternalSymbolParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for StdInternalSymbolParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub(crate) mod cfg;
|
|||
pub(crate) mod codegen_attrs;
|
||||
pub(crate) mod confusables;
|
||||
pub(crate) mod deprecation;
|
||||
pub(crate) mod dummy;
|
||||
pub(crate) mod inline;
|
||||
pub(crate) mod link_attrs;
|
||||
pub(crate) mod lint_helpers;
|
||||
|
|
@ -217,7 +218,14 @@ impl<S: Stage> OnDuplicate<S> {
|
|||
// them will be merged in another PR
|
||||
#[allow(unused)]
|
||||
pub(crate) enum AttributeOrder {
|
||||
/// Duplicates after the first attribute will be an error.
|
||||
/// Duplicates after the first attribute will be an error. I.e. only keep the lowest attribute.
|
||||
///
|
||||
/// Attributes are processed from bottom to top, so this raises an error on all the attributes
|
||||
/// further above the lowest one:
|
||||
/// ```
|
||||
/// #[stable(since="1.0")] //~ WARNING duplicated attribute
|
||||
/// #[stable(since="2.0")]
|
||||
/// ```
|
||||
///
|
||||
/// This should be used where duplicates would be ignored, but carry extra
|
||||
/// meaning that could cause confusion. For example, `#[stable(since="1.0")]
|
||||
|
|
@ -227,6 +235,13 @@ pub(crate) enum AttributeOrder {
|
|||
/// Duplicates preceding the last instance of the attribute will be a
|
||||
/// warning, with a note that this will be an error in the future.
|
||||
///
|
||||
/// Attributes are processed from bottom to top, so this raises a warning on all the attributes
|
||||
/// below the higher one:
|
||||
/// ```
|
||||
/// #[path="foo.rs"]
|
||||
/// #[path="bar.rs"] //~ WARNING duplicated attribute
|
||||
/// ```
|
||||
///
|
||||
/// This is the same as `FutureWarnFollowing`, except the last attribute is
|
||||
/// the one that is "used". Ideally these can eventually migrate to
|
||||
/// `ErrorPreceding`.
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@ use crate::attributes::codegen_attrs::{
|
|||
};
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::dummy::DummyParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
|
||||
use crate::attributes::link_attrs::{
|
||||
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
|
||||
StdInternalSymbolParser,
|
||||
};
|
||||
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
|
|
@ -127,6 +131,7 @@ attribute_parsers!(
|
|||
|
||||
// tidy-alphabetical-start
|
||||
Single<DeprecationParser>,
|
||||
Single<DummyParser>,
|
||||
Single<ExportNameParser>,
|
||||
Single<IgnoreParser>,
|
||||
Single<InlineParser>,
|
||||
|
|
@ -145,6 +150,9 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<ColdParser>>,
|
||||
Single<WithoutArgs<ConstContinueParser>>,
|
||||
Single<WithoutArgs<ConstStabilityIndirectParser>>,
|
||||
Single<WithoutArgs<ExportStableParser>>,
|
||||
Single<WithoutArgs<FfiConstParser>>,
|
||||
Single<WithoutArgs<FfiPureParser>>,
|
||||
Single<WithoutArgs<LoopMatchParser>>,
|
||||
Single<WithoutArgs<MayDangleParser>>,
|
||||
Single<WithoutArgs<NoImplicitPreludeParser>>,
|
||||
|
|
@ -152,6 +160,7 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<NonExhaustiveParser>>,
|
||||
Single<WithoutArgs<PassByValueParser>>,
|
||||
Single<WithoutArgs<PubTransparentParser>>,
|
||||
Single<WithoutArgs<StdInternalSymbolParser>>,
|
||||
Single<WithoutArgs<TrackCallerParser>>,
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
|
|
|||
|
|
@ -203,6 +203,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER,
|
||||
UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER,
|
||||
},
|
||||
AttributeKind::FfiConst(_) => {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST
|
||||
}
|
||||
AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE,
|
||||
AttributeKind::StdInternalSymbol(_) => {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -213,17 +220,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
|
||||
match name {
|
||||
sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR,
|
||||
sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE,
|
||||
sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST,
|
||||
sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND,
|
||||
sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR,
|
||||
sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR,
|
||||
sym::rustc_allocator_zeroed => {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
|
||||
}
|
||||
sym::rustc_std_internal_symbol => {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
|
||||
}
|
||||
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
|
||||
sym::linkage => {
|
||||
if let Some(val) = attr.value_str() {
|
||||
|
|
|
|||
|
|
@ -271,6 +271,10 @@ pub fn check_builtin_meta_item(
|
|||
if matches!(
|
||||
name,
|
||||
sym::inline
|
||||
| sym::export_stable
|
||||
| sym::ffi_const
|
||||
| sym::ffi_pure
|
||||
| sym::rustc_std_internal_symbol
|
||||
| sym::may_dangle
|
||||
| sym::rustc_as_ptr
|
||||
| sym::rustc_pub_transparent
|
||||
|
|
|
|||
|
|
@ -204,10 +204,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
|
||||
| AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
|
||||
) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target),
|
||||
Attribute::Parsed(AttributeKind::ExportStable) => {
|
||||
// handled in `check_export`
|
||||
}
|
||||
&Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => {
|
||||
self.check_ffi_const(attr_span, target)
|
||||
}
|
||||
&Attribute::Parsed(AttributeKind::FfiPure(attr_span)) => {
|
||||
self.check_ffi_pure(attr_span, attrs, target)
|
||||
}
|
||||
Attribute::Parsed(
|
||||
AttributeKind::BodyStability { .. }
|
||||
| AttributeKind::ConstStabilityIndirect
|
||||
| AttributeKind::MacroTransparency(_),
|
||||
| AttributeKind::MacroTransparency(_)
|
||||
| AttributeKind::Dummy,
|
||||
) => { /* do nothing */ }
|
||||
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
|
||||
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
|
||||
|
|
@ -233,6 +243,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
&Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => {
|
||||
self.check_pass_by_value(attr_span, span, target)
|
||||
}
|
||||
&Attribute::Parsed(AttributeKind::StdInternalSymbol(attr_span)) => {
|
||||
self.check_rustc_std_internal_symbol(attr_span, span, target)
|
||||
}
|
||||
Attribute::Unparsed(attr_item) => {
|
||||
style = Some(attr_item.style);
|
||||
match attr.path().as_slice() {
|
||||
|
|
@ -258,9 +271,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
),
|
||||
[sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target),
|
||||
[sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target),
|
||||
[sym::rustc_std_internal_symbol, ..] => {
|
||||
self.check_rustc_std_internal_symbol(attr, span, target)
|
||||
}
|
||||
[sym::rustc_no_implicit_autorefs, ..] => {
|
||||
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
|
||||
}
|
||||
|
|
@ -300,8 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::rustc_has_incoherent_inherent_impls, ..] => {
|
||||
self.check_has_incoherent_inherent_impls(attr, span, target)
|
||||
}
|
||||
[sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target),
|
||||
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
|
||||
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
|
||||
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
||||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
|
|
@ -346,7 +354,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| sym::cfg_attr
|
||||
| sym::cfg_trace
|
||||
| sym::cfg_attr_trace
|
||||
| sym::export_stable // handled in `check_export`
|
||||
// need to be fixed
|
||||
| sym::cfi_encoding // FIXME(cfi_encoding)
|
||||
| sym::pointee // FIXME(derive_coerce_pointee)
|
||||
|
|
@ -1507,7 +1514,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span });
|
||||
return;
|
||||
}
|
||||
if attrs.iter().any(|a| a.has_name(sym::ffi_const)) {
|
||||
if find_attr!(attrs, AttributeKind::FfiConst(_)) {
|
||||
// `#[ffi_const]` functions cannot be `#[ffi_pure]`
|
||||
self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span });
|
||||
}
|
||||
|
|
@ -2214,13 +2221,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
|
||||
fn check_rustc_std_internal_symbol(&self, attr_span: Span, span: Span, target: Target) {
|
||||
match target {
|
||||
Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {}
|
||||
_ => {
|
||||
self.tcx
|
||||
.dcx()
|
||||
.emit_err(errors::RustcStdInternalSymbol { attr_span: attr.span(), span });
|
||||
self.tcx.dcx().emit_err(errors::RustcStdInternalSymbol { attr_span, span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::iter;
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
|
@ -14,7 +15,7 @@ use rustc_middle::ty::{
|
|||
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility,
|
||||
};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::errors::UnexportableItem;
|
||||
|
||||
|
|
@ -44,7 +45,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
|
|||
}
|
||||
|
||||
fn item_is_exportable(&self, def_id: LocalDefId) -> bool {
|
||||
let has_attr = self.tcx.has_attr(def_id, sym::export_stable);
|
||||
let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable);
|
||||
if !self.in_exportable_mod && !has_attr {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -80,7 +81,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
|
|||
fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
let def_id = item.hir_id().owner.def_id;
|
||||
let old_exportable_mod = self.in_exportable_mod;
|
||||
if self.tcx.get_attr(def_id, sym::export_stable).is_some() {
|
||||
if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) {
|
||||
self.in_exportable_mod = true;
|
||||
}
|
||||
let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false);
|
||||
|
|
|
|||
|
|
@ -1933,7 +1933,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
StringPart::highlighted("multiple different versions".to_string()),
|
||||
StringPart::normal(" of crate `".to_string()),
|
||||
StringPart::highlighted(format!("{crate_name}")),
|
||||
StringPart::normal("` in the dependency graph\n".to_string()),
|
||||
StringPart::normal("` in the dependency graph".to_string()),
|
||||
],
|
||||
);
|
||||
if points_at_type {
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@
|
|||
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
|
||||
- [m68k-unknown-none-elf](platform-support/m68k-unknown-none-elf.md)
|
||||
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
|
||||
- [mips64-unknown-linux-muslabi64](platform-support/mips64-unknown-linux-muslabi64.md)
|
||||
- [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
|
||||
- [mipsel-unknown-linux-gnu](platform-support/mipsel-unknown-linux-gnu.md)
|
||||
- [mips\*-mti-none-elf](platform-support/mips-mti-none-elf.md)
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ target | std | host | notes
|
|||
`mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc
|
||||
[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux musl 1.2.3
|
||||
`mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, N64 ABI (kernel 4.4, glibc 2.23)
|
||||
`mips64-unknown-linux-muslabi64` | ✓ | | MIPS64 Linux, N64 ABI, musl 1.2.3
|
||||
[`mips64-unknown-linux-muslabi64`](platform-support/mips64-unknown-linux-muslabi64.md) | ✓ | ✓ | MIPS64 Linux, N64 ABI, musl 1.2.3
|
||||
`mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23)
|
||||
`mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3
|
||||
`mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
# mips64-unknown-linux-muslabi64
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Target for 64-bit big endian MIPS Linux programs using musl libc and the N64 ABI.
|
||||
|
||||
## Target maintainers
|
||||
|
||||
[@Gelbpunkt](https://github.com/Gelbpunkt)
|
||||
|
||||
## Requirements
|
||||
|
||||
Building the target itself requires a 64-bit big endian MIPS compiler that is
|
||||
supported by `cc-rs`.
|
||||
|
||||
## Building the target
|
||||
|
||||
The target can be built by enabling it for a `rustc` build.
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["mips64-unknown-linux-muslabi64"]
|
||||
```
|
||||
|
||||
Make sure your C compiler is included in `$PATH`, then add it to the
|
||||
`bootstrap.toml`:
|
||||
|
||||
```toml
|
||||
[target.mips64-unknown-linux-muslabi64]
|
||||
cc = "mips64-linux-musl-gcc"
|
||||
cxx = "mips64-linux-musl-g++"
|
||||
ar = "mips64-linux-musl-ar"
|
||||
linker = "mips64-linux-musl-gcc"
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for this target. To compile for
|
||||
this target, you will first need to build Rust with the target enabled (see
|
||||
"Building the target" above).
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
This target can be cross-compiled from any host.
|
||||
|
||||
## Testing
|
||||
|
||||
This target can be tested as normal with `x.py` on a 64-bit big endian MIPS
|
||||
host or via QEMU emulation.
|
||||
|
|
@ -4,37 +4,35 @@
|
|||
|
||||
The `wasm32-wasip1` target is a WebAssembly compilation target which
|
||||
assumes that the [WASIp1] (aka "WASI preview1") set of "syscalls" are available
|
||||
for use in the standard library. Historically this target in the Rust compiler
|
||||
was one of the first for WebAssembly where Rust and C code are explicitly
|
||||
intended to interoperate as well.
|
||||
for use in the standard library. This target explicitly supports interop with
|
||||
non-Rust code such as C and C++.
|
||||
|
||||
There's a bit of history to the target and current development which is also
|
||||
worth explaining before going much further. Historically this target was
|
||||
originally called `wasm32-wasi` in both rustc and Clang. This was first added
|
||||
to Rust in 2019. In the intervening years leading up to 2024 the WASI standard
|
||||
continued to be developed and was eventually "rebased" on top of the [Component
|
||||
Model]. This was a large change to the WASI specification and was released as
|
||||
0.2.0 ("WASIp2" colloquially) in January 2024. The previous target's name in
|
||||
rustc, `wasm32-wasi`, was then renamed to `wasm32-wasip1`, to avoid
|
||||
confusion with this new target to be added to rustc as `wasm32-wasip2`.
|
||||
Some more context can be found in these MCPs:
|
||||
The [WASIp1] set of syscalls is standard insofar as it was written down once by
|
||||
a set of folks and has not changed since then. Additionally the [WASIp1]
|
||||
syscalls have been adapted and adopted into a number of runtimes and embeddings.
|
||||
It is not standard in the sense that there are no formal semantics for each
|
||||
syscall and APIs are no longer receiving any maintenance (e.g. no new APIs, no
|
||||
new documentation, etc). After [WASIp1] was originally developed in 2019 the
|
||||
WASI standard effort has since been "rebased" on top of the [Component Model].
|
||||
This was a large change to the WASI specification and was released as 0.2.0
|
||||
("WASIp2" colloquially) in January 2024. Current standardization efforts are
|
||||
focused on the Component Model-based definition of WASI. At this point the
|
||||
`wasm32-wasip1` Rust target is intended for historical compatibility with
|
||||
[WASIp1] set of syscalls.
|
||||
|
||||
* [Rename wasm32-wasi target to wasm32-wasip1](https://github.com/rust-lang/compiler-team/issues/607)
|
||||
* [Smooth the renaming transition of wasm32-wasi](https://github.com/rust-lang/compiler-team/issues/695)
|
||||
|
||||
At this point the `wasm32-wasip1` target is intended for historical
|
||||
compatibility with the first version of the WASI standard. As of now (January
|
||||
2024) the 0.2.0 target of WASI ("WASIp2") is relatively new. The state of
|
||||
WASI will likely change in few years after which point this documentation will
|
||||
probably receive another update.
|
||||
|
||||
[WASI Preview1]: https://github.com/WebAssembly/WASI/tree/main/legacy/preview1
|
||||
[WASIp1]: https://github.com/WebAssembly/WASI/tree/main/legacy/preview1
|
||||
[Component Model]: https://github.com/webassembly/component-model
|
||||
|
||||
Today the `wasm32-wasip1` target will generate core WebAssembly modules
|
||||
which will import functions from the `wasi_snapshot_preview1` module for
|
||||
OS-related functionality (e.g. printing).
|
||||
|
||||
> **Note**: Prior to March 2024 this target was known as `wasm32-wasi` with some
|
||||
> historical context found in old MCPs:
|
||||
>
|
||||
> * [Rename wasm32-wasi target to wasm32-wasip1](https://github.com/rust-lang/compiler-team/issues/607)
|
||||
> * [Smooth the renaming transition of wasm32-wasi](https://github.com/rust-lang/compiler-team/issues/695)
|
||||
|
||||
## Target maintainers
|
||||
|
||||
When this target was added to the compiler platform-specific documentation here
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use rustc_ast::ast;
|
|||
use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
|
||||
use rustc_hir::def::CtorKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{HeaderSafety, Safety};
|
||||
use rustc_metadata::rendered_const;
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_span::{Pos, kw, sym};
|
||||
|
|
@ -381,10 +382,22 @@ impl FromClean<clean::Union> for Union {
|
|||
|
||||
impl FromClean<rustc_hir::FnHeader> for FunctionHeader {
|
||||
fn from_clean(header: &rustc_hir::FnHeader, renderer: &JsonRenderer<'_>) -> Self {
|
||||
let is_unsafe = match header.safety {
|
||||
HeaderSafety::SafeTargetFeatures => {
|
||||
// The type system's internal implementation details consider
|
||||
// safe functions with the `#[target_feature]` attribute to be analogous
|
||||
// to unsafe functions: `header.is_unsafe()` returns `true` for them.
|
||||
// For rustdoc, this isn't the right decision, so we explicitly return `false`.
|
||||
// Context: https://github.com/rust-lang/rust/issues/142655
|
||||
false
|
||||
}
|
||||
HeaderSafety::Normal(Safety::Safe) => false,
|
||||
HeaderSafety::Normal(Safety::Unsafe) => true,
|
||||
};
|
||||
FunctionHeader {
|
||||
is_async: header.is_async(),
|
||||
is_const: header.is_const(),
|
||||
is_unsafe: header.is_unsafe(),
|
||||
is_unsafe,
|
||||
abi: header.abi.into_json(renderer),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,40 @@
|
|||
//@ only-x86_64
|
||||
|
||||
//@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]'
|
||||
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
|
||||
#[target_feature(enable = "avx")]
|
||||
pub fn test1() {}
|
||||
|
||||
//@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
|
||||
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
|
||||
#[target_feature(enable = "avx,avx2")]
|
||||
pub fn test2() {}
|
||||
|
||||
//@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
|
||||
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
|
||||
#[target_feature(enable = "avx", enable = "avx2")]
|
||||
pub fn test3() {}
|
||||
|
||||
//@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]'
|
||||
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
|
||||
#[target_feature(enable = "avx", enable = "avx2,avx512f")]
|
||||
pub fn test4() {}
|
||||
|
||||
//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
|
||||
//@ is "$.index[?(@.name=='test_unsafe_fn')].inner.function.header.is_unsafe" true
|
||||
#[target_feature(enable = "avx")]
|
||||
pub unsafe fn test_unsafe_fn() {}
|
||||
|
||||
pub struct Example;
|
||||
|
||||
impl Example {
|
||||
//@ is "$.index[?(@.name=='safe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
|
||||
//@ is "$.index[?(@.name=='safe_assoc_fn')].inner.function.header.is_unsafe" false
|
||||
#[target_feature(enable = "avx")]
|
||||
pub fn safe_assoc_fn() {}
|
||||
|
||||
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
|
||||
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].inner.function.header.is_unsafe" true
|
||||
#[target_feature(enable = "avx")]
|
||||
pub unsafe fn unsafe_assoc_fn() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,12 +40,6 @@ error: malformed `crate_name` attribute input
|
|||
LL | #[crate_name]
|
||||
| ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]`
|
||||
|
||||
error: malformed `export_stable` attribute input
|
||||
--> $DIR/malformed-attrs.rs:81:1
|
||||
|
|
||||
LL | #[export_stable = 1]
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]`
|
||||
|
||||
error: malformed `coverage` attribute input
|
||||
--> $DIR/malformed-attrs.rs:90:1
|
||||
|
|
||||
|
|
@ -140,24 +134,12 @@ error: malformed `fundamental` attribute input
|
|||
LL | #[fundamental()]
|
||||
| ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]`
|
||||
|
||||
error: malformed `ffi_pure` attribute input
|
||||
--> $DIR/malformed-attrs.rs:165:5
|
||||
|
|
||||
LL | #[unsafe(ffi_pure = 1)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]`
|
||||
|
||||
error: malformed `link_ordinal` attribute input
|
||||
--> $DIR/malformed-attrs.rs:167:5
|
||||
|
|
||||
LL | #[link_ordinal]
|
||||
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]`
|
||||
|
||||
error: malformed `ffi_const` attribute input
|
||||
--> $DIR/malformed-attrs.rs:171:5
|
||||
|
|
||||
LL | #[unsafe(ffi_const = 1)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]`
|
||||
|
||||
error: malformed `linkage` attribute input
|
||||
--> $DIR/malformed-attrs.rs:173:5
|
||||
|
|
||||
|
|
@ -481,6 +463,15 @@ LL | #[target_feature]
|
|||
| expected this to be a list
|
||||
| help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
|
||||
|
||||
error[E0565]: malformed `export_stable` attribute input
|
||||
--> $DIR/malformed-attrs.rs:81:1
|
||||
|
|
||||
LL | #[export_stable = 1]
|
||||
| ^^^^^^^^^^^^^^^^---^
|
||||
| | |
|
||||
| | didn't expect any arguments here
|
||||
| help: must be of the form: `#[export_stable]`
|
||||
|
||||
error[E0539]: malformed `link_name` attribute input
|
||||
--> $DIR/malformed-attrs.rs:86:1
|
||||
|
|
||||
|
|
@ -537,6 +528,24 @@ LL | #[rustc_layout_scalar_valid_range_end]
|
|||
| expected this to be a list
|
||||
| help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
|
||||
|
||||
error[E0565]: malformed `ffi_pure` attribute input
|
||||
--> $DIR/malformed-attrs.rs:165:5
|
||||
|
|
||||
LL | #[unsafe(ffi_pure = 1)]
|
||||
| ^^^^^^^^^^^^^^^^^^---^^
|
||||
| | |
|
||||
| | didn't expect any arguments here
|
||||
| help: must be of the form: `#[ffi_pure]`
|
||||
|
||||
error[E0565]: malformed `ffi_const` attribute input
|
||||
--> $DIR/malformed-attrs.rs:171:5
|
||||
|
|
||||
LL | #[unsafe(ffi_const = 1)]
|
||||
| ^^^^^^^^^^^^^^^^^^^---^^
|
||||
| | |
|
||||
| | didn't expect any arguments here
|
||||
| help: must be of the form: `#[ffi_const]`
|
||||
|
||||
error[E0565]: malformed `non_exhaustive` attribute input
|
||||
--> $DIR/malformed-attrs.rs:197:1
|
||||
|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue