mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #153124 - JonathanBrouwer:rollup-3OajkjU, r=JonathanBrouwer
Rollup of 7 pull requests Successful merges: - rust-lang/rust#153079 (Revert "Move aarch64-apple dist builder to dynamic llvm linking") - rust-lang/rust#152651 (Avoid duplicate `requirement` diag args in `RegionOriginNote`) - rust-lang/rust#152978 (Port `#[rustc_autodiff]` to the attribute parser infrastructure) - rust-lang/rust#153091 (Migration of `LintDiagnostic` - part 4) - rust-lang/rust#153112 (Query key cleanups) - rust-lang/rust#153118 (mailmap: add redddy) - rust-lang/rust#153120 (Clean up some code related to `QueryVTable::execute_query_fn`)
This commit is contained in:
@@ -579,6 +579,9 @@ Ralph Giles <giles@thaumas.net> Ralph Giles <giles@mozilla.com>
|
||||
Ramkumar Ramachandra <r@artagnon.com> <artagnon@gmail.com>
|
||||
Raphaël Huchet <rap2hpoutre@users.noreply.github.com>
|
||||
rChaser53 <tayoshizawa29@gmail.com>
|
||||
Redddy <rust@redddy.com>
|
||||
Redddy <rust@redddy.com> <midzy0228@gmail.com>
|
||||
Redddy <rust@redddy.com> <78539407+reddevilmidzy@users.noreply.github.com>
|
||||
Rémy Rakic <remy.rakic@gmail.com>
|
||||
Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+github@gmail.com>
|
||||
Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+rust@gmail.com>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
//! This crate handles the user facing autodiff macro. For each `#[autodiff(...)]` attribute,
|
||||
//! we create an [`AutoDiffItem`] which contains the source and target function names. The source
|
||||
//! we create an `RustcAutodiff` which contains the source and target function names. The source
|
||||
//! is the function to which the autodiff attribute is applied, and the target is the function
|
||||
//! getting generated by us (with a name given by the user as the first autodiff arg).
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::expand::typetree::TypeTree;
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::expand::{Decodable, Encodable, HashStable_Generic};
|
||||
use crate::{Ty, TyKind};
|
||||
|
||||
@@ -31,6 +32,12 @@ pub enum DiffMode {
|
||||
Reverse,
|
||||
}
|
||||
|
||||
impl DiffMode {
|
||||
pub fn all_modes() -> &'static [Symbol] {
|
||||
&[sym::Source, sym::Forward, sym::Reverse]
|
||||
}
|
||||
}
|
||||
|
||||
/// Dual and Duplicated (and their Only variants) are getting lowered to the same Enzyme Activity.
|
||||
/// However, under forward mode we overwrite the previous shadow value, while for reverse mode
|
||||
/// we add to the previous shadow value. To not surprise users, we picked different names.
|
||||
@@ -76,43 +83,20 @@ pub fn is_dual_or_const(&self) -> bool {
|
||||
use DiffActivity::*;
|
||||
matches!(self, |Dual| DualOnly | Dualv | DualvOnly | Const)
|
||||
}
|
||||
}
|
||||
/// We generate one of these structs for each `#[autodiff(...)]` attribute.
|
||||
#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct AutoDiffItem {
|
||||
/// The name of the function getting differentiated
|
||||
pub source: String,
|
||||
/// The name of the function being generated
|
||||
pub target: String,
|
||||
pub attrs: AutoDiffAttrs,
|
||||
pub inputs: Vec<TypeTree>,
|
||||
pub output: TypeTree,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct AutoDiffAttrs {
|
||||
/// Conceptually either forward or reverse mode AD, as described in various autodiff papers and
|
||||
/// e.g. in the [JAX
|
||||
/// Documentation](https://jax.readthedocs.io/en/latest/_tutorials/advanced-autodiff.html#how-it-s-made-two-foundational-autodiff-functions).
|
||||
pub mode: DiffMode,
|
||||
/// A user-provided, batching width. If not given, we will default to 1 (no batching).
|
||||
/// Calling a differentiated, non-batched function through a loop 100 times is equivalent to:
|
||||
/// - Calling the function 50 times with a batch size of 2
|
||||
/// - Calling the function 25 times with a batch size of 4,
|
||||
/// etc. A batched function takes more (or longer) arguments, and might be able to benefit from
|
||||
/// cache locality, better re-usal of primal values, and other optimizations.
|
||||
/// We will (before LLVM's vectorizer runs) just generate most LLVM-IR instructions `width`
|
||||
/// times, so this massively increases code size. As such, values like 1024 are unlikely to
|
||||
/// work. We should consider limiting this to u8 or u16, but will leave it at u32 for
|
||||
/// experiments for now and focus on documenting the implications of a large width.
|
||||
pub width: u32,
|
||||
pub ret_activity: DiffActivity,
|
||||
pub input_activity: Vec<DiffActivity>,
|
||||
}
|
||||
|
||||
impl AutoDiffAttrs {
|
||||
pub fn has_primal_ret(&self) -> bool {
|
||||
matches!(self.ret_activity, DiffActivity::Active | DiffActivity::Dual)
|
||||
pub fn all_activities() -> &'static [Symbol] {
|
||||
&[
|
||||
sym::None,
|
||||
sym::Active,
|
||||
sym::ActiveOnly,
|
||||
sym::Const,
|
||||
sym::Dual,
|
||||
sym::Dualv,
|
||||
sym::DualOnly,
|
||||
sym::DualvOnly,
|
||||
sym::Duplicated,
|
||||
sym::DuplicatedOnly,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,59 +225,3 @@ fn from_str(s: &str) -> Result<DiffActivity, ()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AutoDiffAttrs {
|
||||
pub fn has_ret_activity(&self) -> bool {
|
||||
self.ret_activity != DiffActivity::None
|
||||
}
|
||||
pub fn has_active_only_ret(&self) -> bool {
|
||||
self.ret_activity == DiffActivity::ActiveOnly
|
||||
}
|
||||
|
||||
pub const fn error() -> Self {
|
||||
AutoDiffAttrs {
|
||||
mode: DiffMode::Error,
|
||||
width: 0,
|
||||
ret_activity: DiffActivity::None,
|
||||
input_activity: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn source() -> Self {
|
||||
AutoDiffAttrs {
|
||||
mode: DiffMode::Source,
|
||||
width: 0,
|
||||
ret_activity: DiffActivity::None,
|
||||
input_activity: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.mode != DiffMode::Error
|
||||
}
|
||||
|
||||
pub fn is_source(&self) -> bool {
|
||||
self.mode == DiffMode::Source
|
||||
}
|
||||
pub fn apply_autodiff(&self) -> bool {
|
||||
!matches!(self.mode, DiffMode::Error | DiffMode::Source)
|
||||
}
|
||||
|
||||
pub fn into_item(
|
||||
self,
|
||||
source: String,
|
||||
target: String,
|
||||
inputs: Vec<TypeTree>,
|
||||
output: TypeTree,
|
||||
) -> AutoDiffItem {
|
||||
AutoDiffItem { source, target, inputs, output, attrs: self }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AutoDiffItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Differentiating {} -> {}", self.source, self.target)?;
|
||||
write!(f, " with attributes: {:?}", self.attrs)?;
|
||||
write!(f, " with inputs: {:?}", self.inputs)?;
|
||||
write!(f, " with output: {:?}", self.output)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_hir::attrs::{AttributeKind, RustcAutodiff};
|
||||
use rustc_hir::{MethodKind, Target};
|
||||
use rustc_span::{Symbol, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::attributes::prelude::Allow;
|
||||
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::parser::{ArgParser, MetaItemOrLitParser};
|
||||
use crate::target_checking::AllowedTargets;
|
||||
|
||||
pub(crate) struct RustcAutodiffParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_autodiff];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
]);
|
||||
const TEMPLATE: AttributeTemplate = template!(
|
||||
List: &["MODE", "WIDTH", "INPUT_ACTIVITIES", "OUTPUT_ACTIVITY"],
|
||||
"https://doc.rust-lang.org/std/autodiff/index.html"
|
||||
);
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
|
||||
let list = match args {
|
||||
ArgParser::NoArgs => return Some(AttributeKind::RustcAutodiff(None)),
|
||||
ArgParser::List(list) => list,
|
||||
ArgParser::NameValue(_) => {
|
||||
cx.expected_list_or_no_args(cx.attr_span);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let mut items = list.mixed().peekable();
|
||||
|
||||
// Parse name
|
||||
let Some(mode) = items.next() else {
|
||||
cx.expected_at_least_one_argument(list.span);
|
||||
return None;
|
||||
};
|
||||
let Some(mode) = mode.meta_item() else {
|
||||
cx.expected_identifier(mode.span());
|
||||
return None;
|
||||
};
|
||||
let Ok(()) = mode.args().no_args() else {
|
||||
cx.expected_identifier(mode.span());
|
||||
return None;
|
||||
};
|
||||
let Some(mode) = mode.path().word() else {
|
||||
cx.expected_identifier(mode.span());
|
||||
return None;
|
||||
};
|
||||
let Ok(mode) = DiffMode::from_str(mode.as_str()) else {
|
||||
cx.expected_specific_argument(mode.span, DiffMode::all_modes());
|
||||
return None;
|
||||
};
|
||||
|
||||
// Parse width
|
||||
let width = if let Some(width) = items.peek()
|
||||
&& let MetaItemOrLitParser::Lit(width) = width
|
||||
&& let LitKind::Int(width, _) = width.kind
|
||||
&& let Ok(width) = width.0.try_into()
|
||||
{
|
||||
_ = items.next();
|
||||
width
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
// Parse activities
|
||||
let mut activities = ThinVec::new();
|
||||
for activity in items {
|
||||
let MetaItemOrLitParser::MetaItemParser(activity) = activity else {
|
||||
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
|
||||
return None;
|
||||
};
|
||||
let Ok(()) = activity.args().no_args() else {
|
||||
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
|
||||
return None;
|
||||
};
|
||||
let Some(activity) = activity.path().word() else {
|
||||
cx.expected_specific_argument(activity.span(), DiffActivity::all_activities());
|
||||
return None;
|
||||
};
|
||||
let Ok(activity) = DiffActivity::from_str(activity.as_str()) else {
|
||||
cx.expected_specific_argument(activity.span, DiffActivity::all_activities());
|
||||
return None;
|
||||
};
|
||||
|
||||
activities.push(activity);
|
||||
}
|
||||
let Some(ret_activity) = activities.pop() else {
|
||||
cx.expected_specific_argument(
|
||||
list.span.with_lo(list.span.hi()),
|
||||
DiffActivity::all_activities(),
|
||||
);
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(AttributeKind::RustcAutodiff(Some(Box::new(RustcAutodiff {
|
||||
mode,
|
||||
width,
|
||||
input_activity: activities,
|
||||
ret_activity,
|
||||
}))))
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
mod prelude;
|
||||
|
||||
pub(crate) mod allow_unstable;
|
||||
pub(crate) mod autodiff;
|
||||
pub(crate) mod body;
|
||||
pub(crate) mod cfg;
|
||||
pub(crate) mod cfg_select;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use crate::AttributeParser;
|
||||
// Glob imports to avoid big, bitrotty import lists
|
||||
use crate::attributes::allow_unstable::*;
|
||||
use crate::attributes::autodiff::*;
|
||||
use crate::attributes::body::*;
|
||||
use crate::attributes::cfi_encoding::*;
|
||||
use crate::attributes::codegen_attrs::*;
|
||||
@@ -204,6 +205,7 @@ mod late {
|
||||
Single<ReexportTestHarnessMainParser>,
|
||||
Single<RustcAbiParser>,
|
||||
Single<RustcAllocatorZeroedVariantParser>,
|
||||
Single<RustcAutodiffParser>,
|
||||
Single<RustcBuiltinMacroParser>,
|
||||
Single<RustcDefPathParser>,
|
||||
Single<RustcDeprecatedSafe2024Parser>,
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
use rustc_data_structures::frozen::Frozen;
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_errors::LintDiagnostic;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
@@ -715,7 +714,7 @@ fn deref(&self) -> &Self::Target {
|
||||
}
|
||||
}
|
||||
|
||||
struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
|
||||
pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
|
||||
root_cx: &'a mut BorrowCheckRootCtxt<'tcx>,
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
@@ -1428,13 +1427,15 @@ fn check_backward_incompatible_drop(
|
||||
borrow,
|
||||
Some((WriteKind::StorageDeadOrDrop, place)),
|
||||
);
|
||||
this.infcx.tcx.node_span_lint(
|
||||
this.infcx.tcx.emit_node_span_lint(
|
||||
TAIL_EXPR_DROP_ORDER,
|
||||
CRATE_HIR_ID,
|
||||
borrowed,
|
||||
|diag| {
|
||||
session_diagnostics::TailExprDropOrder { borrowed }.decorate_lint(diag);
|
||||
explain.add_explanation_to_diagnostic(&this, diag, "", None, None);
|
||||
session_diagnostics::TailExprDropOrder {
|
||||
borrowed,
|
||||
callback: |diag| {
|
||||
explain.add_explanation_to_diagnostic(&this, diag, "", None, None);
|
||||
},
|
||||
},
|
||||
);
|
||||
// We may stop at the first case
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::{GenericArg, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
@@ -595,9 +595,20 @@ pub(crate) struct SimdIntrinsicArgConst {
|
||||
pub intrinsic: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag("relative drop order changing in Rust 2024")]
|
||||
pub(crate) struct TailExprDropOrder {
|
||||
#[label("this temporary value will be dropped at the end of the block")]
|
||||
pub(crate) struct TailExprDropOrder<F: FnOnce(&mut Diag<'_, ()>)> {
|
||||
pub borrowed: Span,
|
||||
pub callback: F,
|
||||
}
|
||||
|
||||
impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for TailExprDropOrder<F> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let Self { borrowed, callback } = self;
|
||||
let mut diag = Diag::new(dcx, level, "relative drop order changing in Rust 2024")
|
||||
.with_span_label(
|
||||
borrowed,
|
||||
"this temporary value will be dropped at the end of the block",
|
||||
);
|
||||
callback(&mut diag);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ mod llvm_enzyme {
|
||||
use std::string::String;
|
||||
|
||||
use rustc_ast::expand::autodiff_attrs::{
|
||||
AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
|
||||
valid_ty_for_activity,
|
||||
DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, valid_ty_for_activity,
|
||||
};
|
||||
use rustc_ast::token::{Lit, LitKind, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::*;
|
||||
@@ -20,6 +19,7 @@ mod llvm_enzyme {
|
||||
MetaItemInner, MgcaDisambiguation, PatKind, Path, PathSegment, TyKind, Visibility,
|
||||
};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_hir::attrs::RustcAutodiff;
|
||||
use rustc_span::{Ident, Span, Symbol, sym};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
use tracing::{debug, trace};
|
||||
@@ -87,7 +87,7 @@ pub(crate) fn from_ast(
|
||||
meta_item: &ThinVec<MetaItemInner>,
|
||||
has_ret: bool,
|
||||
mode: DiffMode,
|
||||
) -> AutoDiffAttrs {
|
||||
) -> RustcAutodiff {
|
||||
let dcx = ecx.sess.dcx();
|
||||
|
||||
// Now we check, whether the user wants autodiff in batch/vector mode, or scalar mode.
|
||||
@@ -105,7 +105,7 @@ pub(crate) fn from_ast(
|
||||
span: meta_item[1].span(),
|
||||
width: x,
|
||||
});
|
||||
return AutoDiffAttrs::error();
|
||||
return RustcAutodiff::error();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -129,7 +129,7 @@ pub(crate) fn from_ast(
|
||||
};
|
||||
}
|
||||
if errors {
|
||||
return AutoDiffAttrs::error();
|
||||
return RustcAutodiff::error();
|
||||
}
|
||||
|
||||
// If a return type exist, we need to split the last activity,
|
||||
@@ -145,11 +145,11 @@ pub(crate) fn from_ast(
|
||||
(&DiffActivity::None, activities.as_slice())
|
||||
};
|
||||
|
||||
AutoDiffAttrs {
|
||||
RustcAutodiff {
|
||||
mode,
|
||||
width,
|
||||
ret_activity: *ret_activity,
|
||||
input_activity: input_activity.to_vec(),
|
||||
input_activity: input_activity.iter().cloned().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ pub(crate) fn expand_with_mode(
|
||||
ts.pop();
|
||||
let ts: TokenStream = TokenStream::from_iter(ts);
|
||||
|
||||
let x: AutoDiffAttrs = from_ast(ecx, &meta_item_vec, has_ret, mode);
|
||||
let x: RustcAutodiff = from_ast(ecx, &meta_item_vec, has_ret, mode);
|
||||
if !x.is_active() {
|
||||
// We encountered an error, so we return the original item.
|
||||
// This allows us to potentially parse other attributes.
|
||||
@@ -603,7 +603,7 @@ fn gen_turbofish_expr(
|
||||
fn gen_enzyme_decl(
|
||||
ecx: &ExtCtxt<'_>,
|
||||
sig: &ast::FnSig,
|
||||
x: &AutoDiffAttrs,
|
||||
x: &RustcAutodiff,
|
||||
span: Span,
|
||||
) -> ast::FnSig {
|
||||
let dcx = ecx.sess.dcx();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::ptr;
|
||||
|
||||
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
|
||||
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
|
||||
use rustc_ast::expand::typetree::FncTree;
|
||||
use rustc_codegen_ssa::common::TypeKind;
|
||||
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_hir::attrs::RustcAutodiff;
|
||||
use rustc_middle::ty::{Instance, PseudoCanonicalInput, TyCtxt, TypingEnv};
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_target::callconv::PassMode;
|
||||
@@ -18,7 +20,7 @@ pub(crate) fn adjust_activity_to_abi<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
da: &mut Vec<DiffActivity>,
|
||||
da: &mut ThinVec<DiffActivity>,
|
||||
) {
|
||||
let fn_ty = instance.ty(tcx, typing_env);
|
||||
|
||||
@@ -295,7 +297,7 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
|
||||
outer_name: &str,
|
||||
ret_ty: &'ll Type,
|
||||
fn_args: &[&'ll Value],
|
||||
attrs: AutoDiffAttrs,
|
||||
attrs: &RustcAutodiff,
|
||||
dest: PlaceRef<'tcx, &'ll Value>,
|
||||
fnc_tree: FncTree,
|
||||
) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size, WrappingRange,
|
||||
};
|
||||
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
|
||||
use rustc_codegen_ssa::codegen_attrs::autodiff_attrs;
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization};
|
||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||
@@ -15,6 +14,7 @@
|
||||
use rustc_data_structures::assert_matches;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_middle::mir::BinOp;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::offload_meta::OffloadMetadata;
|
||||
@@ -1367,7 +1367,9 @@ fn codegen_autodiff<'ll, 'tcx>(
|
||||
let val_arr = get_args_from_tuple(bx, args[2], fn_diff);
|
||||
let diff_symbol = symbol_name_for_instance_in_crate(tcx, fn_diff.clone(), LOCAL_CRATE);
|
||||
|
||||
let Some(mut diff_attrs) = autodiff_attrs(tcx, fn_diff.def_id()) else {
|
||||
let Some(Some(mut diff_attrs)) =
|
||||
find_attr!(tcx, fn_diff.def_id(), RustcAutodiff(attr) => attr.clone())
|
||||
else {
|
||||
bug!("could not find autodiff attrs")
|
||||
};
|
||||
|
||||
@@ -1389,7 +1391,7 @@ fn codegen_autodiff<'ll, 'tcx>(
|
||||
&diff_symbol,
|
||||
llret_ty,
|
||||
&val_arr,
|
||||
diff_attrs.clone(),
|
||||
&diff_attrs,
|
||||
result,
|
||||
fnc_tree,
|
||||
);
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use rustc_abi::{Align, ExternAbi};
|
||||
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
|
||||
use rustc_ast::{LitKind, MetaItem, MetaItemInner};
|
||||
use rustc_hir::attrs::{
|
||||
AttributeKind, EiiImplResolution, InlineAttr, Linkage, RtsanSetting, UsedBy,
|
||||
};
|
||||
@@ -14,7 +10,6 @@
|
||||
};
|
||||
use rustc_middle::mir::mono::Visibility;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self as ty, TyCtxt};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::parse::feature_err;
|
||||
@@ -614,116 +609,6 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
|
||||
tcx.codegen_fn_attrs(tcx.trait_item_of(def_id)?).alignment
|
||||
}
|
||||
|
||||
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
|
||||
/// macros. There are two forms. The pure one without args to mark primal functions (the functions
|
||||
/// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the
|
||||
/// placeholder functions. We wrote the rustc_autodiff attributes ourself, so this should never
|
||||
/// panic, unless we introduced a bug when parsing the autodiff macro.
|
||||
//FIXME(jdonszelmann): put in the main loop. No need to have two..... :/ Let's do that when we make autodiff parsed.
|
||||
pub fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
||||
#[allow(deprecated)]
|
||||
let attrs = tcx.get_attrs(id, sym::rustc_autodiff);
|
||||
|
||||
let attrs = attrs.filter(|attr| attr.has_name(sym::rustc_autodiff)).collect::<Vec<_>>();
|
||||
|
||||
// check for exactly one autodiff attribute on placeholder functions.
|
||||
// There should only be one, since we generate a new placeholder per ad macro.
|
||||
let attr = match &attrs[..] {
|
||||
[] => return None,
|
||||
[attr] => attr,
|
||||
_ => {
|
||||
span_bug!(attrs[1].span(), "cg_ssa: rustc_autodiff should only exist once per source");
|
||||
}
|
||||
};
|
||||
|
||||
let list = attr.meta_item_list().unwrap_or_default();
|
||||
|
||||
// empty autodiff attribute macros (i.e. `#[autodiff]`) are used to mark source functions
|
||||
if list.is_empty() {
|
||||
return Some(AutoDiffAttrs::source());
|
||||
}
|
||||
|
||||
let [mode, width_meta, input_activities @ .., ret_activity] = &list[..] else {
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain mode, width and activities");
|
||||
};
|
||||
let mode = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = mode {
|
||||
p1.segments.first().unwrap().ident
|
||||
} else {
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain mode");
|
||||
};
|
||||
|
||||
// parse mode
|
||||
let mode = match mode.as_str() {
|
||||
"Forward" => DiffMode::Forward,
|
||||
"Reverse" => DiffMode::Reverse,
|
||||
_ => {
|
||||
span_bug!(mode.span, "rustc_autodiff attribute contains invalid mode");
|
||||
}
|
||||
};
|
||||
|
||||
let width: u32 = match width_meta {
|
||||
MetaItemInner::MetaItem(MetaItem { path: p1, .. }) => {
|
||||
let w = p1.segments.first().unwrap().ident;
|
||||
match w.as_str().parse() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
span_bug!(w.span, "rustc_autodiff width should fit u32");
|
||||
}
|
||||
}
|
||||
}
|
||||
MetaItemInner::Lit(lit) => {
|
||||
if let LitKind::Int(val, _) = lit.kind {
|
||||
match val.get().try_into() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
span_bug!(lit.span, "rustc_autodiff width should fit u32");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
span_bug!(lit.span, "rustc_autodiff width should be an integer");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// First read the ret symbol from the attribute
|
||||
let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity else {
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain the return activity");
|
||||
};
|
||||
let ret_symbol = p1.segments.first().unwrap().ident;
|
||||
|
||||
// Then parse it into an actual DiffActivity
|
||||
let Ok(ret_activity) = DiffActivity::from_str(ret_symbol.as_str()) else {
|
||||
span_bug!(ret_symbol.span, "invalid return activity");
|
||||
};
|
||||
|
||||
// Now parse all the intermediate (input) activities
|
||||
let mut arg_activities: Vec<DiffActivity> = vec![];
|
||||
for arg in input_activities {
|
||||
let arg_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p2, .. }) = arg {
|
||||
match p2.segments.first() {
|
||||
Some(x) => x.ident,
|
||||
None => {
|
||||
span_bug!(
|
||||
arg.span(),
|
||||
"rustc_autodiff attribute must contain the input activity"
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
span_bug!(arg.span(), "rustc_autodiff attribute must contain the input activity");
|
||||
};
|
||||
|
||||
match DiffActivity::from_str(arg_symbol.as_str()) {
|
||||
Ok(arg_activity) => arg_activities.push(arg_activity),
|
||||
Err(_) => {
|
||||
span_bug!(arg_symbol.span, "invalid input activity");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(AutoDiffAttrs { mode, width, ret_activity, input_activity: arg_activities })
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
codegen_fn_attrs,
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub use ReprAttr::*;
|
||||
use rustc_abi::Align;
|
||||
pub use rustc_ast::attr::data_structures::*;
|
||||
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
|
||||
use rustc_ast::expand::typetree::TypeTree;
|
||||
use rustc_ast::token::DocFragmentKind;
|
||||
use rustc_ast::{AttrStyle, Path, ast};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
@@ -794,6 +797,103 @@ pub struct RustcCleanQueries {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
|
||||
pub struct RustcAutodiff {
|
||||
/// Conceptually either forward or reverse mode AD, as described in various autodiff papers and
|
||||
/// e.g. in the [JAX
|
||||
/// Documentation](https://jax.readthedocs.io/en/latest/_tutorials/advanced-autodiff.html#how-it-s-made-two-foundational-autodiff-functions).
|
||||
pub mode: DiffMode,
|
||||
/// A user-provided, batching width. If not given, we will default to 1 (no batching).
|
||||
/// Calling a differentiated, non-batched function through a loop 100 times is equivalent to:
|
||||
/// - Calling the function 50 times with a batch size of 2
|
||||
/// - Calling the function 25 times with a batch size of 4,
|
||||
/// etc. A batched function takes more (or longer) arguments, and might be able to benefit from
|
||||
/// cache locality, better re-usal of primal values, and other optimizations.
|
||||
/// We will (before LLVM's vectorizer runs) just generate most LLVM-IR instructions `width`
|
||||
/// times, so this massively increases code size. As such, values like 1024 are unlikely to
|
||||
/// work. We should consider limiting this to u8 or u16, but will leave it at u32 for
|
||||
/// experiments for now and focus on documenting the implications of a large width.
|
||||
pub width: u32,
|
||||
pub input_activity: ThinVec<DiffActivity>,
|
||||
pub ret_activity: DiffActivity,
|
||||
}
|
||||
|
||||
impl RustcAutodiff {
|
||||
pub fn has_primal_ret(&self) -> bool {
|
||||
matches!(self.ret_activity, DiffActivity::Active | DiffActivity::Dual)
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcAutodiff {
|
||||
pub fn has_ret_activity(&self) -> bool {
|
||||
self.ret_activity != DiffActivity::None
|
||||
}
|
||||
pub fn has_active_only_ret(&self) -> bool {
|
||||
self.ret_activity == DiffActivity::ActiveOnly
|
||||
}
|
||||
|
||||
pub fn error() -> Self {
|
||||
RustcAutodiff {
|
||||
mode: DiffMode::Error,
|
||||
width: 0,
|
||||
ret_activity: DiffActivity::None,
|
||||
input_activity: ThinVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source() -> Self {
|
||||
RustcAutodiff {
|
||||
mode: DiffMode::Source,
|
||||
width: 0,
|
||||
ret_activity: DiffActivity::None,
|
||||
input_activity: ThinVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.mode != DiffMode::Error
|
||||
}
|
||||
|
||||
pub fn is_source(&self) -> bool {
|
||||
self.mode == DiffMode::Source
|
||||
}
|
||||
pub fn apply_autodiff(&self) -> bool {
|
||||
!matches!(self.mode, DiffMode::Error | DiffMode::Source)
|
||||
}
|
||||
|
||||
pub fn into_item(
|
||||
self,
|
||||
source: String,
|
||||
target: String,
|
||||
inputs: Vec<TypeTree>,
|
||||
output: TypeTree,
|
||||
) -> AutoDiffItem {
|
||||
AutoDiffItem { source, target, inputs, output, attrs: self }
|
||||
}
|
||||
}
|
||||
|
||||
/// We generate one of these structs for each `#[autodiff(...)]` attribute.
|
||||
#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct AutoDiffItem {
|
||||
/// The name of the function getting differentiated
|
||||
pub source: String,
|
||||
/// The name of the function being generated
|
||||
pub target: String,
|
||||
pub attrs: RustcAutodiff,
|
||||
pub inputs: Vec<TypeTree>,
|
||||
pub output: TypeTree,
|
||||
}
|
||||
|
||||
impl fmt::Display for AutoDiffItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Differentiating {} -> {}", self.source, self.target)?;
|
||||
write!(f, " with attributes: {:?}", self.attrs)?;
|
||||
write!(f, " with inputs: {:?}", self.inputs)?;
|
||||
write!(f, " with output: {:?}", self.output)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents parsed *built-in* inert attributes.
|
||||
///
|
||||
/// ## Overview
|
||||
@@ -1186,6 +1286,9 @@ pub enum AttributeKind {
|
||||
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
||||
RustcAsPtr(Span),
|
||||
|
||||
/// Represents `#[rustc_autodiff]`.
|
||||
RustcAutodiff(Option<Box<RustcAutodiff>>),
|
||||
|
||||
/// Represents `#[rustc_default_body_unstable]`.
|
||||
RustcBodyStability {
|
||||
stability: DefaultBodyStability,
|
||||
|
||||
@@ -102,6 +102,7 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate {
|
||||
RustcAllowConstFnUnstable(..) => No,
|
||||
RustcAllowIncoherentImpl(..) => No,
|
||||
RustcAsPtr(..) => Yes,
|
||||
RustcAutodiff(..) => Yes,
|
||||
RustcBodyStability { .. } => No,
|
||||
RustcBuiltinMacro { .. } => Yes,
|
||||
RustcCaptureAnalysis => No,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use rustc_ast::ast::{Path, join_path_idents};
|
||||
use rustc_ast::attr::data_structures::CfgEntry;
|
||||
use rustc_ast::attr::version::RustcVersion;
|
||||
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
|
||||
use rustc_ast::token::{CommentKind, DocFragmentKind};
|
||||
use rustc_ast::{AttrId, AttrStyle, IntTy, UintTy};
|
||||
use rustc_ast_pretty::pp::Printer;
|
||||
@@ -191,7 +192,7 @@ fn print_attribute(&self, p: &mut Printer) {
|
||||
|
||||
print_tup!(A B C D E F G H);
|
||||
print_skip!(Span, (), ErrorGuaranteed, AttrId);
|
||||
print_disp!(u8, u16, u128, usize, bool, NonZero<u32>, Limit);
|
||||
print_disp!(u8, u16, u32, u128, usize, bool, NonZero<u32>, Limit);
|
||||
print_debug!(
|
||||
Symbol,
|
||||
Ident,
|
||||
@@ -206,4 +207,6 @@ fn print_attribute(&self, p: &mut Printer) {
|
||||
DefId,
|
||||
RustcVersion,
|
||||
CfgEntry,
|
||||
DiffActivity,
|
||||
DiffMode,
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
use rustc_ast::{self as ast, *};
|
||||
use rustc_ast_pretty::pprust::expr_to_string;
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
use rustc_errors::{Applicability, LintDiagnostic, msg};
|
||||
use rustc_errors::{Applicability, Diagnostic, msg};
|
||||
use rustc_feature::GateIssue;
|
||||
use rustc_hir::attrs::{AttributeKind, DocAttribute};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@@ -235,7 +235,7 @@ fn report_unsafe(
|
||||
&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
span: Span,
|
||||
decorate: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
decorate: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
// This comes from a macro that has `#[allow_internal_unsafe]`.
|
||||
if span.allows_unsafe() {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_errors::{Diag, LintBuffer, LintDiagnostic, MultiSpan};
|
||||
use rustc_errors::{Diag, Diagnostic, LintBuffer, LintDiagnostic, MultiSpan};
|
||||
use rustc_feature::Features;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
@@ -522,17 +522,28 @@ fn opt_span_lint<S: Into<MultiSpan>>(
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
);
|
||||
|
||||
// FIXME: These methods should not take an Into<MultiSpan> -- instead, callers should need to
|
||||
// set the span in their `decorate` function (preferably using set_span).
|
||||
/// Emit a lint at the appropriate level, with an optional associated span.
|
||||
///
|
||||
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
|
||||
#[track_caller]
|
||||
fn opt_span_diag_lint<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
decorate: impl for<'a> Diagnostic<'a, ()>,
|
||||
);
|
||||
|
||||
/// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`,
|
||||
/// typically generated by `#[derive(LintDiagnostic)]`).
|
||||
fn emit_span_lint<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: S,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
decorator: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
self.opt_span_lint(lint, Some(span), |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
});
|
||||
self.opt_span_diag_lint(lint, Some(span), decorator);
|
||||
}
|
||||
|
||||
/// Emit a lint at `span` from a lazily-constructed lint struct (some type that implements
|
||||
@@ -570,6 +581,12 @@ fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<
|
||||
});
|
||||
}
|
||||
|
||||
/// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
|
||||
/// generated by `#[derive(LintDiagnostic)]`).
|
||||
fn emit_diag_lint(&self, lint: &'static Lint, decorator: impl for<'a> Diagnostic<'a, ()>) {
|
||||
self.opt_span_diag_lint(lint, None as Option<Span>, decorator);
|
||||
}
|
||||
|
||||
/// Emit a lint at the appropriate level, with no associated span.
|
||||
///
|
||||
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
|
||||
@@ -644,6 +661,20 @@ fn opt_span_lint<S: Into<MultiSpan>>(
|
||||
}
|
||||
}
|
||||
|
||||
fn opt_span_diag_lint<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
decorate: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
let hir_id = self.last_node_with_lint_attrs;
|
||||
|
||||
match span {
|
||||
Some(s) => self.tcx.emit_node_span_lint(lint, hir_id, s, decorate),
|
||||
None => self.tcx.emit_node_lint(lint, hir_id, decorate),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
|
||||
self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs)
|
||||
}
|
||||
@@ -664,6 +695,15 @@ fn opt_span_lint<S: Into<MultiSpan>>(
|
||||
self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate)
|
||||
}
|
||||
|
||||
fn opt_span_diag_lint<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
decorator: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
self.builder.opt_span_diag_lint(lint, span.map(|s| s.into()), decorator)
|
||||
}
|
||||
|
||||
fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
|
||||
self.builder.lint_level(lint)
|
||||
}
|
||||
|
||||
@@ -269,7 +269,6 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
&& let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||
&& find_attr!(cx.tcx, fn_id, RustcAsPtr(_))
|
||||
{
|
||||
// FIXME: use `emit_node_lint` when `#[primary_span]` is added.
|
||||
cx.tcx.emit_node_span_lint(
|
||||
DANGLING_POINTERS_FROM_TEMPORARIES,
|
||||
expr.hir_id,
|
||||
|
||||
@@ -638,7 +638,7 @@ fn path_contains_attribute_kind(cx: &EarlyContext<'_>, path: &Path) {
|
||||
cx.emit_span_lint(
|
||||
BAD_USE_OF_FIND_ATTR,
|
||||
segment.span(),
|
||||
AttributeKindInFindAttr {},
|
||||
AttributeKindInFindAttr,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{Diag, LintDiagnostic, MultiSpan, msg};
|
||||
use rustc_errors::{Diag, Diagnostic, MultiSpan, msg};
|
||||
use rustc_feature::{Features, GateIssue};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
@@ -10,8 +10,8 @@
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::lint::{
|
||||
LevelAndSource, LintExpectation, LintLevelSource, ShallowLintLevelMap, lint_level,
|
||||
reveal_actual_level,
|
||||
LevelAndSource, LintExpectation, LintLevelSource, ShallowLintLevelMap, diag_lint_level,
|
||||
lint_level, reveal_actual_level,
|
||||
};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{RegisteredTools, TyCtxt};
|
||||
@@ -822,8 +822,11 @@ fn add(
|
||||
RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
|
||||
let name =
|
||||
tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
|
||||
let lint = RenamedLint { name: name.as_str(), replace, suggestion };
|
||||
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
|
||||
self.emit_span_lint(
|
||||
RENAMED_AND_REMOVED_LINTS,
|
||||
sp.into(),
|
||||
RenamedLint { name: name.as_str(), replace, suggestion },
|
||||
);
|
||||
}
|
||||
|
||||
// If this lint was renamed, apply the new lint instead of ignoring the
|
||||
@@ -844,8 +847,11 @@ fn add(
|
||||
if self.lint_added_lints {
|
||||
let name =
|
||||
tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
|
||||
let lint = RemovedLint { name: name.as_str(), reason };
|
||||
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
|
||||
self.emit_span_lint(
|
||||
RENAMED_AND_REMOVED_LINTS,
|
||||
sp.into(),
|
||||
RemovedLint { name: name.as_str(), reason },
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -861,8 +867,11 @@ fn add(
|
||||
from_rustc,
|
||||
}
|
||||
});
|
||||
let lint = UnknownLint { name, suggestion };
|
||||
self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint);
|
||||
self.emit_span_lint(
|
||||
UNKNOWN_LINTS,
|
||||
sp.into(),
|
||||
UnknownLint { name, suggestion },
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -967,8 +976,6 @@ pub fn lint_level(&self, lint: &'static Lint) -> LevelAndSource {
|
||||
|
||||
/// Used to emit a lint-related diagnostic based on the current state of
|
||||
/// this lint context.
|
||||
///
|
||||
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
|
||||
#[track_caller]
|
||||
pub(crate) fn opt_span_lint(
|
||||
&self,
|
||||
@@ -980,25 +987,34 @@ pub(crate) fn opt_span_lint(
|
||||
lint_level(self.sess, lint, level, span, decorate)
|
||||
}
|
||||
|
||||
/// Used to emit a lint-related diagnostic based on the current state of
|
||||
/// this lint context.
|
||||
#[track_caller]
|
||||
pub(crate) fn opt_span_diag_lint(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<MultiSpan>,
|
||||
decorator: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
let level = self.lint_level(lint);
|
||||
diag_lint_level(self.sess, lint, level, span, decorator)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn emit_span_lint(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
span: MultiSpan,
|
||||
decorate: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
decorator: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
let level = self.lint_level(lint);
|
||||
lint_level(self.sess, lint, level, Some(span), |lint| {
|
||||
decorate.decorate_lint(lint);
|
||||
});
|
||||
diag_lint_level(self.sess, lint, level, Some(span), decorator);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) {
|
||||
pub fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> Diagnostic<'a, ()>) {
|
||||
let level = self.lint_level(lint);
|
||||
lint_level(self.sess, lint, level, None, |lint| {
|
||||
decorate.decorate_lint(lint);
|
||||
});
|
||||
diag_lint_level(self.sess, lint, level, None, decorator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+192
-174
@@ -5,8 +5,8 @@
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
|
||||
ElidedLifetimeInPathSubdiag, EmissionGuarantee, Level, LintDiagnostic, MultiSpan,
|
||||
Subdiagnostic, SuggestionStyle, msg,
|
||||
ElidedLifetimeInPathSubdiag, EmissionGuarantee, Level, MultiSpan, Subdiagnostic,
|
||||
SuggestionStyle, msg,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@@ -24,7 +24,7 @@
|
||||
use crate::lifetime_syntax::LifetimeSyntaxCategories;
|
||||
|
||||
// array_into_iter.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust {$edition}"
|
||||
)]
|
||||
@@ -65,7 +65,7 @@ pub(crate) enum ShadowedIntoIterDiagSub {
|
||||
}
|
||||
|
||||
// autorefs.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("implicit autoref creates a reference to the dereference of a raw pointer")]
|
||||
#[note(
|
||||
"creating a reference requires the pointer target to be valid and imposes aliasing requirements"
|
||||
@@ -119,7 +119,7 @@ pub(crate) struct ImplicitUnsafeAutorefsSuggestion {
|
||||
}
|
||||
|
||||
// builtin.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("denote infinite loops with `loop {\"{\"} ... {\"}\"}`")]
|
||||
pub(crate) struct BuiltinWhileTrue {
|
||||
#[suggestion(
|
||||
@@ -132,7 +132,7 @@ pub(crate) struct BuiltinWhileTrue {
|
||||
pub replace: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the `{$ident}:` in this pattern is redundant")]
|
||||
pub(crate) struct BuiltinNonShorthandFieldPatterns {
|
||||
pub ident: Ident,
|
||||
@@ -145,7 +145,7 @@ pub(crate) struct BuiltinNonShorthandFieldPatterns {
|
||||
pub prefix: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum BuiltinUnsafe {
|
||||
#[diag(
|
||||
"`allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site"
|
||||
@@ -210,14 +210,14 @@ pub(crate) enum BuiltinUnsafe {
|
||||
GlobalAsm,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("missing documentation for {$article} {$desc}")]
|
||||
pub(crate) struct BuiltinMissingDoc<'a> {
|
||||
pub article: &'a str,
|
||||
pub desc: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("type could implement `Copy`; consider adding `impl Copy`")]
|
||||
pub(crate) struct BuiltinMissingCopyImpl;
|
||||
|
||||
@@ -227,14 +227,18 @@ pub(crate) struct BuiltinMissingDebugImpl<'a> {
|
||||
}
|
||||
|
||||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation"));
|
||||
diag.arg("debug", self.tcx.def_path_str(self.def_id));
|
||||
impl<'a> Diagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let Self { tcx, def_id } = self;
|
||||
Diag::new(
|
||||
dcx,
|
||||
level,
|
||||
msg!("type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation"),
|
||||
).with_arg("debug", tcx.def_path_str(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("anonymous parameters are deprecated and will be removed in the next edition")]
|
||||
pub(crate) struct BuiltinAnonymousParams<'a> {
|
||||
#[suggestion("try naming the parameter or explicitly ignoring it", code = "_: {ty_snip}")]
|
||||
@@ -242,7 +246,7 @@ pub(crate) struct BuiltinAnonymousParams<'a> {
|
||||
pub ty_snip: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unused doc comment")]
|
||||
pub(crate) struct BuiltinUnusedDocComment<'a> {
|
||||
pub kind: &'a str,
|
||||
@@ -260,7 +264,7 @@ pub(crate) enum BuiltinUnusedDocCommentSub {
|
||||
BlockHelp,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("functions generic over types or consts must be mangled")]
|
||||
pub(crate) struct BuiltinNoMangleGeneric {
|
||||
// Use of `#[no_mangle]` suggests FFI intent; correct
|
||||
@@ -274,20 +278,20 @@ pub(crate) struct BuiltinNoMangleGeneric {
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("const items should never be `#[no_mangle]`")]
|
||||
pub(crate) struct BuiltinConstNoMangle {
|
||||
#[suggestion("try a static value", code = "pub static ", applicability = "machine-applicable")]
|
||||
pub suggestion: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell"
|
||||
)]
|
||||
pub(crate) struct BuiltinMutablesTransmutes;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("use of an unstable feature")]
|
||||
pub(crate) struct BuiltinUnstableFeatures;
|
||||
|
||||
@@ -297,19 +301,20 @@ pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> {
|
||||
pub session: &'a Session,
|
||||
}
|
||||
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("`#[track_caller]` on async functions is a no-op"));
|
||||
diag.span_label(self.label, msg!("this function will not propagate the caller location"));
|
||||
impl<'a> Diagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(dcx, level, "`#[track_caller]` on async functions is a no-op")
|
||||
.with_span_label(self.label, "this function will not propagate the caller location");
|
||||
rustc_session::parse::add_feature_diagnostics(
|
||||
diag,
|
||||
&mut diag,
|
||||
self.session,
|
||||
sym::async_fn_track_caller,
|
||||
);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unreachable `pub` {$what}")]
|
||||
pub(crate) struct BuiltinUnreachablePub<'a> {
|
||||
pub what: &'a str,
|
||||
@@ -320,7 +325,7 @@ pub(crate) struct BuiltinUnreachablePub<'a> {
|
||||
pub help: bool,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the `expr` fragment specifier will accept more expressions in the 2024 edition")]
|
||||
pub(crate) struct MacroExprFragment2024 {
|
||||
#[suggestion(
|
||||
@@ -340,18 +345,18 @@ pub(crate) struct BuiltinTypeAliasBounds<'hir> {
|
||||
pub ty: Option<&'hir hir::Ty<'hir>>,
|
||||
}
|
||||
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(if self.in_where_clause {
|
||||
impl<'a> Diagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(dcx, level, if self.in_where_clause {
|
||||
msg!("where clauses on type aliases are not enforced")
|
||||
} else {
|
||||
msg!("bounds on generic parameters in type aliases are not enforced")
|
||||
});
|
||||
diag.span_label(self.label, msg!("will not be checked at usage sites of the type alias"));
|
||||
diag.note(msg!(
|
||||
"this is a known limitation of the type checker that may be lifted in a future edition.
|
||||
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information"
|
||||
));
|
||||
})
|
||||
.with_span_label(self.label, msg!("will not be checked at usage sites of the type alias"))
|
||||
.with_note(msg!(
|
||||
"this is a known limitation of the type checker that may be lifted in a future edition.
|
||||
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information"
|
||||
));
|
||||
if self.enable_feat_help {
|
||||
diag.help(msg!("add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics"));
|
||||
}
|
||||
@@ -413,10 +418,11 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"{$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters"
|
||||
)]
|
||||
@@ -425,7 +431,7 @@ pub(crate) struct BuiltinTrivialBounds<'a> {
|
||||
pub predicate: Clause<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("use of a double negation")]
|
||||
#[note(
|
||||
"the prefix `--` could be misinterpreted as a decrement operator which exists in other languages"
|
||||
@@ -445,7 +451,7 @@ pub(crate) struct BuiltinDoubleNegationsAddParens {
|
||||
pub end_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint {
|
||||
#[diag("`...` range patterns are deprecated")]
|
||||
Parenthesise {
|
||||
@@ -469,7 +475,7 @@ pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`{$kw}` is a keyword in the {$next} edition")]
|
||||
pub(crate) struct BuiltinKeywordIdents {
|
||||
pub kw: Ident,
|
||||
@@ -483,7 +489,7 @@ pub(crate) struct BuiltinKeywordIdents {
|
||||
pub prefix: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("outlives requirements can be inferred")]
|
||||
pub(crate) struct BuiltinExplicitOutlives {
|
||||
pub count: usize,
|
||||
@@ -505,7 +511,7 @@ pub(crate) struct BuiltinExplicitOutlivesSuggestion {
|
||||
pub applicability: Applicability,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes"
|
||||
)]
|
||||
@@ -517,7 +523,7 @@ pub(crate) struct BuiltinIncompleteFeatures {
|
||||
pub help: Option<BuiltinIncompleteFeaturesHelp>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the feature `{$name}` is internal to the compiler or standard library")]
|
||||
#[note("using it is strongly discouraged")]
|
||||
pub(crate) struct BuiltinInternalFeatures {
|
||||
@@ -542,11 +548,11 @@ pub(crate) struct BuiltinUnpermittedTypeInit<'a> {
|
||||
pub tcx: TyCtxt<'a>,
|
||||
}
|
||||
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(self.msg);
|
||||
diag.arg("ty", self.ty);
|
||||
diag.span_label(self.label, msg!("this code causes undefined behavior when executed"));
|
||||
impl<'a> Diagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(dcx, level, self.msg)
|
||||
.with_arg("ty", self.ty)
|
||||
.with_span_label(self.label, msg!("this code causes undefined behavior when executed"));
|
||||
if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
|
||||
// Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited.
|
||||
diag.span_label(
|
||||
@@ -554,7 +560,8 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
msg!("help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done"),
|
||||
);
|
||||
}
|
||||
self.sub.add_to_diag(diag);
|
||||
self.sub.add_to_diag(&mut diag);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,7 +631,7 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("dereferencing a null pointer")]
|
||||
pub(crate) struct BuiltinDerefNullptr {
|
||||
#[label("this code causes undefined behavior when executed")]
|
||||
@@ -633,7 +640,7 @@ pub(crate) struct BuiltinDerefNullptr {
|
||||
|
||||
// FIXME: migrate fluent::lint::builtin_asm_labels
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum BuiltinSpecialModuleNameUsed {
|
||||
#[diag("found module declaration for lib.rs")]
|
||||
#[note("lib.rs is the root of this crate's library target")]
|
||||
@@ -645,7 +652,7 @@ pub(crate) enum BuiltinSpecialModuleNameUsed {
|
||||
}
|
||||
|
||||
// deref_into_dyn_supertrait.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("this `Deref` implementation is covered by an implicit supertrait coercion")]
|
||||
pub(crate) struct SupertraitAsDerefTarget<'a> {
|
||||
pub self_ty: Ty<'a>,
|
||||
@@ -667,7 +674,7 @@ pub(crate) struct SupertraitAsDerefTargetLabel {
|
||||
}
|
||||
|
||||
// enum_intrinsics_non_enums.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the return value of `mem::discriminant` is unspecified when called with a non-enum type")]
|
||||
pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> {
|
||||
pub ty_param: Ty<'a>,
|
||||
@@ -677,7 +684,7 @@ pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> {
|
||||
pub note: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("the return value of `mem::variant_count` is unspecified when called with a non-enum type")]
|
||||
#[note(
|
||||
"the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum"
|
||||
@@ -705,7 +712,7 @@ pub(crate) struct ExpectationNote {
|
||||
}
|
||||
|
||||
// ptr_nulls.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum UselessPtrNullChecksDiag<'a> {
|
||||
#[diag(
|
||||
"function pointers are not nullable, so checking them for null will always return false"
|
||||
@@ -730,7 +737,7 @@ pub(crate) enum UselessPtrNullChecksDiag<'a> {
|
||||
FnRet { fn_name: Ident },
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum InvalidNullArgumentsDiag {
|
||||
#[diag(
|
||||
"calling this function with a null pointer is undefined behavior, even if the result of the function is unused"
|
||||
@@ -755,7 +762,7 @@ pub(crate) enum InvalidNullArgumentsDiag {
|
||||
}
|
||||
|
||||
// for_loops_over_fallibles.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement"
|
||||
)]
|
||||
@@ -838,7 +845,7 @@ pub(crate) enum UseLetUnderscoreIgnoreSuggestion {
|
||||
}
|
||||
|
||||
// drop_forget_useless.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("calls to `std::mem::drop` with a reference instead of an owned value does nothing")]
|
||||
pub(crate) struct DropRefDiag<'a> {
|
||||
pub arg_ty: Ty<'a>,
|
||||
@@ -848,7 +855,7 @@ pub(crate) struct DropRefDiag<'a> {
|
||||
pub sugg: UseLetUnderscoreIgnoreSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("calls to `std::mem::drop` with a value that implements `Copy` does nothing")]
|
||||
pub(crate) struct DropCopyDiag<'a> {
|
||||
pub arg_ty: Ty<'a>,
|
||||
@@ -858,7 +865,7 @@ pub(crate) struct DropCopyDiag<'a> {
|
||||
pub sugg: UseLetUnderscoreIgnoreSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("calls to `std::mem::forget` with a reference instead of an owned value does nothing")]
|
||||
pub(crate) struct ForgetRefDiag<'a> {
|
||||
pub arg_ty: Ty<'a>,
|
||||
@@ -868,7 +875,7 @@ pub(crate) struct ForgetRefDiag<'a> {
|
||||
pub sugg: UseLetUnderscoreIgnoreSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("calls to `std::mem::forget` with a value that implements `Copy` does nothing")]
|
||||
pub(crate) struct ForgetCopyDiag<'a> {
|
||||
pub arg_ty: Ty<'a>,
|
||||
@@ -878,7 +885,7 @@ pub(crate) struct ForgetCopyDiag<'a> {
|
||||
pub sugg: UseLetUnderscoreIgnoreSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing"
|
||||
)]
|
||||
@@ -903,7 +910,7 @@ pub(crate) struct UndroppedManuallyDropsSuggestion {
|
||||
}
|
||||
|
||||
// invalid_from_utf8.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum InvalidFromUtf8Diag {
|
||||
#[diag("calls to `{$method}` with an invalid literal are undefined behavior")]
|
||||
Unchecked {
|
||||
@@ -922,7 +929,7 @@ pub(crate) enum InvalidFromUtf8Diag {
|
||||
}
|
||||
|
||||
// interior_mutable_consts.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("mutation of an interior mutable `const` item with call to `{$method_name}`")]
|
||||
#[note("each usage of a `const` item creates a new temporary")]
|
||||
#[note("only the temporaries and never the original `const {$const_name}` will be modified")]
|
||||
@@ -957,7 +964,7 @@ pub(crate) enum ConstItemInteriorMutationsSuggestionStatic {
|
||||
}
|
||||
|
||||
// reference_casting.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum InvalidReferenceCastingDiag<'tcx> {
|
||||
#[diag(
|
||||
"casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`"
|
||||
@@ -1002,7 +1009,7 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> {
|
||||
}
|
||||
|
||||
// map_unit_fn.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`Iterator::map` call that discard the iterator's values")]
|
||||
#[note(
|
||||
"`Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated"
|
||||
@@ -1026,7 +1033,7 @@ pub(crate) struct MappingToUnit {
|
||||
}
|
||||
|
||||
// internal.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("prefer `{$preferred}` over `{$used}`, it has better performance")]
|
||||
#[note("a `use rustc_data_structures::fx::{$preferred}` may be necessary")]
|
||||
pub(crate) struct DefaultHashTypesDiag<'a> {
|
||||
@@ -1034,7 +1041,7 @@ pub(crate) struct DefaultHashTypesDiag<'a> {
|
||||
pub used: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("using `{$query}` can result in unstable query results")]
|
||||
#[note(
|
||||
"if you believe this case to be fine, allow this lint and add a comment explaining your rationale"
|
||||
@@ -1043,7 +1050,7 @@ pub(crate) struct QueryInstability {
|
||||
pub query: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`{$method}` accesses information that is not tracked by the query system")]
|
||||
#[note(
|
||||
"if you believe this case to be fine, allow this lint and add a comment explaining your rationale"
|
||||
@@ -1052,16 +1059,16 @@ pub(crate) struct QueryUntracked {
|
||||
pub method: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`")]
|
||||
pub(crate) struct SpanUseEqCtxtDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("using `Symbol::intern` on a string literal")]
|
||||
#[help("consider adding the symbol to `compiler/rustc_span/src/symbol.rs`")]
|
||||
pub(crate) struct SymbolInternStringLiteralDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("usage of `ty::TyKind::<kind>`")]
|
||||
pub(crate) struct TykindKind {
|
||||
#[suggestion(
|
||||
@@ -1072,12 +1079,12 @@ pub(crate) struct TykindKind {
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("usage of `ty::TyKind`")]
|
||||
#[help("try using `Ty` instead")]
|
||||
pub(crate) struct TykindDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("usage of qualified `ty::{$ty}`")]
|
||||
pub(crate) struct TyQualified {
|
||||
pub ty: String,
|
||||
@@ -1089,14 +1096,14 @@ pub(crate) struct TyQualified {
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("do not use `rustc_type_ir::inherent` unless you're inside of the trait solver")]
|
||||
#[note(
|
||||
"the method or struct you're looking for is likely defined somewhere else downstream in the compiler"
|
||||
)]
|
||||
pub(crate) struct TypeIrInherentUsage;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver"
|
||||
)]
|
||||
@@ -1105,12 +1112,12 @@ pub(crate) struct TyQualified {
|
||||
)]
|
||||
pub(crate) struct TypeIrTraitUsage;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("do not use `rustc_type_ir` unless you are implementing type system internals")]
|
||||
#[note("use `rustc_middle::ty` instead")]
|
||||
pub(crate) struct TypeIrDirectUse;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("non-glob import of `rustc_type_ir::inherent`")]
|
||||
pub(crate) struct NonGlobImportTypeIrInherent {
|
||||
#[suggestion(
|
||||
@@ -1122,18 +1129,18 @@ pub(crate) struct NonGlobImportTypeIrInherent {
|
||||
pub snippet: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("implementing `LintPass` by hand")]
|
||||
#[help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")]
|
||||
pub(crate) struct LintPassByHand;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$msg}")]
|
||||
pub(crate) struct BadOptAccessDiag<'a> {
|
||||
pub msg: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"dangerous use of `extern crate {$name}` which is not guaranteed to exist exactly once in the sysroot"
|
||||
)]
|
||||
@@ -1144,14 +1151,14 @@ pub(crate) struct ImplicitSysrootCrateImportDiag<'a> {
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("use of `AttributeKind` in `find_attr!(...)` invocation")]
|
||||
#[note("`find_attr!(...)` already imports `AttributeKind::*`")]
|
||||
#[help("remove `AttributeKind`")]
|
||||
pub(crate) struct AttributeKindInFindAttr {}
|
||||
pub(crate) struct AttributeKindInFindAttr;
|
||||
|
||||
// let_underscore.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum NonBindingLet {
|
||||
#[diag("non-binding let on a synchronization lock")]
|
||||
SyncLock {
|
||||
@@ -1213,7 +1220,7 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
}
|
||||
|
||||
// levels.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$lint_level}({$lint_source}) incompatible with previous forbid")]
|
||||
pub(crate) struct OverruledAttributeLint<'a> {
|
||||
#[label("overruled by previous forbid")]
|
||||
@@ -1224,7 +1231,7 @@ pub(crate) struct OverruledAttributeLint<'a> {
|
||||
pub sub: OverruledAttributeSub,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")]
|
||||
pub(crate) struct DeprecatedLintName<'a> {
|
||||
pub name: String,
|
||||
@@ -1233,7 +1240,7 @@ pub(crate) struct DeprecatedLintName<'a> {
|
||||
pub replace: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")]
|
||||
#[help("change it to {$replace}")]
|
||||
pub(crate) struct DeprecatedLintNameFromCommandLine<'a> {
|
||||
@@ -1243,7 +1250,7 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> {
|
||||
pub requested_level: RequestedLevel<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint `{$name}` has been renamed to `{$replace}`")]
|
||||
pub(crate) struct RenamedLint<'a> {
|
||||
pub name: &'a str,
|
||||
@@ -1264,7 +1271,7 @@ pub(crate) enum RenamedLintSuggestion<'a> {
|
||||
WithoutSpan { replace: &'a str },
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint `{$name}` has been renamed to `{$replace}`")]
|
||||
pub(crate) struct RenamedLintFromCommandLine<'a> {
|
||||
pub name: &'a str,
|
||||
@@ -1275,14 +1282,14 @@ pub(crate) struct RenamedLintFromCommandLine<'a> {
|
||||
pub requested_level: RequestedLevel<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint `{$name}` has been removed: {$reason}")]
|
||||
pub(crate) struct RemovedLint<'a> {
|
||||
pub name: &'a str,
|
||||
pub reason: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("lint `{$name}` has been removed: {$reason}")]
|
||||
pub(crate) struct RemovedLintFromCommandLine<'a> {
|
||||
pub name: &'a str,
|
||||
@@ -1291,7 +1298,7 @@ pub(crate) struct RemovedLintFromCommandLine<'a> {
|
||||
pub requested_level: RequestedLevel<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unknown lint: `{$name}`")]
|
||||
pub(crate) struct UnknownLint {
|
||||
pub name: String,
|
||||
@@ -1324,7 +1331,7 @@ pub(crate) enum UnknownLintSuggestion {
|
||||
WithoutSpan { replace: Symbol, from_rustc: bool },
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unknown lint: `{$name}`", code = E0602)]
|
||||
pub(crate) struct UnknownLintFromCommandLine<'a> {
|
||||
pub name: String,
|
||||
@@ -1334,7 +1341,7 @@ pub(crate) struct UnknownLintFromCommandLine<'a> {
|
||||
pub requested_level: RequestedLevel<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$level}({$name}) is ignored unless specified at crate level")]
|
||||
pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
|
||||
pub level: &'a str,
|
||||
@@ -1376,18 +1383,18 @@ pub(crate) struct DanglingPointersFromLocals<'tcx> {
|
||||
}
|
||||
|
||||
// multiple_supertrait_upcastable.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`{$ident}` is dyn-compatible and has multiple supertraits")]
|
||||
pub(crate) struct MultipleSupertraitUpcastable {
|
||||
pub ident: Ident,
|
||||
}
|
||||
|
||||
// non_ascii_idents.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("identifier contains non-ASCII characters")]
|
||||
pub(crate) struct IdentifierNonAsciiChar;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"identifier contains {$codepoints_len ->
|
||||
[one] { $identifier_type ->
|
||||
@@ -1421,7 +1428,7 @@ pub(crate) struct IdentifierUncommonCodepoints {
|
||||
pub identifier_type: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike")]
|
||||
pub(crate) struct ConfusableIdentifierPair {
|
||||
pub existing_sym: Symbol,
|
||||
@@ -1432,7 +1439,7 @@ pub(crate) struct ConfusableIdentifierPair {
|
||||
pub main_label: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables"
|
||||
)]
|
||||
@@ -1450,9 +1457,9 @@ pub(crate) struct NonFmtPanicUnused {
|
||||
}
|
||||
|
||||
// Used because of two suggestions based on one Option<Span>
|
||||
impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!(
|
||||
impl<'a> Diagnostic<'a, ()> for NonFmtPanicUnused {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(dcx, level, msg!(
|
||||
"panic message contains {$count ->
|
||||
[one] an unused
|
||||
*[other] unused
|
||||
@@ -1460,9 +1467,9 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
[one] placeholder
|
||||
*[other] placeholders
|
||||
}"
|
||||
));
|
||||
diag.arg("count", self.count);
|
||||
diag.note(msg!("this message is not used as a format string when given without arguments, but will be in Rust 2021"));
|
||||
))
|
||||
.with_arg("count", self.count)
|
||||
.with_note(msg!("this message is not used as a format string when given without arguments, but will be in Rust 2021"));
|
||||
if let Some(span) = self.suggestion {
|
||||
diag.span_suggestion(
|
||||
span.shrink_to_hi(),
|
||||
@@ -1482,10 +1489,11 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"panic message contains {$count ->
|
||||
[one] a brace
|
||||
@@ -1504,7 +1512,7 @@ pub(crate) struct NonFmtPanicBraces {
|
||||
}
|
||||
|
||||
// nonstandard_style.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$sort} `{$name}` should have an upper camel case name")]
|
||||
pub(crate) struct NonCamelCaseType<'a> {
|
||||
pub sort: &'a str,
|
||||
@@ -1532,7 +1540,7 @@ pub(crate) enum NonCamelCaseTypeSub {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$sort} `{$name}` should have a snake case name")]
|
||||
pub(crate) struct NonSnakeCaseDiag<'a> {
|
||||
pub sort: &'a str,
|
||||
@@ -1630,7 +1638,7 @@ pub(crate) struct NonUpperCaseGlobalSubTool {
|
||||
}
|
||||
|
||||
// noop_method_call.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("call to `.{$method}()` on a reference in this situation does nothing")]
|
||||
#[note(
|
||||
"the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed"
|
||||
@@ -1649,7 +1657,7 @@ pub(crate) struct NoopMethodCallDiag<'a> {
|
||||
pub suggest_derive: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type"
|
||||
)]
|
||||
@@ -1657,7 +1665,7 @@ pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type"
|
||||
)]
|
||||
@@ -1685,8 +1693,9 @@ pub(crate) enum NonLocalDefinitionsDiag {
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
impl<'a> Diagnostic<'a, ()> for NonLocalDefinitionsDiag {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(dcx, level, "");
|
||||
match self {
|
||||
NonLocalDefinitionsDiag::Impl {
|
||||
depth,
|
||||
@@ -1759,6 +1768,7 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1773,7 +1783,7 @@ pub(crate) struct NonLocalDefinitionsCargoUpdateNote {
|
||||
}
|
||||
|
||||
// precedence.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`-` has lower precedence than method calls, which might be unexpected")]
|
||||
#[note("e.g. `-4.abs()` equals `-4`; while `(-4).abs()` equals `4`")]
|
||||
pub(crate) struct AmbiguousNegativeLiteralsDiag {
|
||||
@@ -1808,7 +1818,7 @@ pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
|
||||
}
|
||||
|
||||
// disallowed_pass_by_ref.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("passing `{$ty}` by reference")]
|
||||
pub(crate) struct DisallowedPassByRefDiag {
|
||||
pub ty: String,
|
||||
@@ -1817,7 +1827,7 @@ pub(crate) struct DisallowedPassByRefDiag {
|
||||
}
|
||||
|
||||
// redundant_semicolon.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"unnecessary trailing {$multiple ->
|
||||
[true] semicolons
|
||||
@@ -1853,11 +1863,11 @@ pub(crate) struct DropTraitConstraintsDiag<'a> {
|
||||
}
|
||||
|
||||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped"));
|
||||
diag.arg("predicate", self.predicate);
|
||||
diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
|
||||
impl<'a> Diagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
Diag::new(dcx, level, msg!("bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped"))
|
||||
.with_arg("predicate", self.predicate)
|
||||
.with_arg("needs_drop", self.tcx.def_path_str(self.def_id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1867,10 +1877,10 @@ pub(crate) struct DropGlue<'a> {
|
||||
}
|
||||
|
||||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped"));
|
||||
diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
|
||||
impl<'a> Diagnostic<'a, ()> for DropGlue<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
Diag::new(dcx, level, msg!("types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped"))
|
||||
.with_arg("needs_drop", self.tcx.def_path_str(self.def_id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1925,7 +1935,7 @@ pub(crate) enum IntegerToPtrTransmutesSuggestion<'tcx> {
|
||||
}
|
||||
|
||||
// types.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("range endpoint is out of range for `{$ty}`")]
|
||||
pub(crate) struct RangeEndpointOutOfRange<'a> {
|
||||
pub ty: &'a str,
|
||||
@@ -1958,7 +1968,7 @@ pub(crate) enum UseInclusiveRange<'a> {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("literal out of range for `{$ty}`")]
|
||||
pub(crate) struct OverflowingBinHex<'a> {
|
||||
pub ty: &'a str,
|
||||
@@ -2016,7 +2026,7 @@ pub(crate) struct OverflowingBinHexSignBitSub<'a> {
|
||||
pub int_ty: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("literal out of range for `{$ty}`")]
|
||||
#[note("the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`")]
|
||||
pub(crate) struct OverflowingInt<'a> {
|
||||
@@ -2034,7 +2044,7 @@ pub(crate) struct OverflowingIntHelp<'a> {
|
||||
pub suggestion_ty: &'a str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("only `u8` can be cast into `char`")]
|
||||
pub(crate) struct OnlyCastu8ToChar {
|
||||
#[suggestion(
|
||||
@@ -2046,7 +2056,7 @@ pub(crate) struct OnlyCastu8ToChar {
|
||||
pub literal: u128,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("literal out of range for `{$ty}`")]
|
||||
#[note("the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`")]
|
||||
pub(crate) struct OverflowingUInt<'a> {
|
||||
@@ -2056,7 +2066,7 @@ pub(crate) struct OverflowingUInt<'a> {
|
||||
pub max: u128,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("literal out of range for `{$ty}`")]
|
||||
#[note(
|
||||
"the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`"
|
||||
@@ -2066,31 +2076,31 @@ pub(crate) struct OverflowingLiteral<'a> {
|
||||
pub lit: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("surrogate values are not valid for `char`")]
|
||||
#[note("`0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values")]
|
||||
pub(crate) struct SurrogateCharCast {
|
||||
pub literal: u128,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("value exceeds maximum `char` value")]
|
||||
#[note("maximum valid `char` value is `0x10FFFF`")]
|
||||
pub(crate) struct TooLargeCharCast {
|
||||
pub literal: u128,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type"
|
||||
)]
|
||||
pub(crate) struct UsesPowerAlignment;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("comparison is useless due to type limits")]
|
||||
pub(crate) struct UnusedComparisons;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum InvalidNanComparisons {
|
||||
#[diag("incorrect NaN comparison, NaN cannot be directly compared to itself")]
|
||||
EqNe {
|
||||
@@ -2120,7 +2130,7 @@ pub(crate) enum InvalidNanComparisonsSuggestion {
|
||||
Spanless,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum AmbiguousWidePointerComparisons<'a> {
|
||||
#[diag(
|
||||
"ambiguous wide pointer comparison, the comparison includes metadata which may not be expected"
|
||||
@@ -2233,7 +2243,7 @@ pub(crate) struct AmbiguousWidePointerComparisonsExpectSuggestion<'a> {
|
||||
pub(crate) after: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
|
||||
#[diag(
|
||||
"function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique"
|
||||
@@ -2309,12 +2319,16 @@ pub(crate) struct ImproperCTypes<'a> {
|
||||
}
|
||||
|
||||
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
|
||||
impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("`extern` {$desc} uses type `{$ty}`, which is not FFI-safe"));
|
||||
diag.arg("ty", self.ty);
|
||||
diag.arg("desc", self.desc);
|
||||
diag.span_label(self.label, msg!("not FFI-safe"));
|
||||
impl<'a> Diagnostic<'a, ()> for ImproperCTypes<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag = Diag::new(
|
||||
dcx,
|
||||
level,
|
||||
msg!("`extern` {$desc} uses type `{$ty}`, which is not FFI-safe"),
|
||||
)
|
||||
.with_arg("ty", self.ty)
|
||||
.with_arg("desc", self.desc)
|
||||
.with_span_label(self.label, msg!("not FFI-safe"));
|
||||
if let Some(help) = self.help {
|
||||
diag.help(help);
|
||||
}
|
||||
@@ -2322,6 +2336,7 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
if let Some(note) = self.span_note {
|
||||
diag.span_note(note, msg!("the type is defined here"));
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2332,34 +2347,34 @@ pub(crate) struct ImproperGpuKernelArg<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("function with the \"gpu-kernel\" ABI has a mangled name")]
|
||||
#[help("use `unsafe(no_mangle)` or `unsafe(export_name = \"<name>\")`")]
|
||||
#[note("mangled names make it hard to find the kernel, this is usually not intended")]
|
||||
pub(crate) struct MissingGpuKernelExportName;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("enum variant is more than three times larger ({$largest} bytes) than the next largest")]
|
||||
pub(crate) struct VariantSizeDifferencesDiag {
|
||||
pub largest: u64,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("atomic loads cannot have `Release` or `AcqRel` ordering")]
|
||||
#[help("consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`")]
|
||||
pub(crate) struct AtomicOrderingLoad;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("atomic stores cannot have `Acquire` or `AcqRel` ordering")]
|
||||
#[help("consider using ordering modes `Release`, `SeqCst` or `Relaxed`")]
|
||||
pub(crate) struct AtomicOrderingStore;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("memory fences cannot have `Relaxed` ordering")]
|
||||
#[help("consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`")]
|
||||
pub(crate) struct AtomicOrderingFence;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"`{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write"
|
||||
)]
|
||||
@@ -2371,7 +2386,7 @@ pub(crate) struct InvalidAtomicOrderingDiag {
|
||||
}
|
||||
|
||||
// unused.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unused {$op} that must be used")]
|
||||
pub(crate) struct UnusedOp<'a> {
|
||||
pub op: &'a str,
|
||||
@@ -2406,7 +2421,7 @@ pub(crate) enum UnusedOpSuggestion {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unused result of type `{$ty}`")]
|
||||
pub(crate) struct UnusedResult<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
@@ -2414,7 +2429,7 @@ pub(crate) struct UnusedResult<'a> {
|
||||
|
||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
||||
// pre/post strings
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"unused {$pre}{$count ->
|
||||
[one] closure
|
||||
@@ -2430,7 +2445,7 @@ pub(crate) struct UnusedClosure<'a> {
|
||||
|
||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
||||
// pre/post strings
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
"unused {$pre}{$count ->
|
||||
[one] coroutine
|
||||
@@ -2481,12 +2496,13 @@ pub(crate) enum UnusedDefSuggestion {
|
||||
}
|
||||
|
||||
// Needed because of def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(msg!("unused {$pre}`{$def}`{$post} that must be used"));
|
||||
diag.arg("pre", self.pre);
|
||||
diag.arg("post", self.post);
|
||||
diag.arg("def", self.cx.tcx.def_path_str(self.def_id));
|
||||
impl<'a> Diagnostic<'a, ()> for UnusedDef<'_, '_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
let mut diag =
|
||||
Diag::new(dcx, level, msg!("unused {$pre}`{$def}`{$post} that must be used"))
|
||||
.with_arg("pre", self.pre)
|
||||
.with_arg("post", self.post)
|
||||
.with_arg("def", self.cx.tcx.def_path_str(self.def_id));
|
||||
// check for #[must_use = "..."]
|
||||
if let Some(note) = self.note {
|
||||
diag.note(note.to_string());
|
||||
@@ -2494,10 +2510,11 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
if let Some(sugg) = self.suggestion {
|
||||
diag.subdiagnostic(sugg);
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("path statement drops value")]
|
||||
pub(crate) struct PathStatementDrop {
|
||||
#[subdiagnostic]
|
||||
@@ -2523,11 +2540,11 @@ pub(crate) enum PathStatementDropSub {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("path statement with no effect")]
|
||||
pub(crate) struct PathStatementNoEffect;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unnecessary {$delim} around {$item}")]
|
||||
pub(crate) struct UnusedDelim<'a> {
|
||||
pub delim: &'static str,
|
||||
@@ -2547,17 +2564,17 @@ pub(crate) struct UnusedDelimSuggestion {
|
||||
pub end_replace: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("braces around {$node} is unnecessary")]
|
||||
pub(crate) struct UnusedImportBracesDiag {
|
||||
pub node: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unnecessary allocation, use `&` instead")]
|
||||
pub(crate) struct UnusedAllocationDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unnecessary allocation, use `&mut` instead")]
|
||||
pub(crate) struct UnusedAllocationMutDiag;
|
||||
|
||||
@@ -2580,14 +2597,14 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("binding has unit type `()`")]
|
||||
pub(crate) struct UnitBindingsDiag {
|
||||
#[label("this pattern is inferred to be the unit type `()`")]
|
||||
pub label: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum InvalidAsmLabel {
|
||||
#[diag("avoid using named labels in inline assembly")]
|
||||
#[help("only local labels of the form `<number>:` should be used in inline asm")]
|
||||
@@ -3344,7 +3361,7 @@ pub(crate) struct AssociatedConstElidedLifetime {
|
||||
pub lifetimes_in_scope: MultiSpan,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("creating a {$shared_label}reference to mutable static")]
|
||||
pub(crate) struct RefOfMutStatic<'a> {
|
||||
#[label("{$shared_label}reference to mutable static")]
|
||||
@@ -3384,9 +3401,9 @@ pub(crate) enum MutRefSugg {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")]
|
||||
pub(crate) struct UnqualifiedLocalImportsDiag {}
|
||||
pub(crate) struct UnqualifiedLocalImportsDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag("will be parsed as a guarded string in Rust 2024")]
|
||||
@@ -3438,8 +3455,8 @@ pub(crate) struct MismatchedLifetimeSyntaxes {
|
||||
pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>,
|
||||
}
|
||||
|
||||
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
|
||||
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MismatchedLifetimeSyntaxes {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
let counts = self.inputs.len() + self.outputs.len();
|
||||
let message = match counts {
|
||||
LifetimeSyntaxCategories { hidden: 0, elided: 0, named: 0 } => {
|
||||
@@ -3462,7 +3479,7 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
|
||||
msg!("hiding or eliding a lifetime that's named elsewhere is confusing")
|
||||
}
|
||||
};
|
||||
diag.primary_message(message);
|
||||
let mut diag = Diag::new(dcx, level, message);
|
||||
|
||||
for s in self.inputs.hidden {
|
||||
diag.span_label(s, msg!("the lifetime is hidden here"));
|
||||
@@ -3497,6 +3514,7 @@ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
|
||||
diag.subdiagnostic(s);
|
||||
}
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3933,7 +3951,7 @@ pub(crate) struct MalformedOnConstAttrLint {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`Eq::assert_receiver_is_total_eq` should never be implemented by hand")]
|
||||
#[note("this method was used to add checks to the `Eq` derive macro")]
|
||||
pub(crate) struct EqInternalMethodImplemented;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rustc_hir::{self as hir, AmbigArg};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath};
|
||||
use rustc_middle::ty::{self, BottomUpFolder, Ty, TypeFoldable};
|
||||
use rustc_session::{declare_lint, declare_lint_pass};
|
||||
@@ -201,7 +201,7 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("opaque type `{$ty}` does not satisfy its associated type bounds")]
|
||||
struct OpaqueHiddenInferredBoundLint<'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
|
||||
@@ -77,7 +77,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
cx.emit_span_lint(
|
||||
UNQUALIFIED_LOCAL_IMPORTS,
|
||||
first_seg.ident.span,
|
||||
lints::UnqualifiedLocalImportsDiag {},
|
||||
lints::UnqualifiedLocalImportsDiag,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ macro_rules! arena_types {
|
||||
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>,
|
||||
[decode] attribute: rustc_hir::Attribute,
|
||||
[] name_set: rustc_data_structures::unord::UnordSet<rustc_span::Symbol>,
|
||||
[] autodiff_item: rustc_ast::expand::autodiff_attrs::AutoDiffItem,
|
||||
[] autodiff_item: rustc_hir::attrs::AutoDiffItem,
|
||||
[] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>,
|
||||
[] valtree: rustc_middle::ty::ValTreeKind<rustc_middle::ty::TyCtxt<'tcx>>,
|
||||
[] stable_order_of_exportable_impls:
|
||||
|
||||
@@ -51,14 +51,14 @@
|
||||
use std::hash::Hash;
|
||||
|
||||
use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use super::{KeyFingerprintStyle, SerializedDepNodeIndex};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::dep_graph::DepNodeKey;
|
||||
use crate::mir::mono::MonoItem;
|
||||
use crate::ty::{TyCtxt, tls};
|
||||
|
||||
@@ -168,58 +168,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for query keys as seen by dependency-node tracking.
|
||||
pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
|
||||
fn key_fingerprint_style() -> KeyFingerprintStyle;
|
||||
|
||||
/// This method turns a query key into an opaque `Fingerprint` to be used
|
||||
/// in `DepNode`.
|
||||
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint;
|
||||
|
||||
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String;
|
||||
|
||||
/// This method tries to recover the query key from the given `DepNode`,
|
||||
/// something which is needed when forcing `DepNode`s during red-green
|
||||
/// evaluation. The query system will only call this method if
|
||||
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
|
||||
/// It is always valid to return `None` here, in which case incremental
|
||||
/// compilation will treat the query as having changed instead of forcing it.
|
||||
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
|
||||
}
|
||||
|
||||
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
|
||||
impl<'tcx, T> DepNodeKey<'tcx> for T
|
||||
where
|
||||
T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
|
||||
{
|
||||
#[inline(always)]
|
||||
default fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||
KeyFingerprintStyle::Opaque
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
|
||||
tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
self.hash_stable(&mut hcx, &mut hasher);
|
||||
hasher.finish()
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
|
||||
// Make sure to print dep node params with reduced queries since printing
|
||||
// may themselves call queries, which may lead to (possibly untracked!)
|
||||
// query cycles.
|
||||
tcx.with_reduced_queries(|| format!("{self:?}"))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct stores function pointers and other metadata for a particular DepKind.
|
||||
///
|
||||
/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
|
||||
|
||||
@@ -1,11 +1,67 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
||||
|
||||
use crate::dep_graph::{DepNode, DepNodeKey, KeyFingerprintStyle};
|
||||
use crate::dep_graph::{DepNode, KeyFingerprintStyle};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
/// Trait for query keys as seen by dependency-node tracking.
|
||||
pub trait DepNodeKey<'tcx>: Debug + Sized {
|
||||
fn key_fingerprint_style() -> KeyFingerprintStyle;
|
||||
|
||||
/// This method turns a query key into an opaque `Fingerprint` to be used
|
||||
/// in `DepNode`.
|
||||
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint;
|
||||
|
||||
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String;
|
||||
|
||||
/// This method tries to recover the query key from the given `DepNode`,
|
||||
/// something which is needed when forcing `DepNode`s during red-green
|
||||
/// evaluation. The query system will only call this method if
|
||||
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
|
||||
/// It is always valid to return `None` here, in which case incremental
|
||||
/// compilation will treat the query as having changed instead of forcing it.
|
||||
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
|
||||
}
|
||||
|
||||
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
|
||||
impl<'tcx, T> DepNodeKey<'tcx> for T
|
||||
where
|
||||
T: for<'a> HashStable<StableHashingContext<'a>> + Debug,
|
||||
{
|
||||
#[inline(always)]
|
||||
default fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||
KeyFingerprintStyle::Opaque
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
|
||||
tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
self.hash_stable(&mut hcx, &mut hasher);
|
||||
hasher.finish()
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
|
||||
// Make sure to print dep node params with reduced queries since printing
|
||||
// may themselves call queries, which may lead to (possibly untracked!)
|
||||
// query cycles.
|
||||
tcx.with_reduced_queries(|| format!("{self:?}"))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DepNodeKey<'tcx> for () {
|
||||
#[inline(always)]
|
||||
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
use tracing::instrument;
|
||||
|
||||
pub use self::dep_node::{
|
||||
DepKind, DepKindVTable, DepNode, DepNodeKey, WorkProductId, dep_kind_from_label, label_strs,
|
||||
DepKind, DepKindVTable, DepNode, WorkProductId, dep_kind_from_label, label_strs,
|
||||
};
|
||||
pub use self::dep_node_key::DepNodeKey;
|
||||
pub use self::graph::{
|
||||
DepGraph, DepGraphData, DepNodeIndex, QuerySideEffect, TaskDepsRef, WorkProduct,
|
||||
WorkProductMap, hash_result,
|
||||
|
||||
@@ -299,7 +299,6 @@ fn explain_lint_level_source(
|
||||
/// for example:
|
||||
/// - [`TyCtxt::emit_node_span_lint`]
|
||||
/// - [`TyCtxt::node_span_lint`]
|
||||
/// - [`TyCtxt::emit_node_lint`]
|
||||
/// - [`TyCtxt::node_lint`]
|
||||
/// - `LintContext::opt_span_lint`
|
||||
///
|
||||
@@ -490,7 +489,6 @@ fn lint_level_impl(
|
||||
///
|
||||
/// - [`TyCtxt::emit_node_span_lint`]
|
||||
/// - [`TyCtxt::node_span_lint`]
|
||||
/// - [`TyCtxt::emit_node_lint`]
|
||||
/// - [`TyCtxt::node_lint`]
|
||||
/// - `LintContext::opt_span_lint`
|
||||
///
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use rustc_data_structures::sharded::ShardedHashMap;
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
pub use rustc_data_structures::vec_cache::VecCache;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_index::Idx;
|
||||
use rustc_span::def_id::{DefId, DefIndex};
|
||||
|
||||
use crate::dep_graph::DepNodeIndex;
|
||||
use crate::ich::StableHashingContext;
|
||||
|
||||
/// Traits that all query keys must satisfy.
|
||||
pub trait QueryCacheKey = Hash + Eq + Copy + Debug + for<'a> HashStable<StableHashingContext<'a>>;
|
||||
use crate::query::keys::QueryKey;
|
||||
|
||||
/// Trait for types that serve as an in-memory cache for query results,
|
||||
/// for a given key (argument) type and value (return) type.
|
||||
@@ -21,7 +15,7 @@
|
||||
/// Types implementing this trait are associated with actual key/value types
|
||||
/// by the `Cache` associated type of the `rustc_middle::query::Key` trait.
|
||||
pub trait QueryCache: Sized {
|
||||
type Key: QueryCacheKey;
|
||||
type Key: QueryKey;
|
||||
type Value: Copy;
|
||||
|
||||
/// Returns the cached value (and other information) associated with the
|
||||
@@ -53,7 +47,7 @@ fn default() -> Self {
|
||||
|
||||
impl<K, V> QueryCache for DefaultCache<K, V>
|
||||
where
|
||||
K: QueryCacheKey,
|
||||
K: QueryKey,
|
||||
V: Copy,
|
||||
{
|
||||
type Key = K;
|
||||
@@ -180,7 +174,7 @@ fn len(&self) -> usize {
|
||||
|
||||
impl<K, V> QueryCache for VecCache<K, V, DepNodeIndex>
|
||||
where
|
||||
K: Idx + QueryCacheKey,
|
||||
K: Idx + QueryKey,
|
||||
V: Copy,
|
||||
{
|
||||
type Key = K;
|
||||
|
||||
@@ -35,17 +35,16 @@ fn try_get_cached<'tcx, C>(tcx: TyCtxt<'tcx>, cache: &C, key: &C::Key) -> Option
|
||||
#[inline(always)]
|
||||
pub(crate) fn query_get_at<'tcx, C>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
execute_query: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
|
||||
query_cache: &C,
|
||||
span: Span,
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
key: C::Key,
|
||||
) -> C::Value
|
||||
where
|
||||
C: QueryCache,
|
||||
{
|
||||
match try_get_cached(tcx, query_cache, &key) {
|
||||
match try_get_cached(tcx, &query.cache, &key) {
|
||||
Some(value) => value,
|
||||
None => execute_query(tcx, span, key, QueryMode::Get).unwrap(),
|
||||
None => (query.execute_query_fn)(tcx, span, key, QueryMode::Get).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,15 +53,14 @@ pub(crate) fn query_get_at<'tcx, C>(
|
||||
#[inline]
|
||||
pub(crate) fn query_ensure<'tcx, C>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
execute_query: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
|
||||
query_cache: &C,
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
key: C::Key,
|
||||
ensure_mode: EnsureMode,
|
||||
) where
|
||||
C: QueryCache,
|
||||
{
|
||||
if try_get_cached(tcx, query_cache, &key).is_none() {
|
||||
execute_query(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode });
|
||||
if try_get_cached(tcx, &query.cache, &key).is_none() {
|
||||
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +69,7 @@ pub(crate) fn query_ensure<'tcx, C>(
|
||||
#[inline]
|
||||
pub(crate) fn query_ensure_error_guaranteed<'tcx, C, T>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
execute_query: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
|
||||
query_cache: &C,
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
key: C::Key,
|
||||
// This arg is needed to match the signature of `query_ensure`,
|
||||
// but should always be `EnsureMode::Ok`.
|
||||
@@ -84,10 +81,10 @@ pub(crate) fn query_ensure_error_guaranteed<'tcx, C, T>(
|
||||
{
|
||||
assert_matches!(ensure_mode, EnsureMode::Ok);
|
||||
|
||||
if let Some(res) = try_get_cached(tcx, query_cache, &key) {
|
||||
if let Some(res) = try_get_cached(tcx, &query.cache, &key) {
|
||||
erase::restore_val(res).map(drop)
|
||||
} else {
|
||||
execute_query(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode })
|
||||
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode })
|
||||
.map(erase::restore_val)
|
||||
.map(|res| res.map(drop))
|
||||
// Either we actually executed the query, which means we got a full `Result`,
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
//! Defines the set of legal keys that can be used in queries.
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::hir_id::OwnerId;
|
||||
use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol};
|
||||
|
||||
use crate::dep_graph::DepNodeIndex;
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::infer::canonical::CanonicalQueryInput;
|
||||
use crate::mir::mono::CollectionMode;
|
||||
use crate::query::{DefIdCache, DefaultCache, SingleCache, VecCache};
|
||||
@@ -20,9 +24,10 @@
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct LocalCrate;
|
||||
|
||||
/// The `Key` trait controls what types can legally be used as the key
|
||||
/// for a query.
|
||||
pub trait Key: Sized {
|
||||
pub trait QueryKeyBounds = Copy + Debug + Eq + Hash + for<'a> HashStable<StableHashingContext<'a>>;
|
||||
|
||||
/// Controls what types can legally be used as the key for a query.
|
||||
pub trait QueryKey: Sized + QueryKeyBounds {
|
||||
/// The type of in-memory cache to use for queries with this key type.
|
||||
///
|
||||
/// In practice the cache type must implement [`QueryCache`], though that
|
||||
@@ -47,15 +52,15 @@ fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsLocalKey: Key {
|
||||
type LocalKey;
|
||||
pub trait AsLocalQueryKey: QueryKey {
|
||||
type LocalQueryKey;
|
||||
|
||||
/// Given an instance of this key, what crate is it referring to?
|
||||
/// This is used to find the provider.
|
||||
fn as_local_key(&self) -> Option<Self::LocalKey>;
|
||||
fn as_local_key(&self) -> Option<Self::LocalQueryKey>;
|
||||
}
|
||||
|
||||
impl Key for () {
|
||||
impl QueryKey for () {
|
||||
type Cache<V> = SingleCache<V>;
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
@@ -63,37 +68,37 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::InstanceKind<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::InstanceKind<'tcx> {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.def_span(self.def_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::Instance<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::Instance<'tcx> {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.def_span(self.def_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
|
||||
impl<'tcx> QueryKey for mir::interpret::GlobalId<'tcx> {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.instance.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
|
||||
impl<'tcx> QueryKey for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::LitToConstInput<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::LitToConstInput<'tcx> {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for CrateNum {
|
||||
impl QueryKey for CrateNum {
|
||||
type Cache<V> = VecCache<Self, V, DepNodeIndex>;
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
@@ -101,16 +106,16 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsLocalKey for CrateNum {
|
||||
type LocalKey = LocalCrate;
|
||||
impl AsLocalQueryKey for CrateNum {
|
||||
type LocalQueryKey = LocalCrate;
|
||||
|
||||
#[inline(always)]
|
||||
fn as_local_key(&self) -> Option<Self::LocalKey> {
|
||||
fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
|
||||
(*self == LOCAL_CRATE).then_some(LocalCrate)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for OwnerId {
|
||||
impl QueryKey for OwnerId {
|
||||
type Cache<V> = VecCache<Self, V, DepNodeIndex>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
@@ -122,7 +127,7 @@ fn key_as_def_id(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for LocalDefId {
|
||||
impl QueryKey for LocalDefId {
|
||||
type Cache<V> = VecCache<Self, V, DepNodeIndex>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
@@ -134,7 +139,7 @@ fn key_as_def_id(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for DefId {
|
||||
impl QueryKey for DefId {
|
||||
type Cache<V> = DefIdCache<V>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
@@ -147,16 +152,16 @@ fn key_as_def_id(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsLocalKey for DefId {
|
||||
type LocalKey = LocalDefId;
|
||||
impl AsLocalQueryKey for DefId {
|
||||
type LocalQueryKey = LocalDefId;
|
||||
|
||||
#[inline(always)]
|
||||
fn as_local_key(&self) -> Option<Self::LocalKey> {
|
||||
fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
|
||||
self.as_local()
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for LocalModDefId {
|
||||
impl QueryKey for LocalModDefId {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.def_span(*self)
|
||||
}
|
||||
@@ -167,19 +172,19 @@ fn key_as_def_id(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for SimplifiedType {
|
||||
impl QueryKey for SimplifiedType {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (DefId, DefId) {
|
||||
impl QueryKey for (DefId, DefId) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.1.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (DefId, Ident) {
|
||||
impl QueryKey for (DefId, Ident) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.def_span(self.0)
|
||||
}
|
||||
@@ -190,73 +195,73 @@ fn key_as_def_id(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (LocalDefId, LocalDefId, Ident) {
|
||||
impl QueryKey for (LocalDefId, LocalDefId, Ident) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.1.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (CrateNum, DefId) {
|
||||
impl QueryKey for (CrateNum, DefId) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.1.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsLocalKey for (CrateNum, DefId) {
|
||||
type LocalKey = DefId;
|
||||
impl AsLocalQueryKey for (CrateNum, DefId) {
|
||||
type LocalQueryKey = DefId;
|
||||
|
||||
#[inline(always)]
|
||||
fn as_local_key(&self) -> Option<Self::LocalKey> {
|
||||
fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
|
||||
(self.0 == LOCAL_CRATE).then(|| self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (CrateNum, SimplifiedType) {
|
||||
impl QueryKey for (CrateNum, SimplifiedType) {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl AsLocalKey for (CrateNum, SimplifiedType) {
|
||||
type LocalKey = SimplifiedType;
|
||||
impl AsLocalQueryKey for (CrateNum, SimplifiedType) {
|
||||
type LocalQueryKey = SimplifiedType;
|
||||
|
||||
#[inline(always)]
|
||||
fn as_local_key(&self) -> Option<Self::LocalKey> {
|
||||
fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
|
||||
(self.0 == LOCAL_CRATE).then(|| self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (DefId, ty::SizedTraitKind) {
|
||||
impl QueryKey for (DefId, ty::SizedTraitKind) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for GenericArgsRef<'tcx> {
|
||||
impl<'tcx> QueryKey for GenericArgsRef<'tcx> {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (DefId, GenericArgsRef<'tcx>) {
|
||||
impl<'tcx> QueryKey for (DefId, GenericArgsRef<'tcx>) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::TraitRef<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::TraitRef<'tcx> {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.def_span(self.def_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for GenericArg<'tcx> {
|
||||
impl<'tcx> QueryKey for GenericArg<'tcx> {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for Ty<'tcx> {
|
||||
impl<'tcx> QueryKey for Ty<'tcx> {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
@@ -270,19 +275,19 @@ fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
|
||||
impl<'tcx> QueryKey for (Ty<'tcx>, Ty<'tcx>) {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::Clauses<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::Clauses<'tcx> {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> {
|
||||
impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.value.default_span(tcx)
|
||||
}
|
||||
@@ -292,19 +297,19 @@ fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for Symbol {
|
||||
impl QueryKey for Symbol {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for Option<Symbol> {
|
||||
impl QueryKey for Option<Symbol> {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for &'tcx OsStr {
|
||||
impl<'tcx> QueryKey for &'tcx OsStr {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
@@ -312,55 +317,55 @@ fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
|
||||
/// Canonical query goals correspond to abstract trait operations that
|
||||
/// are not tied to any crate in particular.
|
||||
impl<'tcx, T: Clone> Key for CanonicalQueryInput<'tcx, T> {
|
||||
impl<'tcx, T: QueryKeyBounds> QueryKey for CanonicalQueryInput<'tcx, T> {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Clone> Key for (CanonicalQueryInput<'tcx, T>, bool) {
|
||||
impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, bool) {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, rustc_abi::VariantIdx) {
|
||||
impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
||||
impl<'tcx> QueryKey for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
impl<'tcx> QueryKey for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
impl<'tcx> QueryKey for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for ty::Value<'tcx> {
|
||||
impl<'tcx> QueryKey for ty::Value<'tcx> {
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (LocalExpnId, &'tcx TokenStream) {
|
||||
impl<'tcx> QueryKey for (LocalExpnId, &'tcx TokenStream) {
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.expn_data().call_site
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
|
||||
impl<'tcx> QueryKey for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
|
||||
// Just forward to `Ty<'tcx>`
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
@@ -375,7 +380,7 @@ fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) {
|
||||
impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
|
||||
pub use self::caches::{
|
||||
DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache,
|
||||
};
|
||||
pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
|
||||
pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter};
|
||||
pub use self::keys::{AsLocalKey, Key, LocalCrate};
|
||||
pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey};
|
||||
pub use self::plumbing::{
|
||||
ActiveKeyStatus, CycleError, CycleErrorHandling, EnsureMode, IntoQueryParam, QueryMode,
|
||||
QueryState, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk,
|
||||
|
||||
@@ -157,6 +157,15 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
|
||||
/// Used when reporting query cycle errors and similar problems.
|
||||
pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
|
||||
|
||||
/// Function pointer that is called by the query methods on [`TyCtxt`] and
|
||||
/// friends[^1], after they have checked the in-memory cache and found no
|
||||
/// existing value for this key.
|
||||
///
|
||||
/// Transitive responsibilities include trying to load a disk-cached value
|
||||
/// if possible (incremental only), invoking the query provider if necessary,
|
||||
/// and putting the obtained value into the in-memory cache.
|
||||
///
|
||||
/// [^1]: [`TyCtxt`], [`TyCtxtAt`], [`TyCtxtEnsureOk`], [`TyCtxtEnsureDone`]
|
||||
pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>,
|
||||
}
|
||||
|
||||
@@ -383,7 +392,7 @@ pub mod $name {
|
||||
|
||||
pub type LocalKey<'tcx> = if_separate_provide_extern!(
|
||||
[$($modifiers)*]
|
||||
(<Key<'tcx> as $crate::query::AsLocalKey>::LocalKey)
|
||||
(<Key<'tcx> as $crate::query::AsLocalQueryKey>::LocalQueryKey)
|
||||
(Key<'tcx>)
|
||||
);
|
||||
|
||||
@@ -427,8 +436,8 @@ pub fn provided_to_erased<'tcx>(
|
||||
erase::erase_val(value)
|
||||
}
|
||||
|
||||
pub type Storage<'tcx> =
|
||||
<Key<'tcx> as $crate::query::Key>::Cache<Erased<Value<'tcx>>>;
|
||||
pub type Cache<'tcx> =
|
||||
<Key<'tcx> as $crate::query::QueryKey>::Cache<Erased<Value<'tcx>>>;
|
||||
|
||||
// Ensure that keys grow no larger than 88 bytes by accident.
|
||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||
@@ -495,8 +504,7 @@ pub fn $name(
|
||||
(crate::query::inner::query_ensure)
|
||||
)(
|
||||
self.tcx,
|
||||
self.tcx.query_system.query_vtables.$name.execute_query_fn,
|
||||
&self.tcx.query_system.query_vtables.$name.cache,
|
||||
&self.tcx.query_system.query_vtables.$name,
|
||||
$crate::query::IntoQueryParam::into_query_param(key),
|
||||
$crate::query::EnsureMode::Ok,
|
||||
)
|
||||
@@ -511,8 +519,7 @@ impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
|
||||
pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
|
||||
crate::query::inner::query_ensure(
|
||||
self.tcx,
|
||||
self.tcx.query_system.query_vtables.$name.execute_query_fn,
|
||||
&self.tcx.query_system.query_vtables.$name.cache,
|
||||
&self.tcx.query_system.query_vtables.$name,
|
||||
$crate::query::IntoQueryParam::into_query_param(key),
|
||||
$crate::query::EnsureMode::Done,
|
||||
);
|
||||
@@ -540,9 +547,8 @@ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
|
||||
|
||||
erase::restore_val::<$V>(inner::query_get_at(
|
||||
self.tcx,
|
||||
self.tcx.query_system.query_vtables.$name.execute_query_fn,
|
||||
&self.tcx.query_system.query_vtables.$name.cache,
|
||||
self.span,
|
||||
&self.tcx.query_system.query_vtables.$name,
|
||||
$crate::query::IntoQueryParam::into_query_param(key),
|
||||
))
|
||||
}
|
||||
@@ -575,7 +581,7 @@ pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
|
||||
/// Holds a `QueryVTable` for each query.
|
||||
pub struct QueryVTables<'tcx> {
|
||||
$(
|
||||
pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Storage<'tcx>>,
|
||||
pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Cache<'tcx>>,
|
||||
)*
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
use rustc_data_structures::sync::{
|
||||
self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
|
||||
};
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, LintDiagnostic, MultiSpan};
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
|
||||
@@ -2554,18 +2554,17 @@ pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
|
||||
/// generated by `#[derive(LintDiagnostic)]`).
|
||||
/// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
|
||||
/// by `#[derive(Diagnostic)]`).
|
||||
#[track_caller]
|
||||
pub fn emit_node_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
id: HirId,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
decorator: impl for<'a> Diagnostic<'a, ()>,
|
||||
) {
|
||||
self.node_lint(lint, id, |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
})
|
||||
let level = self.lint_level_at_node(lint, id);
|
||||
diag_lint_level(self.sess, lint, level, None, decorator);
|
||||
}
|
||||
|
||||
/// Emit a lint at the appropriate level for a hir node.
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{InliningThreshold, OptLevel};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::{inline, pass_manager as pm};
|
||||
|
||||
@@ -37,11 +36,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||
}
|
||||
|
||||
// FIXME(autodiff): replace this as per discussion in https://github.com/rust-lang/rust/pull/149033#discussion_r2535465880
|
||||
#[allow(deprecated)]
|
||||
if tcx.has_attr(def_id, sym::autodiff_forward)
|
||||
|| tcx.has_attr(def_id, sym::autodiff_reverse)
|
||||
|| tcx.has_attr(def_id, sym::rustc_autodiff)
|
||||
{
|
||||
if find_attr!(tcx, def_id, RustcAutodiff(..)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::mir::AssertKind;
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::query::QueryKey;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::lint::{self, Lint};
|
||||
use rustc_span::def_id::DefId;
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
@@ -299,6 +298,7 @@ fn check_attributes(
|
||||
| AttributeKind::RustcAllocatorZeroed
|
||||
| AttributeKind::RustcAllocatorZeroedVariant { .. }
|
||||
| AttributeKind::RustcAsPtr(..)
|
||||
| AttributeKind::RustcAutodiff(..)
|
||||
| AttributeKind::RustcBodyStability { .. }
|
||||
| AttributeKind::RustcBuiltinMacro { .. }
|
||||
| AttributeKind::RustcCaptureAnalysis
|
||||
@@ -390,22 +390,13 @@ fn check_attributes(
|
||||
Attribute::Unparsed(attr_item) => {
|
||||
style = Some(attr_item.style);
|
||||
match attr.path().as_slice() {
|
||||
[sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
|
||||
self.check_autodiff(hir_id, attr, span, target)
|
||||
}
|
||||
[
|
||||
// ok
|
||||
sym::allow
|
||||
| sym::expect
|
||||
| sym::warn
|
||||
| sym::deny
|
||||
| sym::forbid
|
||||
// internal
|
||||
| sym::rustc_on_unimplemented
|
||||
| sym::rustc_layout
|
||||
| sym::rustc_autodiff
|
||||
// crate-level attrs, are checked below
|
||||
| sym::feature,
|
||||
| sym::forbid,
|
||||
..
|
||||
] => {}
|
||||
[name, rest@..] => {
|
||||
@@ -1863,18 +1854,6 @@ fn check_mix_no_mangle_export(&self, hir_id: HirId, attrs: &[Attribute]) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `#[autodiff]` is applied to an item other than a function item.
|
||||
fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) {
|
||||
debug!("check_autodiff");
|
||||
match target {
|
||||
Target::Fn => {}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AutoDiffAttr { attr_span: span });
|
||||
self.abort.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_loop_match(&self, hir_id: HirId, attr_span: Span, target: Target) {
|
||||
let node_span = self.tcx.hir_span(hir_id);
|
||||
|
||||
|
||||
@@ -19,14 +19,6 @@
|
||||
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
|
||||
pub(crate) struct IncorrectDoNotRecommendLocation;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`#[autodiff]` should be applied to a function")]
|
||||
pub(crate) struct AutoDiffAttr {
|
||||
#[primary_span]
|
||||
#[label("not a function")]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`#[loop_match]` should be applied to a loop")]
|
||||
pub(crate) struct LoopMatchAttr {
|
||||
|
||||
@@ -270,6 +270,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared main part of both [`execute_query_incr_inner`] and [`execute_query_non_incr_inner`].
|
||||
#[inline(never)]
|
||||
fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
@@ -650,8 +651,10 @@ fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Called by a macro-generated impl of [`QueryVTable::execute_query_fn`],
|
||||
/// in non-incremental mode.
|
||||
#[inline(always)]
|
||||
pub(super) fn get_query_non_incr<'tcx, C: QueryCache>(
|
||||
pub(super) fn execute_query_non_incr_inner<'tcx, C: QueryCache>(
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
@@ -662,8 +665,10 @@ pub(super) fn get_query_non_incr<'tcx, C: QueryCache>(
|
||||
ensure_sufficient_stack(|| try_execute_query::<C, false>(query, tcx, span, key, None).0)
|
||||
}
|
||||
|
||||
/// Called by a macro-generated impl of [`QueryVTable::execute_query_fn`],
|
||||
/// in incremental mode.
|
||||
#[inline(always)]
|
||||
pub(super) fn get_query_incr<'tcx, C: QueryCache>(
|
||||
pub(super) fn execute_query_incr_inner<'tcx, C: QueryCache>(
|
||||
query: &'tcx QueryVTable<'tcx, C>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
use rustc_middle::queries::{self, ExternProviders, Providers};
|
||||
use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
|
||||
use rustc_middle::query::plumbing::{QuerySystem, QueryVTable};
|
||||
use rustc_middle::query::{AsLocalKey, QueryCache, QueryMode};
|
||||
use rustc_middle::query::{AsLocalQueryKey, QueryCache, QueryMode};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
};
|
||||
use rustc_middle::query::plumbing::QueryVTable;
|
||||
use rustc_middle::query::{
|
||||
Key, QueryCache, QueryJobId, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, erase,
|
||||
QueryCache, QueryJobId, QueryKey, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra,
|
||||
erase,
|
||||
};
|
||||
use rustc_middle::ty::codec::TyEncoder;
|
||||
use rustc_middle::ty::print::with_reduced_queries;
|
||||
@@ -274,7 +275,7 @@ fn mk_query_stack_frame_extra<'tcx, Cache>(
|
||||
) -> QueryStackFrameExtra
|
||||
where
|
||||
Cache: QueryCache,
|
||||
Cache::Key: Key,
|
||||
Cache::Key: QueryKey,
|
||||
{
|
||||
let def_id = key.key_as_def_id();
|
||||
|
||||
@@ -313,7 +314,7 @@ pub(crate) fn create_deferred_query_stack_frame<'tcx, C>(
|
||||
) -> QueryStackFrame<QueryStackDeferred<'tcx>>
|
||||
where
|
||||
C: QueryCache,
|
||||
C::Key: Key + DynSend + DynSync,
|
||||
C::Key: QueryKey + DynSend + DynSync,
|
||||
QueryVTable<'tcx, C>: DynSync,
|
||||
{
|
||||
let kind = vtable.dep_kind;
|
||||
@@ -475,7 +476,12 @@ pub(crate) mod query_impl { $(pub(crate) mod $name {
|
||||
use super::super::*;
|
||||
use ::rustc_middle::query::erase::{self, Erased};
|
||||
|
||||
pub(crate) mod get_query_incr {
|
||||
// It seems to be important that every query has its own monomorphic
|
||||
// copy of `execute_query_incr` and `execute_query_non_incr`.
|
||||
// Trying to inline these wrapper functions into their generic
|
||||
// "inner" helpers tends to break `tests/run-make/short-ice`.
|
||||
|
||||
pub(crate) mod execute_query_incr {
|
||||
use super::*;
|
||||
|
||||
// Adding `__rust_end_short_backtrace` marker to backtraces so that we emit the frames
|
||||
@@ -489,7 +495,7 @@ pub(crate) fn __rust_end_short_backtrace<'tcx>(
|
||||
) -> Option<Erased<queries::$name::Value<'tcx>>> {
|
||||
#[cfg(debug_assertions)]
|
||||
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
|
||||
execution::get_query_incr(
|
||||
execution::execute_query_incr_inner(
|
||||
&tcx.query_system.query_vtables.$name,
|
||||
tcx,
|
||||
span,
|
||||
@@ -499,7 +505,7 @@ pub(crate) fn __rust_end_short_backtrace<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod get_query_non_incr {
|
||||
pub(crate) mod execute_query_non_incr {
|
||||
use super::*;
|
||||
|
||||
#[inline(never)]
|
||||
@@ -509,7 +515,7 @@ pub(crate) fn __rust_end_short_backtrace<'tcx>(
|
||||
key: queries::$name::Key<'tcx>,
|
||||
__mode: QueryMode,
|
||||
) -> Option<Erased<queries::$name::Value<'tcx>>> {
|
||||
Some(execution::get_query_non_incr(
|
||||
Some(execution::execute_query_non_incr_inner(
|
||||
&tcx.query_system.query_vtables.$name,
|
||||
tcx,
|
||||
span,
|
||||
@@ -549,7 +555,7 @@ pub(crate) fn __rust_begin_short_backtrace<'tcx>(
|
||||
}
|
||||
|
||||
pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
|
||||
-> QueryVTable<'tcx, queries::$name::Storage<'tcx>>
|
||||
-> QueryVTable<'tcx, queries::$name::Cache<'tcx>>
|
||||
{
|
||||
QueryVTable {
|
||||
name: stringify!($name),
|
||||
@@ -604,9 +610,9 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
|
||||
format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
|
||||
description_fn: $crate::queries::_description_fns::$name,
|
||||
execute_query_fn: if incremental {
|
||||
query_impl::$name::get_query_incr::__rust_end_short_backtrace
|
||||
query_impl::$name::execute_query_incr::__rust_end_short_backtrace
|
||||
} else {
|
||||
query_impl::$name::get_query_non_incr::__rust_end_short_backtrace
|
||||
query_impl::$name::execute_query_non_incr::__rust_end_short_backtrace
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -615,7 +621,7 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
|
||||
pub(crate) enum VTableGetter {}
|
||||
|
||||
impl<'tcx> GetQueryVTable<'tcx> for VTableGetter {
|
||||
type Cache = rustc_middle::queries::$name::Storage<'tcx>;
|
||||
type Cache = rustc_middle::queries::$name::Cache<'tcx>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_vtable(tcx: TyCtxt<'tcx>) -> &'tcx QueryVTable<'tcx, Self::Cache> {
|
||||
|
||||
@@ -157,6 +157,8 @@
|
||||
Abi,
|
||||
AcqRel,
|
||||
Acquire,
|
||||
Active,
|
||||
ActiveOnly,
|
||||
Alignment,
|
||||
Arc,
|
||||
ArcWeak,
|
||||
@@ -213,6 +215,12 @@
|
||||
Deref,
|
||||
DispatchFromDyn,
|
||||
Display,
|
||||
Dual,
|
||||
DualOnly,
|
||||
Dualv,
|
||||
DualvOnly,
|
||||
Duplicated,
|
||||
DuplicatedOnly,
|
||||
DynTrait,
|
||||
Enum,
|
||||
Eq,
|
||||
@@ -310,6 +318,7 @@
|
||||
Slice,
|
||||
SliceIndex,
|
||||
Some,
|
||||
Source,
|
||||
SpanCtxt,
|
||||
Str,
|
||||
String,
|
||||
|
||||
@@ -422,7 +422,7 @@ pub enum RegionOriginNote<'a> {
|
||||
|
||||
impl Subdiagnostic for RegionOriginNote<'_> {
|
||||
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
let mut label_or_note = |span, msg: DiagMessage| {
|
||||
let label_or_note = |diag: &mut Diag<'_, G>, span, msg: DiagMessage| {
|
||||
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 span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
|
||||
@@ -436,22 +436,26 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
};
|
||||
match self {
|
||||
RegionOriginNote::Plain { span, msg } => {
|
||||
label_or_note(span, msg);
|
||||
label_or_note(diag, span, msg);
|
||||
}
|
||||
RegionOriginNote::WithName { span, msg, name, continues } => {
|
||||
label_or_note(span, msg);
|
||||
diag.arg("name", name);
|
||||
diag.arg("continues", continues);
|
||||
label_or_note(diag, span, msg);
|
||||
}
|
||||
RegionOriginNote::WithRequirement {
|
||||
span,
|
||||
requirement,
|
||||
expected_found: Some((expected, found)),
|
||||
} => {
|
||||
label_or_note(
|
||||
span,
|
||||
msg!(
|
||||
"...so that the {$requirement ->
|
||||
// `RegionOriginNote` can appear multiple times on one diagnostic with different
|
||||
// `requirement` values. Scope args per-note and eagerly translate to avoid
|
||||
// cross-note arg collisions.
|
||||
// See https://github.com/rust-lang/rust/issues/143872 for details.
|
||||
diag.store_args();
|
||||
diag.arg("requirement", requirement);
|
||||
let msg = diag.eagerly_translate(msg!(
|
||||
"...so that the {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
@@ -464,9 +468,9 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
),
|
||||
);
|
||||
diag.arg("requirement", requirement);
|
||||
));
|
||||
diag.restore_args();
|
||||
label_or_note(diag, span, msg);
|
||||
|
||||
diag.note_expected_found("", expected, "", found);
|
||||
}
|
||||
@@ -474,10 +478,10 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
// FIXME: this really should be handled at some earlier stage. Our
|
||||
// handling of region checking when type errors are present is
|
||||
// *terrible*.
|
||||
label_or_note(
|
||||
span,
|
||||
msg!(
|
||||
"...so that {$requirement ->
|
||||
diag.store_args();
|
||||
diag.arg("requirement", requirement);
|
||||
let msg = diag.eagerly_translate(msg!(
|
||||
"...so that {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
@@ -490,9 +494,9 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
),
|
||||
);
|
||||
diag.arg("requirement", requirement);
|
||||
));
|
||||
diag.restore_args();
|
||||
label_or_note(diag, span, msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ auto:
|
||||
- name: dist-aarch64-apple
|
||||
env:
|
||||
SCRIPT: >-
|
||||
./x.py dist bootstrap enzyme
|
||||
./x.py dist bootstrap
|
||||
--include-default-paths
|
||||
--host=aarch64-apple-darwin
|
||||
--target=aarch64-apple-darwin
|
||||
@@ -513,7 +513,6 @@ auto:
|
||||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
--set llvm.link-shared=true
|
||||
--set rust.lto=thin
|
||||
--set rust.codegen-units=1
|
||||
# Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | let sfoo: *mut Foo = &mut SFOO;
|
||||
| ^^^^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | let ptr = unsafe { &mut BB };
|
||||
| ^^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
|
||||
@@ -28,9 +28,9 @@ error: `Eq::assert_receiver_is_total_eq` should never be implemented by hand
|
||||
LL | fn assert_receiver_is_total_eq(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this method was used to add checks to the `Eq` derive macro
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #152336 <https://github.com/rust-lang/rust/issues/152336>
|
||||
= note: this method was used to add checks to the `Eq` derive macro
|
||||
note: the lint level is defined here
|
||||
--> $DIR/internal_eq_trait_method_impls.rs:1:21
|
||||
|
|
||||
|
||||
@@ -9,8 +9,8 @@ LL | | (Box::new(__static_ref_initialize()));
|
||||
LL | | });
|
||||
| |______________^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _y = &X;
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
@@ -18,8 +18,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | let _y = &mut X;
|
||||
| ^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y = &raw mut X;
|
||||
@@ -31,8 +31,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let ref _a = X;
|
||||
| ^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:54:25
|
||||
@@ -40,8 +40,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let (_b, _c) = (&X, &Y);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let (_b, _c) = (&raw const X, &Y);
|
||||
@@ -53,8 +53,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let (_b, _c) = (&X, &Y);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let (_b, _c) = (&X, &raw const Y);
|
||||
@@ -66,8 +66,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | foo(&X);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | foo(&raw const X);
|
||||
@@ -79,8 +79,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _ = Z.len();
|
||||
| ^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:72:33
|
||||
@@ -88,8 +88,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _ = format!("{:?}", Z);
|
||||
| ^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:76:18
|
||||
@@ -97,8 +97,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _v = &A.value;
|
||||
| ^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let _v = &raw const A.value;
|
||||
@@ -110,8 +110,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _s = &A.s.value;
|
||||
| ^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let _s = &raw const A.s.value;
|
||||
@@ -123,8 +123,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let ref _v = A.value;
|
||||
| ^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a mutable reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:14:14
|
||||
@@ -135,8 +135,8 @@ LL | &mut ($x.0)
|
||||
LL | let _x = bar!(FOO);
|
||||
| --------- in this macro invocation
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 12 warnings emitted
|
||||
|
||||
@@ -4,8 +4,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let _y = &X;
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
@@ -18,8 +18,8 @@ error: creating a mutable reference to mutable static
|
||||
LL | let _y = &mut X;
|
||||
| ^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y = &raw mut X;
|
||||
@@ -31,8 +31,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let ref _a = X;
|
||||
| ^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
error: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:54:25
|
||||
@@ -40,8 +40,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let (_b, _c) = (&X, &Y);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let (_b, _c) = (&raw const X, &Y);
|
||||
@@ -53,8 +53,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let (_b, _c) = (&X, &Y);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let (_b, _c) = (&X, &raw const Y);
|
||||
@@ -66,8 +66,8 @@ error: creating a shared reference to mutable static
|
||||
LL | foo(&X);
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | foo(&raw const X);
|
||||
@@ -79,8 +79,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let _ = Z.len();
|
||||
| ^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
error: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:72:33
|
||||
@@ -88,8 +88,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let _ = format!("{:?}", Z);
|
||||
| ^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
error: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:76:18
|
||||
@@ -97,8 +97,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let _v = &A.value;
|
||||
| ^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let _v = &raw const A.value;
|
||||
@@ -110,8 +110,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let _s = &A.s.value;
|
||||
| ^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | let _s = &raw const A.s.value;
|
||||
@@ -123,8 +123,8 @@ error: creating a shared reference to mutable static
|
||||
LL | let ref _v = A.value;
|
||||
| ^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
error: creating a mutable reference to mutable static
|
||||
--> $DIR/static-mut-refs.rs:14:14
|
||||
@@ -135,8 +135,8 @@ LL | &mut ($x.0)
|
||||
LL | let _x = bar!(FOO);
|
||||
| --------- in this macro invocation
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: panic message contains a brace
|
||||
LL | panic!("here's a brace: {");
|
||||
| ^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
|
||||
help: add a "{}" format string to use the message literally
|
||||
|
|
||||
@@ -18,8 +18,8 @@ warning: panic message contains a brace
|
||||
LL | unreachable!("here's a brace: {");
|
||||
| ^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to use the message literally
|
||||
|
|
||||
LL | unreachable!("{}", "here's a brace: {");
|
||||
@@ -31,8 +31,8 @@ warning: panic message contains a brace
|
||||
LL | std::panic!("another one: }");
|
||||
| ^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to use the message literally
|
||||
|
|
||||
LL | std::panic!("{}", "another one: }");
|
||||
@@ -44,8 +44,8 @@ warning: panic message contains an unused formatting placeholder
|
||||
LL | core::panic!("Hello {}");
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string when given without arguments, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add the missing argument
|
||||
|
|
||||
LL | core::panic!("Hello {}", ...);
|
||||
@@ -61,8 +61,8 @@ warning: panic message contains unused formatting placeholders
|
||||
LL | assert!(false, "{:03x} {test} bla");
|
||||
| ^^^^^^ ^^^^^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string when given without arguments, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add the missing arguments
|
||||
|
|
||||
LL | assert!(false, "{:03x} {test} bla", ...);
|
||||
@@ -120,8 +120,8 @@ warning: panic message contains braces
|
||||
LL | debug_assert!(false, "{{}} bla");
|
||||
| ^^^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to use the message literally
|
||||
|
|
||||
LL | debug_assert!(false, "{}", "{{}} bla");
|
||||
@@ -241,8 +241,8 @@ warning: panic message contains an unused formatting placeholder
|
||||
LL | panic!(concat!("{", "}"));
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string when given without arguments, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add the missing argument
|
||||
|
|
||||
LL | panic!(concat!("{", "}"), ...);
|
||||
@@ -258,8 +258,8 @@ warning: panic message contains braces
|
||||
LL | panic!(concat!("{", "{"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to use the message literally
|
||||
|
|
||||
LL | panic!("{}", concat!("{", "{"));
|
||||
@@ -271,8 +271,8 @@ warning: panic message contains an unused formatting placeholder
|
||||
LL | fancy_panic::fancy_panic!("test {} 123");
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: this message is not used as a format string when given without arguments, but will be in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
|
||||
warning: panic message is not a string literal
|
||||
--> $DIR/non-fmt-panic.rs:53:12
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | S1 { a: unsafe { &mut X1 } }
|
||||
| ^^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | static n: &'static usize = unsafe { &n_mut };
|
||||
| ^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | let _ = unsafe { (&TEST) as *const usize };
|
||||
| ^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
@@ -18,8 +18,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | let _ = unsafe { (&mut TEST) as *const usize };
|
||||
| ^^^^^^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
LL | let _ = unsafe { (&raw mut TEST) as *const usize };
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(static_mut_xc::a, 3);
|
||||
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
@@ -14,8 +14,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(static_mut_xc::a, 4);
|
||||
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-xc.rs:25:16
|
||||
@@ -23,8 +23,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(static_mut_xc::a, 5);
|
||||
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-xc.rs:28:16
|
||||
@@ -32,8 +32,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(static_mut_xc::a, 15);
|
||||
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-xc.rs:31:16
|
||||
@@ -41,8 +41,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(static_mut_xc::a, -3);
|
||||
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: creating a shared reference to mutable static
|
||||
--> $DIR/static-mut-xc.rs:33:18
|
||||
@@ -50,8 +50,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | static_bound(&static_mut_xc::a);
|
||||
| ^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
LL | static_bound(&raw const static_mut_xc::a);
|
||||
@@ -63,8 +63,8 @@ warning: creating a mutable reference to mutable static
|
||||
LL | static_bound_set(&mut static_mut_xc::a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
help: use `&raw mut` instead to create a raw pointer
|
||||
|
|
||||
LL | static_bound_set(&raw mut static_mut_xc::a);
|
||||
|
||||
@@ -4,8 +4,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
|
||||
| ^^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
|
||||
help: use `&raw const` instead to create a raw pointer
|
||||
|
|
||||
@@ -18,8 +18,8 @@ warning: creating a shared reference to mutable static
|
||||
LL | assert_eq!(S, *(S as *const *const u8));
|
||||
| ^ shared reference to mutable static
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
||||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//@ compile-flags: --crate-type=lib
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/143872
|
||||
|
||||
trait Project {
|
||||
type Ty;
|
||||
}
|
||||
|
||||
impl Project for &'_ &'static () {
|
||||
type Ty = ();
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn get<'s>(s: &'s str, _: ()) -> &'_ str;
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR lifetime may not live long enough
|
||||
s
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
error[E0803]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:13:12
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: ()) -> &'_ str;
|
||||
| ^^
|
||||
note: ...so that the method type is compatible with trait
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected `fn(&'s _, ()) -> &'s _`
|
||||
found `fn(&_, ()) -> &'static _`
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that the types are compatible
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected `<&&() as Project>`
|
||||
found `<&&'static () as Project>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:31
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected trait `<&&'s () as Project>`
|
||||
found trait `<&&'static () as Project>`
|
||||
note: the lifetime `'s` as defined here...
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:12
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^
|
||||
= note: ...does not necessarily outlive the static lifetime
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/compare-impl-item-conflicting-lifetime-requirements.rs:17:5
|
||||
|
|
||||
LL | fn get<'s>(s: &'s str, _: <&&'s () as Project>::Ty) -> &'static str {
|
||||
| ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | lifetime `'s` defined here
|
||||
| requires that `'s` must outlive `'static`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0803.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
Reference in New Issue
Block a user