Auto merge of #138933 - matthiaskrgr:rollup-sjtqkoq, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #135745 (Recognise new IPv6 non-global range from IETF RFC 9602)
 - #137247 (cg_llvm: Reduce the visibility of types, modules and using declarations in `rustc_codegen_llvm`.)
 - #138317 (privacy: Visit types and traits in impls in type privacy lints)
 - #138581 (Abort in deadlock handler if we fail to get a query map)
 - #138776 (coverage: Separate span-extraction from unexpansion)
 - #138886 (Fix autofix for `self` and `self as …` in `unused_imports` lint)
 - #138924 (Reduce `kw::Empty` usage, part 3)
 - #138929 (Visitors track whether an assoc item is in a trait impl or an inherent impl)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-03-25 19:53:57 +00:00
commit 43f0014ef0
51 changed files with 683 additions and 395 deletions

View File

@ -1318,7 +1318,9 @@ impl WalkItemKind for ItemKind {
visit_polarity(vis, polarity);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl));
items.flat_map_in_place(|item| {
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
});
}
ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
visit_safety(vis, safety);

View File

@ -23,7 +23,7 @@ use crate::ptr::P;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AssocCtxt {
Trait,
Impl,
Impl { of_trait: bool },
}
#[derive(Copy, Clone, Debug, PartialEq)]
@ -422,7 +422,12 @@ impl WalkItemKind for ItemKind {
try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty));
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(
visitor,
visit_assoc_item,
items,
AssocCtxt::Impl { of_trait: of_trait.is_some() }
);
}
ItemKind::Struct(struct_definition, generics)
| ItemKind::Union(struct_definition, generics) => {

View File

@ -61,8 +61,14 @@ pub(crate) struct DelegationResults<'hir> {
impl<'hir> LoweringContext<'_, 'hir> {
/// Defines whether the delegatee is an associated function whose first parameter is `self`.
pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span);
pub(crate) fn delegatee_is_method(
&self,
item_id: NodeId,
path_id: NodeId,
span: Span,
is_in_trait_impl: bool,
) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
let Ok(sig_id) = sig_id else {
return false;
};
@ -88,9 +94,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
delegation: &Delegation,
item_id: NodeId,
is_in_trait_impl: bool,
) -> DelegationResults<'hir> {
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
match sig_id {
Ok(sig_id) => {
let (param_count, c_variadic) = self.param_count(sig_id);
@ -110,8 +117,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
item_id: NodeId,
path_id: NodeId,
span: Span,
is_in_trait_impl: bool,
) -> Result<DefId, ErrorGuaranteed> {
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
let sig_id = if is_in_trait_impl { item_id } else { path_id };
self.get_resolution_id(sig_id, span)
}

View File

@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::{self as hir, HirId, PredicateOrigin};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
@ -104,10 +103,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
}
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
let def_id = self.resolver.node_id_to_def_id[&item.id];
let parent_id = self.tcx.local_parent(def_id);
let parent_hir = self.lower_node(parent_id).unwrap();
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir))
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
}
fn lower_foreign_item(&mut self, item: &ForeignItem) {
@ -405,10 +401,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
(trait_ref, lowered_ty)
});
self.is_in_trait_impl = trait_ref.is_some();
let new_impl_items = self
.arena
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
let new_impl_items = self.arena.alloc_from_iter(
impl_items
.iter()
.map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
);
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function.
@ -485,7 +482,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ItemKind::Delegation(box delegation) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let delegation_results = self.lower_delegation(delegation, id);
let delegation_results = self.lower_delegation(delegation, id, false);
hir::ItemKind::Fn {
ident,
sig: delegation_results.sig,
@ -628,29 +625,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
fn lower_assoc_item(
&mut self,
item: &AssocItem,
ctxt: AssocCtxt,
parent_hir: &'hir hir::OwnerInfo<'hir>,
) -> hir::OwnerNode<'hir> {
let parent_item = parent_hir.node().expect_item();
match parent_item.kind {
hir::ItemKind::Impl(impl_) => {
self.is_in_trait_impl = impl_.of_trait.is_some();
}
hir::ItemKind::Trait(..) => {}
kind => {
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
}
}
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
// Evaluate with the lifetimes in `params` in-scope.
// This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn.
match ctxt {
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
AssocCtxt::Impl { of_trait } => {
hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
}
}
}
@ -891,7 +874,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(generics, kind, ty.is_some())
}
AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id);
let delegation_results = self.lower_delegation(delegation, i.id, false);
let item_kind = hir::TraitItemKind::Fn(
delegation_results.sig,
hir::TraitFn::Provided(delegation_results.body_id),
@ -922,7 +905,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
},
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
@ -942,7 +925,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr(span, hir::ExprKind::Err(guar))
}
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
fn lower_impl_item(
&mut self,
i: &AssocItem,
is_in_trait_impl: bool,
) -> &'hir hir::ImplItem<'hir> {
debug_assert_ne!(i.ident.name, kw::Empty);
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
@ -978,7 +965,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
sig,
i.id,
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
sig.header.coroutine_kind,
attrs,
);
@ -1018,7 +1005,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
}
AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id);
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
(
delegation_results.generics,
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
@ -1041,7 +1028,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(item)
}
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
hir::ImplItemRef {
id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
ident: self.lower_ident(i.ident),
@ -1053,7 +1040,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
has_self: self.delegatee_is_method(
i.id,
delegation.id,
i.span,
is_in_trait_impl,
),
},
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")

View File

@ -121,7 +121,6 @@ struct LoweringContext<'a, 'hir> {
catch_scope: Option<HirId>,
loop_scope: Option<HirId>,
is_in_loop_condition: bool,
is_in_trait_impl: bool,
is_in_dyn_type: bool,
current_hir_id_owner: hir::OwnerId,
@ -173,7 +172,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
catch_scope: None,
loop_scope: None,
is_in_loop_condition: false,
is_in_trait_impl: false,
is_in_dyn_type: false,
coroutine_kind: None,
task_context: None,

View File

@ -860,7 +860,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
this.visit_trait_ref(t);
this.visit_ty(self_ty);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true });
});
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
@ -913,7 +913,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|this| this.visit_generics(generics),
);
this.visit_ty(self_ty);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false });
});
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
@ -1414,7 +1414,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_defaultness(item.span, item.kind.defaultness());
}
if ctxt == AssocCtxt::Impl {
if let AssocCtxt::Impl { .. } = ctxt {
match &item.kind {
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
self.dcx().emit_err(errors::AssocConstWithoutBody {

View File

@ -5,7 +5,7 @@ use rustc_attr_data_structures::{
StableSince, UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_errors::ErrorGuaranteed;
use rustc_span::{Span, Symbol, kw, sym};
use rustc_span::{Span, Symbol, sym};
use super::util::parse_version;
use super::{AcceptMapping, AttributeParser, SingleAttributeParser};
@ -61,11 +61,7 @@ impl AttributeParser for StabilityParser {
}),
(&[sym::rustc_allowed_through_unstable_modules], |this, cx, args| {
reject_outside_std!(cx);
this.allowed_through_unstable_modules =
Some(match args.name_value().and_then(|i| i.value_as_str()) {
Some(msg) => msg,
None => kw::Empty,
});
this.allowed_through_unstable_modules = args.name_value().and_then(|i| i.value_as_str())
}),
];

View File

@ -157,7 +157,7 @@ mod llvm_enzyme {
};
(sig.clone(), false)
}
Annotatable::AssocItem(assoc_item, _) => {
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
let sig = match &assoc_item.kind {
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
_ => {
@ -296,7 +296,7 @@ mod llvm_enzyme {
}
Annotatable::Item(iitem.clone())
}
Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
assoc_item.attrs.push(attr);
}
@ -327,7 +327,7 @@ mod llvm_enzyme {
kind: assoc_item,
tokens: None,
});
Annotatable::AssocItem(d_fn, Impl)
Annotatable::AssocItem(d_fn, Impl { of_trait: false })
} else {
let mut d_fn =
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));

View File

@ -121,18 +121,11 @@ impl CfgEval<'_> {
let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
Annotatable::Item(self.flat_map_item(item).pop().unwrap())
}
Annotatable::AssocItem(_, AssocCtxt::Trait) => {
Annotatable::AssocItem(_, ctxt) => {
let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
Annotatable::AssocItem(
self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
AssocCtxt::Trait,
)
}
Annotatable::AssocItem(_, AssocCtxt::Impl) => {
let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
Annotatable::AssocItem(
self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
AssocCtxt::Impl,
self.flat_map_assoc_item(item, ctxt).pop().unwrap(),
ctxt,
)
}
Annotatable::ForeignItem(_) => {

View File

@ -103,7 +103,7 @@ impl MultiItemModifier for Expander {
fn dummy_annotatable() -> Annotatable {
Annotatable::GenericParam(ast::GenericParam {
id: ast::DUMMY_NODE_ID,
ident: Ident::empty(),
ident: Ident::dummy(),
attrs: Default::default(),
bounds: Default::default(),
is_placeholder: false,

View File

@ -728,7 +728,7 @@ impl ThinBuffer {
}
}
pub unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer {
pub(crate) unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer {
let mut ptr = NonNull::new(ptr).unwrap();
ThinBuffer(unsafe { ptr.as_mut() })
}

View File

@ -29,7 +29,7 @@ use back::owned_target_machine::OwnedTargetMachine;
use back::write::{create_informational_target_machine, create_target_machine};
use context::SimpleCx;
use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig};
pub(crate) use llvm_util::target_features_cfg;
use llvm_util::target_features_cfg;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
@ -71,9 +71,7 @@ mod debuginfo;
mod declare;
mod errors;
mod intrinsic;
// FIXME(Zalathar): Fix all the unreachable-pub warnings that would occur if
// this isn't pub, then make it not pub.
pub mod llvm;
mod llvm;
mod llvm_util;
mod mono_item;
mod type_;

View File

@ -5,17 +5,17 @@ use std::{slice, str};
use rustc_fs_util::path_to_c_string;
pub struct ArchiveRO {
pub(crate) struct ArchiveRO {
pub raw: &'static mut super::Archive,
}
unsafe impl Send for ArchiveRO {}
pub struct Iter<'a> {
pub(crate) struct Iter<'a> {
raw: &'a mut super::ArchiveIterator<'a>,
}
pub struct Child<'a> {
pub(crate) struct Child<'a> {
pub raw: &'a mut super::ArchiveChild<'a>,
}

View File

@ -3,13 +3,13 @@
use libc::c_uint;
use rustc_span::InnerSpan;
pub use self::Diagnostic::*;
pub use self::OptimizationDiagnosticKind::*;
pub(crate) use self::Diagnostic::*;
use self::OptimizationDiagnosticKind::*;
use super::{DiagnosticInfo, SMDiagnostic};
use crate::value::Value;
#[derive(Copy, Clone, Debug)]
pub enum OptimizationDiagnosticKind {
pub(crate) enum OptimizationDiagnosticKind {
OptimizationRemark,
OptimizationMissed,
OptimizationAnalysis,
@ -19,9 +19,10 @@ pub enum OptimizationDiagnosticKind {
OptimizationRemarkOther,
}
pub struct OptimizationDiagnostic<'ll> {
pub(crate) struct OptimizationDiagnostic<'ll> {
pub kind: OptimizationDiagnosticKind,
pub pass_name: String,
#[expect(dead_code)]
pub function: &'ll Value,
pub line: c_uint,
pub column: c_uint,
@ -73,14 +74,14 @@ impl<'ll> OptimizationDiagnostic<'ll> {
}
}
pub struct SrcMgrDiagnostic {
pub(crate) struct SrcMgrDiagnostic {
pub level: super::DiagnosticLevel,
pub message: String,
pub source: Option<(String, Vec<InnerSpan>)>,
}
impl SrcMgrDiagnostic {
pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
pub(crate) unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
// Recover the post-substitution assembly code from LLVM for better
// diagnostics.
let mut have_source = false;
@ -120,7 +121,7 @@ impl SrcMgrDiagnostic {
}
#[derive(Clone)]
pub struct InlineAsmDiagnostic {
pub(crate) struct InlineAsmDiagnostic {
pub level: super::DiagnosticLevel,
pub cookie: u64,
pub message: String,
@ -158,7 +159,7 @@ impl InlineAsmDiagnostic {
}
}
pub enum Diagnostic<'ll> {
pub(crate) enum Diagnostic<'ll> {
Optimization(OptimizationDiagnostic<'ll>),
InlineAsm(InlineAsmDiagnostic),
PGO(&'ll DiagnosticInfo),
@ -166,11 +167,12 @@ pub enum Diagnostic<'ll> {
Unsupported(&'ll DiagnosticInfo),
/// LLVM has other types that we do not wrap here.
#[expect(dead_code)]
UnknownDiagnostic(&'ll DiagnosticInfo),
}
impl<'ll> Diagnostic<'ll> {
pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
pub(crate) unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
use super::DiagnosticKind as Dk;
unsafe {

View File

@ -31,20 +31,20 @@ unsafe extern "C" {
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
pub enum LLVMRustVerifierFailureAction {
pub(crate) enum LLVMRustVerifierFailureAction {
LLVMAbortProcessAction = 0,
LLVMPrintMessageAction = 1,
LLVMReturnStatusAction = 2,
}
#[cfg(llvm_enzyme)]
pub use self::Enzyme_AD::*;
pub(crate) use self::Enzyme_AD::*;
#[cfg(llvm_enzyme)]
pub mod Enzyme_AD {
pub(crate) mod Enzyme_AD {
use libc::c_void;
unsafe extern "C" {
pub fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
}
unsafe extern "C" {
static mut EnzymePrintPerf: c_void;
@ -56,42 +56,42 @@ pub mod Enzyme_AD {
static mut EnzymeInline: c_void;
static mut RustTypeRules: c_void;
}
pub fn set_print_perf(print: bool) {
pub(crate) fn set_print_perf(print: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8);
}
}
pub fn set_print_activity(print: bool) {
pub(crate) fn set_print_activity(print: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8);
}
}
pub fn set_print_type(print: bool) {
pub(crate) fn set_print_type(print: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8);
}
}
pub fn set_print(print: bool) {
pub(crate) fn set_print(print: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8);
}
}
pub fn set_strict_aliasing(strict: bool) {
pub(crate) fn set_strict_aliasing(strict: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8);
}
}
pub fn set_loose_types(loose: bool) {
pub(crate) fn set_loose_types(loose: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8);
}
}
pub fn set_inline(val: bool) {
pub(crate) fn set_inline(val: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8);
}
}
pub fn set_rust_rules(val: bool) {
pub(crate) fn set_rust_rules(val: bool) {
unsafe {
EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8);
}
@ -99,34 +99,34 @@ pub mod Enzyme_AD {
}
#[cfg(not(llvm_enzyme))]
pub use self::Fallback_AD::*;
pub(crate) use self::Fallback_AD::*;
#[cfg(not(llvm_enzyme))]
pub mod Fallback_AD {
pub(crate) mod Fallback_AD {
#![allow(unused_variables)]
pub fn set_inline(val: bool) {
pub(crate) fn set_inline(val: bool) {
unimplemented!()
}
pub fn set_print_perf(print: bool) {
pub(crate) fn set_print_perf(print: bool) {
unimplemented!()
}
pub fn set_print_activity(print: bool) {
pub(crate) fn set_print_activity(print: bool) {
unimplemented!()
}
pub fn set_print_type(print: bool) {
pub(crate) fn set_print_type(print: bool) {
unimplemented!()
}
pub fn set_print(print: bool) {
pub(crate) fn set_print(print: bool) {
unimplemented!()
}
pub fn set_strict_aliasing(strict: bool) {
pub(crate) fn set_strict_aliasing(strict: bool) {
unimplemented!()
}
pub fn set_loose_types(loose: bool) {
pub(crate) fn set_loose_types(loose: bool) {
unimplemented!()
}
pub fn set_rust_rules(val: bool) {
pub(crate) fn set_rust_rules(val: bool) {
unimplemented!()
}
}

View File

@ -32,10 +32,10 @@ use crate::llvm;
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
/// which has a different ABI from Rust or C++ `bool`.
pub type Bool = c_int;
pub(crate) type Bool = c_int;
pub const True: Bool = 1 as Bool;
pub const False: Bool = 0 as Bool;
pub(crate) const True: Bool = 1 as Bool;
pub(crate) const False: Bool = 0 as Bool;
/// Wrapper for a raw enum value returned from LLVM's C APIs.
///
@ -44,7 +44,7 @@ pub const False: Bool = 0 as Bool;
/// value and returns it. Instead, return this raw wrapper, then convert to the
/// Rust-side enum explicitly.
#[repr(transparent)]
pub struct RawEnum<T> {
pub(crate) struct RawEnum<T> {
value: u32,
/// We don't own or consume a `T`, but we can produce one.
_rust_side_type: PhantomData<fn() -> T>,
@ -64,7 +64,7 @@ impl<T: TryFrom<u32>> RawEnum<T> {
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
#[allow(dead_code)] // Variants constructed by C++.
pub enum LLVMRustResult {
pub(crate) enum LLVMRustResult {
Success,
Failure,
}
@ -83,7 +83,7 @@ pub enum LLVMRustResult {
/// C++ API.
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum ModuleFlagMergeBehavior {
pub(crate) enum ModuleFlagMergeBehavior {
Error = 1,
Warning = 2,
Require = 3,
@ -101,7 +101,7 @@ pub enum ModuleFlagMergeBehavior {
/// See <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/CallingConv.h>
#[derive(Copy, Clone, PartialEq, Debug, TryFromU32)]
#[repr(C)]
pub enum CallConv {
pub(crate) enum CallConv {
CCallConv = 0,
FastCallConv = 8,
ColdCallConv = 9,
@ -126,7 +126,7 @@ pub enum CallConv {
/// Must match the layout of `LLVMLinkage`.
#[derive(Copy, Clone, PartialEq, TryFromU32)]
#[repr(C)]
pub enum Linkage {
pub(crate) enum Linkage {
ExternalLinkage = 0,
AvailableExternallyLinkage = 1,
LinkOnceAnyLinkage = 2,
@ -153,7 +153,7 @@ pub enum Linkage {
/// Must match the layout of `LLVMVisibility`.
#[repr(C)]
#[derive(Copy, Clone, PartialEq, TryFromU32)]
pub enum Visibility {
pub(crate) enum Visibility {
Default = 0,
Hidden = 1,
Protected = 2,
@ -171,8 +171,9 @@ impl Visibility {
/// LLVMUnnamedAddr
#[repr(C)]
pub enum UnnamedAddr {
pub(crate) enum UnnamedAddr {
No,
#[expect(dead_code)]
Local,
Global,
}
@ -180,7 +181,7 @@ pub enum UnnamedAddr {
/// LLVMDLLStorageClass
#[derive(Copy, Clone)]
#[repr(C)]
pub enum DLLStorageClass {
pub(crate) enum DLLStorageClass {
#[allow(dead_code)]
Default = 0,
DllImport = 1, // Function to be imported from DLL.
@ -193,7 +194,8 @@ pub enum DLLStorageClass {
/// though it is not ABI compatible (since it's a C++ enum)
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub enum AttributeKind {
#[expect(dead_code, reason = "Some variants are unused, but are kept to match the C++")]
pub(crate) enum AttributeKind {
AlwaysInline = 0,
ByVal = 1,
Cold = 2,
@ -241,7 +243,7 @@ pub enum AttributeKind {
/// LLVMIntPredicate
#[derive(Copy, Clone)]
#[repr(C)]
pub enum IntPredicate {
pub(crate) enum IntPredicate {
IntEQ = 32,
IntNE = 33,
IntUGT = 34,
@ -275,7 +277,7 @@ impl IntPredicate {
/// LLVMRealPredicate
#[derive(Copy, Clone)]
#[repr(C)]
pub enum RealPredicate {
pub(crate) enum RealPredicate {
RealPredicateFalse = 0,
RealOEQ = 1,
RealOGT = 2,
@ -321,7 +323,8 @@ impl RealPredicate {
/// LLVMTypeKind
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub enum TypeKind {
#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
pub(crate) enum TypeKind {
Void = 0,
Half = 1,
Float = 2,
@ -373,7 +376,7 @@ impl TypeKind {
/// LLVMAtomicRmwBinOp
#[derive(Copy, Clone)]
#[repr(C)]
pub enum AtomicRmwBinOp {
pub(crate) enum AtomicRmwBinOp {
AtomicXchg = 0,
AtomicAdd = 1,
AtomicSub = 2,
@ -409,7 +412,7 @@ impl AtomicRmwBinOp {
/// LLVMAtomicOrdering
#[derive(Copy, Clone)]
#[repr(C)]
pub enum AtomicOrdering {
pub(crate) enum AtomicOrdering {
#[allow(dead_code)]
NotAtomic = 0,
Unordered = 1,
@ -438,7 +441,7 @@ impl AtomicOrdering {
/// LLVMRustFileType
#[derive(Copy, Clone)]
#[repr(C)]
pub enum FileType {
pub(crate) enum FileType {
AssemblyFile,
ObjectFile,
}
@ -446,7 +449,8 @@ pub enum FileType {
/// LLVMMetadataType
#[derive(Copy, Clone)]
#[repr(C)]
pub enum MetadataType {
#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
pub(crate) enum MetadataType {
MD_dbg = 0,
MD_tbaa = 1,
MD_prof = 2,
@ -470,7 +474,7 @@ pub enum MetadataType {
/// LLVMRustAsmDialect
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum AsmDialect {
pub(crate) enum AsmDialect {
Att,
Intel,
}
@ -478,7 +482,7 @@ pub enum AsmDialect {
/// LLVMRustCodeGenOptLevel
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum CodeGenOptLevel {
pub(crate) enum CodeGenOptLevel {
None,
Less,
Default,
@ -487,7 +491,7 @@ pub enum CodeGenOptLevel {
/// LLVMRustPassBuilderOptLevel
#[repr(C)]
pub enum PassBuilderOptLevel {
pub(crate) enum PassBuilderOptLevel {
O0,
O1,
O2,
@ -499,7 +503,7 @@ pub enum PassBuilderOptLevel {
/// LLVMRustOptStage
#[derive(PartialEq)]
#[repr(C)]
pub enum OptStage {
pub(crate) enum OptStage {
PreLinkNoLTO,
PreLinkThinLTO,
PreLinkFatLTO,
@ -509,7 +513,7 @@ pub enum OptStage {
/// LLVMRustSanitizerOptions
#[repr(C)]
pub struct SanitizerOptions {
pub(crate) struct SanitizerOptions {
pub sanitize_address: bool,
pub sanitize_address_recover: bool,
pub sanitize_cfi: bool,
@ -530,7 +534,7 @@ pub struct SanitizerOptions {
/// LLVMRustRelocModel
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum RelocModel {
pub(crate) enum RelocModel {
Static,
PIC,
DynamicNoPic,
@ -542,7 +546,7 @@ pub enum RelocModel {
/// LLVMRustFloatABI
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum FloatAbi {
pub(crate) enum FloatAbi {
Default,
Soft,
Hard,
@ -551,7 +555,7 @@ pub enum FloatAbi {
/// LLVMRustCodeModel
#[derive(Copy, Clone)]
#[repr(C)]
pub enum CodeModel {
pub(crate) enum CodeModel {
Tiny,
Small,
Kernel,
@ -564,7 +568,7 @@ pub enum CodeModel {
#[derive(Copy, Clone)]
#[repr(C)]
#[allow(dead_code)] // Variants constructed by C++.
pub enum DiagnosticKind {
pub(crate) enum DiagnosticKind {
Other,
InlineAsm,
StackSize,
@ -587,7 +591,7 @@ pub enum DiagnosticKind {
#[derive(Copy, Clone)]
#[repr(C)]
#[allow(dead_code)] // Variants constructed by C++.
pub enum DiagnosticLevel {
pub(crate) enum DiagnosticLevel {
Error,
Warning,
Note,
@ -597,7 +601,7 @@ pub enum DiagnosticLevel {
/// LLVMRustArchiveKind
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ArchiveKind {
pub(crate) enum ArchiveKind {
K_GNU,
K_BSD,
K_DARWIN,
@ -607,15 +611,15 @@ pub enum ArchiveKind {
unsafe extern "C" {
// LLVMRustThinLTOData
pub type ThinLTOData;
pub(crate) type ThinLTOData;
// LLVMRustThinLTOBuffer
pub type ThinLTOBuffer;
pub(crate) type ThinLTOBuffer;
}
/// LLVMRustThinLTOModule
#[repr(C)]
pub struct ThinLTOModule {
pub(crate) struct ThinLTOModule {
pub identifier: *const c_char,
pub data: *const u8,
pub len: usize,
@ -624,7 +628,8 @@ pub struct ThinLTOModule {
/// LLVMThreadLocalMode
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ThreadLocalMode {
pub(crate) enum ThreadLocalMode {
#[expect(dead_code)]
NotThreadLocal,
GeneralDynamic,
LocalDynamic,
@ -635,7 +640,7 @@ pub enum ThreadLocalMode {
/// LLVMRustChecksumKind
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ChecksumKind {
pub(crate) enum ChecksumKind {
None,
MD5,
SHA1,
@ -645,7 +650,7 @@ pub enum ChecksumKind {
/// LLVMRustMemoryEffects
#[derive(Copy, Clone)]
#[repr(C)]
pub enum MemoryEffects {
pub(crate) enum MemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
@ -654,7 +659,8 @@ pub enum MemoryEffects {
/// LLVMOpcode
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(C)]
pub enum Opcode {
#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
pub(crate) enum Opcode {
Ret = 1,
Br = 2,
Switch = 3,
@ -735,48 +741,48 @@ struct InvariantOpaque<'a> {
// Opaque pointer types
unsafe extern "C" {
pub type Module;
pub type Context;
pub type Type;
pub type Value;
pub type ConstantInt;
pub type Attribute;
pub type Metadata;
pub type BasicBlock;
pub type Comdat;
pub(crate) type Module;
pub(crate) type Context;
pub(crate) type Type;
pub(crate) type Value;
pub(crate) type ConstantInt;
pub(crate) type Attribute;
pub(crate) type Metadata;
pub(crate) type BasicBlock;
pub(crate) type Comdat;
}
#[repr(C)]
pub struct Builder<'a>(InvariantOpaque<'a>);
pub(crate) struct Builder<'a>(InvariantOpaque<'a>);
#[repr(C)]
pub struct PassManager<'a>(InvariantOpaque<'a>);
pub(crate) struct PassManager<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type TargetMachine;
pub type Archive;
pub(crate) type Archive;
}
#[repr(C)]
pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
pub(crate) struct ArchiveIterator<'a>(InvariantOpaque<'a>);
#[repr(C)]
pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
pub(crate) struct ArchiveChild<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type Twine;
pub type DiagnosticInfo;
pub type SMDiagnostic;
pub(crate) type Twine;
pub(crate) type DiagnosticInfo;
pub(crate) type SMDiagnostic;
}
#[repr(C)]
pub struct RustArchiveMember<'a>(InvariantOpaque<'a>);
pub(crate) struct RustArchiveMember<'a>(InvariantOpaque<'a>);
/// Opaque pointee of `LLVMOperandBundleRef`.
#[repr(C)]
pub(crate) struct OperandBundle<'a>(InvariantOpaque<'a>);
#[repr(C)]
pub struct Linker<'a>(InvariantOpaque<'a>);
pub(crate) struct Linker<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type DiagnosticHandler;
pub(crate) type DiagnosticHandler;
}
pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
pub(crate) type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
pub mod debuginfo {
pub(crate) mod debuginfo {
use std::ptr;
use bitflags::bitflags;
@ -793,7 +799,7 @@ pub mod debuginfo {
/// builder reference typically has a shorter lifetime than the LLVM
/// session (`'ll`) that it participates in.
#[repr(C)]
pub struct DIBuilder<'ll>(InvariantOpaque<'ll>);
pub(crate) struct DIBuilder<'ll>(InvariantOpaque<'ll>);
/// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder
/// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder`
@ -822,22 +828,22 @@ pub mod debuginfo {
}
}
pub type DIDescriptor = Metadata;
pub type DILocation = Metadata;
pub type DIScope = DIDescriptor;
pub type DIFile = DIScope;
pub type DILexicalBlock = DIScope;
pub type DISubprogram = DIScope;
pub type DIType = DIDescriptor;
pub type DIBasicType = DIType;
pub type DIDerivedType = DIType;
pub type DICompositeType = DIDerivedType;
pub type DIVariable = DIDescriptor;
pub type DIGlobalVariableExpression = DIDescriptor;
pub type DIArray = DIDescriptor;
pub type DISubrange = DIDescriptor;
pub type DIEnumerator = DIDescriptor;
pub type DITemplateTypeParameter = DIDescriptor;
pub(crate) type DIDescriptor = Metadata;
pub(crate) type DILocation = Metadata;
pub(crate) type DIScope = DIDescriptor;
pub(crate) type DIFile = DIScope;
pub(crate) type DILexicalBlock = DIScope;
pub(crate) type DISubprogram = DIScope;
pub(crate) type DIType = DIDescriptor;
pub(crate) type DIBasicType = DIType;
pub(crate) type DIDerivedType = DIType;
pub(crate) type DICompositeType = DIDerivedType;
pub(crate) type DIVariable = DIDescriptor;
pub(crate) type DIGlobalVariableExpression = DIDescriptor;
pub(crate) type DIArray = DIDescriptor;
pub(crate) type DISubrange = DIDescriptor;
pub(crate) type DIEnumerator = DIDescriptor;
pub(crate) type DITemplateTypeParameter = DIDescriptor;
bitflags! {
/// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
@ -846,7 +852,7 @@ pub mod debuginfo {
/// assertions in `RustWrapper.cpp` used by `fromRust(LLVMDIFlags)`.
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct DIFlags: u32 {
pub(crate) struct DIFlags: u32 {
const FlagZero = 0;
const FlagPrivate = 1;
const FlagProtected = 2;
@ -886,7 +892,7 @@ pub mod debuginfo {
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct DISPFlags: u32 {
pub(crate) struct DISPFlags: u32 {
const SPFlagZero = 0;
const SPFlagVirtual = 1;
const SPFlagPureVirtual = 2;
@ -900,7 +906,7 @@ pub mod debuginfo {
/// LLVMRustDebugEmissionKind
#[derive(Copy, Clone)]
#[repr(C)]
pub enum DebugEmissionKind {
pub(crate) enum DebugEmissionKind {
NoDebug,
FullDebug,
LineTablesOnly,
@ -932,8 +938,9 @@ pub mod debuginfo {
/// LLVMRustDebugNameTableKind
#[derive(Clone, Copy)]
#[repr(C)]
pub enum DebugNameTableKind {
pub(crate) enum DebugNameTableKind {
Default,
#[expect(dead_code)]
Gnu,
None,
}
@ -943,7 +950,7 @@ pub mod debuginfo {
bitflags! {
#[repr(transparent)]
#[derive(Default)]
pub struct AllocKindFlags : u64 {
pub(crate) struct AllocKindFlags : u64 {
const Unknown = 0;
const Alloc = 1;
const Realloc = 1 << 1;
@ -966,19 +973,20 @@ bitflags! {
}
unsafe extern "C" {
pub type ModuleBuffer;
pub(crate) type ModuleBuffer;
}
pub type SelfProfileBeforePassCallback =
pub(crate) type SelfProfileBeforePassCallback =
unsafe extern "C" fn(*mut c_void, *const c_char, *const c_char);
pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
pub(crate) type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
pub(crate) type GetSymbolsCallback =
unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct MetadataKindId(c_uint);
pub(crate) struct MetadataKindId(c_uint);
impl From<MetadataType> for MetadataKindId {
fn from(value: MetadataType) -> Self {

View File

@ -9,18 +9,18 @@ use libc::c_uint;
use rustc_abi::{Align, Size, WrappingRange};
use rustc_llvm::RustString;
pub use self::CallConv::*;
pub use self::CodeGenOptSize::*;
pub use self::MetadataType::*;
pub use self::ffi::*;
pub(crate) use self::CallConv::*;
pub(crate) use self::CodeGenOptSize::*;
pub(crate) use self::MetadataType::*;
pub(crate) use self::ffi::*;
use crate::common::AsCCharPtr;
pub mod archive_ro;
pub mod diagnostic;
pub mod enzyme_ffi;
pub(crate) mod archive_ro;
pub(crate) mod diagnostic;
pub(crate) mod enzyme_ffi;
mod ffi;
pub use self::enzyme_ffi::*;
pub(crate) use self::enzyme_ffi::*;
impl LLVMRustResult {
pub(crate) fn into_result(self) -> Result<(), ()> {
@ -127,7 +127,7 @@ pub(crate) fn CreateRangeAttr(llcx: &Context, size: Size, range: WrappingRange)
}
#[derive(Copy, Clone)]
pub enum AttributePlace {
pub(crate) enum AttributePlace {
ReturnValue,
Argument(u32),
Function,
@ -145,7 +145,7 @@ impl AttributePlace {
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum CodeGenOptSize {
pub(crate) enum CodeGenOptSize {
CodeGenOptSizeNone = 0,
CodeGenOptSizeDefault = 1,
CodeGenOptSizeAggressive = 2,

View File

@ -14,7 +14,7 @@ Erroneous code example:
#![unstable(feature = "foo_module", reason = "...", issue = "123")]
#[rustc_allowed_through_unstable_modules]
#[rustc_allowed_through_unstable_modules = "deprecation message"]
// #[stable(feature = "foo", since = "1.0")]
struct Foo;
// ^^^ error: `rustc_allowed_through_unstable_modules` attribute must be

View File

@ -153,7 +153,7 @@ impl Annotatable {
pub fn expect_impl_item(self) -> P<ast::AssocItem> {
match self {
Annotatable::AssocItem(i, AssocCtxt::Impl) => i,
Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
_ => panic!("expected Item"),
}
}
@ -403,6 +403,11 @@ pub trait MacResult {
None
}
/// Creates zero or more impl items.
fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
None
}
/// Creates zero or more trait items.
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
None
@ -516,6 +521,10 @@ impl MacResult for MacEager {
self.impl_items
}
fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
self.impl_items
}
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
self.trait_items
}
@ -613,6 +622,10 @@ impl MacResult for DummyResult {
Some(SmallVec::new())
}
fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
Some(SmallVec::new())
}
fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
Some(SmallVec::new())
}

View File

@ -188,9 +188,15 @@ ast_fragments! {
ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
"impl item";
many fn flat_map_assoc_item;
fn visit_assoc_item(AssocCtxt::Impl);
fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
fn make_impl_items;
}
TraitImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
"impl item";
many fn flat_map_assoc_item;
fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
fn make_trait_impl_items;
}
ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
"foreign item";
many fn flat_map_foreign_item;
@ -257,6 +263,7 @@ impl AstFragmentKind {
AstFragmentKind::Items
| AstFragmentKind::TraitItems
| AstFragmentKind::ImplItems
| AstFragmentKind::TraitImplItems
| AstFragmentKind::ForeignItems
| AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true },
AstFragmentKind::Arms
@ -306,6 +313,9 @@ impl AstFragmentKind {
AstFragmentKind::ImplItems => {
AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
}
AstFragmentKind::TraitImplItems => {
AstFragment::TraitImplItems(items.map(Annotatable::expect_impl_item).collect())
}
AstFragmentKind::TraitItems => {
AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
}
@ -347,10 +357,10 @@ pub enum InvocationKind {
},
Attr {
attr: ast::Attribute,
// Re-insertion position for inert attributes.
/// Re-insertion position for inert attributes.
pos: usize,
item: Annotatable,
// Required for resolving derive helper attributes.
/// Required for resolving derive helper attributes.
derives: Vec<ast::Path>,
},
Derive {
@ -360,6 +370,8 @@ pub enum InvocationKind {
},
GlobDelegation {
item: P<ast::AssocItem>,
/// Whether this is a trait impl or an inherent impl
of_trait: bool,
},
}
@ -388,7 +400,7 @@ impl Invocation {
InvocationKind::Bang { span, .. } => *span,
InvocationKind::Attr { attr, .. } => attr.span,
InvocationKind::Derive { path, .. } => path.span,
InvocationKind::GlobDelegation { item } => item.span,
InvocationKind::GlobDelegation { item, .. } => item.span,
}
}
@ -397,7 +409,7 @@ impl Invocation {
InvocationKind::Bang { span, .. } => span,
InvocationKind::Attr { attr, .. } => &mut attr.span,
InvocationKind::Derive { path, .. } => &mut path.span,
InvocationKind::GlobDelegation { item } => &mut item.span,
InvocationKind::GlobDelegation { item, .. } => &mut item.span,
}
}
}
@ -820,7 +832,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
_ => unreachable!(),
},
InvocationKind::GlobDelegation { item } => {
InvocationKind::GlobDelegation { item, of_trait } => {
let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
let suffixes = match ext {
SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
@ -829,7 +841,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
ExpandResult::Retry(()) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(Invocation {
kind: InvocationKind::GlobDelegation { item },
kind: InvocationKind::GlobDelegation { item, of_trait },
..invoc
});
}
@ -847,7 +859,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx, deleg, &item, &suffixes, item.span, true,
);
fragment_kind.expect_from_annotatables(
single_delegations.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl)),
single_delegations
.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl { of_trait })),
)
}
})
@ -973,6 +986,13 @@ pub fn parse_ast_fragment<'a>(
}
AstFragment::ImplItems(items)
}
AstFragmentKind::TraitImplItems => {
let mut items = SmallVec::new();
while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
items.extend(item);
}
AstFragment::TraitImplItems(items)
}
AstFragmentKind::ForeignItems => {
let mut items = SmallVec::new();
while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
@ -1355,13 +1375,13 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
type ItemKind = AssocItemKind;
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
fn to_annotatable(self) -> Annotatable {
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl)
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: false })
}
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
fragment.make_impl_items()
}
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl)
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false })
}
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@ -1390,6 +1410,47 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
}
}
struct TraitImplItemTag;
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItemTag> {
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
type ItemKind = AssocItemKind;
const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems;
fn to_annotatable(self) -> Annotatable {
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: true })
}
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
fragment.make_trait_impl_items()
}
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true })
}
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
_ => unreachable!(),
}
}
fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
match &self.wrapped.kind {
AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
_ => None,
}
}
fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
AssocItemKind::Delegation(deleg)
}
fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
AstNodeWrapper::new(P(item), TraitImplItemTag)
}
fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
items.flatten().collect()
}
}
impl InvocationCollectorNode for P<ast::ForeignItem> {
const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
fn to_annotatable(self) -> Annotatable {
@ -1855,9 +1916,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn collect_glob_delegation(
&mut self,
item: P<ast::AssocItem>,
of_trait: bool,
kind: AstFragmentKind,
) -> AstFragment {
self.collect(kind, InvocationKind::GlobDelegation { item })
self.collect(kind, InvocationKind::GlobDelegation { item, of_trait })
}
/// If `item` is an attribute invocation, remove the attribute and return it together with
@ -2030,8 +2092,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let Some(suffixes) = &deleg.suffixes else {
let traitless_qself =
matches!(&deleg.qself, Some(qself) if qself.position == 0);
let item = match node.to_annotatable() {
Annotatable::AssocItem(item, AssocCtxt::Impl) => item,
let (item, of_trait) = match node.to_annotatable() {
Annotatable::AssocItem(item, AssocCtxt::Impl { of_trait }) => {
(item, of_trait)
}
ann @ (Annotatable::Item(_)
| Annotatable::AssocItem(..)
| Annotatable::Stmt(_)) => {
@ -2046,7 +2110,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
return Default::default();
}
return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
return self
.collect_glob_delegation(item, of_trait, Node::KIND)
.make_ast::<Node>();
};
let single_delegations = build_single_delegations::<Node>(
@ -2126,7 +2192,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
) -> SmallVec<[P<ast::AssocItem>; 1]> {
match ctxt {
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
AssocCtxt::Impl => self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)),
AssocCtxt::Impl { of_trait: false } => {
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
}
AssocCtxt::Impl { of_trait: true } => {
self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
}
}
}

View File

@ -86,6 +86,17 @@ pub(crate) fn placeholder(
kind: ast::AssocItemKind::MacCall(mac_placeholder()),
tokens: None,
})]),
AstFragmentKind::TraitImplItems => {
AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
id,
span,
ident,
vis,
attrs,
kind: ast::AssocItemKind::MacCall(mac_placeholder()),
tokens: None,
})])
}
AstFragmentKind::ForeignItems => {
AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
id,
@ -308,7 +319,8 @@ impl MutVisitor for PlaceholderExpander {
let it = self.remove(item.id);
match ctxt {
AssocCtxt::Trait => it.make_trait_items(),
AssocCtxt::Impl => it.make_impl_items(),
AssocCtxt::Impl { of_trait: false } => it.make_impl_items(),
AssocCtxt::Impl { of_trait: true } => it.make_trait_impl_items(),
}
}
_ => walk_flat_map_assoc_item(self, item, ctxt),

View File

@ -192,7 +192,18 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
// `TyCtxt` TLS reference here.
let query_map = current_gcx2.access(|gcx| {
tls::enter_context(&tls::ImplicitCtxt::new(gcx), || {
tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())
tls::with(|tcx| {
match QueryCtxt::new(tcx).collect_active_jobs() {
Ok(query_map) => query_map,
Err(_) => {
// There was an unexpected error collecting all active jobs, which we need
// to find cycles to break.
// We want to avoid panicking in the deadlock handler, so we abort instead.
eprintln!("internal compiler error: failed to get query map in deadlock handler, aborting process");
process::abort();
}
}
})
})
});
let query_map = FromDyn::from(query_map);
@ -201,7 +212,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
.name("rustc query cycle handler".to_string())
.spawn(move || {
let on_panic = defer(|| {
eprintln!("query cycle handler thread panicked, aborting process");
eprintln!("internal compiler error: query cycle handler thread panicked, aborting process");
// We need to abort here as we failed to resolve the deadlock,
// otherwise the compiler could just hang,
process::abort();

View File

@ -241,7 +241,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
ast_visit::AssocCtxt::Trait => {
lint_callback!(cx, check_trait_item, item);
}
ast_visit::AssocCtxt::Impl => {
ast_visit::AssocCtxt::Impl { .. } => {
lint_callback!(cx, check_impl_item, item);
}
}
@ -250,7 +250,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
ast_visit::AssocCtxt::Trait => {
lint_callback!(cx, check_trait_item_post, item);
}
ast_visit::AssocCtxt::Impl => {
ast_visit::AssocCtxt::Impl { .. } => {
lint_callback!(cx, check_impl_item_post, item);
}
}

View File

@ -7,7 +7,7 @@ use rustc_parse_format::{ParseMode, Parser, Piece};
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::{InnerSpan, Span, Symbol, hygiene, kw, sym};
use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym};
use rustc_trait_selection::infer::InferCtxtExt;
use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
@ -167,7 +167,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
.get_diagnostic_item(sym::Debug)
.is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
let suggest_panic_any = !is_str && panic == sym::std_panic_macro;
let suggest_panic_any = !is_str && panic == Some(sym::std_panic_macro);
let fmt_applicability = if suggest_panic_any {
// If we can use panic_any, use that as the MachineApplicable suggestion.
@ -297,10 +297,13 @@ fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char
))
}
fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol, Symbol) {
fn panic_call<'tcx>(
cx: &LateContext<'tcx>,
f: &'tcx hir::Expr<'tcx>,
) -> (Span, Option<Symbol>, Symbol) {
let mut expn = f.span.ctxt().outer_expn_data();
let mut panic_macro = kw::Empty;
let mut panic_macro = None;
// Unwrap more levels of macro expansion, as panic_2015!()
// was likely expanded from panic!() and possibly from
@ -320,7 +323,7 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
break;
}
expn = parent;
panic_macro = name;
panic_macro = Some(name);
}
let macro_symbol =

View File

@ -273,8 +273,9 @@ struct ExtractedHirInfo {
/// Must have the same context and filename as the body span.
fn_sig_span_extended: Option<Span>,
body_span: Span,
/// "Holes" are regions within the body span that should not be included in
/// coverage spans for this function (e.g. closures and nested items).
/// "Holes" are regions within the function body (or its expansions) that
/// should not be included in coverage spans for this function
/// (e.g. closures and nested items).
hole_spans: Vec<Span>,
}
@ -323,7 +324,7 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir
let function_source_hash = hash_mir_source(tcx, hir_body);
let hole_spans = extract_hole_spans_from_hir(tcx, body_span, hir_body);
let hole_spans = extract_hole_spans_from_hir(tcx, hir_body);
ExtractedHirInfo {
function_source_hash,
@ -340,14 +341,9 @@ fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) ->
tcx.hir_owner_nodes(owner).opt_hash_including_bodies.unwrap().to_smaller_hash().as_u64()
}
fn extract_hole_spans_from_hir<'tcx>(
tcx: TyCtxt<'tcx>,
body_span: Span, // Usually `hir_body.value.span`, but not always
hir_body: &hir::Body<'tcx>,
) -> Vec<Span> {
fn extract_hole_spans_from_hir<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &hir::Body<'tcx>) -> Vec<Span> {
struct HolesVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
body_span: Span,
hole_spans: Vec<Span>,
}
@ -387,14 +383,11 @@ fn extract_hole_spans_from_hir<'tcx>(
}
impl HolesVisitor<'_> {
fn visit_hole_span(&mut self, hole_span: Span) {
// Discard any holes that aren't directly visible within the body span.
if self.body_span.contains(hole_span) && self.body_span.eq_ctxt(hole_span) {
self.hole_spans.push(hole_span);
}
self.hole_spans.push(hole_span);
}
}
let mut visitor = HolesVisitor { tcx, body_span, hole_spans: vec![] };
let mut visitor = HolesVisitor { tcx, hole_spans: vec![] };
visitor.visit_body(hir_body);
visitor.hole_spans

View File

@ -6,10 +6,8 @@ use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
use tracing::{debug, debug_span, instrument};
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
use crate::coverage::spans::from_mir::{
ExtractedCovspans, Hole, SpanFromMir, extract_covspans_from_mir,
};
use crate::coverage::{ExtractedHirInfo, mappings};
use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir};
use crate::coverage::{ExtractedHirInfo, mappings, unexpand};
mod from_mir;
@ -19,7 +17,35 @@ pub(super) fn extract_refined_covspans(
graph: &CoverageGraph,
code_mappings: &mut impl Extend<mappings::CodeMapping>,
) {
let ExtractedCovspans { mut covspans } = extract_covspans_from_mir(mir_body, hir_info, graph);
let &ExtractedHirInfo { body_span, .. } = hir_info;
let raw_spans = from_mir::extract_raw_spans_from_mir(mir_body, graph);
let mut covspans = raw_spans
.into_iter()
.filter_map(|RawSpanFromMir { raw_span, bcb }| try {
let (span, expn_kind) =
unexpand::unexpand_into_body_span_with_expn_kind(raw_span, body_span)?;
// Discard any spans that fill the entire body, because they tend
// to represent compiler-inserted code, e.g. implicitly returning `()`.
if span.source_equal(body_span) {
return None;
};
SpanFromMir { span, expn_kind, bcb }
})
.collect::<Vec<_>>();
// Only proceed if we found at least one usable span.
if covspans.is_empty() {
return;
}
// Also add the adjusted function signature span, if available.
// Otherwise, add a fake span at the start of the body, to avoid an ugly
// gap between the start of the body and the first real span.
// FIXME: Find a more principled way to solve this problem.
covspans.push(SpanFromMir::for_fn_sig(
hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo()),
));
// First, perform the passes that need macro information.
covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
@ -43,7 +69,14 @@ pub(super) fn extract_refined_covspans(
covspans.dedup_by(|b, a| a.span.source_equal(b.span));
// Sort the holes, and merge overlapping/adjacent holes.
let mut holes = hir_info.hole_spans.iter().map(|&span| Hole { span }).collect::<Vec<_>>();
let mut holes = hir_info
.hole_spans
.iter()
.copied()
// Discard any holes that aren't directly visible within the body span.
.filter(|&hole_span| body_span.contains(hole_span) && body_span.eq_ctxt(hole_span))
.map(|span| Hole { span })
.collect::<Vec<_>>();
holes.sort_by(|a, b| compare_spans(a.span, b.span));
holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));

View File

@ -1,3 +1,5 @@
use std::iter;
use rustc_middle::bug;
use rustc_middle::mir::coverage::CoverageKind;
use rustc_middle::mir::{
@ -5,87 +7,50 @@ use rustc_middle::mir::{
};
use rustc_span::{ExpnKind, Span};
use crate::coverage::ExtractedHirInfo;
use crate::coverage::graph::{
BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
};
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
use crate::coverage::spans::Covspan;
use crate::coverage::unexpand::unexpand_into_body_span_with_expn_kind;
pub(crate) struct ExtractedCovspans {
pub(crate) covspans: Vec<SpanFromMir>,
#[derive(Debug)]
pub(crate) struct RawSpanFromMir {
/// A span that has been extracted from a MIR statement/terminator, but
/// hasn't been "unexpanded", so it might not lie within the function body
/// span and might be part of an expansion with a different context.
pub(crate) raw_span: Span,
pub(crate) bcb: BasicCoverageBlock,
}
/// Traverses the MIR body to produce an initial collection of coverage-relevant
/// spans, each associated with a node in the coverage graph (BCB) and possibly
/// other metadata.
pub(crate) fn extract_covspans_from_mir(
mir_body: &mir::Body<'_>,
hir_info: &ExtractedHirInfo,
/// Generates an initial set of coverage spans from the statements and
/// terminators in the function's MIR body, each associated with its
/// corresponding node in the coverage graph.
///
/// This is necessarily an inexact process, because MIR isn't designed to
/// capture source spans at the level of detail we would want for coverage,
/// but it's good enough to be better than nothing.
pub(crate) fn extract_raw_spans_from_mir<'tcx>(
mir_body: &mir::Body<'tcx>,
graph: &CoverageGraph,
) -> ExtractedCovspans {
let &ExtractedHirInfo { body_span, .. } = hir_info;
let mut covspans = vec![];
) -> Vec<RawSpanFromMir> {
let mut raw_spans = vec![];
// We only care about blocks that are part of the coverage graph.
for (bcb, bcb_data) in graph.iter_enumerated() {
bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans);
}
let make_raw_span = |raw_span: Span| RawSpanFromMir { raw_span, bcb };
// Only add the signature span if we found at least one span in the body.
if !covspans.is_empty() {
// If there is no usable signature span, add a fake one (before refinement)
// to avoid an ugly gap between the body start and the first real span.
// FIXME: Find a more principled way to solve this problem.
let fn_sig_span = hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo());
covspans.push(SpanFromMir::for_fn_sig(fn_sig_span));
}
// A coverage graph node can consist of multiple basic blocks.
for &bb in &bcb_data.basic_blocks {
let bb_data = &mir_body[bb];
ExtractedCovspans { covspans }
}
let statements = bb_data.statements.iter();
raw_spans.extend(statements.filter_map(filtered_statement_span).map(make_raw_span));
// Generate a set of coverage spans from the filtered set of `Statement`s and `Terminator`s of
// the `BasicBlock`(s) in the given `BasicCoverageBlockData`. One coverage span is generated
// for each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will
// merge some coverage spans, at which point a coverage span may represent multiple
// `Statement`s and/or `Terminator`s.)
fn bcb_to_initial_coverage_spans<'a, 'tcx>(
mir_body: &'a mir::Body<'tcx>,
body_span: Span,
bcb: BasicCoverageBlock,
bcb_data: &'a BasicCoverageBlockData,
initial_covspans: &mut Vec<SpanFromMir>,
) {
for &bb in &bcb_data.basic_blocks {
let data = &mir_body[bb];
let unexpand = move |expn_span| {
unexpand_into_body_span_with_expn_kind(expn_span, body_span)
// Discard any spans that fill the entire body, because they tend
// to represent compiler-inserted code, e.g. implicitly returning `()`.
.filter(|(span, _)| !span.source_equal(body_span))
};
let mut extract_statement_span = |statement| {
let expn_span = filtered_statement_span(statement)?;
let (span, expn_kind) = unexpand(expn_span)?;
initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
Some(())
};
for statement in data.statements.iter() {
extract_statement_span(statement);
// There's only one terminator, but wrap it in an iterator to
// mirror the handling of statements.
let terminator = iter::once(bb_data.terminator());
raw_spans.extend(terminator.filter_map(filtered_terminator_span).map(make_raw_span));
}
let mut extract_terminator_span = |terminator| {
let expn_span = filtered_terminator_span(terminator)?;
let (span, expn_kind) = unexpand(expn_span)?;
initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
Some(())
};
extract_terminator_span(data.terminator());
}
raw_spans
}
/// If the MIR `Statement` has a span contributive to computing coverage spans,
@ -219,7 +184,7 @@ pub(crate) struct SpanFromMir {
}
impl SpanFromMir {
fn for_fn_sig(fn_sig_span: Span) -> Self {
pub(crate) fn for_fn_sig(fn_sig_span: Span) -> Self {
Self::new(fn_sig_span, None, START_BCB)
}

View File

@ -2871,7 +2871,7 @@ impl<'a> Parser<'a> {
// Skip every token until next possible arg or end.
p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
// Create a placeholder argument for proper arg count (issue #34264).
Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span)), guar))
Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
});
// ...now that we've parsed the first argument, `self` is no longer allowed.
first_param = false;

View File

@ -1348,12 +1348,12 @@ pub(crate) struct DuplicateLangItem {
pub local_span: Option<Span>,
pub lang_item_name: Symbol,
pub crate_name: Symbol,
pub dependency_of: Symbol,
pub dependency_of: Option<Symbol>,
pub is_local: bool,
pub path: String,
pub first_defined_span: Option<Span>,
pub orig_crate_name: Symbol,
pub orig_dependency_of: Symbol,
pub orig_crate_name: Option<Symbol>,
pub orig_dependency_of: Option<Symbol>,
pub orig_is_local: bool,
pub orig_path: String,
pub(crate) duplicate: Duplicate,
@ -1374,10 +1374,16 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for DuplicateLangItem {
diag.code(E0152);
diag.arg("lang_item_name", self.lang_item_name);
diag.arg("crate_name", self.crate_name);
diag.arg("dependency_of", self.dependency_of);
if let Some(dependency_of) = self.dependency_of {
diag.arg("dependency_of", dependency_of);
}
diag.arg("path", self.path);
diag.arg("orig_crate_name", self.orig_crate_name);
diag.arg("orig_dependency_of", self.orig_dependency_of);
if let Some(orig_crate_name) = self.orig_crate_name {
diag.arg("orig_crate_name", orig_crate_name);
}
if let Some(orig_dependency_of) = self.orig_dependency_of {
diag.arg("orig_dependency_of", orig_dependency_of);
}
diag.arg("orig_path", self.orig_path);
if let Some(span) = self.local_span {
diag.span(span);
@ -1385,7 +1391,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for DuplicateLangItem {
if let Some(span) = self.first_defined_span {
diag.span_note(span, fluent::passes_first_defined_span);
} else {
if self.orig_dependency_of.is_empty() {
if self.orig_dependency_of.is_none() {
diag.note(fluent::passes_first_defined_crate);
} else {
diag.note(fluent::passes_first_defined_crate_depends);

View File

@ -16,7 +16,7 @@ use rustc_hir::{LangItem, LanguageItems, MethodKind, Target};
use rustc_middle::query::Providers;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_session::cstore::ExternCrate;
use rustc_span::{Span, kw};
use rustc_span::Span;
use crate::errors::{
DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem,
@ -98,7 +98,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
{
let lang_item_name = lang_item.name();
let crate_name = self.tcx.crate_name(item_def_id.krate);
let mut dependency_of = kw::Empty;
let mut dependency_of = None;
let is_local = item_def_id.is_local();
let path = if is_local {
String::new()
@ -112,8 +112,8 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
};
let first_defined_span = self.item_spans.get(&original_def_id).copied();
let mut orig_crate_name = kw::Empty;
let mut orig_dependency_of = kw::Empty;
let mut orig_crate_name = None;
let mut orig_dependency_of = None;
let orig_is_local = original_def_id.is_local();
let orig_path = if orig_is_local {
String::new()
@ -127,11 +127,11 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
};
if first_defined_span.is_none() {
orig_crate_name = self.tcx.crate_name(original_def_id.krate);
orig_crate_name = Some(self.tcx.crate_name(original_def_id.krate));
if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
self.tcx.extern_crate(original_def_id.krate)
{
orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
orig_dependency_of = Some(self.tcx.crate_name(*inner_dependency_of));
}
}
@ -140,7 +140,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
} else {
match self.tcx.extern_crate(item_def_id.krate) {
Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
dependency_of = self.tcx.crate_name(*inner_dependency_of);
dependency_of = Some(self.tcx.crate_name(*inner_dependency_of));
Duplicate::CrateDepends
}
_ => Duplicate::Crate,

View File

@ -72,7 +72,9 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
pub trait DefIdVisitor<'tcx> {
type Result: VisitorResult = ();
const SHALLOW: bool = false;
const SKIP_ASSOC_TYS: bool = false;
fn skip_assoc_tys(&self) -> bool {
false
}
fn tcx(&self) -> TyCtxt<'tcx>;
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
@ -213,7 +215,7 @@ where
}
}
ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => {
if V::SKIP_ASSOC_TYS {
if self.def_id_visitor.skip_assoc_tys() {
// Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias`
// as visible/reachable even if `Type` is private.
@ -324,7 +326,9 @@ impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
for FindMin<'a, 'tcx, VL, SHALLOW>
{
const SHALLOW: bool = SHALLOW;
const SKIP_ASSOC_TYS: bool = true;
fn skip_assoc_tys(&self) -> bool {
true
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
@ -342,7 +346,7 @@ trait VisibilityLike: Sized {
def_id: LocalDefId,
) -> Self;
// Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
// Returns an over-approximation (`skip_assoc_tys()` = true) of visibility due to
// associated types for which we can't determine visibility precisely.
fn of_impl<const SHALLOW: bool>(
def_id: LocalDefId,
@ -1352,6 +1356,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
required_effective_vis: Option<EffectiveVisibility>,
in_assoc_ty: bool,
in_primary_interface: bool,
skip_assoc_tys: bool,
}
impl SearchInterfaceForPrivateItemsVisitor<'_> {
@ -1398,6 +1403,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
self
}
fn trait_ref(&mut self) -> &mut Self {
self.in_primary_interface = true;
if let Some(trait_ref) = self.tcx.impl_trait_ref(self.item_def_id) {
let _ = self.visit_trait(trait_ref.instantiate_identity());
}
self
}
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
if self.leaks_private_dep(def_id) {
self.tcx.emit_node_span_lint(
@ -1495,6 +1508,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
type Result = ControlFlow<()>;
fn skip_assoc_tys(&self) -> bool {
self.skip_assoc_tys
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
@ -1531,6 +1547,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
required_effective_vis,
in_assoc_ty: false,
in_primary_interface: true,
skip_assoc_tys: false,
}
}
@ -1726,13 +1743,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
self.effective_visibilities,
);
// check that private components do not appear in the generics or predicates of inherent impls
// this check is intentionally NOT performed for impls of traits, per #90586
let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev));
// Generics and predicates of trait impls are intentionally not checked
// for private components (#90586).
if impl_.of_trait.is_none() {
self.check(item.owner_id.def_id, impl_vis, Some(impl_ev))
.generics()
.predicates();
check.generics().predicates();
}
// Skip checking private components in associated types, due to lack of full
// normalization they produce very ridiculous false positives.
// FIXME: Remove this when full normalization is implemented.
check.skip_assoc_tys = true;
check.ty().trait_ref();
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
min(

View File

@ -79,14 +79,20 @@ impl QueryContext for QueryCtxt<'_> {
tls::with_related_context(self.tcx, |icx| icx.query)
}
fn collect_active_jobs(self) -> QueryMap {
/// Returns a query map representing active query jobs.
/// It returns an incomplete map as an error if it fails
/// to take locks.
fn collect_active_jobs(self) -> Result<QueryMap, QueryMap> {
let mut jobs = QueryMap::default();
let mut complete = true;
for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
collect(self.tcx, &mut jobs);
if collect(self.tcx, &mut jobs).is_none() {
complete = false;
}
}
jobs
if complete { Ok(jobs) } else { Err(jobs) }
}
// Interactions with on_disk_cache
@ -139,7 +145,12 @@ impl QueryContext for QueryCtxt<'_> {
}
fn depth_limit_error(self, job: QueryJobId) {
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
// FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
let query_map = match self.collect_active_jobs() {
Ok(query_map) => query_map,
Err(query_map) => query_map,
};
let (info, depth) = job.find_dep_kind_root(query_map);
let suggested_limit = match self.recursion_limit() {
Limit(0) => Limit(2),
@ -677,7 +688,7 @@ macro_rules! define_queries {
}
}
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) -> Option<()> {
let make_query = |tcx, key| {
let kind = rustc_middle::dep_graph::dep_kinds::$name;
let name = stringify!($name);
@ -697,6 +708,7 @@ macro_rules! define_queries {
stringify!($name)
);
}
res
}
pub(crate) fn alloc_self_profile_query_strings<'tcx>(
@ -756,7 +768,7 @@ macro_rules! define_queries {
// These arrays are used for iteration and can't be indexed by `DepKind`.
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap) -> Option<()>] =
&[$(query_impl::$name::try_collect_active_jobs),*];
const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[

View File

@ -588,7 +588,12 @@ pub fn print_query_stack<Qcx: QueryContext>(
// state if it was responsible for triggering the panic.
let mut count_printed = 0;
let mut count_total = 0;
let query_map = qcx.collect_active_jobs();
// Make use of a partial query map if we fail to take locks collecting active queries.
let query_map = match qcx.collect_active_jobs() {
Ok(query_map) => query_map,
Err(query_map) => query_map,
};
if let Some(ref mut file) = file {
let _ = writeln!(file, "\n\nquery stack during panic:");

View File

@ -86,7 +86,7 @@ pub trait QueryContext: HasDepContext {
/// Get the query information from the TLS context.
fn current_query_job(self) -> Option<QueryJobId>;
fn collect_active_jobs(self) -> QueryMap;
fn collect_active_jobs(self) -> Result<QueryMap, QueryMap>;
/// Load a side effect associated to the node in the previous session.
fn load_side_effect(

View File

@ -260,8 +260,11 @@ where
Q: QueryConfig<Qcx>,
Qcx: QueryContext,
{
let error =
try_execute.find_cycle_in_stack(qcx.collect_active_jobs(), &qcx.current_query_job(), span);
// Ensure there was no errors collecting all active jobs.
// We need the complete map to ensure we find a cycle to break.
let query_map = qcx.collect_active_jobs().expect("failed to collect active queries");
let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span);
(mk_cycle(query, qcx, error), None)
}

View File

@ -131,7 +131,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
return Some(self.new_module(
parent,
ModuleKind::Def(def_kind, def_id, self.tcx.item_name(def_id)),
ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
expn_id,
self.def_span(def_id),
// FIXME: Account for `#[no_implicit_prelude]` attributes.
@ -594,7 +594,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// HACK(eddyb) unclear how good this is, but keeping `$crate`
// in `source` breaks `tests/ui/imports/import-crate-var.rs`,
// while the current crate doesn't have a valid `crate_name`.
if crate_name != kw::Empty {
if let Some(crate_name) = crate_name {
// `crate_name` should not be interpreted as relative.
module_path.push(Segment::from_ident_and_id(
Ident { name: kw::PathRoot, span: source.ident.span },
@ -603,7 +603,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
source.ident.name = crate_name;
}
if rename.is_none() {
ident.name = crate_name;
ident.name = sym::dummy;
}
self.r.dcx().emit_err(errors::CrateImported { span: item.span });
@ -775,7 +775,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ItemKind::Mod(.., ref mod_kind) => {
let module = self.r.new_module(
Some(parent),
ModuleKind::Def(def_kind, def_id, ident.name),
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
expansion.to_expn_id(),
item.span,
parent.no_implicit_prelude
@ -811,7 +811,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ItemKind::Enum(_, _) | ItemKind::Trait(..) => {
let module = self.r.new_module(
Some(parent),
ModuleKind::Def(def_kind, def_id, ident.name),
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
expansion.to_expn_id(),
item.span,
parent.no_implicit_prelude,
@ -884,10 +884,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}
// These items do not add names to modules.
ItemKind::Impl(box Impl { of_trait: Some(..), .. }) => {
self.r.trait_impl_items.insert(local_def_id);
}
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
ItemKind::Impl(box Impl { of_trait: Some(..), .. })
| ItemKind::Impl { .. }
| ItemKind::ForeignMod(..)
| ItemKind::GlobalAsm(..) => {}
ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
unreachable!()
@ -1377,7 +1377,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
AssocCtxt::Trait => {
self.visit_invoc_in_module(item.id);
}
AssocCtxt::Impl => {
AssocCtxt::Impl { .. } => {
let invoc_id = item.id.placeholder_to_expn_id();
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
self.r
@ -1397,9 +1397,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
if !(ctxt == AssocCtxt::Impl
&& matches!(item.vis.kind, ast::VisibilityKind::Inherited)
&& self.r.trait_impl_items.contains(&self.r.tcx.local_parent(local_def_id)))
if !(matches!(ctxt, AssocCtxt::Impl { of_trait: true })
&& matches!(item.vis.kind, ast::VisibilityKind::Inherited))
{
// Trait impl item visibility is inherited from its trait when not specified
// explicitly. In that case we cannot determine it here in early resolve,

View File

@ -337,7 +337,8 @@ fn calc_unused_spans(
}
}
contains_self |= use_tree.prefix == kw::SelfLower
&& matches!(use_tree.kind, ast::UseTreeKind::Simple(None));
&& matches!(use_tree.kind, ast::UseTreeKind::Simple(_))
&& !unused_import.unused.contains(&use_tree_id);
previous_unused = remove.is_some();
}
if unused_spans.is_empty() {

View File

@ -2438,7 +2438,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else {
return None;
};
let module_name = crate_module.kind.name().unwrap();
let module_name = crate_module.kind.name().unwrap_or(kw::Empty);
let import_snippet = match import.kind {
ImportKind::Single { source, target, .. } if source != target => {
format!("{source} as {target}")

View File

@ -3375,7 +3375,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|i, s, c| MethodNotMemberOfTrait(i, s, c),
);
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
},
);
@ -3409,7 +3409,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|i, s, c| TypeNotMemberOfTrait(i, s, c),
);
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
});
},
);

View File

@ -503,18 +503,18 @@ enum ModuleKind {
///
/// * A normal module either `mod from_file;` or `mod from_block { }`
/// or the crate root (which is conceptually a top-level module).
/// Note that the crate root's [name][Self::name] will be [`kw::Empty`].
/// The crate root will have `None` for the symbol.
/// * A trait or an enum (it implicitly contains associated types, methods and variant
/// constructors).
Def(DefKind, DefId, Symbol),
Def(DefKind, DefId, Option<Symbol>),
}
impl ModuleKind {
/// Get name of the module.
fn name(&self) -> Option<Symbol> {
match self {
match *self {
ModuleKind::Block => None,
ModuleKind::Def(.., name) => Some(*name),
ModuleKind::Def(.., name) => name,
}
}
}
@ -1191,10 +1191,6 @@ pub struct Resolver<'ra, 'tcx> {
/// and how the `impl Trait` fragments were introduced.
invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
/// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
/// FIXME: Replace with a more general AST map (together with some other fields).
trait_impl_items: FxHashSet<LocalDefId>,
legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
/// Amount of lifetime parameters for each item in the crate.
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
@ -1402,7 +1398,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut module_self_bindings = FxHashMap::default();
let graph_root = arenas.new_module(
None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
ModuleKind::Def(DefKind::Mod, root_def_id, None),
ExpnId::root(),
crate_span,
attr::contains_name(attrs, sym::no_implicit_prelude),
@ -1411,7 +1407,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);
let empty_module = arenas.new_module(
None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
ModuleKind::Def(DefKind::Mod, root_def_id, None),
ExpnId::root(),
DUMMY_SP,
true,
@ -1558,7 +1554,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
def_id_to_node_id,
placeholder_field_indices: Default::default(),
invocation_parents,
trait_impl_items: Default::default(),
legacy_const_generic_args: Default::default(),
item_generics_num_lifetimes: Default::default(),
main_def: Default::default(),
@ -2286,7 +2281,8 @@ fn module_to_string(mut module: Module<'_>) -> Option<String> {
loop {
if let ModuleKind::Def(.., name) = module.kind {
if let Some(parent) = module.parent {
names.push(name);
// `unwrap` is safe: the presence of a parent means it's not the crate root.
names.push(name.unwrap());
module = parent
} else {
break;

View File

@ -168,7 +168,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
hygiene::update_dollar_crate_names(|ctxt| {
let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
match self.resolve_crate_root(ident).kind {
ModuleKind::Def(.., name) if name != kw::Empty => name,
ModuleKind::Def(.., name) if let Some(name) = name => name,
_ => kw::Crate,
}
});
@ -264,7 +264,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
}
InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang),
InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
InvocationKind::GlobDelegation { ref item } => {
InvocationKind::GlobDelegation { ref item, .. } => {
let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
deleg_impl = Some(self.invocation_parent(invoc_id));
// It is sufficient to consider glob delegation a bang macro for now.
@ -1067,11 +1067,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);
if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
let location = match parent_scope.module.kind {
ModuleKind::Def(_, _, name) if name == kw::Empty => {
"the crate root".to_string()
}
ModuleKind::Def(kind, def_id, name) => {
format!("{} `{name}`", kind.descr(def_id))
if let Some(name) = name {
format!("{} `{name}`", kind.descr(def_id))
} else {
"the crate root".to_string()
}
}
ModuleKind::Block => "this scope".to_string(),
};

View File

@ -1623,6 +1623,8 @@ impl Ipv6Addr {
// IANA says N/A.
|| matches!(self.segments(), [0x2002, _, _, _, _, _, _, _])
|| self.is_documentation()
// Segment Routing (SRv6) SIDs (`5f00::/16`)
|| matches!(self.segments(), [0x5f00, ..])
|| self.is_unique_local()
|| self.is_unicast_link_local())
}

View File

@ -689,6 +689,8 @@ fn ipv6_properties() {
check!("2002::", &[0x20, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
check!("5f00::", &[0x5f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
check!(

View File

@ -624,7 +624,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
// TODO(calebcartwright): Not sure the skip spans are correct
let (ai, skip_span, assoc_ctxt) = match visitor_kind {
AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl),
// There is no difference between trait and inherent assoc item formatting
AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }),
_ => unreachable!(),
};
skip_out_of_file_lines_range_visitor!(self, ai.span);

View File

@ -0,0 +1,5 @@
// Ensure we reject `#![crate_name = ""]`.
#![crate_name = ""] //~ ERROR crate name must not be empty
fn main() {}

View File

@ -0,0 +1,8 @@
error: crate name must not be empty
--> $DIR/crate-name-empty.rs:3:1
|
LL | #![crate_name = ""]
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -0,0 +1,29 @@
//@ run-rustfix
#![deny(unused_imports)]
#![allow(unreachable_code)]
use std::collections::{self as coll};
//~^ ERROR unused import: `HashMap`
//~^ ERROR unused import: `self as std_io`
use std::sync::Mutex;
//~^ ERROR unused import: `self as std_sync`
use std::sync::mpsc::Sender;
//~^ ERROR unused import: `self as std_sync_mpsc`
use std::collections::hash_map::{self as std_coll_hm};
//~^ ERROR unused import: `Keys`
use std::borrow::Cow;
//~^ ERROR unused import: `self`
fn main() {
let _ = coll::BTreeSet::<String>::default();
let _ = Mutex::new(String::new());
let _: Cow<'static, str> = "foo".into();
let _: Sender<u32> = todo!();
let _: std_coll_hm::Entry<'static, u32, u32> = todo!();
}

View File

@ -0,0 +1,30 @@
//@ run-rustfix
#![deny(unused_imports)]
#![allow(unreachable_code)]
use std::collections::{HashMap, self as coll};
//~^ ERROR unused import: `HashMap`
use std::io::{self as std_io};
//~^ ERROR unused import: `self as std_io`
use std::sync::{Mutex, self as std_sync};
//~^ ERROR unused import: `self as std_sync`
use std::sync::{mpsc::{self as std_sync_mpsc, Sender}};
//~^ ERROR unused import: `self as std_sync_mpsc`
use std::collections::{hash_map::{self as std_coll_hm, Keys}};
//~^ ERROR unused import: `Keys`
use std::borrow::{self, Cow};
//~^ ERROR unused import: `self`
fn main() {
let _ = coll::BTreeSet::<String>::default();
let _ = Mutex::new(String::new());
let _: Cow<'static, str> = "foo".into();
let _: Sender<u32> = todo!();
let _: std_coll_hm::Entry<'static, u32, u32> = todo!();
}

View File

@ -0,0 +1,44 @@
error: unused import: `HashMap`
--> $DIR/lint-unused-imports-self-single.rs:6:24
|
LL | use std::collections::{HashMap, self as coll};
| ^^^^^^^
|
note: the lint level is defined here
--> $DIR/lint-unused-imports-self-single.rs:3:9
|
LL | #![deny(unused_imports)]
| ^^^^^^^^^^^^^^
error: unused import: `self as std_io`
--> $DIR/lint-unused-imports-self-single.rs:9:15
|
LL | use std::io::{self as std_io};
| ^^^^^^^^^^^^^^
error: unused import: `self as std_sync`
--> $DIR/lint-unused-imports-self-single.rs:12:24
|
LL | use std::sync::{Mutex, self as std_sync};
| ^^^^^^^^^^^^^^^^
error: unused import: `self as std_sync_mpsc`
--> $DIR/lint-unused-imports-self-single.rs:15:24
|
LL | use std::sync::{mpsc::{self as std_sync_mpsc, Sender}};
| ^^^^^^^^^^^^^^^^^^^^^
error: unused import: `Keys`
--> $DIR/lint-unused-imports-self-single.rs:18:56
|
LL | use std::collections::{hash_map::{self as std_coll_hm, Keys}};
| ^^^^
error: unused import: `self`
--> $DIR/lint-unused-imports-self-single.rs:21:19
|
LL | use std::borrow::{self, Cow};
| ^^^^
error: aborting due to 6 previous errors

View File

@ -77,15 +77,14 @@ pub type Alias = OtherType;
pub struct PublicWithPrivateImpl;
// FIXME: This should trigger.
// See https://github.com/rust-lang/rust/issues/71043
impl OtherTrait for PublicWithPrivateImpl {}
//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
pub trait PubTraitOnPrivate {}
// FIXME: This should trigger.
// See https://github.com/rust-lang/rust/issues/71043
impl PubTraitOnPrivate for OtherType {}
//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface
//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
pub struct AllowedPrivType {
#[allow(exported_private_dependencies)]

View File

@ -70,5 +70,25 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface
LL | pub type Alias = OtherType;
| ^^^^^^^^^^^^^^
error: aborting due to 11 previous errors
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:80:1
|
LL | impl OtherTrait for PublicWithPrivateImpl {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: type `OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:85:1
|
LL | impl PubTraitOnPrivate for OtherType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: type `OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:85:1
|
LL | impl PubTraitOnPrivate for OtherType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 14 previous errors