Auto merge of #152075 - JonathanBrouwer:rollup-TaaDPXF, r=JonathanBrouwer
Rollup of 7 pull requests Successful merges: - rust-lang/rust#148967 (const-eval: always do mem-to-mem copies if there might be padding involved) - rust-lang/rust#152012 (Use `DEVELOPER_DIR` instead of a custom `xcode-select` script) - rust-lang/rust#152044 (Convert to inline diagnostics in `rustc_incremental`) - rust-lang/rust#152046 (Use glob imports for attribute parsers) - rust-lang/rust#152054 (Distinguish error message for `#[diagnostic::on_const]` on const trait impls) - rust-lang/rust#152059 (Fix some autodiff tests require Clto=fat) - rust-lang/rust#152073 (Convert to inline diagnostics in `rustc_mir_dataflow`)
This commit is contained in:
commit
1d05e3c131
38 changed files with 226 additions and 307 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
|
@ -165,9 +165,6 @@ jobs:
|
|||
- name: install sccache
|
||||
run: src/ci/scripts/install-sccache.sh
|
||||
|
||||
- name: select Xcode
|
||||
run: src/ci/scripts/select-xcode.sh
|
||||
|
||||
- name: install clang
|
||||
run: src/ci/scripts/install-clang.sh
|
||||
|
||||
|
|
|
|||
|
|
@ -3789,7 +3789,6 @@ dependencies = [
|
|||
"rustc_hir_analysis",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_hir_typeck",
|
||||
"rustc_incremental",
|
||||
"rustc_index",
|
||||
"rustc_interface",
|
||||
"rustc_lexer",
|
||||
|
|
@ -3799,7 +3798,6 @@ dependencies = [
|
|||
"rustc_metadata",
|
||||
"rustc_middle",
|
||||
"rustc_mir_build",
|
||||
"rustc_mir_dataflow",
|
||||
"rustc_mir_transform",
|
||||
"rustc_monomorphize",
|
||||
"rustc_parse",
|
||||
|
|
@ -4048,7 +4046,6 @@ dependencies = [
|
|||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_fs_util",
|
||||
"rustc_graphviz",
|
||||
"rustc_hashes",
|
||||
|
|
@ -4333,7 +4330,6 @@ dependencies = [
|
|||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_graphviz",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
|
|
|
|||
|
|
@ -16,90 +16,42 @@ use rustc_session::lint::{Lint, LintId};
|
|||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
|
||||
use crate::AttributeParser;
|
||||
use crate::attributes::allow_unstable::{
|
||||
AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
|
||||
};
|
||||
use crate::attributes::body::CoroutineParser;
|
||||
use crate::attributes::cfi_encoding::CfiEncodingParser;
|
||||
use crate::attributes::codegen_attrs::{
|
||||
ColdParser, CoverageParser, EiiForeignItemParser, ExportNameParser, ForceTargetFeatureParser,
|
||||
NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
|
||||
PatchableFunctionEntryParser, RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser,
|
||||
TargetFeatureParser, ThreadLocalParser, TrackCallerParser, UsedParser,
|
||||
};
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::crate_level::{
|
||||
CrateNameParser, CrateTypeParser, MoveSizeLimitParser, NeedsPanicRuntimeParser,
|
||||
NoBuiltinsParser, NoCoreParser, NoMainParser, NoStdParser, PanicRuntimeParser,
|
||||
PatternComplexityLimitParser, ProfilerRuntimeParser, RecursionLimitParser,
|
||||
RustcCoherenceIsCoreParser, RustcPreserveUbChecksParser, TypeLengthLimitParser,
|
||||
WindowsSubsystemParser,
|
||||
};
|
||||
use crate::attributes::debugger::DebuggerViualizerParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::do_not_recommend::DoNotRecommendParser;
|
||||
use crate::attributes::doc::DocParser;
|
||||
use crate::attributes::dummy::DummyParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::instruction_set::InstructionSetParser;
|
||||
use crate::attributes::link_attrs::{
|
||||
CompilerBuiltinsParser, ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser,
|
||||
LinkOrdinalParser, LinkParser, LinkSectionParser, LinkageParser, NeedsAllocatorParser,
|
||||
StdInternalSymbolParser,
|
||||
};
|
||||
use crate::attributes::lint_helpers::{
|
||||
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
|
||||
RustcShouldNotBeCalledOnConstItems,
|
||||
};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::macro_attrs::{
|
||||
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
|
||||
MacroUseParser,
|
||||
};
|
||||
use crate::attributes::must_not_suspend::MustNotSuspendParser;
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||
use crate::attributes::no_link::NoLinkParser;
|
||||
use crate::attributes::non_exhaustive::NonExhaustiveParser;
|
||||
// Glob imports to avoid big, bitrotty import lists
|
||||
use crate::attributes::allow_unstable::*;
|
||||
use crate::attributes::body::*;
|
||||
use crate::attributes::cfi_encoding::*;
|
||||
use crate::attributes::codegen_attrs::*;
|
||||
use crate::attributes::confusables::*;
|
||||
use crate::attributes::crate_level::*;
|
||||
use crate::attributes::debugger::*;
|
||||
use crate::attributes::deprecation::*;
|
||||
use crate::attributes::do_not_recommend::*;
|
||||
use crate::attributes::doc::*;
|
||||
use crate::attributes::dummy::*;
|
||||
use crate::attributes::inline::*;
|
||||
use crate::attributes::instruction_set::*;
|
||||
use crate::attributes::link_attrs::*;
|
||||
use crate::attributes::lint_helpers::*;
|
||||
use crate::attributes::loop_match::*;
|
||||
use crate::attributes::macro_attrs::*;
|
||||
use crate::attributes::must_not_suspend::*;
|
||||
use crate::attributes::must_use::*;
|
||||
use crate::attributes::no_implicit_prelude::*;
|
||||
use crate::attributes::no_link::*;
|
||||
use crate::attributes::non_exhaustive::*;
|
||||
use crate::attributes::path::PathParser as PathAttributeParser;
|
||||
use crate::attributes::pin_v2::PinV2Parser;
|
||||
use crate::attributes::proc_macro_attrs::{
|
||||
ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser,
|
||||
};
|
||||
use crate::attributes::prototype::CustomMirParser;
|
||||
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
|
||||
use crate::attributes::rustc_allocator::{
|
||||
RustcAllocatorParser, RustcAllocatorZeroedParser, RustcAllocatorZeroedVariantParser,
|
||||
RustcDeallocatorParser, RustcReallocatorParser,
|
||||
};
|
||||
use crate::attributes::rustc_dump::{
|
||||
RustcDumpDefParentsParser, RustcDumpItemBoundsParser, RustcDumpPredicatesParser,
|
||||
RustcDumpUserArgsParser, RustcDumpVtableParser,
|
||||
};
|
||||
use crate::attributes::rustc_internal::{
|
||||
RustcHasIncoherentInherentImplsParser, RustcHiddenTypeOfOpaquesParser, RustcLayoutParser,
|
||||
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
|
||||
RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
|
||||
RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser,
|
||||
RustcMirParser, RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
|
||||
RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser,
|
||||
RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser,
|
||||
RustcSimdMonomorphizeLaneLimitParser,
|
||||
};
|
||||
use crate::attributes::semantics::MayDangleParser;
|
||||
use crate::attributes::stability::{
|
||||
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
|
||||
};
|
||||
use crate::attributes::test_attrs::{
|
||||
IgnoreParser, RustcVarianceOfOpaquesParser, RustcVarianceParser, ShouldPanicParser,
|
||||
};
|
||||
use crate::attributes::traits::{
|
||||
AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser,
|
||||
DynIncompatibleTraitParser, FundamentalParser, MarkerParser, ParenSugarParser, PointeeParser,
|
||||
SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser,
|
||||
UnsafeSpecializationMarkerParser,
|
||||
};
|
||||
use crate::attributes::transparency::TransparencyParser;
|
||||
use crate::attributes::pin_v2::*;
|
||||
use crate::attributes::proc_macro_attrs::*;
|
||||
use crate::attributes::prototype::*;
|
||||
use crate::attributes::repr::*;
|
||||
use crate::attributes::rustc_allocator::*;
|
||||
use crate::attributes::rustc_dump::*;
|
||||
use crate::attributes::rustc_internal::*;
|
||||
use crate::attributes::semantics::*;
|
||||
use crate::attributes::stability::*;
|
||||
use crate::attributes::test_attrs::*;
|
||||
use crate::attributes::traits::*;
|
||||
use crate::attributes::transparency::*;
|
||||
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
|
||||
use crate::parser::{ArgParser, RefPathParser};
|
||||
use crate::session_diagnostics::{
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
use either::{Either, Left, Right};
|
||||
use rustc_abi::{BackendRepr, HasDataLayout, Size};
|
||||
use rustc_data_structures::assert_matches;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use tracing::field::Empty;
|
||||
use tracing::{instrument, trace};
|
||||
|
|
@ -884,10 +884,38 @@ where
|
|||
dest.layout().ty,
|
||||
);
|
||||
}
|
||||
// If the source has padding, we want to always do a mem-to-mem copy to ensure consistent
|
||||
// padding in the target independent of layout choices.
|
||||
let src_has_padding = match src.layout().backend_repr {
|
||||
BackendRepr::Scalar(_) => false,
|
||||
BackendRepr::ScalarPair(left, right)
|
||||
if matches!(src.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..)) =>
|
||||
{
|
||||
// Wide pointers never have padding, so we can avoid calling `size()`.
|
||||
debug_assert_eq!(left.size(self) + right.size(self), src.layout().size);
|
||||
false
|
||||
}
|
||||
BackendRepr::ScalarPair(left, right) => {
|
||||
let left_size = left.size(self);
|
||||
let right_size = right.size(self);
|
||||
// We have padding if the sizes don't add up to the total.
|
||||
left_size + right_size != src.layout().size
|
||||
}
|
||||
// Everything else can only exist in memory anyway, so it doesn't matter.
|
||||
BackendRepr::SimdVector { .. }
|
||||
| BackendRepr::ScalableVector { .. }
|
||||
| BackendRepr::Memory { .. } => true,
|
||||
};
|
||||
|
||||
// Let us see if the layout is simple so we take a shortcut,
|
||||
// avoid force_allocation.
|
||||
let src = match self.read_immediate_raw(src)? {
|
||||
let src_val = if src_has_padding {
|
||||
// Do our best to get an mplace. If there's no mplace, then this is stored as an
|
||||
// "optimized" local, so its padding is definitely uninitialized and we are fine.
|
||||
src.to_op(self)?.as_mplace_or_imm()
|
||||
} else {
|
||||
// Do our best to get an immediate, to avoid having to force_allocate the destination.
|
||||
self.read_immediate_raw(src)?
|
||||
};
|
||||
let src = match src_val {
|
||||
Right(src_val) => {
|
||||
assert!(!src.layout().is_unsized());
|
||||
assert!(!dest.layout().is_unsized());
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
|
|||
}
|
||||
|
||||
/// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for
|
||||
/// reading from this thing.
|
||||
/// reading from this thing. This will never actually do a read from memory!
|
||||
fn to_op<M: Machine<'tcx, Provenance = Prov>>(
|
||||
&self,
|
||||
ecx: &InterpCx<'tcx, M>,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ rustc_feature = { path = "../rustc_feature" }
|
|||
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
|
||||
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
|
||||
rustc_hir_typeck = { path = "../rustc_hir_typeck" }
|
||||
rustc_incremental = { path = "../rustc_incremental" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_interface = { path = "../rustc_interface" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
|
|
@ -33,7 +32,6 @@ rustc_macros = { path = "../rustc_macros" }
|
|||
rustc_metadata = { path = "../rustc_metadata" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_mir_build = { path = "../rustc_mir_build" }
|
||||
rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
|
||||
rustc_mir_transform = { path = "../rustc_mir_transform" }
|
||||
rustc_monomorphize = { path = "../rustc_monomorphize" }
|
||||
rustc_parse = { path = "../rustc_parse" }
|
||||
|
|
|
|||
|
|
@ -124,13 +124,11 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
|
|||
rustc_expand::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_incremental::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_interface::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_lint::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_metadata::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_middle::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_mir_transform::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_parse::DEFAULT_LOCALE_RESOURCE,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ rand = "0.9.0"
|
|||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_fs_util = { path = "../rustc_fs_util" }
|
||||
rustc_graphviz = { path = "../rustc_graphviz" }
|
||||
rustc_hashes = { path = "../rustc_hashes" }
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
incremental_assert_loaded =
|
||||
we asserted that an existing incremental cache directory should be successfully loaded, but it was not
|
||||
|
||||
incremental_assert_not_loaded =
|
||||
we asserted that the incremental cache should not be loaded, but it was loaded
|
||||
|
||||
incremental_assertion_auto =
|
||||
`except` specified DepNodes that can not be affected for "{$name}": "{$e}"
|
||||
|
||||
incremental_associated_value_expected = expected an associated value
|
||||
|
||||
incremental_associated_value_expected_for = associated value expected for `{$ident}`
|
||||
|
||||
incremental_canonicalize_path = incremental compilation: error canonicalizing path `{$path}`: {$err}
|
||||
|
||||
incremental_cargo_help_1 =
|
||||
incremental compilation can be disabled by setting the environment variable CARGO_INCREMENTAL=0 (see https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)
|
||||
incremental_cargo_help_2 =
|
||||
the entire build directory can be changed to a different filesystem by setting the environment variable CARGO_TARGET_DIR to a different path (see https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir)
|
||||
|
||||
incremental_copy_workproduct_to_cache =
|
||||
error copying object file `{$from}` to incremental directory as `{$to}`: {$err}
|
||||
|
||||
incremental_corrupt_file = corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant.
|
||||
|
||||
incremental_create_dep_graph = failed to create dependency graph at `{$path}`: {$err}
|
||||
|
||||
incremental_create_incr_comp_dir =
|
||||
could not create incremental compilation {$tag} directory `{$path}`: {$err}
|
||||
|
||||
incremental_create_lock =
|
||||
incremental compilation: could not create session directory lock file: {$lock_err}
|
||||
incremental_create_new = failed to create {$name} at `{$path}`: {$err}
|
||||
|
||||
incremental_delete_full = error deleting incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_delete_incompatible =
|
||||
failed to delete invalidated or incompatible incremental compilation session directory contents `{$path}`: {$err}
|
||||
|
||||
incremental_delete_lock =
|
||||
error deleting lock file for incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_delete_old = unable to delete old {$name} at `{$path}`: {$err}
|
||||
|
||||
incremental_delete_partial = failed to delete partly initialized session dir `{$path}`: {$err}
|
||||
|
||||
incremental_delete_workproduct = file-system error deleting outdated file `{$path}`: {$err}
|
||||
|
||||
incremental_finalize = error finalizing incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_finalized_gc_failed =
|
||||
failed to garbage collect finalized incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_hard_link_failed =
|
||||
hard linking files in the incremental compilation cache failed. copying files instead. consider moving the cache directory to a file system which supports hard linking in session dir `{$path}`
|
||||
|
||||
incremental_invalid_gc_failed =
|
||||
failed to garbage collect invalid incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_load_dep_graph = could not load dep-graph from `{$path}`: {$err}
|
||||
|
||||
incremental_lock_unsupported =
|
||||
the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation
|
||||
|
||||
incremental_missing_depnode = missing `DepNode` variant
|
||||
|
||||
incremental_missing_if_this_changed = no `#[rustc_if_this_changed]` annotation detected
|
||||
|
||||
incremental_move_dep_graph = failed to move dependency graph from `{$from}` to `{$to}`: {$err}
|
||||
|
||||
incremental_no_cfg = no cfg attribute
|
||||
|
||||
incremental_no_path = no path from `{$source}` to `{$target}`
|
||||
|
||||
incremental_not_clean = `{$dep_node_str}` should be clean but is not
|
||||
|
||||
incremental_not_dirty = `{$dep_node_str}` should be dirty but is not
|
||||
|
||||
incremental_not_loaded = `{$dep_node_str}` should have been loaded from disk but it was not
|
||||
|
||||
incremental_ok = OK
|
||||
|
||||
incremental_repeated_depnode_label = dep-node label `{$label}` is repeated
|
||||
|
||||
incremental_session_gc_failed =
|
||||
failed to garbage collect incremental compilation session directory `{$path}`: {$err}
|
||||
|
||||
incremental_unchecked_clean = found unchecked `#[rustc_clean]` attribute
|
||||
|
||||
incremental_undefined_clean_dirty_assertions =
|
||||
clean/dirty auto-assertions not yet defined for {$kind}
|
||||
|
||||
incremental_undefined_clean_dirty_assertions_item =
|
||||
clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}
|
||||
|
||||
incremental_unknown_rustc_clean_argument = unknown `rustc_clean` argument
|
||||
|
||||
incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
|
||||
|
||||
incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized
|
||||
|
||||
incremental_write_new = failed to write {$name} to `{$path}`: {$err}
|
||||
|
|
@ -4,7 +4,7 @@ use rustc_macros::Diagnostic;
|
|||
use rustc_span::{Ident, Span, Symbol};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_unrecognized_depnode)]
|
||||
#[diag("unrecognized `DepNode` variant: {$name}")]
|
||||
pub(crate) struct UnrecognizedDepNode {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -12,28 +12,28 @@ pub(crate) struct UnrecognizedDepNode {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_missing_depnode)]
|
||||
#[diag("missing `DepNode` variant")]
|
||||
pub(crate) struct MissingDepNode {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_missing_if_this_changed)]
|
||||
#[diag("no `#[rustc_if_this_changed]` annotation detected")]
|
||||
pub(crate) struct MissingIfThisChanged {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_ok)]
|
||||
#[diag("OK")]
|
||||
pub(crate) struct Ok {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_no_path)]
|
||||
#[diag("no path from `{$source}` to `{$target}`")]
|
||||
pub(crate) struct NoPath {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -42,7 +42,7 @@ pub(crate) struct NoPath {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_assertion_auto)]
|
||||
#[diag("`except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\"")]
|
||||
pub(crate) struct AssertionAuto<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -51,7 +51,7 @@ pub(crate) struct AssertionAuto<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_undefined_clean_dirty_assertions_item)]
|
||||
#[diag("clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}")]
|
||||
pub(crate) struct UndefinedCleanDirtyItem {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -59,7 +59,7 @@ pub(crate) struct UndefinedCleanDirtyItem {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_undefined_clean_dirty_assertions)]
|
||||
#[diag("clean/dirty auto-assertions not yet defined for {$kind}")]
|
||||
pub(crate) struct UndefinedCleanDirty {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -67,7 +67,7 @@ pub(crate) struct UndefinedCleanDirty {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_repeated_depnode_label)]
|
||||
#[diag("dep-node label `{$label}` is repeated")]
|
||||
pub(crate) struct RepeatedDepNodeLabel<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -75,7 +75,7 @@ pub(crate) struct RepeatedDepNodeLabel<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_unrecognized_depnode_label)]
|
||||
#[diag("dep-node label `{$label}` not recognized")]
|
||||
pub(crate) struct UnrecognizedDepNodeLabel<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -83,7 +83,7 @@ pub(crate) struct UnrecognizedDepNodeLabel<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_not_dirty)]
|
||||
#[diag("`{$dep_node_str}` should be dirty but is not")]
|
||||
pub(crate) struct NotDirty<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -91,7 +91,7 @@ pub(crate) struct NotDirty<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_not_clean)]
|
||||
#[diag("`{$dep_node_str}` should be clean but is not")]
|
||||
pub(crate) struct NotClean<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -99,7 +99,7 @@ pub(crate) struct NotClean<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_not_loaded)]
|
||||
#[diag("`{$dep_node_str}` should have been loaded from disk but it was not")]
|
||||
pub(crate) struct NotLoaded<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -107,21 +107,21 @@ pub(crate) struct NotLoaded<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_unknown_rustc_clean_argument)]
|
||||
#[diag("unknown `rustc_clean` argument")]
|
||||
pub(crate) struct UnknownRustcCleanArgument {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_no_cfg)]
|
||||
#[diag("no cfg attribute")]
|
||||
pub(crate) struct NoCfg {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_associated_value_expected_for)]
|
||||
#[diag("associated value expected for `{$ident}`")]
|
||||
pub(crate) struct AssociatedValueExpectedFor {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
@ -129,21 +129,21 @@ pub(crate) struct AssociatedValueExpectedFor {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_associated_value_expected)]
|
||||
#[diag("expected an associated value")]
|
||||
pub(crate) struct AssociatedValueExpected {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_unchecked_clean)]
|
||||
#[diag("found unchecked `#[rustc_clean]` attribute")]
|
||||
pub(crate) struct UncheckedClean {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_old)]
|
||||
#[diag("unable to delete old {$name} at `{$path}`: {$err}")]
|
||||
pub(crate) struct DeleteOld<'a> {
|
||||
pub name: &'a str,
|
||||
pub path: PathBuf,
|
||||
|
|
@ -151,7 +151,7 @@ pub(crate) struct DeleteOld<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_create_new)]
|
||||
#[diag("failed to create {$name} at `{$path}`: {$err}")]
|
||||
pub(crate) struct CreateNew<'a> {
|
||||
pub name: &'a str,
|
||||
pub path: PathBuf,
|
||||
|
|
@ -159,7 +159,7 @@ pub(crate) struct CreateNew<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_write_new)]
|
||||
#[diag("failed to write {$name} to `{$path}`: {$err}")]
|
||||
pub(crate) struct WriteNew<'a> {
|
||||
pub name: &'a str,
|
||||
pub path: PathBuf,
|
||||
|
|
@ -167,14 +167,14 @@ pub(crate) struct WriteNew<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_canonicalize_path)]
|
||||
#[diag("incremental compilation: error canonicalizing path `{$path}`: {$err}")]
|
||||
pub(crate) struct CanonicalizePath {
|
||||
pub path: PathBuf,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_create_incr_comp_dir)]
|
||||
#[diag("could not create incremental compilation {$tag} directory `{$path}`: {$err}")]
|
||||
pub(crate) struct CreateIncrCompDir<'a> {
|
||||
pub tag: &'a str,
|
||||
pub path: &'a Path,
|
||||
|
|
@ -182,96 +182,112 @@ pub(crate) struct CreateIncrCompDir<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_create_lock)]
|
||||
#[diag("incremental compilation: could not create session directory lock file: {$lock_err}")]
|
||||
pub(crate) struct CreateLock<'a> {
|
||||
pub lock_err: std::io::Error,
|
||||
pub session_dir: &'a Path,
|
||||
#[note(incremental_lock_unsupported)]
|
||||
#[note(
|
||||
"the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation"
|
||||
)]
|
||||
pub is_unsupported_lock: bool,
|
||||
#[help(incremental_cargo_help_1)]
|
||||
#[help(incremental_cargo_help_2)]
|
||||
#[help(
|
||||
"incremental compilation can be disabled by setting the environment variable CARGO_INCREMENTAL=0 (see https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)"
|
||||
)]
|
||||
#[help(
|
||||
"the entire build directory can be changed to a different filesystem by setting the environment variable CARGO_TARGET_DIR to a different path (see https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir)"
|
||||
)]
|
||||
pub is_cargo: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_lock)]
|
||||
#[diag("error deleting lock file for incremental compilation session directory `{$path}`: {$err}")]
|
||||
pub(crate) struct DeleteLock<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_hard_link_failed)]
|
||||
#[diag(
|
||||
"hard linking files in the incremental compilation cache failed. copying files instead. consider moving the cache directory to a file system which supports hard linking in session dir `{$path}`"
|
||||
)]
|
||||
pub(crate) struct HardLinkFailed<'a> {
|
||||
pub path: &'a Path,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_partial)]
|
||||
#[diag("failed to delete partly initialized session dir `{$path}`: {$err}")]
|
||||
pub(crate) struct DeletePartial<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_full)]
|
||||
#[diag("error deleting incremental compilation session directory `{$path}`: {$err}")]
|
||||
pub(crate) struct DeleteFull<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_finalize)]
|
||||
#[diag("error finalizing incremental compilation session directory `{$path}`: {$err}")]
|
||||
pub(crate) struct Finalize<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_invalid_gc_failed)]
|
||||
#[diag(
|
||||
"failed to garbage collect invalid incremental compilation session directory `{$path}`: {$err}"
|
||||
)]
|
||||
pub(crate) struct InvalidGcFailed<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_finalized_gc_failed)]
|
||||
#[diag(
|
||||
"failed to garbage collect finalized incremental compilation session directory `{$path}`: {$err}"
|
||||
)]
|
||||
pub(crate) struct FinalizedGcFailed<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_session_gc_failed)]
|
||||
#[diag("failed to garbage collect incremental compilation session directory `{$path}`: {$err}")]
|
||||
pub(crate) struct SessionGcFailed<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_assert_not_loaded)]
|
||||
#[diag("we asserted that the incremental cache should not be loaded, but it was loaded")]
|
||||
pub(crate) struct AssertNotLoaded;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_assert_loaded)]
|
||||
#[diag(
|
||||
"we asserted that an existing incremental cache directory should be successfully loaded, but it was not"
|
||||
)]
|
||||
pub(crate) struct AssertLoaded;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_incompatible)]
|
||||
#[diag(
|
||||
"failed to delete invalidated or incompatible incremental compilation session directory contents `{$path}`: {$err}"
|
||||
)]
|
||||
pub(crate) struct DeleteIncompatible {
|
||||
pub path: PathBuf,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_load_dep_graph)]
|
||||
#[diag("could not load dep-graph from `{$path}`: {$err}")]
|
||||
pub(crate) struct LoadDepGraph {
|
||||
pub path: PathBuf,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_move_dep_graph)]
|
||||
#[diag("failed to move dependency graph from `{$from}` to `{$to}`: {$err}")]
|
||||
pub(crate) struct MoveDepGraph<'a> {
|
||||
pub from: &'a Path,
|
||||
pub to: &'a Path,
|
||||
|
|
@ -279,14 +295,14 @@ pub(crate) struct MoveDepGraph<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_create_dep_graph)]
|
||||
#[diag("failed to create dependency graph at `{$path}`: {$err}")]
|
||||
pub(crate) struct CreateDepGraph<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_copy_workproduct_to_cache)]
|
||||
#[diag("error copying object file `{$from}` to incremental directory as `{$to}`: {$err}")]
|
||||
pub(crate) struct CopyWorkProductToCache<'a> {
|
||||
pub from: &'a Path,
|
||||
pub to: &'a Path,
|
||||
|
|
@ -294,14 +310,16 @@ pub(crate) struct CopyWorkProductToCache<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_delete_workproduct)]
|
||||
#[diag("file-system error deleting outdated file `{$path}`: {$err}")]
|
||||
pub(crate) struct DeleteWorkProduct<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_corrupt_file)]
|
||||
#[diag(
|
||||
"corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant."
|
||||
)]
|
||||
pub(crate) struct CorruptFile<'a> {
|
||||
pub path: &'a Path,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,5 +21,3 @@ pub fn provide(providers: &mut Providers) {
|
|||
providers.hooks.save_dep_graph =
|
||||
|tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx));
|
||||
}
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ regex = "1"
|
|||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_graphviz = { path = "../rustc_graphviz" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
mir_dataflow_peek_argument_not_a_local =
|
||||
rustc_peek: argument was not a local
|
||||
|
||||
mir_dataflow_peek_argument_untracked =
|
||||
rustc_peek: argument untracked
|
||||
|
||||
mir_dataflow_peek_bit_not_set =
|
||||
rustc_peek: bit not set
|
||||
|
||||
mir_dataflow_peek_must_be_not_temporary =
|
||||
dataflow::sanity_check cannot feed a non-temp to rustc_peek
|
||||
|
||||
mir_dataflow_peek_must_be_place_or_ref_place =
|
||||
rustc_peek: argument expression must be either `place` or `&place`
|
||||
|
||||
mir_dataflow_stop_after_dataflow_ended_compilation =
|
||||
stop_after_dataflow ended compilation
|
||||
|
|
@ -2,39 +2,39 @@ use rustc_macros::Diagnostic;
|
|||
use rustc_span::Span;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_stop_after_dataflow_ended_compilation)]
|
||||
#[diag("stop_after_dataflow ended compilation")]
|
||||
pub(crate) struct StopAfterDataFlowEndedCompilation;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_peek_must_be_place_or_ref_place)]
|
||||
#[diag("rustc_peek: argument expression must be either `place` or `&place`")]
|
||||
pub(crate) struct PeekMustBePlaceOrRefPlace {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_peek_must_be_not_temporary)]
|
||||
#[diag("dataflow::sanity_check cannot feed a non-temp to rustc_peek")]
|
||||
pub(crate) struct PeekMustBeNotTemporary {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_peek_bit_not_set)]
|
||||
#[diag("rustc_peek: bit not set")]
|
||||
pub(crate) struct PeekBitNotSet {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_peek_argument_not_a_local)]
|
||||
#[diag("rustc_peek: argument was not a local")]
|
||||
pub(crate) struct PeekArgumentNotALocal {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_peek_argument_untracked)]
|
||||
#[diag("rustc_peek: argument untracked")]
|
||||
pub(crate) struct PeekArgumentUntracked {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ pub mod rustc_peek;
|
|||
mod un_derefer;
|
||||
pub mod value_analysis;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
pub struct MoveDataTypingEnv<'tcx> {
|
||||
pub move_data: MoveData<'tcx>,
|
||||
pub typing_env: ty::TypingEnv<'tcx>,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,10 @@ passes_deprecated_annotation_has_no_effect =
|
|||
passes_deprecated_attribute =
|
||||
deprecated attribute must be paired with either stable or unstable attribute
|
||||
|
||||
passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls =
|
||||
`#[diagnostic::on_const]` can only be applied to non-const trait impls
|
||||
.label = this is a const trait impl
|
||||
|
||||
passes_diagnostic_diagnostic_on_const_only_for_trait_impls =
|
||||
`#[diagnostic::on_const]` can only be applied to trait impls
|
||||
.label = not a trait impl
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ struct DiagnosticOnConstOnlyForTraitImpls {
|
|||
item_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls)]
|
||||
struct DiagnosticOnConstOnlyForNonConstTraitImpls {
|
||||
#[label]
|
||||
item_span: Span,
|
||||
}
|
||||
|
||||
fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target {
|
||||
match impl_item.kind {
|
||||
hir::ImplItemKind::Const(..) => Target::AssocConst,
|
||||
|
|
@ -630,7 +637,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
if target == (Target::Impl { of_trait: true }) {
|
||||
match item.unwrap() {
|
||||
ItemLike::Item(it) => match it.expect_impl().constness {
|
||||
Constness::Const => {}
|
||||
Constness::Const => {
|
||||
let item_span = self.tcx.hir_span(hir_id);
|
||||
self.tcx.emit_node_span_lint(
|
||||
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr_span,
|
||||
DiagnosticOnConstOnlyForNonConstTraitImpls { item_span },
|
||||
);
|
||||
return;
|
||||
}
|
||||
Constness::NotConst => return,
|
||||
},
|
||||
ItemLike::ForeignItem => {}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const TEST_JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/tes
|
|||
fn auto_jobs() {
|
||||
let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/auto");
|
||||
insta::assert_snapshot!(stdout, @r#"
|
||||
jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}]
|
||||
jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DEVELOPER_DIR":"/Applications/Xcode_15.4.app/Contents/Developer","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}]
|
||||
run_type=auto
|
||||
"#);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ envs:
|
|||
# Ensure that host tooling is tested on our minimum supported macOS version.
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_15.2.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
|
|
@ -112,7 +112,7 @@ auto:
|
|||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_15.4.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
|
||||
USE_XCODE_CLANG: 1
|
||||
# Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
|
||||
# supports the hardware, so only need to test it there.
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ auto:
|
|||
# Ensure that host tooling is built to support our minimum support macOS version.
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_15.4.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
|
||||
USE_XCODE_CLANG: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
|
|
@ -475,7 +475,7 @@ auto:
|
|||
# FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?)
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_15.2.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
|
||||
<<: *job-macos
|
||||
|
||||
- name: dist-aarch64-apple
|
||||
|
|
@ -496,7 +496,7 @@ auto:
|
|||
# supports the hardware.
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
SELECT_XCODE: /Applications/Xcode_15.4.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
|
||||
USE_XCODE_CLANG: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
|
|
@ -511,7 +511,7 @@ auto:
|
|||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
SELECT_XCODE: /Applications/Xcode_15.4.app
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
|
||||
USE_XCODE_CLANG: 1
|
||||
# Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
|
||||
# supports the hardware, so only need to test it there.
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/bash
|
||||
# This script selects the Xcode instance to use.
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
|
||||
|
||||
if isMacOS; then
|
||||
sudo xcode-select -s "${SELECT_XCODE}"
|
||||
fi
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ fn main() {
|
|||
.arg("-Zautodiff=Enable")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("0")
|
||||
.arg("-Clto=fat")
|
||||
.emit("llvm-ir")
|
||||
.run();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ fn main() {
|
|||
rustc()
|
||||
.input("test.rs")
|
||||
.arg("-Zautodiff=Enable,NoTT")
|
||||
.arg("-Clto=fat")
|
||||
.emit("llvm-ir")
|
||||
.arg("-o")
|
||||
.arg("nott.ll")
|
||||
|
|
@ -17,6 +18,7 @@ fn main() {
|
|||
rustc()
|
||||
.input("test.rs")
|
||||
.arg("-Zautodiff=Enable")
|
||||
.arg("-Clto=fat")
|
||||
.emit("llvm-ir")
|
||||
.arg("-o")
|
||||
.arg("with_tt.ll")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
llvm_filecheck().patterns("recursion.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
|
||||
fn main() {
|
||||
// Compile with TypeTree enabled and emit LLVM IR
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
|
||||
// Check that f128 TypeTree metadata is correctly generated
|
||||
llvm_filecheck().patterns("f128.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
|
||||
fn main() {
|
||||
// Compile with TypeTree enabled and emit LLVM IR
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
|
||||
// Check that f16 TypeTree metadata is correctly generated
|
||||
llvm_filecheck().patterns("f16.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
|
||||
fn main() {
|
||||
// Compile with TypeTree enabled and emit LLVM IR
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
|
||||
// Check that f32 TypeTree metadata is correctly generated
|
||||
llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
|
||||
fn main() {
|
||||
// Compile with TypeTree enabled and emit LLVM IR
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
|
||||
// Check that f64 TypeTree metadata is correctly generated
|
||||
llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
|
||||
fn main() {
|
||||
// Compile with TypeTree enabled and emit LLVM IR
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
|
||||
// Check that i32 TypeTree metadata is correctly generated
|
||||
llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
llvm_filecheck().patterns("slice.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run();
|
||||
rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run();
|
||||
llvm_filecheck().patterns("tuple.check").stdin_buf(rfs::read("test.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ const _PARTIAL_OVERWRITE: () = {
|
|||
#[allow(dead_code)]
|
||||
#[cfg(not(target_arch = "s390x"))] // u128 is less aligned on s390x, removing the padding
|
||||
fn fragment_in_dst_padding_gets_overwritten() {
|
||||
// We can't use `repr(align)` here as that would make this not a `ScalarPair` any more.
|
||||
#[repr(C)]
|
||||
struct Pair {
|
||||
x: u128,
|
||||
|
|
|
|||
|
|
@ -37,4 +37,40 @@ const MIXED_PTR: MaybeUninit<*const u8> = { //~ERROR: partial pointer in final v
|
|||
}
|
||||
};
|
||||
|
||||
/// This has pointer bytes in the padding of the memory that the final value is read from.
|
||||
/// To ensure consistent behavior, we want to *always* copy that padding, even if the value
|
||||
/// could be represented as a more efficient ScalarPair. Hence this must fail to compile.
|
||||
fn fragment_in_padding() -> impl Copy {
|
||||
// We can't use `repr(align)` here as that would make this not a `ScalarPair` any more.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Thing {
|
||||
x: u128,
|
||||
y: usize,
|
||||
// at least one pointer worth of padding
|
||||
}
|
||||
// Ensure there is indeed padding.
|
||||
const _: () = assert!(mem::size_of::<Thing>() > 16 + mem::size_of::<usize>());
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
union PreservePad {
|
||||
thing: Thing,
|
||||
bytes: [u8; mem::size_of::<Thing>()],
|
||||
}
|
||||
|
||||
const A: Thing = unsafe { //~ERROR: partial pointer in final value
|
||||
let mut buffer = [PreservePad { bytes: [0u8; mem::size_of::<Thing>()] }; 2];
|
||||
// The offset half a pointer from the end, so that copying a `Thing` copies exactly
|
||||
// half the pointer.
|
||||
let offset = mem::size_of::<Thing>() - mem::size_of::<usize>()/2;
|
||||
// Ensure this is inside the padding.
|
||||
assert!(offset >= std::mem::offset_of!(Thing, y) + mem::size_of::<usize>());
|
||||
|
||||
(&raw mut buffer).cast::<&i32>().byte_add(offset).write_unaligned(&1);
|
||||
buffer[0].thing
|
||||
};
|
||||
|
||||
A
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -14,5 +14,13 @@ LL | const MIXED_PTR: MaybeUninit<*const u8> = {
|
|||
|
|
||||
= note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: encountered partial pointer in final value of constant
|
||||
--> $DIR/ptr_fragments_in_final.rs:61:5
|
||||
|
|
||||
LL | const A: Thing = unsafe {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
pub struct Foo;
|
||||
|
||||
#[diagnostic::on_const(message = "tadaa", note = "boing")]
|
||||
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls
|
||||
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait impls
|
||||
impl const PartialEq for Foo {
|
||||
fn eq(&self, _other: &Foo) -> bool {
|
||||
true
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ note: the lint level is defined here
|
|||
LL | #![deny(misplaced_diagnostic_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[diagnostic::on_const]` can only be applied to trait impls
|
||||
error: `#[diagnostic::on_const]` can only be applied to non-const trait impls
|
||||
--> $DIR/misplaced_attr.rs:8:1
|
||||
|
|
||||
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | impl const PartialEq for Foo {
|
||||
| ---------------------------- not a trait impl
|
||||
| ---------------------------- this is a const trait impl
|
||||
|
||||
error: `#[diagnostic::on_const]` can only be applied to trait impls
|
||||
--> $DIR/misplaced_attr.rs:16:1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue