Auto merge of #139949 - matthiaskrgr:rollup-pxc5tsx, r=matthiaskrgr
Rollup of 8 pull requests
Successful merges:
- #138632 (Stabilize `cfg_boolean_literals`)
- #139416 (unstable book; document `macro_metavar_expr_concat`)
- #139782 (Consistent with treating Ctor Call as Struct in liveness analysis)
- #139885 (document RUSTC_BOOTSTRAP, RUSTC_OVERRIDE_VERSION_STRING, and -Z allow-features in the unstable book)
- #139904 (Explicitly annotate edition for `unpretty=expanded` and `unpretty=hir` tests)
- #139932 (transmutability: Refactor tests for simplicity)
- #139944 (Move eager translation to a method on Diag)
- #139948 (git: ignore `60600a6fa4
` for blame purposes)
r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
commit
883f9f72e8
240 changed files with 1038 additions and 978 deletions
|
@ -31,3 +31,5 @@ ec2cc761bc7067712ecc7734502f703fe3b024c8
|
||||||
c682aa162b0d41e21cc6748f4fecfe01efb69d1f
|
c682aa162b0d41e21cc6748f4fecfe01efb69d1f
|
||||||
# reformat with updated edition 2024
|
# reformat with updated edition 2024
|
||||||
1fcae03369abb4c2cc180cd5a49e1f4440a81300
|
1fcae03369abb4c2cc180cd5a49e1f4440a81300
|
||||||
|
# Breaking up of compiletest runtest.rs
|
||||||
|
60600a6fa403216bfd66e04f948b1822f6450af7
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use rustc_ast::ParamKindOrd;
|
use rustc_ast::ParamKindOrd;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic};
|
use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_span::{Ident, Span, Symbol};
|
use rustc_span::{Ident, Span, Symbol};
|
||||||
|
|
||||||
|
@ -394,11 +394,7 @@ pub(crate) struct EmptyLabelManySpans(pub Vec<Span>);
|
||||||
|
|
||||||
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
|
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
|
||||||
impl Subdiagnostic for EmptyLabelManySpans {
|
impl Subdiagnostic for EmptyLabelManySpans {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
diag.span_labels(self.0, "");
|
diag.span_labels(self.0, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -749,11 +745,7 @@ pub(crate) struct StableFeature {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for StableFeature {
|
impl Subdiagnostic for StableFeature {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("name", self.name);
|
diag.arg("name", self.name);
|
||||||
diag.arg("since", self.since);
|
diag.arg("since", self.since);
|
||||||
diag.help(fluent::ast_passes_stable_since);
|
diag.help(fluent::ast_passes_stable_since);
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_session::config::ExpectedValues;
|
||||||
use rustc_session::lint::BuiltinLintDiag;
|
use rustc_session::lint::BuiltinLintDiag;
|
||||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::kw;
|
|
||||||
use rustc_span::{Span, Symbol, sym};
|
use rustc_span::{Span, Symbol, sym};
|
||||||
|
|
||||||
use crate::session_diagnostics::{self, UnsupportedLiteralReason};
|
use crate::session_diagnostics::{self, UnsupportedLiteralReason};
|
||||||
|
@ -89,20 +88,6 @@ pub fn eval_condition(
|
||||||
let cfg = match cfg {
|
let cfg = match cfg {
|
||||||
MetaItemInner::MetaItem(meta_item) => meta_item,
|
MetaItemInner::MetaItem(meta_item) => meta_item,
|
||||||
MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => {
|
MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => {
|
||||||
if let Some(features) = features {
|
|
||||||
// we can't use `try_gate_cfg` as symbols don't differentiate between `r#true`
|
|
||||||
// and `true`, and we want to keep the former working without feature gate
|
|
||||||
gate_cfg(
|
|
||||||
&(
|
|
||||||
if *b { kw::True } else { kw::False },
|
|
||||||
sym::cfg_boolean_literals,
|
|
||||||
|features: &Features| features.cfg_boolean_literals(),
|
|
||||||
),
|
|
||||||
cfg.span(),
|
|
||||||
sess,
|
|
||||||
features,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return *b;
|
return *b;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans,
|
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans,
|
||||||
SubdiagMessageOp, Subdiagnostic,
|
Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_span::{Ident, Span, Symbol};
|
use rustc_span::{Ident, Span, Symbol};
|
||||||
|
@ -684,13 +684,9 @@ pub(crate) struct FormatUnusedArg {
|
||||||
// Allow the singular form to be a subdiagnostic of the multiple-unused
|
// Allow the singular form to be a subdiagnostic of the multiple-unused
|
||||||
// form of diagnostic.
|
// form of diagnostic.
|
||||||
impl Subdiagnostic for FormatUnusedArg {
|
impl Subdiagnostic for FormatUnusedArg {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("named", self.named);
|
diag.arg("named", self.named);
|
||||||
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
|
let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg);
|
||||||
diag.span_label(self.span, msg);
|
diag.span_label(self.span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_abi::WrappingRange;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
|
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
|
||||||
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
MultiSpan, Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_hir::ConstContext;
|
use rustc_hir::ConstContext;
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
|
@ -290,11 +290,7 @@ pub struct FrameNote {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for FrameNote {
|
impl Subdiagnostic for FrameNote {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("times", self.times);
|
diag.arg("times", self.times);
|
||||||
diag.arg("where_", self.where_);
|
diag.arg("where_", self.where_);
|
||||||
diag.arg("instance", self.instance);
|
diag.arg("instance", self.instance);
|
||||||
|
@ -302,7 +298,7 @@ impl Subdiagnostic for FrameNote {
|
||||||
if self.has_label && !self.span.is_dummy() {
|
if self.has_label && !self.span.is_dummy() {
|
||||||
span.push_span_label(self.span, fluent::const_eval_frame_note_last);
|
span.push_span_label(self.span, fluent::const_eval_frame_note_last);
|
||||||
}
|
}
|
||||||
let msg = f(diag, fluent::const_eval_frame_note.into());
|
let msg = diag.eagerly_translate(fluent::const_eval_frame_note);
|
||||||
diag.span_note(span, msg);
|
diag.span_note(span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,22 +181,9 @@ where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
/// Add a subdiagnostic to an existing diagnostic.
|
/// Add a subdiagnostic to an existing diagnostic.
|
||||||
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>);
|
||||||
self.add_to_diag_with(diag, &|_, m| m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
|
|
||||||
/// (to optionally perform eager translation).
|
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SubdiagMessageOp<G: EmissionGuarantee> =
|
|
||||||
Fn(&mut Diag<'_, G>, SubdiagMessage) -> SubdiagMessage;
|
|
||||||
|
|
||||||
/// Trait implemented by lint types. This should not be implemented manually. Instead, use
|
/// Trait implemented by lint types. This should not be implemented manually. Instead, use
|
||||||
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
|
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
|
||||||
#[rustc_diagnostic_item = "LintDiagnostic"]
|
#[rustc_diagnostic_item = "LintDiagnostic"]
|
||||||
|
@ -1227,15 +1214,21 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// interpolated variables).
|
/// interpolated variables).
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self {
|
pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self {
|
||||||
let dcx = self.dcx;
|
subdiagnostic.add_to_diag(self);
|
||||||
subdiagnostic.add_to_diag_with(self, &|diag, msg| {
|
|
||||||
let args = diag.args.iter();
|
|
||||||
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
|
|
||||||
dcx.eagerly_translate(msg, args)
|
|
||||||
});
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fluent variables are not namespaced from each other, so when
|
||||||
|
/// `Diagnostic`s and `Subdiagnostic`s use the same variable name,
|
||||||
|
/// one value will clobber the other. Eagerly translating the
|
||||||
|
/// diagnostic uses the variables defined right then, before the
|
||||||
|
/// clobbering occurs.
|
||||||
|
pub fn eagerly_translate(&self, msg: impl Into<SubdiagMessage>) -> SubdiagMessage {
|
||||||
|
let args = self.args.iter();
|
||||||
|
let msg = self.subdiagnostic_message_to_diagnostic_message(msg.into());
|
||||||
|
self.dcx.eagerly_translate(msg, args)
|
||||||
|
}
|
||||||
|
|
||||||
with_fn! { with_span,
|
with_fn! { with_span,
|
||||||
/// Add a span.
|
/// Add a span.
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
|
|
|
@ -19,7 +19,7 @@ use {rustc_ast as ast, rustc_hir as hir};
|
||||||
use crate::diagnostic::DiagLocation;
|
use crate::diagnostic::DiagLocation;
|
||||||
use crate::{
|
use crate::{
|
||||||
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level,
|
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level,
|
||||||
SubdiagMessageOp, Subdiagnostic, fluent_generated as fluent,
|
Subdiagnostic, fluent_generated as fluent,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
|
pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
|
||||||
|
@ -384,11 +384,7 @@ pub struct SingleLabelManySpans {
|
||||||
pub label: &'static str,
|
pub label: &'static str,
|
||||||
}
|
}
|
||||||
impl Subdiagnostic for SingleLabelManySpans {
|
impl Subdiagnostic for SingleLabelManySpans {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
diag.span_labels(self.spans, self.label);
|
diag.span_labels(self.spans, self.label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub use codes::*;
|
||||||
pub use diagnostic::{
|
pub use diagnostic::{
|
||||||
BugAbort, Diag, DiagArg, DiagArgMap, DiagArgName, DiagArgValue, DiagInner, DiagStyledString,
|
BugAbort, Diag, DiagArg, DiagArgMap, DiagArgName, DiagArgValue, DiagInner, DiagStyledString,
|
||||||
Diagnostic, EmissionGuarantee, FatalAbort, IntoDiagArg, LintDiagnostic, StringPart, Subdiag,
|
Diagnostic, EmissionGuarantee, FatalAbort, IntoDiagArg, LintDiagnostic, StringPart, Subdiag,
|
||||||
SubdiagMessageOp, Subdiagnostic,
|
Subdiagnostic,
|
||||||
};
|
};
|
||||||
pub use diagnostic_impls::{
|
pub use diagnostic_impls::{
|
||||||
DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
|
DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
|
||||||
|
|
|
@ -95,6 +95,8 @@ declare_features! (
|
||||||
(accepted, c_unwind, "1.81.0", Some(74990)),
|
(accepted, c_unwind, "1.81.0", Some(74990)),
|
||||||
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
|
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
|
||||||
(accepted, cfg_attr_multi, "1.33.0", Some(54881)),
|
(accepted, cfg_attr_multi, "1.33.0", Some(54881)),
|
||||||
|
/// Allows the use of `#[cfg(<true/false>)]`.
|
||||||
|
(accepted, cfg_boolean_literals, "CURRENT_RUSTC_VERSION", Some(131204)),
|
||||||
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
|
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
|
||||||
(accepted, cfg_doctest, "1.40.0", Some(62210)),
|
(accepted, cfg_doctest, "1.40.0", Some(62210)),
|
||||||
/// Enables `#[cfg(panic = "...")]` config key.
|
/// Enables `#[cfg(panic = "...")]` config key.
|
||||||
|
|
|
@ -391,8 +391,6 @@ declare_features! (
|
||||||
(unstable, async_trait_bounds, "1.85.0", Some(62290)),
|
(unstable, async_trait_bounds, "1.85.0", Some(62290)),
|
||||||
/// Allows using C-variadics.
|
/// Allows using C-variadics.
|
||||||
(unstable, c_variadic, "1.34.0", Some(44930)),
|
(unstable, c_variadic, "1.34.0", Some(44930)),
|
||||||
/// Allows the use of `#[cfg(<true/false>)]`.
|
|
||||||
(unstable, cfg_boolean_literals, "1.83.0", Some(131204)),
|
|
||||||
/// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
|
/// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
|
||||||
(unstable, cfg_contract_checks, "1.86.0", Some(128044)),
|
(unstable, cfg_contract_checks, "1.86.0", Some(128044)),
|
||||||
/// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
|
/// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::borrow::Cow;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
|
Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
|
||||||
SubdiagMessageOp, Subdiagnostic,
|
Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
@ -270,11 +270,7 @@ pub(crate) struct SuggestAnnotations {
|
||||||
pub suggestions: Vec<SuggestAnnotation>,
|
pub suggestions: Vec<SuggestAnnotation>,
|
||||||
}
|
}
|
||||||
impl Subdiagnostic for SuggestAnnotations {
|
impl Subdiagnostic for SuggestAnnotations {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
if self.suggestions.is_empty() {
|
if self.suggestions.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -337,11 +333,7 @@ pub(crate) struct TypeMismatchFruTypo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for TypeMismatchFruTypo {
|
impl Subdiagnostic for TypeMismatchFruTypo {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
|
diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
|
||||||
|
|
||||||
// Only explain that `a ..b` is a range if it's split up
|
// Only explain that `a ..b` is a range if it's split up
|
||||||
|
@ -599,11 +591,7 @@ pub(crate) struct RemoveSemiForCoerce {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for RemoveSemiForCoerce {
|
impl Subdiagnostic for RemoveSemiForCoerce {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let mut multispan: MultiSpan = self.semi.into();
|
let mut multispan: MultiSpan = self.semi.into();
|
||||||
multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
|
multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
|
||||||
multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
|
multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
|
||||||
|
@ -778,20 +766,16 @@ pub(crate) enum CastUnknownPointerSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
|
impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
CastUnknownPointerSub::To(span) => {
|
CastUnknownPointerSub::To(span) => {
|
||||||
let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);
|
let msg = diag.eagerly_translate(fluent::hir_typeck_label_to);
|
||||||
diag.span_label(span, msg);
|
diag.span_label(span, msg);
|
||||||
let msg = f(diag, crate::fluent_generated::hir_typeck_note);
|
let msg = diag.eagerly_translate(fluent::hir_typeck_note);
|
||||||
diag.note(msg);
|
diag.note(msg);
|
||||||
}
|
}
|
||||||
CastUnknownPointerSub::From(span) => {
|
CastUnknownPointerSub::From(span) => {
|
||||||
let msg = f(diag, crate::fluent_generated::hir_typeck_label_from);
|
let msg = diag.eagerly_translate(fluent::hir_typeck_label_from);
|
||||||
diag.span_label(span, msg);
|
diag.span_label(span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic};
|
use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_session::lint::Level;
|
use rustc_session::lint::Level;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
@ -26,11 +26,7 @@ pub(crate) enum OverruledAttributeSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for OverruledAttributeSub {
|
impl Subdiagnostic for OverruledAttributeSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
OverruledAttributeSub::DefaultSource { id } => {
|
OverruledAttributeSub::DefaultSource { id } => {
|
||||||
diag.note(fluent::lint_default_source);
|
diag.note(fluent::lint_default_source);
|
||||||
|
|
|
@ -3,9 +3,7 @@ use std::ops::ControlFlow;
|
||||||
|
|
||||||
use hir::intravisit::{self, Visitor};
|
use hir::intravisit::{self, Visitor};
|
||||||
use rustc_ast::Recovered;
|
use rustc_ast::Recovered;
|
||||||
use rustc_errors::{
|
use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic, SuggestionStyle};
|
||||||
Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
|
|
||||||
};
|
|
||||||
use rustc_hir::{self as hir, HirIdSet};
|
use rustc_hir::{self as hir, HirIdSet};
|
||||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::adjustment::Adjust;
|
use rustc_middle::ty::adjustment::Adjust;
|
||||||
|
@ -327,11 +325,7 @@ struct IfLetRescopeRewrite {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for IfLetRescopeRewrite {
|
impl Subdiagnostic for IfLetRescopeRewrite {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
let mut suggestions = vec![];
|
let mut suggestions = vec![];
|
||||||
for match_head in self.match_heads {
|
for match_head in self.match_heads {
|
||||||
match match_head {
|
match match_head {
|
||||||
|
@ -360,7 +354,7 @@ impl Subdiagnostic for IfLetRescopeRewrite {
|
||||||
.chain(repeat('}').take(closing_brackets.count))
|
.chain(repeat('}').take(closing_brackets.count))
|
||||||
.collect(),
|
.collect(),
|
||||||
));
|
));
|
||||||
let msg = f(diag, crate::fluent_generated::lint_suggestion);
|
let msg = diag.eagerly_translate(crate::fluent_generated::lint_suggestion);
|
||||||
diag.multipart_suggestion_with_style(
|
diag.multipart_suggestion_with_style(
|
||||||
msg,
|
msg,
|
||||||
suggestions,
|
suggestions,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_abi::ExternAbi;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
|
Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
|
||||||
EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
|
EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle,
|
||||||
};
|
};
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
@ -449,11 +449,7 @@ pub(crate) struct BuiltinUnpermittedTypeInitSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for BuiltinUnpermittedTypeInitSub {
|
impl Subdiagnostic for BuiltinUnpermittedTypeInitSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let mut err = self.err;
|
let mut err = self.err;
|
||||||
loop {
|
loop {
|
||||||
if let Some(span) = err.span {
|
if let Some(span) = err.span {
|
||||||
|
@ -504,11 +500,7 @@ pub(crate) struct BuiltinClashingExternSub<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for BuiltinClashingExternSub<'_> {
|
impl Subdiagnostic for BuiltinClashingExternSub<'_> {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let mut expected_str = DiagStyledString::new();
|
let mut expected_str = DiagStyledString::new();
|
||||||
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
||||||
let mut found_str = DiagStyledString::new();
|
let mut found_str = DiagStyledString::new();
|
||||||
|
@ -824,11 +816,7 @@ pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
|
impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
for (c, span) in self.spans {
|
for (c, span) in self.spans {
|
||||||
diag.span_label(span, format!("{c:?}"));
|
diag.span_label(span, format!("{c:?}"));
|
||||||
}
|
}
|
||||||
|
@ -842,11 +830,7 @@ pub(crate) enum HiddenUnicodeCodepointsDiagSub {
|
||||||
|
|
||||||
// Used because of multiple multipart_suggestion and note
|
// Used because of multiple multipart_suggestion and note
|
||||||
impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
|
impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
|
HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
|
||||||
diag.multipart_suggestion_with_style(
|
diag.multipart_suggestion_with_style(
|
||||||
|
@ -1015,11 +999,7 @@ pub(crate) struct NonBindingLetSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for NonBindingLetSub {
|
impl Subdiagnostic for NonBindingLetSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
|
let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
|
||||||
|
|
||||||
if can_suggest_binding {
|
if can_suggest_binding {
|
||||||
|
@ -1303,11 +1283,7 @@ pub(crate) enum NonSnakeCaseDiagSub {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for NonSnakeCaseDiagSub {
|
impl Subdiagnostic for NonSnakeCaseDiagSub {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
NonSnakeCaseDiagSub::Label { span } => {
|
NonSnakeCaseDiagSub::Label { span } => {
|
||||||
diag.span_label(span, fluent::lint_label);
|
diag.span_label(span, fluent::lint_label);
|
||||||
|
@ -1629,11 +1605,7 @@ pub(crate) enum OverflowingBinHexSign {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for OverflowingBinHexSign {
|
impl Subdiagnostic for OverflowingBinHexSign {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
OverflowingBinHexSign::Positive => {
|
OverflowingBinHexSign::Positive => {
|
||||||
diag.note(fluent::lint_positive_note);
|
diag.note(fluent::lint_positive_note);
|
||||||
|
|
|
@ -20,14 +20,12 @@ use crate::diagnostics::utils::{
|
||||||
/// The central struct for constructing the `add_to_diag` method from an annotated struct.
|
/// The central struct for constructing the `add_to_diag` method from an annotated struct.
|
||||||
pub(crate) struct SubdiagnosticDerive {
|
pub(crate) struct SubdiagnosticDerive {
|
||||||
diag: syn::Ident,
|
diag: syn::Ident,
|
||||||
f: syn::Ident,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubdiagnosticDerive {
|
impl SubdiagnosticDerive {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
let diag = format_ident!("diag");
|
let diag = format_ident!("diag");
|
||||||
let f = format_ident!("f");
|
Self { diag }
|
||||||
Self { diag, f }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_tokens(self, mut structure: Structure<'_>) -> TokenStream {
|
pub(crate) fn into_tokens(self, mut structure: Structure<'_>) -> TokenStream {
|
||||||
|
@ -86,19 +84,16 @@ impl SubdiagnosticDerive {
|
||||||
};
|
};
|
||||||
|
|
||||||
let diag = &self.diag;
|
let diag = &self.diag;
|
||||||
let f = &self.f;
|
|
||||||
|
|
||||||
// FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here?
|
// FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here?
|
||||||
#[allow(keyword_idents_2024)]
|
#[allow(keyword_idents_2024)]
|
||||||
let ret = structure.gen_impl(quote! {
|
let ret = structure.gen_impl(quote! {
|
||||||
gen impl rustc_errors::Subdiagnostic for @Self {
|
gen impl rustc_errors::Subdiagnostic for @Self {
|
||||||
fn add_to_diag_with<__G, __F>(
|
fn add_to_diag<__G>(
|
||||||
self,
|
self,
|
||||||
#diag: &mut rustc_errors::Diag<'_, __G>,
|
#diag: &mut rustc_errors::Diag<'_, __G>,
|
||||||
#f: &__F
|
|
||||||
) where
|
) where
|
||||||
__G: rustc_errors::EmissionGuarantee,
|
__G: rustc_errors::EmissionGuarantee,
|
||||||
__F: rustc_errors::SubdiagMessageOp<__G>,
|
|
||||||
{
|
{
|
||||||
#implementation
|
#implementation
|
||||||
}
|
}
|
||||||
|
@ -384,11 +379,10 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
||||||
Ok(quote! {})
|
Ok(quote! {})
|
||||||
}
|
}
|
||||||
"subdiagnostic" => {
|
"subdiagnostic" => {
|
||||||
let f = &self.parent.f;
|
|
||||||
let diag = &self.parent.diag;
|
let diag = &self.parent.diag;
|
||||||
let binding = &info.binding;
|
let binding = &info.binding;
|
||||||
self.has_subdiagnostic = true;
|
self.has_subdiagnostic = true;
|
||||||
Ok(quote! { #binding.add_to_diag_with(#diag, #f); })
|
Ok(quote! { #binding.add_to_diag(#diag); })
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let mut span_attrs = vec![];
|
let mut span_attrs = vec![];
|
||||||
|
@ -531,12 +525,11 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
||||||
let span_field = self.span_field.value_ref();
|
let span_field = self.span_field.value_ref();
|
||||||
|
|
||||||
let diag = &self.parent.diag;
|
let diag = &self.parent.diag;
|
||||||
let f = &self.parent.f;
|
|
||||||
let mut calls = TokenStream::new();
|
let mut calls = TokenStream::new();
|
||||||
for (kind, slug, no_span) in kind_slugs {
|
for (kind, slug, no_span) in kind_slugs {
|
||||||
let message = format_ident!("__message");
|
let message = format_ident!("__message");
|
||||||
calls.extend(
|
calls.extend(
|
||||||
quote! { let #message = #f(#diag, crate::fluent_generated::#slug.into()); },
|
quote! { let #message = #diag.eagerly_translate(crate::fluent_generated::#slug); },
|
||||||
);
|
);
|
||||||
|
|
||||||
let name = format_ident!(
|
let name = format_ident!(
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
||||||
MultiSpan, SubdiagMessageOp, Subdiagnostic, pluralize,
|
MultiSpan, Subdiagnostic, pluralize,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
@ -546,11 +546,7 @@ pub(crate) struct UnsafeNotInheritedLintNote {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for UnsafeNotInheritedLintNote {
|
impl Subdiagnostic for UnsafeNotInheritedLintNote {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body);
|
diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body);
|
||||||
let body_start = self.body_span.shrink_to_lo();
|
let body_start = self.body_span.shrink_to_lo();
|
||||||
let body_end = self.body_span.shrink_to_hi();
|
let body_end = self.body_span.shrink_to_hi();
|
||||||
|
@ -1031,11 +1027,7 @@ pub(crate) struct Variant {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
|
impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("ty", self.ty);
|
diag.arg("ty", self.ty);
|
||||||
let mut spans = MultiSpan::from(self.adt_def_span);
|
let mut spans = MultiSpan::from(self.adt_def_span);
|
||||||
|
|
||||||
|
@ -1117,11 +1109,7 @@ pub(crate) struct Rust2024IncompatiblePatSugg {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
|
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
|
||||||
// means if we have nested spans, the innermost ones will be visited first.
|
// means if we have nested spans, the innermost ones will be visited first.
|
||||||
for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
|
for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
|
||||||
|
|
|
@ -512,23 +512,17 @@ struct LocalLabel<'a> {
|
||||||
|
|
||||||
/// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order
|
/// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order
|
||||||
impl Subdiagnostic for LocalLabel<'_> {
|
impl Subdiagnostic for LocalLabel<'_> {
|
||||||
fn add_to_diag_with<
|
fn add_to_diag<G: rustc_errors::EmissionGuarantee>(self, diag: &mut rustc_errors::Diag<'_, G>) {
|
||||||
G: rustc_errors::EmissionGuarantee,
|
|
||||||
F: rustc_errors::SubdiagMessageOp<G>,
|
|
||||||
>(
|
|
||||||
self,
|
|
||||||
diag: &mut rustc_errors::Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("name", self.name);
|
diag.arg("name", self.name);
|
||||||
diag.arg("is_generated_name", self.is_generated_name);
|
diag.arg("is_generated_name", self.is_generated_name);
|
||||||
diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024);
|
diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024);
|
||||||
let msg = f(diag, crate::fluent_generated::mir_transform_tail_expr_local.into());
|
let msg = diag.eagerly_translate(crate::fluent_generated::mir_transform_tail_expr_local);
|
||||||
diag.span_label(self.span, msg);
|
diag.span_label(self.span, msg);
|
||||||
for dtor in self.destructors {
|
for dtor in self.destructors {
|
||||||
dtor.add_to_diag_with(diag, f);
|
dtor.add_to_diag(diag);
|
||||||
}
|
}
|
||||||
let msg = f(diag, crate::fluent_generated::mir_transform_label_local_epilogue);
|
let msg =
|
||||||
|
diag.eagerly_translate(crate::fluent_generated::mir_transform_label_local_epilogue);
|
||||||
diag.span_label(self.span, msg);
|
diag.span_label(self.span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,7 @@ use rustc_ast::util::parser::ExprPrecedence;
|
||||||
use rustc_ast::{Path, Visibility};
|
use rustc_ast::{Path, Visibility};
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, SubdiagMessageOp,
|
Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic,
|
||||||
Subdiagnostic,
|
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
|
@ -1550,11 +1549,7 @@ pub(crate) struct FnTraitMissingParen {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for FnTraitMissingParen {
|
impl Subdiagnostic for FnTraitMissingParen {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
|
diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
|
||||||
diag.span_suggestion_short(
|
diag.span_suggestion_short(
|
||||||
self.span.shrink_to_hi(),
|
self.span.shrink_to_hi(),
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_ast::Label;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
|
Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
|
||||||
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
MultiSpan, Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_hir::{self as hir, ExprKind, Target};
|
use rustc_hir::{self as hir, ExprKind, Target};
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
|
@ -1852,11 +1852,7 @@ pub(crate) struct UnusedVariableStringInterp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for UnusedVariableStringInterp {
|
impl Subdiagnostic for UnusedVariableStringInterp {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation);
|
diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation);
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
crate::fluent_generated::passes_string_interpolation_only_works,
|
crate::fluent_generated::passes_string_interpolation_only_works,
|
||||||
|
|
|
@ -1020,7 +1020,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Call(ref f, args) => {
|
hir::ExprKind::Call(ref f, args) => {
|
||||||
let succ = self.check_is_ty_uninhabited(expr, succ);
|
let is_ctor = |f: &Expr<'_>| matches!(f.kind, hir::ExprKind::Path(hir::QPath::Resolved(_, path)) if matches!(path.res, rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Ctor(_, _), _)));
|
||||||
|
let succ =
|
||||||
|
if !is_ctor(f) { self.check_is_ty_uninhabited(expr, succ) } else { succ };
|
||||||
|
|
||||||
let succ = self.propagate_through_exprs(args, succ);
|
let succ = self.propagate_through_exprs(args, succ);
|
||||||
self.propagate_through_expr(f, succ)
|
self.propagate_through_expr(f, succ)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustc_errors::{Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic};
|
use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic};
|
||||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -55,11 +55,7 @@ pub struct Overlap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for Overlap {
|
impl Subdiagnostic for Overlap {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
let Overlap { span, range } = self;
|
let Overlap { span, range } = self;
|
||||||
|
|
||||||
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
||||||
|
@ -103,11 +99,7 @@ pub struct GappedRange {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for GappedRange {
|
impl Subdiagnostic for GappedRange {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_: &F,
|
|
||||||
) {
|
|
||||||
let GappedRange { span, gap, first_range } = self;
|
let GappedRange { span, gap, first_range } = self;
|
||||||
|
|
||||||
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
|
Applicability, Diag, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
|
||||||
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
|
@ -107,11 +107,7 @@ pub enum AdjustSignatureBorrow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for AdjustSignatureBorrow {
|
impl Subdiagnostic for AdjustSignatureBorrow {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
AdjustSignatureBorrow::Borrow { to_borrow } => {
|
AdjustSignatureBorrow::Borrow { to_borrow } => {
|
||||||
diag.arg("len", to_borrow.len());
|
diag.arg("len", to_borrow.len());
|
||||||
|
@ -381,11 +377,7 @@ pub enum RegionOriginNote<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for RegionOriginNote<'_> {
|
impl Subdiagnostic for RegionOriginNote<'_> {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let mut label_or_note = |span, msg: DiagMessage| {
|
let mut label_or_note = |span, msg: DiagMessage| {
|
||||||
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
|
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
|
||||||
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
|
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
|
||||||
|
@ -446,11 +438,7 @@ pub enum LifetimeMismatchLabels {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for LifetimeMismatchLabels {
|
impl Subdiagnostic for LifetimeMismatchLabels {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
|
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
|
||||||
diag.span_label(param_span, fluent::trait_selection_declared_different);
|
diag.span_label(param_span, fluent::trait_selection_declared_different);
|
||||||
|
@ -495,11 +483,7 @@ pub struct AddLifetimeParamsSuggestion<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let mut mk_suggestion = || {
|
let mut mk_suggestion = || {
|
||||||
let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub)
|
let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub)
|
||||||
else {
|
else {
|
||||||
|
@ -689,11 +673,7 @@ pub struct IntroducesStaticBecauseUnmetLifetimeReq {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
|
impl Subdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(mut self, diag: &mut Diag<'_, G>) {
|
||||||
mut self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
self.unmet_requirements
|
self.unmet_requirements
|
||||||
.push_span_label(self.binding_span, fluent::trait_selection_msl_introduces_static);
|
.push_span_label(self.binding_span, fluent::trait_selection_msl_introduces_static);
|
||||||
diag.span_note(self.unmet_requirements, fluent::trait_selection_msl_unmet_req);
|
diag.span_note(self.unmet_requirements, fluent::trait_selection_msl_unmet_req);
|
||||||
|
@ -1008,17 +988,13 @@ pub struct ConsiderBorrowingParamHelp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for ConsiderBorrowingParamHelp {
|
impl Subdiagnostic for ConsiderBorrowingParamHelp {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
let mut type_param_span: MultiSpan = self.spans.clone().into();
|
let mut type_param_span: MultiSpan = self.spans.clone().into();
|
||||||
for &span in &self.spans {
|
for &span in &self.spans {
|
||||||
// Seems like we can't call f() here as Into<DiagMessage> is required
|
// Seems like we can't call f() here as Into<DiagMessage> is required
|
||||||
type_param_span.push_span_label(span, fluent::trait_selection_tid_consider_borrowing);
|
type_param_span.push_span_label(span, fluent::trait_selection_tid_consider_borrowing);
|
||||||
}
|
}
|
||||||
let msg = f(diag, fluent::trait_selection_tid_param_help.into());
|
let msg = diag.eagerly_translate(fluent::trait_selection_tid_param_help);
|
||||||
diag.span_help(type_param_span, msg);
|
diag.span_help(type_param_span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1053,18 +1029,14 @@ pub struct DynTraitConstraintSuggestion {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for DynTraitConstraintSuggestion {
|
impl Subdiagnostic for DynTraitConstraintSuggestion {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
let mut multi_span: MultiSpan = vec![self.span].into();
|
let mut multi_span: MultiSpan = vec![self.span].into();
|
||||||
multi_span.push_span_label(self.span, fluent::trait_selection_dtcs_has_lifetime_req_label);
|
multi_span.push_span_label(self.span, fluent::trait_selection_dtcs_has_lifetime_req_label);
|
||||||
multi_span
|
multi_span
|
||||||
.push_span_label(self.ident.span, fluent::trait_selection_dtcs_introduces_requirement);
|
.push_span_label(self.ident.span, fluent::trait_selection_dtcs_introduces_requirement);
|
||||||
let msg = f(diag, fluent::trait_selection_dtcs_has_req_note.into());
|
let msg = diag.eagerly_translate(fluent::trait_selection_dtcs_has_req_note);
|
||||||
diag.span_note(multi_span, msg);
|
diag.span_note(multi_span, msg);
|
||||||
let msg = f(diag, fluent::trait_selection_dtcs_suggestion.into());
|
let msg = diag.eagerly_translate(fluent::trait_selection_dtcs_suggestion);
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
self.span.shrink_to_hi(),
|
self.span.shrink_to_hi(),
|
||||||
msg,
|
msg,
|
||||||
|
@ -1101,11 +1073,7 @@ pub struct ReqIntroducedLocations {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for ReqIntroducedLocations {
|
impl Subdiagnostic for ReqIntroducedLocations {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(mut self, diag: &mut Diag<'_, G>) {
|
||||||
mut self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
for sp in self.spans {
|
for sp in self.spans {
|
||||||
self.span.push_span_label(sp, fluent::trait_selection_ril_introduced_here);
|
self.span.push_span_label(sp, fluent::trait_selection_ril_introduced_here);
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1082,7 @@ impl Subdiagnostic for ReqIntroducedLocations {
|
||||||
self.span.push_span_label(self.fn_decl_span, fluent::trait_selection_ril_introduced_by);
|
self.span.push_span_label(self.fn_decl_span, fluent::trait_selection_ril_introduced_by);
|
||||||
}
|
}
|
||||||
self.span.push_span_label(self.cause_span, fluent::trait_selection_ril_because_of);
|
self.span.push_span_label(self.cause_span, fluent::trait_selection_ril_because_of);
|
||||||
let msg = f(diag, fluent::trait_selection_ril_static_introduced_by.into());
|
let msg = diag.eagerly_translate(fluent::trait_selection_ril_static_introduced_by);
|
||||||
diag.span_note(self.span, msg);
|
diag.span_note(self.span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1513,13 +1481,9 @@ pub struct SuggestTuplePatternMany {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for SuggestTuplePatternMany {
|
impl Subdiagnostic for SuggestTuplePatternMany {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("path", self.path);
|
diag.arg("path", self.path);
|
||||||
let message = f(diag, crate::fluent_generated::trait_selection_stp_wrap_many.into());
|
let message = diag.eagerly_translate(fluent::trait_selection_stp_wrap_many);
|
||||||
diag.multipart_suggestions(
|
diag.multipart_suggestions(
|
||||||
message,
|
message,
|
||||||
self.compatible_variants.into_iter().map(|variant| {
|
self.compatible_variants.into_iter().map(|variant| {
|
||||||
|
@ -1752,11 +1716,7 @@ pub struct AddPreciseCapturingAndParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for AddPreciseCapturingAndParams {
|
impl Subdiagnostic for AddPreciseCapturingAndParams {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("new_lifetime", self.new_lifetime);
|
diag.arg("new_lifetime", self.new_lifetime);
|
||||||
diag.multipart_suggestion_verbose(
|
diag.multipart_suggestion_verbose(
|
||||||
fluent::trait_selection_precise_capturing_new_but_apit,
|
fluent::trait_selection_precise_capturing_new_but_apit,
|
||||||
|
@ -1896,11 +1856,7 @@ pub struct AddPreciseCapturingForOvercapture {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for AddPreciseCapturingForOvercapture {
|
impl Subdiagnostic for AddPreciseCapturingForOvercapture {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
_f: &F,
|
|
||||||
) {
|
|
||||||
let applicability = if self.apit_spans.is_empty() {
|
let applicability = if self.apit_spans.is_empty() {
|
||||||
Applicability::MachineApplicable
|
Applicability::MachineApplicable
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
|
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, Subdiagnostic};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
@ -162,17 +162,13 @@ impl RegionExplanation<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subdiagnostic for RegionExplanation<'_> {
|
impl Subdiagnostic for RegionExplanation<'_> {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||||
self,
|
|
||||||
diag: &mut Diag<'_, G>,
|
|
||||||
f: &F,
|
|
||||||
) {
|
|
||||||
diag.arg("pref_kind", self.prefix);
|
diag.arg("pref_kind", self.prefix);
|
||||||
diag.arg("suff_kind", self.suffix);
|
diag.arg("suff_kind", self.suffix);
|
||||||
diag.arg("desc_kind", self.desc.kind);
|
diag.arg("desc_kind", self.desc.kind);
|
||||||
diag.arg("desc_arg", self.desc.arg);
|
diag.arg("desc_arg", self.desc.arg);
|
||||||
|
|
||||||
let msg = f(diag, fluent::trait_selection_region_explanation.into());
|
let msg = diag.eagerly_translate(fluent::trait_selection_region_explanation);
|
||||||
if let Some(span) = self.desc.span {
|
if let Some(span) = self.desc.span {
|
||||||
diag.span_note(span, msg);
|
diag.span_note(span, msg);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,93 +1,115 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::query_context::test::{Def, UltraMinimal};
|
use super::query_context::test::{Def, UltraMinimal};
|
||||||
use crate::maybe_transmutable::MaybeTransmutableQuery;
|
use crate::{Answer, Assume, Reason, layout};
|
||||||
use crate::{Reason, layout};
|
|
||||||
|
type Tree = layout::Tree<Def, !>;
|
||||||
|
type Dfa = layout::Dfa<!>;
|
||||||
|
|
||||||
|
trait Representation {
|
||||||
|
fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Representation for Tree {
|
||||||
|
fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!> {
|
||||||
|
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal)
|
||||||
|
.answer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Representation for Dfa {
|
||||||
|
fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!> {
|
||||||
|
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal)
|
||||||
|
.answer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_transmutable<R: Representation + Clone>(
|
||||||
|
src: &R,
|
||||||
|
dst: &R,
|
||||||
|
assume: Assume,
|
||||||
|
) -> crate::Answer<!> {
|
||||||
|
let src = src.clone();
|
||||||
|
let dst = dst.clone();
|
||||||
|
// The only dimension of the transmutability analysis we want to test
|
||||||
|
// here is the safety analysis. To ensure this, we disable all other
|
||||||
|
// toggleable aspects of the transmutability analysis.
|
||||||
|
R::is_transmutable(src, dst, assume)
|
||||||
|
}
|
||||||
|
|
||||||
mod safety {
|
mod safety {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Answer;
|
use crate::Answer;
|
||||||
|
|
||||||
type Tree = layout::Tree<Def, !>;
|
|
||||||
|
|
||||||
const DST_HAS_SAFETY_INVARIANTS: Answer<!> =
|
const DST_HAS_SAFETY_INVARIANTS: Answer<!> =
|
||||||
Answer::No(crate::Reason::DstMayHaveSafetyInvariants);
|
Answer::No(crate::Reason::DstMayHaveSafetyInvariants);
|
||||||
|
|
||||||
fn is_transmutable(src: &Tree, dst: &Tree, assume_safety: bool) -> crate::Answer<!> {
|
|
||||||
let src = src.clone();
|
|
||||||
let dst = dst.clone();
|
|
||||||
// The only dimension of the transmutability analysis we want to test
|
|
||||||
// here is the safety analysis. To ensure this, we disable all other
|
|
||||||
// toggleable aspects of the transmutability analysis.
|
|
||||||
let assume = crate::Assume {
|
|
||||||
alignment: true,
|
|
||||||
lifetimes: true,
|
|
||||||
validity: true,
|
|
||||||
safety: assume_safety,
|
|
||||||
};
|
|
||||||
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal)
|
|
||||||
.answer()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn src_safe_dst_safe() {
|
fn src_safe_dst_safe() {
|
||||||
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
||||||
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
||||||
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
|
assert_eq!(is_transmutable(&src, &dst, Assume::default()), Answer::Yes);
|
||||||
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
|
assert_eq!(
|
||||||
|
is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }),
|
||||||
|
Answer::Yes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn src_safe_dst_unsafe() {
|
fn src_safe_dst_unsafe() {
|
||||||
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
||||||
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
||||||
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
|
assert_eq!(is_transmutable(&src, &dst, Assume::default()), DST_HAS_SAFETY_INVARIANTS);
|
||||||
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
|
assert_eq!(
|
||||||
|
is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }),
|
||||||
|
Answer::Yes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn src_unsafe_dst_safe() {
|
fn src_unsafe_dst_safe() {
|
||||||
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
||||||
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
|
||||||
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
|
assert_eq!(is_transmutable(&src, &dst, Assume::default()), Answer::Yes);
|
||||||
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
|
assert_eq!(
|
||||||
|
is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }),
|
||||||
|
Answer::Yes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn src_unsafe_dst_unsafe() {
|
fn src_unsafe_dst_unsafe() {
|
||||||
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
||||||
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
|
||||||
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
|
assert_eq!(is_transmutable(&src, &dst, Assume::default()), DST_HAS_SAFETY_INVARIANTS);
|
||||||
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
|
assert_eq!(
|
||||||
|
is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }),
|
||||||
|
Answer::Yes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod bool {
|
mod bool {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Answer;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_permit_identity_transmutation_tree() {
|
fn should_permit_identity_transmutation_tree() {
|
||||||
let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
|
let src = Tree::bool();
|
||||||
layout::Tree::<Def, !>::bool(),
|
assert_eq!(is_transmutable(&src, &src, Assume::default()), Answer::Yes);
|
||||||
layout::Tree::<Def, !>::bool(),
|
assert_eq!(
|
||||||
crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
|
is_transmutable(&src, &src, Assume { validity: true, ..Assume::default() }),
|
||||||
UltraMinimal,
|
Answer::Yes
|
||||||
)
|
);
|
||||||
.answer();
|
|
||||||
assert_eq!(answer, Answer::Yes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_permit_identity_transmutation_dfa() {
|
fn should_permit_identity_transmutation_dfa() {
|
||||||
let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
|
let src = Dfa::bool();
|
||||||
layout::Dfa::<!>::bool(),
|
assert_eq!(is_transmutable(&src, &src, Assume::default()), Answer::Yes);
|
||||||
layout::Dfa::<!>::bool(),
|
assert_eq!(
|
||||||
crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
|
is_transmutable(&src, &src, Assume { validity: true, ..Assume::default() }),
|
||||||
UltraMinimal,
|
Answer::Yes
|
||||||
)
|
);
|
||||||
.answer();
|
|
||||||
assert_eq!(answer, Answer::Yes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -122,13 +144,7 @@ mod bool {
|
||||||
if src_set.is_subset(&dst_set) {
|
if src_set.is_subset(&dst_set) {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Answer::Yes,
|
Answer::Yes,
|
||||||
MaybeTransmutableQuery::new(
|
is_transmutable(&src_layout, &dst_layout, Assume::default()),
|
||||||
src_layout.clone(),
|
|
||||||
dst_layout.clone(),
|
|
||||||
crate::Assume { validity: false, ..crate::Assume::default() },
|
|
||||||
UltraMinimal,
|
|
||||||
)
|
|
||||||
.answer(),
|
|
||||||
"{:?} SHOULD be transmutable into {:?}",
|
"{:?} SHOULD be transmutable into {:?}",
|
||||||
src_layout,
|
src_layout,
|
||||||
dst_layout
|
dst_layout
|
||||||
|
@ -136,13 +152,11 @@ mod bool {
|
||||||
} else if !src_set.is_disjoint(&dst_set) {
|
} else if !src_set.is_disjoint(&dst_set) {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Answer::Yes,
|
Answer::Yes,
|
||||||
MaybeTransmutableQuery::new(
|
is_transmutable(
|
||||||
src_layout.clone(),
|
&src_layout,
|
||||||
dst_layout.clone(),
|
&dst_layout,
|
||||||
crate::Assume { validity: true, ..crate::Assume::default() },
|
Assume { validity: true, ..Assume::default() }
|
||||||
UltraMinimal,
|
),
|
||||||
)
|
|
||||||
.answer(),
|
|
||||||
"{:?} SHOULD be transmutable (assuming validity) into {:?}",
|
"{:?} SHOULD be transmutable (assuming validity) into {:?}",
|
||||||
src_layout,
|
src_layout,
|
||||||
dst_layout
|
dst_layout
|
||||||
|
@ -150,13 +164,7 @@ mod bool {
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Answer::No(Reason::DstIsBitIncompatible),
|
Answer::No(Reason::DstIsBitIncompatible),
|
||||||
MaybeTransmutableQuery::new(
|
is_transmutable(&src_layout, &dst_layout, Assume::default()),
|
||||||
src_layout.clone(),
|
|
||||||
dst_layout.clone(),
|
|
||||||
crate::Assume { validity: false, ..crate::Assume::default() },
|
|
||||||
UltraMinimal,
|
|
||||||
)
|
|
||||||
.answer(),
|
|
||||||
"{:?} should NOT be transmutable into {:?}",
|
"{:?} should NOT be transmutable into {:?}",
|
||||||
src_layout,
|
src_layout,
|
||||||
dst_layout
|
dst_layout
|
||||||
|
|
0
diff
Normal file
0
diff
Normal file
14
src/doc/unstable-book/src/compiler-flags/allow-features.md
Normal file
14
src/doc/unstable-book/src/compiler-flags/allow-features.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# `allow-features`
|
||||||
|
|
||||||
|
This feature is perma-unstable and has no tracking issue.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
This flag allows limiting the features which can be enabled with `#![feature(...)]` attributes.
|
||||||
|
By default, all features are allowed on nightly and no features are allowed on stable or beta (but see [`RUSTC_BOOTSTRAP`]).
|
||||||
|
|
||||||
|
Features are comma-separated, for example `-Z allow-features=ffi_pure,f16`.
|
||||||
|
If the flag is present, any feature listed will be allowed and any feature not listed will be disallowed.
|
||||||
|
Any unrecognized feature is ignored.
|
||||||
|
|
||||||
|
[`RUSTC_BOOTSTRAP`]: ./rustc-bootstrap.html
|
56
src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
Normal file
56
src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# `RUSTC_BOOTSTRAP`
|
||||||
|
|
||||||
|
This feature is perma-unstable and has no tracking issue.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
The `RUSTC_BOOTSTRAP` environment variable tells rustc to act as if it is a nightly compiler;
|
||||||
|
in particular, it allows `#![feature(...)]` attributes and `-Z` flags even on the stable release channel.
|
||||||
|
|
||||||
|
Setting `RUSTC_BOOTSTRAP=1` instructs rustc to enable this for all crates.
|
||||||
|
Setting `RUSTC_BOOTSTRAP=crate_name` instructs rustc to only apply this to crates named `crate_name`.
|
||||||
|
Setting `RUSTC_BOOTSTRAP=-1` instructs rustc to act as if it is a stable compiler, even on the nightly release channel.
|
||||||
|
Cargo disallows setting `cargo::rustc-env=RUSTC_BOOTSTRAP` in build scripts.
|
||||||
|
Build systems can limit the features they enable with [`-Z allow-features=feature1,feature2`][Z-allow-features].
|
||||||
|
Crates can fully opt out of unstable features by using [`#![forbid(unstable_features)]`][unstable-features] at the crate root (or any other way of enabling lints, such as `-F unstable-features`).
|
||||||
|
|
||||||
|
[Z-allow-features]: ./allow-features.html
|
||||||
|
[unstable-features]: ../../rustc/lints/listing/allowed-by-default.html#unstable-features
|
||||||
|
|
||||||
|
## Why does this environment variable exist?
|
||||||
|
|
||||||
|
`RUSTC_BOOTSTRAP`, as the name suggests, is used for bootstrapping the compiler from an earlier version.
|
||||||
|
In particular, nightly is built with beta, and beta is built with stable.
|
||||||
|
Since the standard library and compiler both use unstable features, `RUSTC_BOOTSTRAP` is required so that we can use the previous version to build them.
|
||||||
|
|
||||||
|
## Why is this environment variable so easy to use for people not in the rust project?
|
||||||
|
|
||||||
|
Originally, `RUSTC_BOOTSTRAP` required passing in a hash of the previous compiler version, to discourage using it for any purpose other than bootstrapping.
|
||||||
|
That constraint was later relaxed; see <https://github.com/rust-lang/rust/issues/36548> for the discussion that happened at that time.
|
||||||
|
|
||||||
|
People have at various times proposed re-adding the technical constraints.
|
||||||
|
However, doing so is extremely disruptive for several major projects that we very much want to keep using the latest stable toolchain version, such as Firefox, Rust for Linux, and Chromium.
|
||||||
|
We continue to allow `RUSTC_BOOTSTRAP` until we can come up with an alternative that does not disrupt our largest constituents.
|
||||||
|
|
||||||
|
## Stability policy
|
||||||
|
|
||||||
|
Despite being usable on stable, this is an unstable feature.
|
||||||
|
Like any other unstable feature, we reserve the right to change or remove this feature in the future, as well as any other unstable feature that it enables.
|
||||||
|
Using this feature opts you out of the normal stability/backwards compatibility guarantee of stable.
|
||||||
|
|
||||||
|
Although we do not take technical measures to prevent it from being used, we strongly discourage using this feature.
|
||||||
|
If at all possible, please contribute to stabilizing the features you care about instead of bypassing the Rust project's stability policy.
|
||||||
|
|
||||||
|
For library crates, we especially discourage the use of this feature.
|
||||||
|
The crates depending on you do not know that you use this feature, have little recourse if it breaks, and can be used in contexts that are hard to predict.
|
||||||
|
|
||||||
|
For libraries that do use this feature, please document the versions you support (including a *maximum* as well as minimum version), and a mechanism to disable it.
|
||||||
|
If you do not have a mechanism to disable the use of `RUSTC_BOOTSTRAP`, consider removing its use altogether, such that people can only use your library if they are already using a nightly toolchain.
|
||||||
|
This leaves the choice of whether to opt-out of Rust's stability guarantees up to the end user building their code.
|
||||||
|
|
||||||
|
## History
|
||||||
|
|
||||||
|
- [Allowed without a hash](https://github.com/rust-lang/rust/pull/37265) ([discussion](https://github.com/rust-lang/rust/issues/36548))
|
||||||
|
- [Extended to crate names](https://github.com/rust-lang/rust/pull/77802) ([discussion](https://github.com/rust-lang/cargo/issues/7088))
|
||||||
|
- [Disallowed for build scripts](https://github.com/rust-lang/cargo/pull/9181) ([discussion](https://github.com/rust-lang/compiler-team/issues/350))
|
||||||
|
- [Extended to emulate stable](https://github.com/rust-lang/rust/pull/132993) ([discussion](https://github.com/rust-lang/rust/issues/123404))
|
|
@ -0,0 +1,39 @@
|
||||||
|
# `RUSTC_OVERRIDE_VERSION_STRING`
|
||||||
|
|
||||||
|
This feature is perma-unstable and has no tracking issue.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
The `RUSTC_OVERRIDE_VERSION_STRING` environment variable overrides the version reported by `rustc --version`. For example:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ rustc --version
|
||||||
|
rustc 1.87.0-nightly (43f0014ef 2025-03-25)
|
||||||
|
$ env RUSTC_OVERRIDE_VERSION_STRING=1.81.0-nightly rustc --version
|
||||||
|
rustc 1.81.0-nightly
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the version string is completely overwritten; i.e. rustc discards commit hash and commit date information unless it is explicitly included in the environment variable. The string only applies to the "release" part of the version; for example:
|
||||||
|
```console
|
||||||
|
$ RUSTC_OVERRIDE_VERSION_STRING="1.81.0-nightly (aaaaaaaaa 2025-03-22)" rustc -vV
|
||||||
|
rustc 1.81.0-nightly (aaaaaaaaa 2025-03-22)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: 43f0014ef0f242418674f49052ed39b70f73bc1c
|
||||||
|
commit-date: 2025-03-25
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.81.0-nightly (aaaaaaaaa 2025-03-22)
|
||||||
|
LLVM version: 20.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Note here that `commit-hash` and `commit-date` do not match the values in the string, and `release` includes the fake hash and date.
|
||||||
|
|
||||||
|
This variable has no effect on whether or not unstable features are allowed to be used. It only affects the output of `--version`.
|
||||||
|
|
||||||
|
## Why does this environment variable exist?
|
||||||
|
|
||||||
|
Various library crates have incomplete or incorrect feature detection.
|
||||||
|
This environment variable allows bisecting crates that do incorrect detection with `version_check::supports_feature`.
|
||||||
|
|
||||||
|
This is not intended to be used for any other case (and, except for bisection, is not particularly useful).
|
||||||
|
|
||||||
|
See <https://github.com/rust-lang/rust/pull/124339> for further discussion.
|
|
@ -1,22 +0,0 @@
|
||||||
# `cfg_boolean_literals`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#131204]
|
|
||||||
|
|
||||||
[#131204]: https://github.com/rust-lang/rust/issues/131204
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The `cfg_boolean_literals` feature makes it possible to use the `true`/`false`
|
|
||||||
literal as cfg predicate. They always evaluate to true/false respectively.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(cfg_boolean_literals)]
|
|
||||||
|
|
||||||
#[cfg(true)]
|
|
||||||
const A: i32 = 5;
|
|
||||||
|
|
||||||
#[cfg(all(false))]
|
|
||||||
const A: i32 = 58 * 89;
|
|
||||||
```
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
# `macro_metavar_expr_concat`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#124225]
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
In stable Rust, there is no way to create new identifiers by joining identifiers to literals or other identifiers without using procedural macros such as [`paste`].
|
||||||
|
`#![feature(macro_metavar_expr_concat)]` introduces a way to do this, using the concat metavariable expression.
|
||||||
|
|
||||||
|
> This feature uses the syntax from [`macro_metavar_expr`] but is otherwise
|
||||||
|
> independent. It replaces the old unstable feature [`concat_idents`].
|
||||||
|
|
||||||
|
> This is an experimental feature; it and its syntax will require a RFC before stabilization.
|
||||||
|
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
`#![feature(macro_metavar_expr_concat)]` provides the `concat` metavariable expression for creating new identifiers:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![feature(macro_metavar_expr_concat)]
|
||||||
|
|
||||||
|
macro_rules! create_some_structs {
|
||||||
|
($name:ident) => {
|
||||||
|
pub struct ${ concat(First, $name) };
|
||||||
|
pub struct ${ concat(Second, $name) };
|
||||||
|
pub struct ${ concat(Third, $name) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
create_some_structs!(Thing);
|
||||||
|
```
|
||||||
|
|
||||||
|
This macro invocation expands to:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct FirstThing;
|
||||||
|
pub struct SecondThing;
|
||||||
|
pub struct ThirdThing;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
This feature builds upon the metavariable expression syntax `${ .. }` as specified in [RFC 3086] ([`macro_metavar_expr`]).
|
||||||
|
`concat` is available like `${ concat(items) }`, where `items` is a comma separated sequence of idents and/or literals.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
#### Create a function or method with a concatenated name
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![feature(macro_metavar_expr_concat)]
|
||||||
|
|
||||||
|
macro_rules! make_getter {
|
||||||
|
($name:ident, $field: ident, $ret:ty) => {
|
||||||
|
impl $name {
|
||||||
|
pub fn ${ concat(get_, $field) }(&self) -> &$ret {
|
||||||
|
&self.$field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Thing {
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
make_getter!(Thing, description, String);
|
||||||
|
```
|
||||||
|
|
||||||
|
This expands to:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct Thing {
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Thing {
|
||||||
|
pub fn get_description(&self) -> &String {
|
||||||
|
&self.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Create names for macro generated tests
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![feature(macro_metavar_expr_concat)]
|
||||||
|
|
||||||
|
macro_rules! test_math {
|
||||||
|
($integer:ident) => {
|
||||||
|
#[test]
|
||||||
|
fn ${ concat(test_, $integer, _, addition) } () {
|
||||||
|
let a: $integer = 73;
|
||||||
|
let b: $integer = 42;
|
||||||
|
assert_eq!(a + b, 115)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ${ concat(test_, $integer, _, subtraction) } () {
|
||||||
|
let a: $integer = 73;
|
||||||
|
let b: $integer = 42;
|
||||||
|
assert_eq!(a - b, 31)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_math!(i32);
|
||||||
|
test_math!(u64);
|
||||||
|
test_math!(u128);
|
||||||
|
```
|
||||||
|
|
||||||
|
Running this returns the following output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
running 6 tests
|
||||||
|
test test_i32_subtraction ... ok
|
||||||
|
test test_i32_addition ... ok
|
||||||
|
test test_u128_addition ... ok
|
||||||
|
test test_u128_subtraction ... ok
|
||||||
|
test test_u64_addition ... ok
|
||||||
|
test test_u64_subtraction ... ok
|
||||||
|
|
||||||
|
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||||
|
```
|
||||||
|
|
||||||
|
[`paste`]: https://crates.io/crates/paste
|
||||||
|
[RFC 3086]: https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html
|
||||||
|
[`concat_idents!`]: https://doc.rust-lang.org/nightly/std/macro.concat_idents.html
|
||||||
|
[`macro_metavar_expr`]: ../language-features/macro-metavar-expr.md
|
||||||
|
[`concat_idents`]: ../library-features/concat-idents.md
|
||||||
|
[#124225]: https://github.com/rust-lang/rust/issues/124225
|
||||||
|
[declarative macros]: https://doc.rust-lang.org/stable/reference/macros-by-example.html
|
|
@ -0,0 +1,10 @@
|
||||||
|
# `macro_metavar_expr`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#83527]
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
> This feature is not to be confused with [`macro_metavar_expr_concat`].
|
||||||
|
|
||||||
|
[`macro_metavar_expr_concat`]: ./macro-metavar-expr-concat.md
|
||||||
|
[#83527]: https://github.com/rust-lang/rust/issues/83527
|
|
@ -6,6 +6,8 @@ The tracking issue for this feature is: [#29599]
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
> This feature is expected to be superseded by [`macro_metavar_expr_concat`](../language-features/macro-metavar-expr-concat.md).
|
||||||
|
|
||||||
The `concat_idents` feature adds a macro for concatenating multiple identifiers
|
The `concat_idents` feature adds a macro for concatenating multiple identifiers
|
||||||
into one identifier.
|
into one identifier.
|
||||||
|
|
||||||
|
|
|
@ -3789,35 +3789,6 @@ The tracking issue for this feature is: [#64797]
|
||||||
[#64797]: https://github.com/rust-lang/rust/issues/64797
|
[#64797]: https://github.com/rust-lang/rust/issues/64797
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
"##,
|
|
||||||
default_severity: Severity::Allow,
|
|
||||||
warn_since: None,
|
|
||||||
deny_since: None,
|
|
||||||
},
|
|
||||||
Lint {
|
|
||||||
label: "cfg_boolean_literals",
|
|
||||||
description: r##"# `cfg_boolean_literals`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#131204]
|
|
||||||
|
|
||||||
[#131204]: https://github.com/rust-lang/rust/issues/131204
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The `cfg_boolean_literals` feature makes it possible to use the `true`/`false`
|
|
||||||
literal as cfg predicate. They always evaluate to true/false respectively.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(cfg_boolean_literals)]
|
|
||||||
|
|
||||||
#[cfg(true)]
|
|
||||||
const A: i32 = 5;
|
|
||||||
|
|
||||||
#[cfg(all(false))]
|
|
||||||
const A: i32 = 58 * 89;
|
|
||||||
```
|
|
||||||
"##,
|
"##,
|
||||||
default_severity: Severity::Allow,
|
default_severity: Severity::Allow,
|
||||||
warn_since: None,
|
warn_since: None,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn syntax() {
|
fn syntax() {
|
||||||
let _ = #[attr] [];
|
let _ = #[attr] [];
|
||||||
let _ = #[attr] [0];
|
let _ = #[attr] [0];
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
enum Foo { pub V, }
|
enum Foo { pub V, }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//@ pp-exact
|
//@ pp-exact
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn simple_attr() {
|
fn simple_attr() {
|
||||||
|
|
||||||
#[attr]
|
#[attr]
|
||||||
|
@ -10,21 +10,21 @@ fn simple_attr() {
|
||||||
if true {}
|
if true {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn if_else_chain() {
|
fn if_else_chain() {
|
||||||
|
|
||||||
#[first_attr]
|
#[first_attr]
|
||||||
if true {} else if false {} else {}
|
if true {} else if false {} else {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn if_let() {
|
fn if_let() {
|
||||||
|
|
||||||
#[attr]
|
#[attr]
|
||||||
if let Some(_) = Some(true) {}
|
if let Some(_) = Some(true) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn let_attr_if() {
|
fn let_attr_if() {
|
||||||
let _ = #[attr] if let _ = 0 {};
|
let _ = #[attr] if let _ = 0 {};
|
||||||
let _ = #[attr] if true {};
|
let _ = #[attr] if true {};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static X: u8;
|
static X: u8;
|
||||||
type X;
|
type X;
|
||||||
|
@ -14,7 +14,7 @@ extern "C" {
|
||||||
pub fn foo();
|
pub fn foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
trait T {
|
trait T {
|
||||||
const X: u8;
|
const X: u8;
|
||||||
type X;
|
type X;
|
||||||
|
@ -30,7 +30,7 @@ trait T {
|
||||||
pub default fn foo();
|
pub default fn foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
impl T for S {
|
impl T for S {
|
||||||
const X: u8;
|
const X: u8;
|
||||||
type X;
|
type X;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
#![feature(cfg_boolean_literals)]
|
|
||||||
#![feature(doc_cfg)]
|
#![feature(doc_cfg)]
|
||||||
|
|
||||||
#[doc(cfg(false))]
|
#[doc(cfg(false))]
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
// #138113: rustdoc didn't gate unstable predicates inside `doc(cfg(..))`
|
// #138113: rustdoc didn't gate unstable predicates inside `doc(cfg(..))`
|
||||||
#![feature(doc_cfg)]
|
#![feature(doc_cfg)]
|
||||||
|
|
||||||
// `cfg_boolean_literals`
|
|
||||||
#[doc(cfg(false))] //~ ERROR `cfg(false)` is experimental and subject to change
|
|
||||||
pub fn cfg_boolean_literals() {}
|
|
||||||
|
|
||||||
// `cfg_version`
|
// `cfg_version`
|
||||||
#[doc(cfg(sanitize = "thread"))] //~ ERROR `cfg(sanitize)` is experimental and subject to change
|
#[doc(cfg(sanitize = "thread"))] //~ ERROR `cfg(sanitize)` is experimental and subject to change
|
||||||
pub fn cfg_sanitize() {}
|
pub fn cfg_sanitize() {}
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
error[E0658]: `cfg(false)` is experimental and subject to change
|
|
||||||
--> $DIR/doc-cfg-unstable.rs:5:11
|
|
||||||
|
|
|
||||||
LL | #[doc(cfg(false))]
|
|
||||||
| ^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #131204 <https://github.com/rust-lang/rust/issues/131204> for more information
|
|
||||||
= help: add `#![feature(cfg_boolean_literals)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: `cfg(sanitize)` is experimental and subject to change
|
error[E0658]: `cfg(sanitize)` is experimental and subject to change
|
||||||
--> $DIR/doc-cfg-unstable.rs:9:11
|
--> $DIR/doc-cfg-unstable.rs:5:11
|
||||||
|
|
|
|
||||||
LL | #[doc(cfg(sanitize = "thread"))]
|
LL | #[doc(cfg(sanitize = "thread"))]
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -18,6 +8,6 @@ LL | #[doc(cfg(sanitize = "thread"))]
|
||||||
= help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable
|
= help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate rustc_span;
|
||||||
|
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level,
|
Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level,
|
||||||
LintDiagnostic, SubdiagMessage, SubdiagMessageOp, Subdiagnostic,
|
LintDiagnostic, SubdiagMessage, Subdiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -56,10 +56,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for TranslatableInDiagnostic {
|
||||||
pub struct UntranslatableInAddtoDiag;
|
pub struct UntranslatableInAddtoDiag;
|
||||||
|
|
||||||
impl Subdiagnostic for UntranslatableInAddtoDiag {
|
impl Subdiagnostic for UntranslatableInAddtoDiag {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(
|
||||||
self,
|
self,
|
||||||
diag: &mut Diag<'_, G>,
|
diag: &mut Diag<'_, G>,
|
||||||
f: &F,
|
|
||||||
) {
|
) {
|
||||||
diag.note("untranslatable diagnostic");
|
diag.note("untranslatable diagnostic");
|
||||||
//~^ ERROR diagnostics should be created using translatable messages
|
//~^ ERROR diagnostics should be created using translatable messages
|
||||||
|
@ -69,10 +68,9 @@ impl Subdiagnostic for UntranslatableInAddtoDiag {
|
||||||
pub struct TranslatableInAddtoDiag;
|
pub struct TranslatableInAddtoDiag;
|
||||||
|
|
||||||
impl Subdiagnostic for TranslatableInAddtoDiag {
|
impl Subdiagnostic for TranslatableInAddtoDiag {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag<G: EmissionGuarantee>(
|
||||||
self,
|
self,
|
||||||
diag: &mut Diag<'_, G>,
|
diag: &mut Diag<'_, G>,
|
||||||
f: &F,
|
|
||||||
) {
|
) {
|
||||||
diag.note(crate::fluent_generated::no_crate_note);
|
diag.note(crate::fluent_generated::no_crate_note);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,19 @@ LL | #![deny(rustc::untranslatable_diagnostic)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:64:19
|
--> $DIR/diagnostics.rs:63:19
|
||||||
|
|
|
|
||||||
LL | diag.note("untranslatable diagnostic");
|
LL | diag.note("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:85:19
|
--> $DIR/diagnostics.rs:83:19
|
||||||
|
|
|
|
||||||
LL | diag.note("untranslatable diagnostic");
|
LL | diag.note("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
|
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
|
||||||
--> $DIR/diagnostics.rs:99:21
|
--> $DIR/diagnostics.rs:97:21
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -35,37 +35,37 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
|
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
|
||||||
--> $DIR/diagnostics.rs:102:21
|
--> $DIR/diagnostics.rs:100:21
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:102:32
|
--> $DIR/diagnostics.rs:100:32
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:120:7
|
--> $DIR/diagnostics.rs:118:7
|
||||||
|
|
|
|
||||||
LL | f("untranslatable diagnostic", crate::fluent_generated::no_crate_example);
|
LL | f("untranslatable diagnostic", crate::fluent_generated::no_crate_example);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:122:50
|
--> $DIR/diagnostics.rs:120:50
|
||||||
|
|
|
|
||||||
LL | f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic");
|
LL | f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:124:7
|
--> $DIR/diagnostics.rs:122:7
|
||||||
|
|
|
|
||||||
LL | f("untranslatable diagnostic", "untranslatable diagnostic");
|
LL | f("untranslatable diagnostic", "untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:124:36
|
--> $DIR/diagnostics.rs:122:36
|
||||||
|
|
|
|
||||||
LL | f("untranslatable diagnostic", "untranslatable diagnostic");
|
LL | f("untranslatable diagnostic", "untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//@ needs-asm-support
|
//@ needs-asm-support
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
core::arch::global_asm!("x: .byte 42");
|
core::arch::global_asm!("x: .byte 42");
|
||||||
|
|
|
@ -7,4 +7,5 @@ extern crate std;
|
||||||
//@ needs-asm-support
|
//@ needs-asm-support
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
global_asm! ("x: .byte 42");
|
global_asm! ("x: .byte 42");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
<() as module>::mac!(); //~ ERROR macros cannot use qualified paths
|
<() as module>::mac!(); //~ ERROR macros cannot use qualified paths
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn f() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn g() {
|
fn g() {
|
||||||
let _ = async {
|
let _ = async {
|
||||||
for await _i in core::async_iter::from_iter(0..3) {
|
for await _i in core::async_iter::from_iter(0..3) {
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
impl S {
|
impl S {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
unsafe async fn f() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
unsafe async fn f() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Ensure that `-Z crate-attr=cfg(FALSE)` can comment out the whole crate
|
// Ensure that `-Z crate-attr=cfg(false)` can comment out the whole crate
|
||||||
//@ compile-flags: --crate-type=lib -Zcrate-attr=cfg(FALSE)
|
//@ compile-flags: --crate-type=lib -Zcrate-attr=cfg(false)
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
// NOTE: duplicate items are load-bearing
|
// NOTE: duplicate items are load-bearing
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
auto trait Foo {}
|
auto trait Foo {}
|
||||||
//~^ WARN `auto` traits are unstable
|
//~^ WARN `auto` traits are unstable
|
||||||
//~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
//~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(false)`.
|
||||||
// This crate has no such attribute, therefore this crate does link to libstd.
|
// This crate has no such attribute, therefore this crate does link to libstd.
|
||||||
|
|
||||||
#![cfg(FALSE)]
|
#![cfg(false)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(false)`.
|
||||||
// Therefore this crate does link to libstd.
|
// Therefore this crate does link to libstd.
|
||||||
|
|
||||||
#![cfg(FALSE)]
|
#![cfg(false)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(false)`.
|
||||||
// Therefore this crate doesn't link to libstd.
|
// Therefore this crate doesn't link to libstd.
|
||||||
|
|
||||||
//@ no-prefer-dynamic
|
//@ no-prefer-dynamic
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![cfg(FALSE)]
|
#![cfg(false)]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
pub fn uwu() {}
|
pub fn uwu() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
pub mod doesnt_exist {
|
pub mod doesnt_exist {
|
||||||
pub fn hello() {}
|
pub fn hello() {}
|
||||||
}
|
}
|
||||||
|
|
14
tests/ui/cfg/both-true-false.rs
Normal file
14
tests/ui/cfg/both-true-false.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/// Test that placing a `cfg(true)` and `cfg(false)` on the same item result in
|
||||||
|
//. it being disabled.`
|
||||||
|
|
||||||
|
#[cfg(false)]
|
||||||
|
#[cfg(true)]
|
||||||
|
fn foo() {}
|
||||||
|
|
||||||
|
#[cfg(true)]
|
||||||
|
#[cfg(false)]
|
||||||
|
fn foo() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(); //~ ERROR cannot find function `foo` in this scope
|
||||||
|
}
|
9
tests/ui/cfg/both-true-false.stderr
Normal file
9
tests/ui/cfg/both-true-false.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0425]: cannot find function `foo` in this scope
|
||||||
|
--> $DIR/both-true-false.rs:13:5
|
||||||
|
|
|
||||||
|
LL | foo();
|
||||||
|
| ^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0425`.
|
|
@ -1,10 +1,10 @@
|
||||||
// Features above `cfg(FALSE)` are in effect in a fully unconfigured crate (issue #104633).
|
// Features above `cfg(false)` are in effect in a fully unconfigured crate (issue #104633).
|
||||||
|
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: --crate-type lib
|
//@ compile-flags: --crate-type lib
|
||||||
|
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![cfg(FALSE)]
|
#![cfg(false)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
|
|
||||||
macro mac() {} // OK
|
macro mac() {} // OK
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// check that cfg correctly chooses between the macro impls (see also
|
// check that cfg correctly chooses between the macro impls (see also
|
||||||
// cfg-macros-foo.rs)
|
// cfg-macros-foo.rs)
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod foo {
|
mod foo {
|
||||||
macro_rules! bar {
|
macro_rules! bar {
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn foo(f: Foo) {
|
||||||
Foo::Bar => {},
|
Foo::Bar => {},
|
||||||
#[cfg(not(FALSE))]
|
#[cfg(not(FALSE))]
|
||||||
Foo::Baz => {},
|
Foo::Baz => {},
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
Basdfwe => {}
|
Basdfwe => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#[cfg_eval]
|
#[cfg_eval]
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg_eval]
|
#[cfg_eval]
|
||||||
let _ = #[cfg(FALSE)] 0;
|
let _ = #[cfg(false)] 0;
|
||||||
//~^ ERROR removing an expression is not supported in this position
|
//~^ ERROR removing an expression is not supported in this position
|
||||||
//~| ERROR expected expression, found `;`
|
//~| ERROR expected expression, found `;`
|
||||||
//~| ERROR removing an expression is not supported in this position
|
//~| ERROR removing an expression is not supported in this position
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/cfg-stmt-recovery.rs:9:13
|
--> $DIR/cfg-stmt-recovery.rs:9:13
|
||||||
|
|
|
|
||||||
LL | let _ = #[cfg(FALSE)] 0;
|
LL | let _ = #[cfg(false)] 0;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: expected expression, found `;`
|
error: expected expression, found `;`
|
||||||
--> $DIR/cfg-stmt-recovery.rs:9:28
|
--> $DIR/cfg-stmt-recovery.rs:9:28
|
||||||
|
|
|
|
||||||
LL | let _ = #[cfg(FALSE)] 0;
|
LL | let _ = #[cfg(false)] 0;
|
||||||
| ^ expected expression
|
| ^ expected expression
|
||||||
|
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/cfg-stmt-recovery.rs:9:13
|
--> $DIR/cfg-stmt-recovery.rs:9:13
|
||||||
|
|
|
|
||||||
LL | let _ = #[cfg(FALSE)] 0;
|
LL | let _ = #[cfg(false)] 0;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
|
@ -7,47 +7,47 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = 413;
|
let a = 413;
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
let a = ();
|
let a = ();
|
||||||
assert_eq!(a, 413);
|
assert_eq!(a, 413);
|
||||||
|
|
||||||
let mut b = 612;
|
let mut b = 612;
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
{
|
{
|
||||||
b = 1111;
|
b = 1111;
|
||||||
}
|
}
|
||||||
assert_eq!(b, 612);
|
assert_eq!(b, 612);
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
undefined_fn();
|
undefined_fn();
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
undefined_macro!();
|
undefined_macro!();
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
undefined_macro![];
|
undefined_macro![];
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
undefined_macro!{};
|
undefined_macro!{};
|
||||||
|
|
||||||
// pretty printer bug...
|
// pretty printer bug...
|
||||||
// #[cfg(FALSE)]
|
// #[cfg(false)]
|
||||||
// undefined_macro!{}
|
// undefined_macro!{}
|
||||||
|
|
||||||
let () = (#[cfg(FALSE)] 341,); // Should this also work on parens?
|
let () = (#[cfg(false)] 341,); // Should this also work on parens?
|
||||||
let t = (1, #[cfg(FALSE)] 3, 4);
|
let t = (1, #[cfg(false)] 3, 4);
|
||||||
assert_eq!(t, (1, 4));
|
assert_eq!(t, (1, 4));
|
||||||
|
|
||||||
let f = |_: u32, _: u32| ();
|
let f = |_: u32, _: u32| ();
|
||||||
f(2, 1, #[cfg(FALSE)] 6);
|
f(2, 1, #[cfg(false)] 6);
|
||||||
|
|
||||||
let _: u32 = a.clone(#[cfg(FALSE)] undefined);
|
let _: u32 = a.clone(#[cfg(false)] undefined);
|
||||||
|
|
||||||
let _: [(); 0] = [#[cfg(FALSE)] 126];
|
let _: [(); 0] = [#[cfg(false)] 126];
|
||||||
let t = [#[cfg(FALSE)] 1, 2, 6];
|
let t = [#[cfg(false)] 1, 2, 6];
|
||||||
assert_eq!(t, [2, 6]);
|
assert_eq!(t, [2, 6]);
|
||||||
|
|
||||||
{
|
{
|
||||||
let r;
|
let r;
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
(r = 5);
|
(r = 5);
|
||||||
#[cfg(not(FALSE))]
|
#[cfg(not(FALSE))]
|
||||||
(r = 10);
|
(r = 10);
|
||||||
|
@ -75,7 +75,7 @@ fn main() {
|
||||||
612
|
612
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!((#[cfg(FALSE)] 1, #[cfg(not(FALSE))] 2), (2,));
|
assert_eq!((#[cfg(false)] 1, #[cfg(not(FALSE))] 2), (2,));
|
||||||
assert_eq!(n, 612);
|
assert_eq!(n, 612);
|
||||||
|
|
||||||
// check that lints work
|
// check that lints work
|
||||||
|
|
9
tests/ui/cfg/cmdline-false.rs
Normal file
9
tests/ui/cfg/cmdline-false.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/// Test that `--cfg false` doesn't cause `cfg(false)` to evaluate to `true`
|
||||||
|
//@ compile-flags: --cfg false
|
||||||
|
|
||||||
|
#[cfg(false)]
|
||||||
|
fn foo() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(); //~ ERROR cannot find function `foo` in this scope
|
||||||
|
}
|
9
tests/ui/cfg/cmdline-false.stderr
Normal file
9
tests/ui/cfg/cmdline-false.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0425]: cannot find function `foo` in this scope
|
||||||
|
--> $DIR/cmdline-false.rs:8:5
|
||||||
|
|
|
||||||
|
LL | foo();
|
||||||
|
| ^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0425`.
|
|
@ -6,16 +6,16 @@
|
||||||
|
|
||||||
// Crate use statements
|
// Crate use statements
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
use flippity;
|
use flippity;
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
static b: bool = false;
|
static b: bool = false;
|
||||||
|
|
||||||
static b: bool = true;
|
static b: bool = true;
|
||||||
|
|
||||||
mod rustrt {
|
mod rustrt {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// This symbol doesn't exist and would be a link error if this
|
// This symbol doesn't exist and would be a link error if this
|
||||||
// module was codegened
|
// module was codegened
|
||||||
|
@ -25,12 +25,12 @@ mod rustrt {
|
||||||
extern "C" {}
|
extern "C" {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
type t = isize;
|
type t = isize;
|
||||||
|
|
||||||
type t = bool;
|
type t = bool;
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
enum tg {
|
enum tg {
|
||||||
foo,
|
foo,
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,12 @@ enum tg {
|
||||||
bar,
|
bar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
struct r {
|
struct r {
|
||||||
i: isize,
|
i: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn r(i: isize) -> r {
|
fn r(i: isize) -> r {
|
||||||
r { i: i }
|
r { i: i }
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ fn r(i: isize) -> r {
|
||||||
r { i: i }
|
r { i: i }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
mod m {
|
mod m {
|
||||||
// This needs to parse but would fail in typeck. Since it's not in
|
// This needs to parse but would fail in typeck. Since it's not in
|
||||||
// the current config it should not be typechecked.
|
// the current config it should not be typechecked.
|
||||||
|
@ -69,7 +69,7 @@ mod m {
|
||||||
mod m {
|
mod m {
|
||||||
// Submodules have slightly different code paths than the top-level
|
// Submodules have slightly different code paths than the top-level
|
||||||
// module, so let's make sure this jazz works here as well
|
// module, so let's make sure this jazz works here as well
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
pub fn f() {}
|
pub fn f() {}
|
||||||
|
|
||||||
pub fn f() {}
|
pub fn f() {}
|
||||||
|
@ -77,7 +77,7 @@ mod m {
|
||||||
|
|
||||||
// Since the FALSE configuration isn't defined main will just be
|
// Since the FALSE configuration isn't defined main will just be
|
||||||
// parsed, but nothing further will be done with it
|
// parsed, but nothing further will be done with it
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
@ -93,14 +93,14 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_in_fn_ctxt() {
|
fn test_in_fn_ctxt() {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn f() {
|
fn f() {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
fn f() {}
|
fn f() {}
|
||||||
f();
|
f();
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
static i: isize = 0;
|
static i: isize = 0;
|
||||||
static i: isize = 1;
|
static i: isize = 1;
|
||||||
assert_eq!(i, 1);
|
assert_eq!(i, 1);
|
||||||
|
@ -109,7 +109,7 @@ fn test_in_fn_ctxt() {
|
||||||
mod test_foreign_items {
|
mod test_foreign_items {
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
pub fn write() -> String;
|
pub fn write() -> String;
|
||||||
pub fn write() -> String;
|
pub fn write() -> String;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ mod test_foreign_items {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test_use_statements {
|
mod test_use_statements {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
use flippity_foo;
|
use flippity_foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,24 +127,24 @@ mod test_methods {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fooable for Foo {
|
impl Fooable for Foo {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn what(&self) {}
|
fn what(&self) {}
|
||||||
|
|
||||||
fn what(&self) {}
|
fn what(&self) {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn the(&self) {}
|
fn the(&self) {}
|
||||||
|
|
||||||
fn the(&self) {}
|
fn the(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Fooable {
|
trait Fooable {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn what(&self);
|
fn what(&self);
|
||||||
|
|
||||||
fn what(&self);
|
fn what(&self);
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn the(&self);
|
fn the(&self);
|
||||||
|
|
||||||
fn the(&self);
|
fn the(&self);
|
||||||
|
|
|
@ -12,7 +12,7 @@ LL | pub mod doesnt_exist {
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/auxiliary/cfged_out.rs:5:5
|
--> $DIR/auxiliary/cfged_out.rs:5:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `uwu` in crate `cfged_out`
|
error[E0425]: cannot find function `uwu` in crate `cfged_out`
|
||||||
|
@ -35,7 +35,7 @@ LL | pub fn uwu() {}
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/auxiliary/cfged_out.rs:2:5
|
--> $DIR/auxiliary/cfged_out.rs:2:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `meow` in module `cfged_out::inner::right`
|
error[E0425]: cannot find function `meow` in module `cfged_out::inner::right`
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
mod gone {
|
mod gone {
|
||||||
pub fn uwu() {}
|
pub fn uwu() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
pub use super::uwu;
|
pub use super::uwu;
|
||||||
//~^ NOTE found an item that was configured out
|
//~^ NOTE found an item that was configured out
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ pub use a::x;
|
||||||
//~| NOTE no `x` in `a`
|
//~| NOTE no `x` in `a`
|
||||||
|
|
||||||
mod a {
|
mod a {
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
pub fn x() {}
|
pub fn x() {}
|
||||||
//~^ NOTE found an item that was configured out
|
//~^ NOTE found an item that was configured out
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@ pub use b::{x, y};
|
||||||
//~| NOTE no `y` in `b`
|
//~| NOTE no `y` in `b`
|
||||||
|
|
||||||
mod b {
|
mod b {
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
pub fn x() {}
|
pub fn x() {}
|
||||||
//~^ NOTE found an item that was configured out
|
//~^ NOTE found an item that was configured out
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
pub fn y() {}
|
pub fn y() {}
|
||||||
//~^ NOTE found an item that was configured out
|
//~^ NOTE found an item that was configured out
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ LL | pub fn x() {}
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-reexport.rs:17:5
|
--> $DIR/diagnostics-reexport.rs:17:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0432]: unresolved imports `b::x`, `b::y`
|
error[E0432]: unresolved imports `b::x`, `b::y`
|
||||||
|
@ -31,7 +31,7 @@ LL | pub fn x() {}
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-reexport.rs:28:5
|
--> $DIR/diagnostics-reexport.rs:28:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
note: found an item that was configured out
|
note: found an item that was configured out
|
||||||
--> $DIR/diagnostics-reexport.rs:32:12
|
--> $DIR/diagnostics-reexport.rs:32:12
|
||||||
|
@ -41,7 +41,7 @@ LL | pub fn y() {}
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-reexport.rs:31:5
|
--> $DIR/diagnostics-reexport.rs:31:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `uwu` in module `inner`
|
error[E0425]: cannot find function `uwu` in module `inner`
|
||||||
|
@ -58,7 +58,7 @@ LL | pub use super::uwu;
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-reexport.rs:7:5
|
--> $DIR/diagnostics-reexport.rs:7:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#![allow(unexpected_cfgs)] // since we want to recognize them as unexpected
|
#![allow(unexpected_cfgs)] // since we want to recognize them as unexpected
|
||||||
|
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
pub fn uwu() {}
|
pub fn uwu() {}
|
||||||
//~^ NOTE found an item that was configured out
|
//~^ NOTE found an item that was configured out
|
||||||
|
|
||||||
#[cfg(FALSE)] //~ NOTE the item is gated here
|
#[cfg(false)] //~ NOTE the item is gated here
|
||||||
//~^ NOTE the item is gated here
|
//~^ NOTE the item is gated here
|
||||||
//~| NOTE the item is gated here
|
//~| NOTE the item is gated here
|
||||||
pub mod doesnt_exist {
|
pub mod doesnt_exist {
|
||||||
|
|
|
@ -12,7 +12,7 @@ LL | pub mod doesnt_exist {
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-same-crate.rs:8:5
|
--> $DIR/diagnostics-same-crate.rs:8:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0432]: unresolved import `super::inner::doesnt_exist`
|
error[E0432]: unresolved import `super::inner::doesnt_exist`
|
||||||
|
@ -29,7 +29,7 @@ LL | pub mod doesnt_exist {
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-same-crate.rs:8:5
|
--> $DIR/diagnostics-same-crate.rs:8:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
|
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
|
||||||
|
@ -46,7 +46,7 @@ LL | pub mod doesnt_exist {
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-same-crate.rs:8:5
|
--> $DIR/diagnostics-same-crate.rs:8:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `uwu` in module `inner`
|
error[E0425]: cannot find function `uwu` in module `inner`
|
||||||
|
@ -63,7 +63,7 @@ LL | pub fn uwu() {}
|
||||||
note: the item is gated here
|
note: the item is gated here
|
||||||
--> $DIR/diagnostics-same-crate.rs:4:5
|
--> $DIR/diagnostics-same-crate.rs:4:5
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(false)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `meow` in module `inner::right`
|
error[E0425]: cannot find function `meow` in module `inner::right`
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(link_cfg)]
|
#![feature(link_cfg)]
|
||||||
#![feature(cfg_boolean_literals)]
|
|
||||||
|
|
||||||
#[cfg(true)]
|
#[cfg(true)]
|
||||||
fn foo() -> bool {
|
fn foo() -> bool {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
//@ compile-flags: --check-cfg=cfg() --cfg=unknown_but_active_cfg
|
//@ compile-flags: --check-cfg=cfg() --cfg=unknown_but_active_cfg
|
||||||
|
|
||||||
#[allow(unexpected_cfgs)]
|
#[allow(unexpected_cfgs)]
|
||||||
#[cfg(FALSE)]
|
#[cfg(unknown_and_inactive_cfg)]
|
||||||
//~^ WARNING unexpected `cfg` condition name
|
//~^ WARNING unexpected `cfg` condition name
|
||||||
fn bar() {}
|
fn bar() {}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
warning: unexpected `cfg` condition name: `FALSE`
|
warning: unexpected `cfg` condition name: `unknown_and_inactive_cfg`
|
||||||
--> $DIR/allow-same-level.rs:15:7
|
--> $DIR/allow-same-level.rs:15:7
|
||||||
|
|
|
|
||||||
LL | #[cfg(FALSE)]
|
LL | #[cfg(unknown_and_inactive_cfg)]
|
||||||
| ^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: to expect this configuration use `--check-cfg=cfg(FALSE)`
|
= help: to expect this configuration use `--check-cfg=cfg(unknown_and_inactive_cfg)`
|
||||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||||
= note: `#[warn(unexpected_cfgs)]` on by default
|
= note: `#[warn(unexpected_cfgs)]` on by default
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#![allow(unexpected_cfgs)]
|
#![allow(unexpected_cfgs)]
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn bar() {}
|
fn bar() {}
|
||||||
|
|
||||||
fn foo() {
|
fn foo() {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#[allow(unexpected_cfgs)]
|
#[allow(unexpected_cfgs)]
|
||||||
mod aa {
|
mod aa {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn bar() {}
|
fn bar() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ extern crate std;
|
||||||
//@ revisions: normal expanded
|
//@ revisions: normal expanded
|
||||||
//@[expanded] check-pass
|
//@[expanded] check-pass
|
||||||
//@[expanded]compile-flags: -Zunpretty=expanded
|
//@[expanded]compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
extern "路濫狼á́́" fn foo() {}
|
extern "路濫狼á́́" fn foo() {}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0703]: invalid ABI: found `路濫狼á́́`
|
error[E0703]: invalid ABI: found `路濫狼á́́`
|
||||||
--> $DIR/unicode.rs:5:8
|
--> $DIR/unicode.rs:6:8
|
||||||
|
|
|
|
||||||
LL | extern "路濫狼á́́" fn foo() {}
|
LL | extern "路濫狼á́́" fn foo() {}
|
||||||
| ^^^^^^^^^ invalid ABI
|
| ^^^^^^^^^ invalid ABI
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//@ revisions: normal expanded
|
//@ revisions: normal expanded
|
||||||
//@[expanded] check-pass
|
//@[expanded] check-pass
|
||||||
//@[expanded]compile-flags: -Zunpretty=expanded
|
//@[expanded]compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
extern "路濫狼á́́" fn foo() {} //[normal]~ ERROR invalid ABI
|
extern "路濫狼á́́" fn foo() {} //[normal]~ ERROR invalid ABI
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
//@ compile-flags:--cfg yes --check-cfg=cfg(yes,no)
|
//@ compile-flags:--cfg yes --check-cfg=cfg(yes,no)
|
||||||
|
|
||||||
fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(FALSE)] T>() {}
|
fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(false)] T>() {}
|
||||||
fn f_ty<#[cfg(FALSE)] 'a: 'a, #[cfg(yes)] T>() {}
|
fn f_ty<#[cfg(false)] 'a: 'a, #[cfg(yes)] T>() {}
|
||||||
|
|
||||||
type FnGood = for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> fn(); // OK
|
type FnGood = for<#[cfg(yes)] 'a, #[cfg(false)] T> fn(); // OK
|
||||||
type FnBad = for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> fn();
|
type FnBad = for<#[cfg(false)] 'a, #[cfg(yes)] T> fn();
|
||||||
//~^ ERROR only lifetime parameters can be used in this context
|
//~^ ERROR only lifetime parameters can be used in this context
|
||||||
|
|
||||||
type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> Copy; // OK
|
type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(false)] T> Copy; // OK
|
||||||
type PolyBad = dyn for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> Copy;
|
type PolyBad = dyn for<#[cfg(false)] 'a, #[cfg(yes)] T> Copy;
|
||||||
//~^ ERROR only lifetime parameters can be used in this context
|
//~^ ERROR only lifetime parameters can be used in this context
|
||||||
|
|
||||||
struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> u8: Copy; // OK
|
struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(false)] T> u8: Copy; // OK
|
||||||
struct WhereBad where for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> u8: Copy;
|
struct WhereBad where for<#[cfg(false)] 'a, #[cfg(yes)] T> u8: Copy;
|
||||||
//~^ ERROR only lifetime parameters can be used in this context
|
//~^ ERROR only lifetime parameters can be used in this context
|
||||||
|
|
||||||
fn f_lt_no<#[cfg_attr(FALSE, unknown)] 'a>() {} // OK
|
fn f_lt_no<#[cfg_attr(FALSE, unknown)] 'a>() {} // OK
|
||||||
|
|
|
@ -31,7 +31,7 @@ LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
--> $DIR/cfg-generic-params.rs:7:48
|
--> $DIR/cfg-generic-params.rs:7:48
|
||||||
|
|
|
|
||||||
LL | type FnBad = for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> fn();
|
LL | type FnBad = for<#[cfg(false)] 'a, #[cfg(yes)] T> fn();
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
@ -41,7 +41,7 @@ LL | type FnBad = for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> fn();
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
--> $DIR/cfg-generic-params.rs:11:54
|
--> $DIR/cfg-generic-params.rs:11:54
|
||||||
|
|
|
|
||||||
LL | type PolyBad = dyn for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> Copy;
|
LL | type PolyBad = dyn for<#[cfg(false)] 'a, #[cfg(yes)] T> Copy;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
@ -51,7 +51,7 @@ LL | type PolyBad = dyn for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> Copy;
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
--> $DIR/cfg-generic-params.rs:15:57
|
--> $DIR/cfg-generic-params.rs:15:57
|
||||||
|
|
|
|
||||||
LL | struct WhereBad where for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> u8: Copy;
|
LL | struct WhereBad where for<#[cfg(false)] 'a, #[cfg(yes)] T> u8: Copy;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#![cfg(FALSE)] //~ ERROR `main` function not found in crate `cfg_in_crate_1`
|
#![cfg(false)] //~ ERROR `main` function not found in crate `cfg_in_crate_1`
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error[E0601]: `main` function not found in crate `cfg_in_crate_1`
|
error[E0601]: `main` function not found in crate `cfg_in_crate_1`
|
||||||
--> $DIR/cfg-in-crate-1.rs:1:15
|
--> $DIR/cfg-in-crate-1.rs:1:15
|
||||||
|
|
|
|
||||||
LL | #![cfg(FALSE)]
|
LL | #![cfg(false)]
|
||||||
| ^ consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
|
| ^ consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
#![feature(custom_test_frameworks)]
|
#![feature(custom_test_frameworks)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = #[cfg(FALSE)] ();
|
let _ = #[cfg(false)] ();
|
||||||
//~^ ERROR removing an expression is not supported in this position
|
//~^ ERROR removing an expression is not supported in this position
|
||||||
let _ = 1 + 2 + #[cfg(FALSE)] 3;
|
let _ = 1 + 2 + #[cfg(false)] 3;
|
||||||
//~^ ERROR removing an expression is not supported in this position
|
//~^ ERROR removing an expression is not supported in this position
|
||||||
let _ = [1, 2, 3][#[cfg(FALSE)] 1];
|
let _ = [1, 2, 3][#[cfg(false)] 1];
|
||||||
//~^ ERROR removing an expression is not supported in this position
|
//~^ ERROR removing an expression is not supported in this position
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/cfg-non-opt-expr.rs:5:13
|
--> $DIR/cfg-non-opt-expr.rs:5:13
|
||||||
|
|
|
|
||||||
LL | let _ = #[cfg(FALSE)] ();
|
LL | let _ = #[cfg(false)] ();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/cfg-non-opt-expr.rs:7:21
|
--> $DIR/cfg-non-opt-expr.rs:7:21
|
||||||
|
|
|
|
||||||
LL | let _ = 1 + 2 + #[cfg(FALSE)] 3;
|
LL | let _ = 1 + 2 + #[cfg(false)] 3;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/cfg-non-opt-expr.rs:9:23
|
--> $DIR/cfg-non-opt-expr.rs:9:23
|
||||||
|
|
|
|
||||||
LL | let _ = [1, 2, 3][#[cfg(FALSE)] 1];
|
LL | let _ = [1, 2, 3][#[cfg(false)] 1];
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
//@ ignore-test (auxiliary, used by other tests)
|
//@ ignore-test (auxiliary, used by other tests)
|
||||||
|
|
||||||
#![cfg_attr(all(), cfg(FALSE))]
|
#![cfg_attr(all(), cfg(false))]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Test the AST pretty printer correctly handles default values for const generics
|
// Test the AST pretty printer correctly handles default values for const generics
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Z unpretty=expanded
|
//@ compile-flags: -Z unpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Test the AST pretty printer correctly handles default values for const generics
|
// Test the AST pretty printer correctly handles default values for const generics
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Z unpretty=expanded
|
//@ compile-flags: -Z unpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn container() {
|
fn container() {
|
||||||
const unsafe WhereIsFerris Now() {}
|
const unsafe WhereIsFerris Now() {}
|
||||||
//~^ ERROR expected one of `extern` or `fn`
|
//~^ ERROR expected one of `extern` or `fn`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn container() {
|
fn container() {
|
||||||
const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 }
|
const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 }
|
||||||
//~^ ERROR expected `fn`
|
//~^ ERROR expected `fn`
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
mod to_reuse {
|
mod to_reuse {
|
||||||
use crate::S;
|
use crate::S;
|
||||||
|
|
||||||
pub fn foo<'a>(#[cfg(FALSE)] a: u8, _b: &'a S) -> u32 {
|
pub fn foo<'a>(#[cfg(false)] a: u8, _b: &'a S) -> u32 {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ proc-macro: another-proc-macro.rs
|
//@ proc-macro: another-proc-macro.rs
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition:2015
|
||||||
|
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ proc-macro: another-proc-macro.rs
|
//@ proc-macro: another-proc-macro.rs
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition:2015
|
||||||
|
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
use std::marker::CoercePointee;
|
use std::marker::CoercePointee;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
use ::std::prelude::rust_2015::*;
|
use ::std::prelude::rust_2015::*;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ proc-macro: another-proc-macro.rs
|
//@ proc-macro: another-proc-macro.rs
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ proc-macro: another-proc-macro.rs
|
//@ proc-macro: another-proc-macro.rs
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ edition: 2015
|
||||||
|
|
||||||
#![feature(derive_coerce_pointee)]
|
#![feature(derive_coerce_pointee)]
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression
|
let _ = #[cfg(false)] if true {}; //~ ERROR removing an expression
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error: removing an expression is not supported in this position
|
error: removing an expression is not supported in this position
|
||||||
--> $DIR/bad-cfg.rs:4:13
|
--> $DIR/bad-cfg.rs:4:13
|
||||||
|
|
|
|
||||||
LL | let _ = #[cfg(FALSE)] if true {};
|
LL | let _ = #[cfg(false)] if true {};
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn simple_attr() {
|
fn simple_attr() {
|
||||||
#[attr] if true {}
|
#[attr] if true {}
|
||||||
#[allow_warnings] if true {}
|
#[allow_warnings] if true {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn if_else_chain() {
|
fn if_else_chain() {
|
||||||
#[first_attr] if true {
|
#[first_attr] if true {
|
||||||
} else if false {
|
} else if false {
|
||||||
|
@ -14,20 +14,20 @@ fn if_else_chain() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn if_let() {
|
fn if_let() {
|
||||||
#[attr] if let Some(_) = Some(true) {}
|
#[attr] if let Some(_) = Some(true) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar() {
|
fn bar() {
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
if true {
|
if true {
|
||||||
let x: () = true; // Should not error due to the #[cfg(FALSE)]
|
let x: () = true; // Should not error due to the #[cfg(false)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(FALSE), cfg(FALSE))]
|
#[cfg_attr(not(FALSE), cfg(false))]
|
||||||
if true {
|
if true {
|
||||||
let a: () = true; // Should not error due to the applied #[cfg(FALSE)]
|
let a: () = true; // Should not error due to the applied #[cfg(false)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn if_else_parse_error() {
|
fn if_else_parse_error() {
|
||||||
if true {
|
if true {
|
||||||
} #[attr] else if false { //~ ERROR expected
|
} #[attr] else if false { //~ ERROR expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn else_attr_ifparse_error() {
|
fn else_attr_ifparse_error() {
|
||||||
if true {
|
if true {
|
||||||
} else #[attr] if false { //~ ERROR outer attributes are not allowed
|
} else #[attr] if false { //~ ERROR outer attributes are not allowed
|
||||||
|
@ -13,7 +13,7 @@ fn else_attr_ifparse_error() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
fn else_parse_error() {
|
fn else_parse_error() {
|
||||||
if true {
|
if true {
|
||||||
} else if false {
|
} else if false {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 1;
|
let x = 1;
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(false)]
|
||||||
if false {
|
if false {
|
||||||
x = 2;
|
x = 2;
|
||||||
} else if true {
|
} else if true {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue