mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
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:
commit
43f0014ef0
@ -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);
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
}),
|
||||
];
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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(_) => {
|
||||
|
@ -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,
|
||||
|
@ -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() })
|
||||
}
|
||||
|
@ -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_;
|
||||
|
@ -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>,
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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: &[
|
||||
|
@ -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:");
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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}")
|
||||
|
@ -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 })
|
||||
});
|
||||
},
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
};
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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!(
|
||||
|
@ -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);
|
||||
|
5
tests/ui/attributes/crate-name-empty.rs
Normal file
5
tests/ui/attributes/crate-name-empty.rs
Normal file
@ -0,0 +1,5 @@
|
||||
// Ensure we reject `#![crate_name = ""]`.
|
||||
|
||||
#![crate_name = ""] //~ ERROR crate name must not be empty
|
||||
|
||||
fn main() {}
|
8
tests/ui/attributes/crate-name-empty.stderr
Normal file
8
tests/ui/attributes/crate-name-empty.stderr
Normal 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
|
||||
|
29
tests/ui/lint/unused/lint-unused-imports-self-single.fixed
Normal file
29
tests/ui/lint/unused/lint-unused-imports-self-single.fixed
Normal 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!();
|
||||
}
|
30
tests/ui/lint/unused/lint-unused-imports-self-single.rs
Normal file
30
tests/ui/lint/unused/lint-unused-imports-self-single.rs
Normal 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!();
|
||||
}
|
44
tests/ui/lint/unused/lint-unused-imports-self-single.stderr
Normal file
44
tests/ui/lint/unused/lint-unused-imports-self-single.stderr
Normal 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
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user