Auto merge of #143363 - jdonszelmann:rollup-7cv1kql, r=jdonszelmann
Rollup of 6 pull requests Successful merges: - rust-lang/rust#134006 (setup typos check in CI) - rust-lang/rust#142876 (Port `#[target_feature]` to new attribute parsing infrastructure) - rust-lang/rust#143038 (avoid suggesting traits from private dependencies) - rust-lang/rust#143083 (Fix rustdoc not correctly showing attributes on re-exports) - rust-lang/rust#143283 (document optional jobs) - rust-lang/rust#143329 (minicore: use core's `diagnostic::on_unimplemented` messages) Failed merges: - rust-lang/rust#143237 (Port `#[no_implicit_prelude]` to the new attribute parsing infrastructure) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a413f77285
170 changed files with 951 additions and 518 deletions
23
.github/workflows/spellcheck.yml
vendored
Normal file
23
.github/workflows/spellcheck.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# This workflow runs spellcheck job
|
||||
|
||||
name: Spellcheck
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
name: run spellchecker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: check typos
|
||||
# sync version with src/tools/tidy/src/ext_tool_checks.rs in spellcheck_runner
|
||||
uses: crate-ci/typos@v1.34.0
|
||||
with:
|
||||
# sync target files with src/tools/tidy/src/ext_tool_checks.rs in check_impl
|
||||
files: ./compiler ./library ./src/bootstrap ./src/librustdoc
|
||||
config: ./typos.toml
|
||||
|
|
@ -4629,6 +4629,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_attr_data_structures",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ path = [
|
|||
"rustfmt.toml",
|
||||
"rust-bors.toml",
|
||||
"triagebot.toml",
|
||||
"typos.toml",
|
||||
"x",
|
||||
"x.ps1",
|
||||
"x.py",
|
||||
|
|
|
|||
|
|
@ -1344,7 +1344,7 @@ impl Expr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an expression with (when possible) *one* outter brace removed
|
||||
/// Returns an expression with (when possible) *one* outer brace removed
|
||||
pub fn maybe_unwrap_block(&self) -> &Expr {
|
||||
if let ExprKind::Block(block, None) = &self.kind
|
||||
&& let [stmt] = block.stmts.as_slice()
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
)?
|
||||
|
||||
// Methods in this trait have one of three forms, with the last two forms
|
||||
// only occuring on `MutVisitor`:
|
||||
// only occurring on `MutVisitor`:
|
||||
//
|
||||
// fn visit_t(&mut self, t: &mut T); // common
|
||||
// fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::AssocCtxt;
|
||||
use rustc_ast::*;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
|
||||
use rustc_hir::def::{DefKind, PerNS, Res};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
|
|
@ -1621,7 +1622,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let safety = self.lower_safety(h.safety, default_safety);
|
||||
|
||||
// Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
|
||||
let safety = if attrs.iter().any(|attr| attr.has_name(sym::target_feature))
|
||||
let safety = if find_attr!(attrs, AttributeKind::TargetFeature { .. })
|
||||
&& safety.is_safe()
|
||||
&& !self.tcx.sess.target.is_like_wasm
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
ast_passes_abi_cannot_be_coroutine =
|
||||
functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`
|
||||
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definiton
|
||||
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definition
|
||||
|
||||
ast_passes_abi_custom_safe_foreign_function =
|
||||
foreign functions with the "custom" ABI cannot be safe
|
||||
|
|
|
|||
|
|
@ -198,10 +198,10 @@ pub enum AttributeKind {
|
|||
Align { align: Align, span: Span },
|
||||
|
||||
/// Represents `#[rustc_allow_const_fn_unstable]`.
|
||||
AllowConstFnUnstable(ThinVec<Symbol>),
|
||||
AllowConstFnUnstable(ThinVec<Symbol>, Span),
|
||||
|
||||
/// Represents `#[allow_internal_unstable]`.
|
||||
AllowInternalUnstable(ThinVec<(Symbol, Span)>),
|
||||
AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
||||
AsPtr(Span),
|
||||
|
|
@ -309,6 +309,9 @@ pub enum AttributeKind {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[target_feature(enable = "...")]`
|
||||
TargetFeature(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
/// Represents `#[track_caller]`
|
||||
TrackCaller(Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ impl AttributeKind {
|
|||
RustcLayoutScalarValidRangeStart(..) => Yes,
|
||||
RustcObjectLifetimeDefault => No,
|
||||
SkipDuringMethodDispatch { .. } => No,
|
||||
TargetFeature(..) => No,
|
||||
TrackCaller(..) => Yes,
|
||||
Used { .. } => No,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ pub(crate) struct AllowInternalUnstableParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for AllowInternalUnstableParser {
|
||||
const PATH: &[Symbol] = &[sym::allow_internal_unstable];
|
||||
type Item = (Symbol, Span);
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowInternalUnstable;
|
||||
const CONVERT: ConvertFn<Self::Item> =
|
||||
|items, span| AttributeKind::AllowInternalUnstable(items, span);
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");
|
||||
|
||||
fn extend<'c>(
|
||||
|
|
@ -30,7 +31,8 @@ pub(crate) struct AllowConstFnUnstableParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable];
|
||||
type Item = Symbol;
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowConstFnUnstable;
|
||||
const CONVERT: ConvertFn<Self::Item> =
|
||||
|items, first_span| AttributeKind::AllowConstFnUnstable(items, first_span);
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");
|
||||
|
||||
fn extend<'c>(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use crate::{fluent_generated, parse_version};
|
|||
|
||||
/// Emitter of a builtin lint from `cfg_matches`.
|
||||
///
|
||||
/// Used to support emiting a lint (currently on check-cfg), either:
|
||||
/// Used to support emitting a lint (currently on check-cfg), either:
|
||||
/// - as an early buffered lint (in `rustc`)
|
||||
/// - or has a "normal" lint from HIR (in `rustdoc`)
|
||||
pub trait CfgMatchesLintEmitter {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use rustc_session::parse::feature_err;
|
|||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use super::{
|
||||
AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
|
||||
SingleAttributeParser,
|
||||
AcceptMapping, AttributeOrder, AttributeParser, CombineAttributeParser, ConvertFn,
|
||||
NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
|
||||
};
|
||||
use crate::context::{AcceptContext, FinalizeContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
|
|
@ -280,3 +280,53 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TargetFeatureParser;
|
||||
|
||||
impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
|
||||
type Item = (Symbol, Span);
|
||||
const PATH: &[Symbol] = &[sym::target_feature];
|
||||
const CONVERT: ConvertFn<Self::Item> = |items, span| AttributeKind::TargetFeature(items, span);
|
||||
const TEMPLATE: AttributeTemplate = template!(List: "enable = \"feat1, feat2\"");
|
||||
|
||||
fn extend<'c>(
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
args: &'c ArgParser<'_>,
|
||||
) -> impl IntoIterator<Item = Self::Item> + 'c {
|
||||
let mut features = Vec::new();
|
||||
let ArgParser::List(list) = args else {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return features;
|
||||
};
|
||||
for item in list.mixed() {
|
||||
let Some(name_value) = item.meta_item() else {
|
||||
cx.expected_name_value(item.span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
|
||||
// Validate name
|
||||
let Some(name) = name_value.path().word_sym() else {
|
||||
cx.expected_name_value(name_value.path().span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
if name != sym::enable {
|
||||
cx.expected_name_value(name_value.path().span(), Some(sym::enable));
|
||||
return features;
|
||||
}
|
||||
|
||||
// Use value
|
||||
let Some(name_value) = name_value.args().name_value() else {
|
||||
cx.expected_name_value(item.span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
let Some(value_str) = name_value.value_as_str() else {
|
||||
cx.expected_string_literal(name_value.value_span, Some(name_value.value_as_lit()));
|
||||
return features;
|
||||
};
|
||||
for feature in value_str.as_str().split(",") {
|
||||
features.push((Symbol::intern(feature), item.span()));
|
||||
}
|
||||
}
|
||||
features
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for Without
|
|||
}
|
||||
}
|
||||
|
||||
type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind;
|
||||
type ConvertFn<E> = fn(ThinVec<E>, Span) -> AttributeKind;
|
||||
|
||||
/// Alternative to [`AttributeParser`] that automatically handles state management.
|
||||
/// If multiple attributes appear on an element, combines the values of each into a
|
||||
|
|
@ -295,14 +295,21 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
|
|||
|
||||
/// Use in combination with [`CombineAttributeParser`].
|
||||
/// `Combine<T: CombineAttributeParser>` implements [`AttributeParser`].
|
||||
pub(crate) struct Combine<T: CombineAttributeParser<S>, S: Stage>(
|
||||
PhantomData<(S, T)>,
|
||||
ThinVec<<T as CombineAttributeParser<S>>::Item>,
|
||||
);
|
||||
pub(crate) struct Combine<T: CombineAttributeParser<S>, S: Stage> {
|
||||
phantom: PhantomData<(S, T)>,
|
||||
/// A list of all items produced by parsing attributes so far. One attribute can produce any amount of items.
|
||||
items: ThinVec<<T as CombineAttributeParser<S>>::Item>,
|
||||
/// The full span of the first attribute that was encountered.
|
||||
first_span: Option<Span>,
|
||||
}
|
||||
|
||||
impl<T: CombineAttributeParser<S>, S: Stage> Default for Combine<T, S> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default(), Default::default())
|
||||
Self {
|
||||
phantom: Default::default(),
|
||||
items: Default::default(),
|
||||
first_span: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -310,10 +317,18 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
|
|||
const ATTRIBUTES: AcceptMapping<Self, S> = &[(
|
||||
T::PATH,
|
||||
<T as CombineAttributeParser<S>>::TEMPLATE,
|
||||
|group: &mut Combine<T, S>, cx, args| group.1.extend(T::extend(cx, args)),
|
||||
|group: &mut Combine<T, S>, cx, args| {
|
||||
// Keep track of the span of the first attribute, for diagnostics
|
||||
group.first_span.get_or_insert(cx.attr_span);
|
||||
group.items.extend(T::extend(cx, args))
|
||||
},
|
||||
)];
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
if self.1.is_empty() { None } else { Some(T::CONVERT(self.1)) }
|
||||
if let Some(first_span) = self.first_span {
|
||||
Some(T::CONVERT(self.items, first_span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub(crate) struct ReprParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for ReprParser {
|
||||
type Item = (ReprAttr, Span);
|
||||
const PATH: &[Symbol] = &[sym::repr];
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::Repr;
|
||||
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::Repr(items);
|
||||
// FIXME(jdonszelmann): never used
|
||||
const TEMPLATE: AttributeTemplate =
|
||||
template!(List: "C | Rust | align(...) | packed(...) | <integer type> | transparent");
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
|||
|
||||
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
|
||||
use crate::attributes::codegen_attrs::{
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TrackCallerParser,
|
||||
UsedParser,
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser,
|
||||
TrackCallerParser, UsedParser,
|
||||
};
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
|
|
@ -118,6 +118,7 @@ attribute_parsers!(
|
|||
Combine<AllowConstFnUnstableParser>,
|
||||
Combine<AllowInternalUnstableParser>,
|
||||
Combine<ReprParser>,
|
||||
Combine<TargetFeatureParser>,
|
||||
// tidy-alphabetical-end
|
||||
|
||||
// tidy-alphabetical-start
|
||||
|
|
@ -189,7 +190,7 @@ impl Stage for Late {
|
|||
}
|
||||
}
|
||||
|
||||
/// used when parsing attributes for miscelaneous things *before* ast lowering
|
||||
/// used when parsing attributes for miscellaneous things *before* ast lowering
|
||||
pub struct Early;
|
||||
/// used when parsing attributes during ast lowering
|
||||
pub struct Late;
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ mod llvm_enzyme {
|
|||
/// so instead we manually build something that should pass the type checker.
|
||||
/// We also add a inline_asm line, as one more barrier for rustc to prevent inlining
|
||||
/// or const propagation. inline_asm will also triggers an Enzyme crash if due to another
|
||||
/// bug would ever try to accidentially differentiate this placeholder function body.
|
||||
/// bug would ever try to accidentally differentiate this placeholder function body.
|
||||
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
|
||||
/// from optimizing any arguments away.
|
||||
fn gen_enzyme_body(
|
||||
|
|
@ -606,7 +606,7 @@ mod llvm_enzyme {
|
|||
return body;
|
||||
}
|
||||
|
||||
// Everything from here onwards just tries to fullfil the return type. Fun!
|
||||
// Everything from here onwards just tries to fulfil the return type. Fun!
|
||||
|
||||
// having an active-only return means we'll drop the original return type.
|
||||
// So that can be treated identical to not having one in the first place.
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ fn call_simple_intrinsic<'ll, 'tcx>(
|
|||
sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
|
||||
sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the instrinsic fallback body.
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
|
||||
sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]),
|
||||
sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]),
|
||||
|
|
@ -118,7 +118,7 @@ fn call_simple_intrinsic<'ll, 'tcx>(
|
|||
sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
|
||||
sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the instrinsic fallback body.
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
|
||||
sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]),
|
||||
sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ unsafe extern "C" {
|
|||
pub(crate) fn LLVMDumpValue(V: &Value);
|
||||
pub(crate) fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
|
||||
pub(crate) fn LLVMGetReturnType(T: &Type) -> &Type;
|
||||
pub(crate) fn LLVMGetParams(Fnc: &Value, parms: *mut &Value);
|
||||
pub(crate) fn LLVMGetParams(Fnc: &Value, params: *mut &Value);
|
||||
pub(crate) fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> Option<&Value>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ fn emit_xtensa_va_arg<'ll, 'tcx>(
|
|||
|
||||
// On big-endian, for values smaller than the slot size we'd have to align the read to the end
|
||||
// of the slot rather than the start. While the ISA and GCC support big-endian, all the Xtensa
|
||||
// targets supported by rustc are litte-endian so don't worry about it.
|
||||
// targets supported by rustc are little-endian so don't worry about it.
|
||||
|
||||
// if from_regsave {
|
||||
// unsafe { *regsave_value_ptr }
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
|
|||
|
||||
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
|
||||
|
||||
codegen_ssa_feature_not_valid = the feature named `{$feature}` is not valid for this target
|
||||
.label = `{$feature}` is not valid for this target
|
||||
.help = consider removing the leading `+` in the feature name
|
||||
|
||||
codegen_ssa_field_associated_value_expected = associated value expected for `{$name}`
|
||||
|
||||
codegen_ssa_forbidden_ctarget_feature =
|
||||
|
|
@ -289,7 +293,7 @@ codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executab
|
|||
|
||||
codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}`
|
||||
|
||||
codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings
|
||||
codegen_ssa_thorin_mixed_input_encodings = input objects have mixed encodings
|
||||
|
||||
codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections
|
||||
|
||||
|
|
|
|||
|
|
@ -2767,7 +2767,7 @@ fn add_upstream_rust_crates(
|
|||
|
||||
if sess.target.is_like_aix {
|
||||
// Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
|
||||
// the dependency name when outputing a shared library. Thus, `ld` will
|
||||
// the dependency name when outputting a shared library. Thus, `ld` will
|
||||
// use the full path to shared libraries as the dependency if passed it
|
||||
// by default unless `noipath` is passed.
|
||||
// https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command.
|
||||
|
|
@ -3051,7 +3051,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
|||
// Supported architecture names can be found in the source:
|
||||
// https://github.com/apple-oss-distributions/ld64/blob/ld64-951.9/src/abstraction/MachOFileAbstraction.hpp#L578-L648
|
||||
//
|
||||
// Intentially verbose to ensure that the list always matches correctly
|
||||
// Intentionally verbose to ensure that the list always matches correctly
|
||||
// with the list in the source above.
|
||||
let ld64_arch = match llvm_arch {
|
||||
"armv7k" => "armv7k",
|
||||
|
|
@ -3118,7 +3118,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
|||
// We do not currently know the actual SDK version though, so we have a few options:
|
||||
// 1. Use the minimum version supported by rustc.
|
||||
// 2. Use the same as the deployment target.
|
||||
// 3. Use an arbitary recent version.
|
||||
// 3. Use an arbitrary recent version.
|
||||
// 4. Omit the version.
|
||||
//
|
||||
// The first option is too low / too conservative, and means that users will not get the
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
|
|||
"n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2,
|
||||
"n64" if !is_32bit => {}
|
||||
"" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
|
||||
"" => sess.dcx().fatal("LLVM ABI must be specifed for 64-bit MIPS targets"),
|
||||
"" => sess.dcx().fatal("LLVM ABI must be specified for 64-bit MIPS targets"),
|
||||
s if is_32bit => {
|
||||
sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,49 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
});
|
||||
}
|
||||
}
|
||||
AttributeKind::TargetFeature(features, attr_span) => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(*attr_span, "target_feature applied to non-fn");
|
||||
continue;
|
||||
};
|
||||
let safe_target_features =
|
||||
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
|
||||
codegen_fn_attrs.safe_target_features = safe_target_features;
|
||||
if safe_target_features {
|
||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||
// The `#[target_feature]` attribute is allowed on
|
||||
// WebAssembly targets on all functions. Prior to stabilizing
|
||||
// the `target_feature_11` feature, `#[target_feature]` was
|
||||
// only permitted on unsafe functions because on most targets
|
||||
// execution of instructions that are not supported is
|
||||
// considered undefined behavior. For WebAssembly which is a
|
||||
// 100% safe target at execution time it's not possible to
|
||||
// execute undefined instructions, and even if a future
|
||||
// feature was added in some form for this it would be a
|
||||
// deterministic trap. There is no undefined behavior when
|
||||
// executing WebAssembly so `#[target_feature]` is allowed
|
||||
// on safe functions (but again, only for WebAssembly)
|
||||
//
|
||||
// Note that this is also allowed if `actually_rustdoc` so
|
||||
// if a target is documenting some wasm-specific code then
|
||||
// it's not spuriously denied.
|
||||
//
|
||||
// Now that `#[target_feature]` is permitted on safe functions,
|
||||
// this exception must still exist for allowing the attribute on
|
||||
// `main`, `start`, and other functions that are not usually
|
||||
// allowed.
|
||||
} else {
|
||||
check_target_feature_trait_unsafe(tcx, did, *attr_span);
|
||||
}
|
||||
}
|
||||
from_target_feature_attr(
|
||||
tcx,
|
||||
did,
|
||||
features,
|
||||
rust_target_features,
|
||||
&mut codegen_fn_attrs.target_features,
|
||||
);
|
||||
}
|
||||
AttributeKind::TrackCaller(attr_span) => {
|
||||
let is_closure = tcx.is_closure_like(did.to_def_id());
|
||||
|
||||
|
|
@ -190,49 +233,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
|
||||
}
|
||||
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
|
||||
sym::target_feature => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(attr.span(), "target_feature applied to non-fn");
|
||||
continue;
|
||||
};
|
||||
let safe_target_features =
|
||||
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
|
||||
codegen_fn_attrs.safe_target_features = safe_target_features;
|
||||
if safe_target_features {
|
||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||
// The `#[target_feature]` attribute is allowed on
|
||||
// WebAssembly targets on all functions. Prior to stabilizing
|
||||
// the `target_feature_11` feature, `#[target_feature]` was
|
||||
// only permitted on unsafe functions because on most targets
|
||||
// execution of instructions that are not supported is
|
||||
// considered undefined behavior. For WebAssembly which is a
|
||||
// 100% safe target at execution time it's not possible to
|
||||
// execute undefined instructions, and even if a future
|
||||
// feature was added in some form for this it would be a
|
||||
// deterministic trap. There is no undefined behavior when
|
||||
// executing WebAssembly so `#[target_feature]` is allowed
|
||||
// on safe functions (but again, only for WebAssembly)
|
||||
//
|
||||
// Note that this is also allowed if `actually_rustdoc` so
|
||||
// if a target is documenting some wasm-specific code then
|
||||
// it's not spuriously denied.
|
||||
//
|
||||
// Now that `#[target_feature]` is permitted on safe functions,
|
||||
// this exception must still exist for allowing the attribute on
|
||||
// `main`, `start`, and other functions that are not usually
|
||||
// allowed.
|
||||
} else {
|
||||
check_target_feature_trait_unsafe(tcx, did, attr.span());
|
||||
}
|
||||
}
|
||||
from_target_feature_attr(
|
||||
tcx,
|
||||
did,
|
||||
attr,
|
||||
rust_target_features,
|
||||
&mut codegen_fn_attrs.target_features,
|
||||
);
|
||||
}
|
||||
sym::linkage => {
|
||||
if let Some(val) = attr.value_str() {
|
||||
let linkage = Some(linkage_by_name(tcx, did, val.as_str()));
|
||||
|
|
@ -536,10 +536,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
.map(|features| (features.name.as_str(), true))
|
||||
.collect(),
|
||||
) {
|
||||
let span = tcx
|
||||
.get_attrs(did, sym::target_feature)
|
||||
.next()
|
||||
.map_or_else(|| tcx.def_span(did), |a| a.span());
|
||||
let span =
|
||||
find_attr!(tcx.get_all_attrs(did), AttributeKind::TargetFeature(_, span) => *span)
|
||||
.unwrap_or_else(|| tcx.def_span(did));
|
||||
|
||||
tcx.dcx()
|
||||
.create_err(errors::TargetFeatureDisableOrEnable {
|
||||
features,
|
||||
|
|
|
|||
|
|
@ -1292,3 +1292,14 @@ pub(crate) struct NoMangleNameless {
|
|||
pub span: Span,
|
||||
pub definition: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_feature_not_valid)]
|
||||
pub(crate) struct FeatureNotValid<'a> {
|
||||
pub feature: &'a str,
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[help]
|
||||
pub plus_hint: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use rustc_attr_data_structures::InstructionSetAttr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
|
|
@ -12,110 +10,85 @@ use rustc_session::Session;
|
|||
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_target::target_features::{self, RUSTC_SPECIFIC_FEATURES, Stability};
|
||||
use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::errors;
|
||||
use crate::errors::FeatureNotValid;
|
||||
use crate::{errors, target_features};
|
||||
|
||||
/// Compute the enabled target features from the `#[target_feature]` function attribute.
|
||||
/// Enabled target features are added to `target_features`.
|
||||
pub(crate) fn from_target_feature_attr(
|
||||
tcx: TyCtxt<'_>,
|
||||
did: LocalDefId,
|
||||
attr: &hir::Attribute,
|
||||
features: &[(Symbol, Span)],
|
||||
rust_target_features: &UnordMap<String, target_features::Stability>,
|
||||
target_features: &mut Vec<TargetFeature>,
|
||||
) {
|
||||
let Some(list) = attr.meta_item_list() else { return };
|
||||
let bad_item = |span| {
|
||||
let msg = "malformed `target_feature` attribute input";
|
||||
let code = "enable = \"..\"";
|
||||
tcx.dcx()
|
||||
.struct_span_err(span, msg)
|
||||
.with_span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders)
|
||||
.emit();
|
||||
};
|
||||
let rust_features = tcx.features();
|
||||
let abi_feature_constraints = tcx.sess.target.abi_required_features();
|
||||
for item in list {
|
||||
// Only `enable = ...` is accepted in the meta-item list.
|
||||
if !item.has_name(sym::enable) {
|
||||
bad_item(item.span());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Must be of the form `enable = "..."` (a string).
|
||||
let Some(value) = item.value_str() else {
|
||||
bad_item(item.span());
|
||||
for &(feature, feature_span) in features {
|
||||
let feature_str = feature.as_str();
|
||||
let Some(stability) = rust_target_features.get(feature_str) else {
|
||||
let plus_hint = feature_str
|
||||
.strip_prefix('+')
|
||||
.is_some_and(|stripped| rust_target_features.contains_key(stripped));
|
||||
tcx.dcx().emit_err(FeatureNotValid {
|
||||
feature: feature_str,
|
||||
span: feature_span,
|
||||
plus_hint,
|
||||
});
|
||||
continue;
|
||||
};
|
||||
|
||||
// We allow comma separation to enable multiple features.
|
||||
for feature in value.as_str().split(',') {
|
||||
let Some(stability) = rust_target_features.get(feature) else {
|
||||
let msg = format!("the feature named `{feature}` is not valid for this target");
|
||||
let mut err = tcx.dcx().struct_span_err(item.span(), msg);
|
||||
err.span_label(item.span(), format!("`{feature}` is not valid for this target"));
|
||||
if let Some(stripped) = feature.strip_prefix('+') {
|
||||
let valid = rust_target_features.contains_key(stripped);
|
||||
if valid {
|
||||
err.help("consider removing the leading `+` in the feature name");
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
continue;
|
||||
};
|
||||
|
||||
// Only allow target features whose feature gates have been enabled
|
||||
// and which are permitted to be toggled.
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature,
|
||||
reason,
|
||||
});
|
||||
} else if let Some(nightly_feature) = stability.requires_nightly()
|
||||
&& !rust_features.enabled(nightly_feature)
|
||||
{
|
||||
feature_err(
|
||||
&tcx.sess,
|
||||
nightly_feature,
|
||||
item.span(),
|
||||
format!("the target feature `{feature}` is currently unstable"),
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
// Add this and the implied features.
|
||||
let feature_sym = Symbol::intern(feature);
|
||||
for &name in tcx.implied_target_features(feature_sym) {
|
||||
// But ensure the ABI does not forbid enabling this.
|
||||
// Here we do assume that the backend doesn't add even more implied features
|
||||
// we don't know about, at least no features that would have ABI effects!
|
||||
// We skip this logic in rustdoc, where we want to allow all target features of
|
||||
// all targets, so we can't check their ABI compatibility and anyway we are not
|
||||
// generating code so "it's fine".
|
||||
if !tcx.sess.opts.actually_rustdoc {
|
||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||
// For "neon" specifically, we emit an FCW instead of a hard error.
|
||||
// See <https://github.com/rust-lang/rust/issues/134375>.
|
||||
if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" {
|
||||
tcx.emit_node_span_lint(
|
||||
AARCH64_SOFTFLOAT_NEON,
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
item.span(),
|
||||
errors::Aarch64SoftfloatNeon,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature: name.as_str(),
|
||||
reason: "this feature is incompatible with the target ABI",
|
||||
});
|
||||
}
|
||||
// Only allow target features whose feature gates have been enabled
|
||||
// and which are permitted to be toggled.
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: feature_span,
|
||||
feature: feature_str,
|
||||
reason,
|
||||
});
|
||||
} else if let Some(nightly_feature) = stability.requires_nightly()
|
||||
&& !rust_features.enabled(nightly_feature)
|
||||
{
|
||||
feature_err(
|
||||
&tcx.sess,
|
||||
nightly_feature,
|
||||
feature_span,
|
||||
format!("the target feature `{feature}` is currently unstable"),
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
// Add this and the implied features.
|
||||
for &name in tcx.implied_target_features(feature) {
|
||||
// But ensure the ABI does not forbid enabling this.
|
||||
// Here we do assume that the backend doesn't add even more implied features
|
||||
// we don't know about, at least no features that would have ABI effects!
|
||||
// We skip this logic in rustdoc, where we want to allow all target features of
|
||||
// all targets, so we can't check their ABI compatibility and anyway we are not
|
||||
// generating code so "it's fine".
|
||||
if !tcx.sess.opts.actually_rustdoc {
|
||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||
// For "neon" specifically, we emit an FCW instead of a hard error.
|
||||
// See <https://github.com/rust-lang/rust/issues/134375>.
|
||||
if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" {
|
||||
tcx.emit_node_span_lint(
|
||||
AARCH64_SOFTFLOAT_NEON,
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
feature_span,
|
||||
errors::Aarch64SoftfloatNeon,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: feature_span,
|
||||
feature: name.as_str(),
|
||||
reason: "this feature is incompatible with the target ABI",
|
||||
});
|
||||
}
|
||||
}
|
||||
target_features.push(TargetFeature { name, implied: name != feature_sym })
|
||||
}
|
||||
target_features.push(TargetFeature { name, implied: name != feature })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +430,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
// one, just keep it.
|
||||
}
|
||||
_ => {
|
||||
// Overwrite stabilite.
|
||||
// Overwrite stability.
|
||||
occupied_entry.insert(stability);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
//
|
||||
// This function is opt-in for back ends.
|
||||
//
|
||||
// The default implementation calls `self.expect()` before emiting the branch
|
||||
// The default implementation calls `self.expect()` before emitting the branch
|
||||
// by calling `self.cond_br()`
|
||||
fn cond_br_with_expect(
|
||||
&mut self,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pub fn rustc_allow_const_fn_unstable(
|
|||
) -> bool {
|
||||
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
|
||||
|
||||
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate))
|
||||
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms, _) if syms.contains(&feature_gate))
|
||||
}
|
||||
|
||||
/// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable".
|
||||
|
|
|
|||
|
|
@ -572,7 +572,7 @@ where
|
|||
Right((local, offset, locals_addr, layout)) => {
|
||||
if offset.is_some() {
|
||||
// This has been projected to a part of this local, or had the type changed.
|
||||
// FIMXE: there are cases where we could still avoid allocating an mplace.
|
||||
// FIXME: there are cases where we could still avoid allocating an mplace.
|
||||
Left(place.force_mplace(self)?)
|
||||
} else {
|
||||
debug_assert_eq!(locals_addr, self.frame().locals_addr());
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
fn add_data_range(&mut self, ptr: Pointer<Option<M::Provenance>>, size: Size) {
|
||||
if let Some(data_bytes) = self.data_bytes.as_mut() {
|
||||
// We only have to store the offset, the rest is the same for all pointers here.
|
||||
// The logic is agnostic to wether the offset is relative or absolute as long as
|
||||
// The logic is agnostic to whether the offset is relative or absolute as long as
|
||||
// it is consistent.
|
||||
let (_prov, offset) = ptr.into_raw_parts();
|
||||
// Add this.
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ fn check_validity_requirement_strict<'tcx>(
|
|||
// require dereferenceability also require non-null, we don't actually get any false negatives
|
||||
// due to this.
|
||||
// The value we are validating is temporary and discarded at the end of this function, so
|
||||
// there is no point in reseting provenance and padding.
|
||||
// there is no point in resetting provenance and padding.
|
||||
cx.validate_operand(
|
||||
&allocated.into(),
|
||||
/*recursive*/ false,
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ unsafe impl<K: Idx, #[may_dangle] V, I> Drop for VecCache<K, V, I> {
|
|||
// we are also guaranteed to just need to deallocate any large arrays (not iterate over
|
||||
// contents).
|
||||
//
|
||||
// Confirm no need to deallocate invidual entries. Note that `V: Copy` is asserted on
|
||||
// Confirm no need to deallocate individual entries. Note that `V: Copy` is asserted on
|
||||
// insert/lookup but not necessarily construction, primarily to avoid annoyingly propagating
|
||||
// the bounds into struct definitions everywhere.
|
||||
assert!(!std::mem::needs_drop::<K>());
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ fn normalize<'a>(MdStream(stream): MdStream<'a>, linkdefs: &mut Vec<MdTree<'a>>)
|
|||
let new_defs = stream.iter().filter(|tt| matches!(tt, MdTree::LinkDef { .. }));
|
||||
linkdefs.extend(new_defs.cloned());
|
||||
|
||||
// Run plaintest expansions on types that need it, call this function on nested types
|
||||
// Run plaintext expansions on types that need it, call this function on nested types
|
||||
for item in stream {
|
||||
match item {
|
||||
MdTree::PlainText(txt) => expand_plaintext(txt, &mut new_stream, MdTree::PlainText),
|
||||
|
|
|
|||
|
|
@ -880,7 +880,7 @@ impl SyntaxExtension {
|
|||
is_local: bool,
|
||||
) -> SyntaxExtension {
|
||||
let allow_internal_unstable =
|
||||
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i) => i)
|
||||
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
|
||||
.map(|i| i.as_slice())
|
||||
.unwrap_or_default();
|
||||
// FIXME(jdonszelman): allow_internal_unsafe isn't yet new-style
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ impl server::Span for Rustc<'_, '_> {
|
|||
.lookup_char_pos(span.lo())
|
||||
.file
|
||||
.name
|
||||
.prefer_remapped_unconditionaly()
|
||||
.prefer_remapped_unconditionally()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ impl<'hir> ConstArg<'hir, AmbigArg> {
|
|||
}
|
||||
|
||||
impl<'hir> ConstArg<'hir> {
|
||||
/// Converts a `ConstArg` in an unambigous position to one in an ambiguous position. This is
|
||||
/// Converts a `ConstArg` in an unambiguous position to one in an ambiguous position. This is
|
||||
/// fallible as the [`ConstArgKind::Infer`] variant is not present in ambiguous positions.
|
||||
///
|
||||
/// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
|
||||
|
|
@ -508,7 +508,7 @@ pub enum GenericArg<'hir> {
|
|||
Lifetime(&'hir Lifetime),
|
||||
Type(&'hir Ty<'hir, AmbigArg>),
|
||||
Const(&'hir ConstArg<'hir, AmbigArg>),
|
||||
/// Inference variables in [`GenericArg`] are always represnted by
|
||||
/// Inference variables in [`GenericArg`] are always represented by
|
||||
/// `GenericArg::Infer` instead of the `Infer` variants on [`TyKind`] and
|
||||
/// [`ConstArgKind`] as it is not clear until hir ty lowering whether a
|
||||
/// `_` argument is a type or const argument.
|
||||
|
|
@ -3323,7 +3323,7 @@ impl<'hir> Ty<'hir, AmbigArg> {
|
|||
}
|
||||
|
||||
impl<'hir> Ty<'hir> {
|
||||
/// Converts a `Ty` in an unambigous position to one in an ambiguous position. This is
|
||||
/// Converts a `Ty` in an unambiguous position to one in an ambiguous position. This is
|
||||
/// fallible as the [`TyKind::Infer`] variant is not present in ambiguous positions.
|
||||
///
|
||||
/// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
|
||||
|
|
@ -4224,7 +4224,7 @@ impl fmt::Display for Constness {
|
|||
}
|
||||
}
|
||||
|
||||
/// The actualy safety specified in syntax. We may treat
|
||||
/// The actual safety specified in syntax. We may treat
|
||||
/// its safety different within the type system to create a
|
||||
/// "sound by default" system that needs checking this enum
|
||||
/// explicitly to allow unsafe operations.
|
||||
|
|
|
|||
|
|
@ -1088,7 +1088,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
// FIXME(#97583): Print associated item bindings properly (i.e., not as equality
|
||||
// predicates!).
|
||||
// FIXME: Turn this into a structured, translateable & more actionable suggestion.
|
||||
// FIXME: Turn this into a structured, translatable & more actionable suggestion.
|
||||
let mut where_bounds = vec![];
|
||||
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
||||
let bound_id = bound.def_id();
|
||||
|
|
@ -1588,7 +1588,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&infcx_
|
||||
};
|
||||
|
||||
tcx.all_traits()
|
||||
tcx.all_traits_including_private()
|
||||
.filter(|trait_def_id| {
|
||||
// Consider only traits with the associated type
|
||||
tcx.associated_items(*trait_def_id)
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
Err(SelectionError::TraitDynIncompatible(_)) => {
|
||||
// Dyn compatibility errors in coercion will *always* be due to the
|
||||
// fact that the RHS of the coercion is a non-dyn compatible `dyn Trait`
|
||||
// writen in source somewhere (otherwise we will never have lowered
|
||||
// written in source somewhere (otherwise we will never have lowered
|
||||
// the dyn trait from HIR to middle).
|
||||
//
|
||||
// There's no reason to emit yet another dyn compatibility error,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
// We want to emit an error if the const is not structurally resolveable
|
||||
// We want to emit an error if the const is not structurally resolvable
|
||||
// as otherwise we can wind up conservatively proving `Copy` which may
|
||||
// infer the repeat expr count to something that never required `Copy` in
|
||||
// the first place.
|
||||
|
|
@ -2461,7 +2461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
spans.push_span_label(param.param.span(), "");
|
||||
}
|
||||
}
|
||||
// Highligh each parameter being depended on for a generic type.
|
||||
// Highlight each parameter being depended on for a generic type.
|
||||
for ((&(_, param), deps), &(_, expected_ty)) in
|
||||
params_with_generics.iter().zip(&dependants).zip(formal_and_expected_inputs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
let def_id = pick.item.def_id;
|
||||
let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args);
|
||||
|
||||
debug!("method_predicates after instantitation = {:?}", method_predicates);
|
||||
debug!("method_predicates after instantiation = {:?}", method_predicates);
|
||||
|
||||
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args);
|
||||
debug!("type scheme instantiated, sig={:?}", sig);
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// type parameters or early-bound regions.
|
||||
let tcx = self.tcx;
|
||||
// We use `Ident::with_dummy_span` since no built-in operator methods have
|
||||
// any macro-specific hygeine, so the span's context doesn't really matter.
|
||||
// any macro-specific hygiene, so the span's context doesn't really matter.
|
||||
let Some(method_item) =
|
||||
self.associated_value(trait_def_id, Ident::with_dummy_span(method_name))
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1725,7 +1725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if unsatisfied_predicates.is_empty()
|
||||
// ...or if we already suggested that name because of `rustc_confusable` annotation
|
||||
&& Some(similar_candidate.name()) != confusable_suggested
|
||||
// and if the we aren't in an expansion.
|
||||
// and if we aren't in an expansion.
|
||||
&& !span.from_expansion()
|
||||
{
|
||||
self.find_likely_intended_associated_item(
|
||||
|
|
@ -3481,9 +3481,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
item_name: Ident,
|
||||
valid_out_of_scope_traits: Vec<DefId>,
|
||||
mut valid_out_of_scope_traits: Vec<DefId>,
|
||||
explain: bool,
|
||||
) -> bool {
|
||||
valid_out_of_scope_traits.retain(|id| self.tcx.is_user_visible_dep(id.krate));
|
||||
if !valid_out_of_scope_traits.is_empty() {
|
||||
let mut candidates = valid_out_of_scope_traits;
|
||||
candidates.sort_by_key(|id| self.tcx.def_path_str(id));
|
||||
|
|
@ -4388,7 +4389,7 @@ pub(crate) struct TraitInfo {
|
|||
/// Retrieves all traits in this crate and any dependent crates,
|
||||
/// and wraps them into `TraitInfo` for custom sorting.
|
||||
pub(crate) fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
|
||||
tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
|
||||
tcx.all_traits_including_private().map(|def_id| TraitInfo { def_id }).collect()
|
||||
}
|
||||
|
||||
fn print_disambiguation_help<'tcx>(
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
|
||||
// In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
|
||||
| PatKind::Or(_)
|
||||
// Like or-patterns, guard patterns just propogate to their subpatterns.
|
||||
// Like or-patterns, guard patterns just propagate to their subpatterns.
|
||||
| PatKind::Guard(..) => AdjustMode::Pass,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -566,7 +566,7 @@ impl Cursor<'_> {
|
|||
}
|
||||
|
||||
if !found {
|
||||
// recovery strategy: a closing statement might have precending whitespace/newline
|
||||
// recovery strategy: a closing statement might have preceding whitespace/newline
|
||||
// but not have enough dashes to properly close. In this case, we eat until there,
|
||||
// and report a mismatch in the parser.
|
||||
let mut rest = self.as_str();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ declare_lint! {
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Otherwise try to find an alternative way to achive your goals using only raw pointers:
|
||||
/// Otherwise try to find an alternative way to achieve your goals using only raw pointers:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::ptr;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
|
|||
// }
|
||||
// }
|
||||
// where `something()` would have to be a call or path.
|
||||
// We have nothing meaninful to do with this.
|
||||
// We have nothing meaningful to do with this.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ impl IfLetRescope {
|
|||
}
|
||||
}
|
||||
}
|
||||
// At this point, any `if let` fragment in the cascade is definitely preceeded by `else`,
|
||||
// At this point, any `if let` fragment in the cascade is definitely preceded by `else`,
|
||||
// so a opening bracket is mandatory before each `match`.
|
||||
add_bracket_to_match_head = true;
|
||||
if let Some(alt) = alt {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
|
|||
let init = cx.expr_or_init(e);
|
||||
let orig_cast = if init.span != e.span { Some(init.span) } else { None };
|
||||
|
||||
// small cache to avoid recomputing needlesly computing peel_casts of init
|
||||
// small cache to avoid recomputing needlessly computing peel_casts of init
|
||||
let mut peel_casts = {
|
||||
let mut peel_casts_cache = None;
|
||||
move || *peel_casts_cache.get_or_insert_with(|| peel_casts(cx, init))
|
||||
|
|
|
|||
|
|
@ -1224,7 +1224,7 @@ declare_lint! {
|
|||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// A public `use` declaration should not be used to publicly re-export a
|
||||
/// A public `use` declaration should not be used to publically re-export a
|
||||
/// private `extern crate`. `pub extern crate` should be used instead.
|
||||
///
|
||||
/// This was historically allowed, but is not the intended behavior
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ decl_derive! {
|
|||
[PrintAttribute] =>
|
||||
/// Derives `PrintAttribute` for `AttributeKind`.
|
||||
/// This macro is pretty specific to `rustc_attr_data_structures` and likely not that useful in
|
||||
/// other places. It's deriving something close to `Debug` without printing some extraenous
|
||||
/// other places. It's deriving something close to `Debug` without printing some extraneous
|
||||
/// things like spans.
|
||||
print_attribute::print_attribute
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,8 +273,8 @@ fn add_query_desc_cached_impl(
|
|||
// macro producing a higher order macro that has all its token in the macro declaration we lose
|
||||
// any meaningful spans, resulting in rust-analyzer being unable to make the connection between
|
||||
// the query name and the corresponding providers field. The trick to fix this is to have
|
||||
// `rustc_queries` emit a field access with the given name's span which allows it to succesfully
|
||||
// show references / go to definition to the correspondig provider assignment which is usually
|
||||
// `rustc_queries` emit a field access with the given name's span which allows it to successfully
|
||||
// show references / go to definition to the corresponding provider assignment which is usually
|
||||
// the more interesting place.
|
||||
let ra_hint = quote! {
|
||||
let crate::query::Providers { #name: _, .. };
|
||||
|
|
|
|||
|
|
@ -437,8 +437,8 @@ impl<'a> CrateLocator<'a> {
|
|||
let (rlibs, rmetas, dylibs, interfaces) =
|
||||
candidates.entry(hash).or_default();
|
||||
{
|
||||
// As a perforamnce optimisation we canonicalize the path and skip
|
||||
// ones we've already seeen. This allows us to ignore crates
|
||||
// As a performance optimisation we canonicalize the path and skip
|
||||
// ones we've already seen. This allows us to ignore crates
|
||||
// we know are exactual equal to ones we've already found.
|
||||
// Going to the same crate through different symlinks does not change the result.
|
||||
let path = try_canonicalize(&spf.path)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ impl<'tcx> From<ErrorHandled> for ValTreeCreationError<'tcx> {
|
|||
|
||||
impl<'tcx> From<InterpErrorInfo<'tcx>> for ValTreeCreationError<'tcx> {
|
||||
fn from(err: InterpErrorInfo<'tcx>) -> Self {
|
||||
// An error ocurred outside the const-eval query, as part of constructing the valtree. We
|
||||
// An error occurred outside the const-eval query, as part of constructing the valtree. We
|
||||
// don't currently preserve the details of this error, since `InterpErrorInfo` cannot be put
|
||||
// into a query result and it can only be access of some mutable or external memory.
|
||||
let (_kind, backtrace) = err.into_parts();
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ pub struct Body<'tcx> {
|
|||
/// us to see the difference and forego optimization on the inlined promoted items.
|
||||
pub phase: MirPhase,
|
||||
|
||||
/// How many passses we have executed since starting the current phase. Used for debug output.
|
||||
/// How many passes we have executed since starting the current phase. Used for debug output.
|
||||
pub pass_count: usize,
|
||||
|
||||
pub source: MirSource<'tcx>,
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ pub enum StatementKind<'tcx> {
|
|||
/// computing these locals.
|
||||
///
|
||||
/// If the local is already allocated, calling `StorageLive` again will implicitly free the
|
||||
/// local and then allocate fresh uninitilized memory. If a local is already deallocated,
|
||||
/// local and then allocate fresh uninitialized memory. If a local is already deallocated,
|
||||
/// calling `StorageDead` again is a NOP.
|
||||
StorageLive(Local),
|
||||
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ rustc_queries! {
|
|||
/// Returns whether the type alias given by `DefId` is lazy.
|
||||
///
|
||||
/// I.e., if the type alias expands / ought to expand to a [free] [alias type]
|
||||
/// instead of the underyling aliased type.
|
||||
/// instead of the underlying aliased type.
|
||||
///
|
||||
/// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -2287,7 +2287,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// All traits in the crate graph, including those not visible to the user.
|
||||
pub fn all_traits(self) -> impl Iterator<Item = DefId> {
|
||||
pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
|
||||
iter::once(LOCAL_CRATE)
|
||||
.chain(self.crates(()).iter().copied())
|
||||
.flat_map(move |cnum| self.traits(cnum).iter().copied())
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub enum InstanceKind<'tcx> {
|
|||
/// - coroutines
|
||||
Item(DefId),
|
||||
|
||||
/// An intrinsic `fn` item (with`#[rustc_instrinsic]`).
|
||||
/// An intrinsic `fn` item (with`#[rustc_intrinsic]`).
|
||||
///
|
||||
/// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
|
||||
/// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
|
||||
|
|
@ -445,10 +445,10 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// async_drop_in_place<T>::coroutine.poll, when T is a standart coroutine,
|
||||
// async_drop_in_place<T>::coroutine.poll, when T is a standard coroutine,
|
||||
// should be resolved to this coroutine's future_drop_poll (through FutureDropPollShim proxy).
|
||||
// async_drop_in_place<async_drop_in_place<T>::coroutine>::coroutine.poll,
|
||||
// when T is a standart coroutine, should be resolved to this coroutine's future_drop_poll.
|
||||
// when T is a standard coroutine, should be resolved to this coroutine's future_drop_poll.
|
||||
// async_drop_in_place<async_drop_in_place<T>::coroutine>::coroutine.poll,
|
||||
// when T is not a coroutine, should be resolved to the innermost
|
||||
// async_drop_in_place<T>::coroutine's poll function (through FutureDropPollShim proxy)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ fn true_significant_drop_ty<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the list of types with a "potentially sigificant" that may be dropped
|
||||
/// Returns the list of types with a "potentially significant" that may be dropped
|
||||
/// by dropping a value of type `ty`.
|
||||
#[instrument(level = "trace", skip(tcx, typing_env))]
|
||||
pub fn extract_component_raw<'tcx>(
|
||||
|
|
|
|||
|
|
@ -1676,7 +1676,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
/// This is particularly useful for getting the type of the result of
|
||||
/// [`UnOp::PtrMetadata`](crate::mir::UnOp::PtrMetadata).
|
||||
///
|
||||
/// Panics if `self` is not dereferencable.
|
||||
/// Panics if `self` is not dereferenceable.
|
||||
#[track_caller]
|
||||
pub fn pointee_metadata_ty_or_projection(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
let Some(pointee_ty) = self.builtin_deref(true) else {
|
||||
|
|
|
|||
|
|
@ -365,11 +365,11 @@ fn extend_type_not_partial_eq<'tcx>(
|
|||
struct UsedParamsNeedInstantiationVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structual.
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structural.
|
||||
adts_with_manual_partialeq: FxHashSet<Span>,
|
||||
/// The type has no `PartialEq` implementation, neither manual or derived.
|
||||
adts_without_partialeq: FxHashSet<Span>,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structual,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structural,
|
||||
/// but we don't have a span to point at, so we'll just add them as a `note`.
|
||||
manual: FxHashSet<Ty<'tcx>>,
|
||||
/// The type has no `PartialEq` implementation, neither manual or derived, but
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ fn insert_discr_cast_to_u128<'tcx>(
|
|||
StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))),
|
||||
));
|
||||
|
||||
// Cast the discriminant to a u128 (base for comparisions of enum discriminants).
|
||||
// Cast the discriminant to a u128 (base for comparisons of enum discriminants).
|
||||
let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128);
|
||||
let rvalue = Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr_in_discr_ty), const_u128);
|
||||
let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into();
|
||||
|
|
@ -467,7 +467,7 @@ fn insert_niche_check<'tcx>(
|
|||
source_info,
|
||||
);
|
||||
|
||||
// Compare the discriminant agains the valid_range.
|
||||
// Compare the discriminant against the valid_range.
|
||||
let start_const = Operand::Constant(Box::new(ConstOperand {
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
//! _b = some other value // also has VnIndex i
|
||||
//! ```
|
||||
//!
|
||||
//! We consider it to be replacable by:
|
||||
//! We consider it to be replaceable by:
|
||||
//! ```ignore (MIR)
|
||||
//! _a = some value // has VnIndex i
|
||||
//! // some MIR
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ struct LocalLabel<'a> {
|
|||
/// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order
|
||||
impl Subdiagnostic for LocalLabel<'_> {
|
||||
fn add_to_diag<G: rustc_errors::EmissionGuarantee>(self, diag: &mut rustc_errors::Diag<'_, G>) {
|
||||
// Becuase parent uses this field , we need to remove it delay before adding it.
|
||||
// Because parent uses this field , we need to remove it delay before adding it.
|
||||
diag.remove_arg("name");
|
||||
diag.arg("name", self.name);
|
||||
diag.remove_arg("is_generated_name");
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ fn compute_replacement<'tcx>(
|
|||
// reborrowed references.
|
||||
let mut storage_to_remove = DenseBitSet::new_empty(body.local_decls.len());
|
||||
|
||||
let fully_replacable_locals = fully_replacable_locals(ssa);
|
||||
let fully_replaceable_locals = fully_replaceable_locals(ssa);
|
||||
|
||||
// Returns true iff we can use `place` as a pointee.
|
||||
//
|
||||
|
|
@ -204,7 +204,7 @@ fn compute_replacement<'tcx>(
|
|||
let needs_unique = ty.is_mutable_ptr();
|
||||
|
||||
// If this a mutable reference that we cannot fully replace, mark it as unknown.
|
||||
if needs_unique && !fully_replacable_locals.contains(local) {
|
||||
if needs_unique && !fully_replaceable_locals.contains(local) {
|
||||
debug!("not fully replaceable");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -303,7 +303,7 @@ fn compute_replacement<'tcx>(
|
|||
|
||||
// This a reborrow chain, recursively allow the replacement.
|
||||
//
|
||||
// This also allows to detect cases where `target.local` is not replacable,
|
||||
// This also allows to detect cases where `target.local` is not replaceable,
|
||||
// and mark it as such.
|
||||
if let &[PlaceElem::Deref] = &target.projection[..] {
|
||||
assert!(perform_opt);
|
||||
|
|
@ -313,7 +313,7 @@ fn compute_replacement<'tcx>(
|
|||
} else if perform_opt {
|
||||
self.allowed_replacements.insert((target.local, loc));
|
||||
} else if needs_unique {
|
||||
// This mutable reference is not fully replacable, so drop it.
|
||||
// This mutable reference is not fully replaceable, so drop it.
|
||||
self.targets[place.local] = Value::Unknown;
|
||||
}
|
||||
}
|
||||
|
|
@ -326,22 +326,22 @@ fn compute_replacement<'tcx>(
|
|||
|
||||
/// Compute the set of locals that can be fully replaced.
|
||||
///
|
||||
/// We consider a local to be replacable iff it's only used in a `Deref` projection `*_local` or
|
||||
/// We consider a local to be replaceable iff it's only used in a `Deref` projection `*_local` or
|
||||
/// non-use position (like storage statements and debuginfo).
|
||||
fn fully_replacable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
|
||||
let mut replacable = DenseBitSet::new_empty(ssa.num_locals());
|
||||
fn fully_replaceable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
|
||||
let mut replaceable = DenseBitSet::new_empty(ssa.num_locals());
|
||||
|
||||
// First pass: for each local, whether its uses can be fully replaced.
|
||||
for local in ssa.locals() {
|
||||
if ssa.num_direct_uses(local) == 0 {
|
||||
replacable.insert(local);
|
||||
replaceable.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: a local can only be fully replaced if all its copies can.
|
||||
ssa.meet_copy_equivalence(&mut replacable);
|
||||
ssa.meet_copy_equivalence(&mut replaceable);
|
||||
|
||||
replacable
|
||||
replaceable
|
||||
}
|
||||
|
||||
/// Utility to help performing substitution of `*pattern` by `target`.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub(super) fn provide(providers: &mut Providers) {
|
|||
providers.mir_shims = make_shim;
|
||||
}
|
||||
|
||||
// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> acceses
|
||||
// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses
|
||||
struct FixProxyFutureDropVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
replace_to: Local,
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ fn collect_items_rec<'tcx>(
|
|||
});
|
||||
}
|
||||
// Only updating `usage_map` for used items as otherwise we may be inserting the same item
|
||||
// multiple times (if it is first 'mentioned' and then later actuall used), and the usage map
|
||||
// multiple times (if it is first 'mentioned' and then later actually used), and the usage map
|
||||
// logic does not like that.
|
||||
// This is part of the output of collection and hence only relevant for "used" items.
|
||||
// ("Mentioned" items are only considered internally during collection.)
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ fn mono_item_visibility<'tcx>(
|
|||
// * First is weak lang items. These are basically mechanisms for
|
||||
// libcore to forward-reference symbols defined later in crates like
|
||||
// the standard library or `#[panic_handler]` definitions. The
|
||||
// definition of these weak lang items needs to be referencable by
|
||||
// definition of these weak lang items needs to be referenceable by
|
||||
// libcore, so we're no longer a candidate for internalization.
|
||||
// Removal of these functions can't be done by LLVM but rather must be
|
||||
// done by the linker as it's a non-local decision.
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ where
|
|||
/// Register additional assumptions for aliases corresponding to `[const]` item bounds.
|
||||
///
|
||||
/// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
|
||||
/// Instead, they only hold if the const conditons on the alias also hold. This is why
|
||||
/// Instead, they only hold if the const conditions on the alias also hold. This is why
|
||||
/// we also register the const conditions of the alias after matching the goal against
|
||||
/// the assumption.
|
||||
fn consider_additional_alias_assumptions(
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ where
|
|||
/// This takes the `shallow_certainty` which represents whether we're confident
|
||||
/// that the final result of the current goal only depends on the nested goals.
|
||||
///
|
||||
/// In case this is `Certainy::Maybe`, there may still be additional nested goals
|
||||
/// In case this is `Certainty::Maybe`, there may still be additional nested goals
|
||||
/// or inference constraints required for this candidate to be hold. The candidate
|
||||
/// always requires all already added constraints and nested goals.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ where
|
|||
// Right now this includes both the impl and the assoc item where bounds,
|
||||
// and I don't think the assoc item where-bounds are allowed to be coinductive.
|
||||
//
|
||||
// Projecting to the IAT also "steps out the impl contructor", so we would have
|
||||
// Projecting to the IAT also "steps out the impl constructor", so we would have
|
||||
// to be very careful when changing the impl where-clauses to be productive.
|
||||
self.add_goals(
|
||||
GoalSource::Misc,
|
||||
|
|
|
|||
|
|
@ -1301,7 +1301,7 @@ where
|
|||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// FIXME(#57893): For backwards compatability with the old trait solver implementation,
|
||||
/// FIXME(#57893): For backwards compatibility with the old trait solver implementation,
|
||||
/// we need to handle overlap between builtin and user-written impls for trait objects.
|
||||
///
|
||||
/// This overlap is unsound in general and something which we intend to fix separately.
|
||||
|
|
|
|||
|
|
@ -298,6 +298,8 @@ fn emit_malformed_attribute(
|
|||
| sym::deprecated
|
||||
| sym::optimize
|
||||
| sym::cold
|
||||
| sym::target_feature
|
||||
| sym::rustc_allow_const_fn_unstable
|
||||
| sym::naked
|
||||
| sym::no_mangle
|
||||
| sym::must_use
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ passes_no_sanitize =
|
|||
`#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
|
||||
.label = not {$accepted_kind}
|
||||
|
||||
passes_non_exaustive_with_default_field_values =
|
||||
passes_non_exhaustive_with_default_field_values =
|
||||
`#[non_exhaustive]` can't be used to annotate items with default field values
|
||||
.label = this struct has default field values
|
||||
|
||||
|
|
|
|||
|
|
@ -146,20 +146,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::ConstContinue(attr_span)) => {
|
||||
self.check_const_continue(hir_id, *attr_span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self
|
||||
.check_allow_internal_unstable(
|
||||
hir_id,
|
||||
syms.first().unwrap().1,
|
||||
span,
|
||||
target,
|
||||
attrs,
|
||||
),
|
||||
Attribute::Parsed(AttributeKind::AllowConstFnUnstable { .. }) => {
|
||||
self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target)
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(_, first_span)) => {
|
||||
self.check_allow_internal_unstable(hir_id, *first_span, span, target, attrs)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowConstFnUnstable(_, first_span)) => {
|
||||
self.check_rustc_allow_const_fn_unstable(hir_id, *first_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
|
||||
self.check_deprecated(hir_id, attr, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::TargetFeature(_, attr_span)) => {
|
||||
self.check_target_feature(hir_id, *attr_span, span, target, attrs)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
|
||||
|
|
@ -230,9 +228,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item),
|
||||
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
||||
[sym::target_feature, ..] => {
|
||||
self.check_target_feature(hir_id, attr, span, target, attrs)
|
||||
}
|
||||
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
|
||||
[sym::doc, ..] => self.check_doc_attrs(
|
||||
attr,
|
||||
|
|
@ -816,7 +811,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_target_feature(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
|
|
@ -834,7 +829,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
|
||||
|
||||
self.dcx().emit_err(errors::LangItemWithTargetFeature {
|
||||
attr_span: attr.span(),
|
||||
attr_span,
|
||||
name: lang_item,
|
||||
sig_span: sig.span,
|
||||
});
|
||||
|
|
@ -846,7 +841,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::TargetFeatureOnStatement,
|
||||
);
|
||||
}
|
||||
|
|
@ -855,11 +850,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "target_feature");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "target_feature");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
attr_span: attr.span(),
|
||||
attr_span,
|
||||
defn_span: span,
|
||||
on_crate: hir_id == CRATE_HIR_ID,
|
||||
});
|
||||
|
|
@ -2169,7 +2164,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_rustc_allow_const_fn_unstable(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
) {
|
||||
|
|
@ -2181,15 +2176,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => self
|
||||
.inline_attr_str_error_with_macro_def(
|
||||
hir_id,
|
||||
attr.span(),
|
||||
"allow_internal_unstable",
|
||||
),
|
||||
.inline_attr_str_error_with_macro_def(hir_id, attr_span, "allow_internal_unstable"),
|
||||
_ => {
|
||||
self.tcx
|
||||
.dcx()
|
||||
.emit_err(errors::RustcAllowConstFnUnstable { attr_span: attr.span(), span });
|
||||
self.tcx.dcx().emit_err(errors::RustcAllowConstFnUnstable { attr_span, span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2323,8 +2312,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
return;
|
||||
}
|
||||
AttributeKind::TargetFeature(features, span) if features.len() == 0 => {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
*span,
|
||||
errors::Unused {
|
||||
attr_span: *span,
|
||||
note: errors::UnusedNote::EmptyList { name: sym::target_feature },
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Warn on useless empty attributes.
|
||||
|
|
@ -2336,7 +2337,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::feature,
|
||||
sym::target_feature,
|
||||
]) && attr.meta_item_list().is_some_and(|list| list.is_empty())
|
||||
{
|
||||
errors::UnusedNote::EmptyList { name: attr.name().unwrap() }
|
||||
|
|
|
|||
|
|
@ -1199,7 +1199,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
|
|||
let def_kind = tcx.def_kind(item.owner_id);
|
||||
|
||||
let mut dead_codes = Vec::new();
|
||||
// Only diagnose unused assoc items in inherient impl and used trait,
|
||||
// Only diagnose unused assoc items in inherent impl and used trait,
|
||||
// for unused assoc items in impls of trait,
|
||||
// we have diagnosed them in the trait if they are unused,
|
||||
// for unused assoc items in unused trait,
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ pub(crate) struct NonExhaustiveWrongLocation {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_non_exaustive_with_default_field_values)]
|
||||
#[diag(passes_non_exhaustive_with_default_field_values)]
|
||||
pub(crate) struct NonExhaustiveWithDefaultFieldValues {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
//! # Constructors and fields
|
||||
//!
|
||||
//! In the value `Pair(Some(0), true)`, `Pair` is called the constructor of the value, and `Some(0)`
|
||||
//! and `true` are its fields. Every matcheable value can be decomposed in this way. Examples of
|
||||
//! and `true` are its fields. Every matchable value can be decomposed in this way. Examples of
|
||||
//! constructors are: `Some`, `None`, `(,)` (the 2-tuple constructor), `Foo {..}` (the constructor
|
||||
//! for a struct `Foo`), and `2` (the constructor for the number `2`).
|
||||
//!
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
//! [`Constructor::is_covered_by`].
|
||||
//!
|
||||
//! Note 1: variable bindings (like the `x` in `Some(x)`) match anything, so we treat them as wildcards.
|
||||
//! Note 2: this only applies to matcheable values. For example a value of type `Rc<u64>` can't be
|
||||
//! Note 2: this only applies to matchable values. For example a value of type `Rc<u64>` can't be
|
||||
//! deconstructed that way.
|
||||
//!
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1342,7 +1342,7 @@ impl DepNodeColorMap {
|
|||
|
||||
/// This tries to atomically mark a node green and assign `index` as the new
|
||||
/// index. This returns `Ok` if `index` gets assigned, otherwise it returns
|
||||
/// the alreadly allocated index in `Err`.
|
||||
/// the already allocated index in `Err`.
|
||||
#[inline]
|
||||
pub(super) fn try_mark_green(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -878,12 +878,12 @@ pub(crate) struct MacroExpandedExternCrateCannotShadowExternArguments {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_elided_anonymous_lifetime_report_error, code = E0637)]
|
||||
pub(crate) struct ElidedAnonymousLivetimeReportError {
|
||||
pub(crate) struct ElidedAnonymousLifetimeReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) suggestion: Option<ElidedAnonymousLivetimeReportErrorSuggestion>,
|
||||
pub(crate) suggestion: Option<ElidedAnonymousLifetimeReportErrorSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
@ -897,7 +897,7 @@ pub(crate) struct LendingIteratorReportError {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_anonymous_lifetime_non_gat_report_error)]
|
||||
pub(crate) struct AnonymousLivetimeNonGatReportError {
|
||||
pub(crate) struct AnonymousLifetimeNonGatReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) lifetime: Span,
|
||||
|
|
@ -908,7 +908,7 @@ pub(crate) struct AnonymousLivetimeNonGatReportError {
|
|||
resolve_elided_anonymous_lifetime_report_error_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct ElidedAnonymousLivetimeReportErrorSuggestion {
|
||||
pub(crate) struct ElidedAnonymousLifetimeReportErrorSuggestion {
|
||||
#[suggestion_part(code = "for<'a> ")]
|
||||
pub(crate) lo: Span,
|
||||
#[suggestion_part(code = "'a ")]
|
||||
|
|
@ -917,7 +917,7 @@ pub(crate) struct ElidedAnonymousLivetimeReportErrorSuggestion {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_explicit_anonymous_lifetime_report_error, code = E0637)]
|
||||
pub(crate) struct ExplicitAnonymousLivetimeReportError {
|
||||
pub(crate) struct ExplicitAnonymousLifetimeReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
|
|
|
|||
|
|
@ -1892,7 +1892,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
..
|
||||
} = rib.kind
|
||||
{
|
||||
Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
|
||||
Some(errors::ElidedAnonymousLifetimeReportErrorSuggestion {
|
||||
lo: span.shrink_to_lo(),
|
||||
hi: lifetime.ident.span.shrink_to_hi(),
|
||||
})
|
||||
|
|
@ -1918,18 +1918,18 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
ty: ty.span,
|
||||
});
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
|
||||
self.r.dcx().emit_err(errors::AnonymousLifetimeNonGatReportError {
|
||||
lifetime: lifetime.ident.span,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
|
||||
self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError {
|
||||
span: lifetime.ident.span,
|
||||
suggestion,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
|
||||
self.r.dcx().emit_err(errors::ExplicitAnonymousLifetimeReportError {
|
||||
span: lifetime.ident.span,
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ pub fn source_span_for_markdown_range_inner(
|
|||
let fragment = &fragments[i];
|
||||
let sp = fragment.span;
|
||||
// we need to calculate the span start,
|
||||
// then use that in our calulations for the span end
|
||||
// then use that in our calculations for the span end
|
||||
let lo = sp.lo() + BytePos(match_start as u32);
|
||||
return Some((
|
||||
sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)),
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use thin_vec::ThinVec;
|
|||
/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
|
||||
const STR_SENTINEL: u8 = 0xC1;
|
||||
|
||||
/// For byte strings there are no bytes that canot occur. Just use this value
|
||||
/// For byte strings there are no bytes that cannot occur. Just use this value
|
||||
/// as a best-effort sentinel. There is no validation skipped so the potential
|
||||
/// for badness is lower than in the `STR_SENTINEL` case.
|
||||
const BYTE_STR_SENTINEL: u8 = 0xC2;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ pub struct CoverageOptions {
|
|||
/// to keep supporting this flag, remove it.
|
||||
pub no_mir_spans: bool,
|
||||
|
||||
/// `-Zcoverage-options=discard-all-spans-in-codegen`: During codgen,
|
||||
/// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
|
||||
/// discard all coverage spans as though they were invalid. Needed by
|
||||
/// regression tests for #133606, because we don't have an easy way to
|
||||
/// reproduce it from actual source code.
|
||||
|
|
|
|||
|
|
@ -1545,7 +1545,7 @@ impl RemapFileNameExt for rustc_span::FileName {
|
|||
"one and only one scope should be passed to for_scope"
|
||||
);
|
||||
if sess.opts.unstable_opts.remap_path_scope.contains(scope) {
|
||||
self.prefer_remapped_unconditionaly()
|
||||
self.prefer_remapped_unconditionally()
|
||||
} else {
|
||||
self.prefer_local()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,11 @@ impl<'tcx> SmirCtxt<'tcx> {
|
|||
|
||||
pub fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
|
||||
tables
|
||||
.tcx
|
||||
.all_traits_including_private()
|
||||
.map(|trait_def_id| tables.trait_def(trait_def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls {
|
||||
|
|
|
|||
|
|
@ -1600,7 +1600,7 @@ pub struct VariantIdx(usize);
|
|||
index_impl!(VariantIdx);
|
||||
|
||||
crate_def! {
|
||||
/// Hold infomation about an Opaque definition, particularly useful in `RPITIT`.
|
||||
/// Hold information about an Opaque definition, particularly useful in `RPITIT`.
|
||||
#[derive(Serialize)]
|
||||
pub OpaqueDef;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ impl FileName {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn prefer_remapped_unconditionaly(&self) -> FileNameDisplay<'_> {
|
||||
pub fn prefer_remapped_unconditionally(&self) -> FileNameDisplay<'_> {
|
||||
FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2397,7 +2397,7 @@ pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, s
|
|||
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
|
||||
pub struct Ident {
|
||||
// `name` should never be the empty symbol. If you are considering that,
|
||||
// you are probably conflating "empty identifer with "no identifier" and
|
||||
// you are probably conflating "empty identifier with "no identifier" and
|
||||
// you should use `Option<Ident>` instead.
|
||||
pub name: Symbol,
|
||||
pub span: Span,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ where
|
|||
}
|
||||
|
||||
if arg.layout.is_single_vector_element(cx, size) {
|
||||
// pass non-transparant wrappers around a vector as `PassMode::Cast`
|
||||
// pass non-transparent wrappers around a vector as `PassMode::Cast`
|
||||
arg.cast_to(Reg { kind: RegKind::Vector, size });
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ edition = "2024"
|
|||
itertools = "0.12"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_attr_data_structures = {path = "../rustc_attr_data_structures"}
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{Diag, MultiSpan, pluralize};
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -8,7 +9,7 @@ use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
|||
use rustc_middle::ty::print::{FmtPrinter, Printer};
|
||||
use rustc_middle::ty::{self, Ty, suggest_constraining_type_param};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{BytePos, Span, Symbol, sym};
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
|
|
@ -535,8 +536,7 @@ impl<T> Trait<T> for X {
|
|||
}
|
||||
}
|
||||
TypeError::TargetFeatureCast(def_id) => {
|
||||
let target_spans =
|
||||
tcx.get_attrs(def_id, sym::target_feature).map(|attr| attr.span());
|
||||
let target_spans = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TargetFeature(.., span) => *span);
|
||||
diag.note(
|
||||
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1855,7 +1855,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let trait_def_id = trait_pred.def_id();
|
||||
let trait_name = self.tcx.item_name(trait_def_id);
|
||||
let crate_name = self.tcx.crate_name(trait_def_id.krate);
|
||||
if let Some(other_trait_def_id) = self.tcx.all_traits().find(|def_id| {
|
||||
if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| {
|
||||
trait_name == self.tcx.item_name(trait_def_id)
|
||||
&& trait_def_id.krate != def_id.krate
|
||||
&& crate_name == self.tcx.crate_name(def_id.krate)
|
||||
|
|
|
|||
|
|
@ -4432,7 +4432,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
candidate_impls: &[ImplCandidate<'tcx>],
|
||||
span: Span,
|
||||
) {
|
||||
// We can only suggest the slice coersion for function and binary operation arguments,
|
||||
// We can only suggest the slice coercion for function and binary operation arguments,
|
||||
// since the suggestion would make no sense in turbofish or call
|
||||
let (ObligationCauseCode::BinOp { .. } | ObligationCauseCode::FunctionArg { .. }) =
|
||||
obligation.cause.code()
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
// Do not suggest constraining the `&self` param, but rather the return type.
|
||||
// If that is wrong (because it is not sufficient), a follow up error will tell the
|
||||
// user to fix it. This way we lower the chances of *over* constraining, but still
|
||||
// get the cake of "correctly" contrained in two steps.
|
||||
// get the cake of "correctly" constrained in two steps.
|
||||
visitor.visit_ty_unambig(self.ty_sup);
|
||||
}
|
||||
visitor.visit_ty_unambig(self.ty_sub);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ use crate::traits::{
|
|||
///
|
||||
/// Currently that is `Self` in supertraits. This is needed
|
||||
/// because `dyn_compatibility_violations` can't be used during
|
||||
/// type collection, as type collection is needed for `dyn_compatiblity_violations` itself.
|
||||
/// type collection, as type collection is needed for `dyn_compatibility_violations` itself.
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
pub fn hir_ty_lowering_dyn_compatibility_violations(
|
||||
tcx: TyCtxt<'_>,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub fn evaluate_host_effect_obligation<'tcx>(
|
|||
Err(EvaluationFailure::NoSolution) => {}
|
||||
}
|
||||
|
||||
match evaluate_host_effect_from_selection_candiate(selcx, obligation) {
|
||||
match evaluate_host_effect_from_selection_candidate(selcx, obligation) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
|
||||
Err(EvaluationFailure::NoSolution) => {}
|
||||
|
|
@ -398,7 +398,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
|
|||
.collect())
|
||||
}
|
||||
|
||||
fn evaluate_host_effect_from_selection_candiate<'tcx>(
|
||||
fn evaluate_host_effect_from_selection_candidate<'tcx>(
|
||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||
obligation: &HostEffectObligation<'tcx>,
|
||||
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ pub enum EvaluateConstErr {
|
|||
/// some unevaluated constant with either generic parameters or inference variables in its
|
||||
/// generic arguments.
|
||||
HasGenericsOrInfers,
|
||||
/// The type this constant evalauted to is not valid for use in const generics. This should
|
||||
/// The type this constant evaluated to is not valid for use in const generics. This should
|
||||
/// always result in an error when checking the constant is correctly typed for the parameter
|
||||
/// it is an argument to, so a bug is delayed when encountering this.
|
||||
InvalidConstParamTy(ErrorGuaranteed),
|
||||
|
|
|
|||
|
|
@ -904,7 +904,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let goal_kind =
|
||||
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
|
||||
|
||||
// If we have not yet determiend the `ClosureKind` of the closure or coroutine-closure,
|
||||
// If we have not yet determined the `ClosureKind` of the closure or coroutine-closure,
|
||||
// then additionally register an `AsyncFnKindHelper` goal which will fail if the kind
|
||||
// is constrained to an insufficient type later on.
|
||||
if let Some(closure_kind) = self.infcx.shallow_resolve(kind_ty).to_opt_closure_kind() {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks the `#[define_opaque]` attributes on items and collectes opaques to define
|
||||
/// Checks the `#[define_opaque]` attributes on items and collects opaques to define
|
||||
/// from the referenced types.
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn collect_taits_from_defines_attr(&mut self) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::{self as ty, Interner};
|
|||
/// slightly different typing rules depending on the current context. See the
|
||||
/// doc comment for each variant for how and why they are used.
|
||||
///
|
||||
/// In most cases you can get the correct typing mode automically via:
|
||||
/// In most cases you can get the correct typing mode automatically via:
|
||||
/// - `mir::Body::typing_mode`
|
||||
/// - `rustc_lint::LateContext::typing_mode`
|
||||
///
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue