Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2024-06-19 05:02:35 +00:00
commit 3e93254d5e
305 changed files with 5833 additions and 3641 deletions

View file

@ -4520,7 +4520,16 @@ dependencies = [
name = "rustc_next_trait_solver"
version = "0.0.0"
dependencies = [
"bitflags 2.5.0",
"derivative",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_type_ir",
"rustc_type_ir_macros",
"tracing",
]
[[package]]

View file

@ -307,6 +307,8 @@ impl TraitBoundModifiers {
pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifiers),
Outlives(Lifetime),
/// Precise capturing syntax: `impl Sized + use<'a>`
Use(ThinVec<PreciseCapturingArg>, Span),
}
impl GenericBound {
@ -314,6 +316,7 @@ impl GenericBound {
match self {
GenericBound::Trait(t, ..) => t.span,
GenericBound::Outlives(l) => l.ident.span,
GenericBound::Use(_, span) => *span,
}
}
}
@ -2162,7 +2165,7 @@ pub enum TyKind {
/// The `NodeId` exists to prevent lowering from having to
/// generate `NodeId`s on the fly, which would complicate
/// the generation of opaque `type Foo = impl Trait` items significantly.
ImplTrait(NodeId, GenericBounds, Option<P<(ThinVec<PreciseCapturingArg>, Span)>>),
ImplTrait(NodeId, GenericBounds),
/// No-op; kept solely so that we can pretty-print faithfully.
Paren(P<Ty>),
/// Unused for now.

View file

@ -523,14 +523,9 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
TyKind::TraitObject(bounds, _syntax) => {
visit_vec(bounds, |bound| vis.visit_param_bound(bound))
}
TyKind::ImplTrait(id, bounds, precise_capturing) => {
TyKind::ImplTrait(id, bounds) => {
vis.visit_id(id);
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
if let Some((precise_capturing, _span)) = precise_capturing.as_deref_mut() {
for arg in precise_capturing {
vis.visit_precise_capturing_arg(arg);
}
}
}
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
@ -923,6 +918,11 @@ fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) {
match pb {
GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis),
GenericBound::Use(args, _) => {
for arg in args {
vis.visit_precise_capturing_arg(arg);
}
}
}
}

View file

@ -184,7 +184,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
None => break None,
},
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds, _) => {
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
match bounds.last() {
Some(ast::GenericBound::Trait(bound, _)) => {
match path_return_type(&bound.trait_ref.path) {
@ -192,7 +192,9 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
None => break None,
}
}
Some(ast::GenericBound::Outlives(_)) | None => break None,
Some(ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..)) | None => {
break None;
}
}
}

View file

@ -52,6 +52,16 @@ pub enum BoundKind {
/// E.g., `trait A: B`
SuperTraits,
}
impl BoundKind {
pub fn descr(self) -> &'static str {
match self {
BoundKind::Bound => "bounds",
BoundKind::Impl => "`impl Trait`",
BoundKind::TraitObject => "`dyn` trait object bounds",
BoundKind::SuperTraits => "supertrait bounds",
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
@ -497,13 +507,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
TyKind::TraitObject(bounds, ..) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
}
TyKind::ImplTrait(_, bounds, precise_capturing) => {
TyKind::ImplTrait(_, bounds) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
if let Some((precise_capturing, _span)) = precise_capturing.as_deref() {
for arg in precise_capturing {
try_visit!(visitor.visit_precise_capturing_arg(arg));
}
}
}
TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)),
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}
@ -688,6 +693,10 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB
match bound {
GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
GenericBound::Use(args, _) => {
walk_list!(visitor, visit_precise_capturing_arg, args);
V::Result::output()
}
}
}

View file

@ -128,7 +128,7 @@ ast_lowering_never_pattern_with_guard =
a guard on a never pattern will never be run
.suggestion = remove this guard
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed on argument-position `impl Trait`
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
ast_lowering_previously_used_here = previously used here

View file

@ -50,10 +50,10 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{DiagArgFromDisplay, DiagCtxt, StashKey};
use rustc_hir as hir;
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::{self as hir};
use rustc_hir::{
ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName, TraitCandidate,
};
@ -188,7 +188,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
pub(crate) fn dcx(&self) -> &'hir DiagCtxt {
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
self.tcx.dcx()
}
}
@ -1384,6 +1384,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
None
}
// Ignore `use` syntax since that is not valid in objects.
GenericBound::Use(_, span) => {
this.dcx()
.span_delayed_bug(*span, "use<> not allowed in dyn types");
None
}
}));
let lifetime_bound =
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
@ -1391,7 +1397,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
});
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
}
TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => {
TyKind::ImplTrait(def_node_id, bounds) => {
let span = t.span;
match itctx {
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
@ -1401,12 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
fn_kind,
itctx,
precise_capturing.as_deref().map(|(args, span)| (args.as_slice(), *span)),
),
ImplTraitContext::Universal => {
if let Some(&(_, span)) = precise_capturing.as_deref() {
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span),
_ => None,
}) {
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
};
}
let span = t.span;
// HACK: pprust breaks strings with newlines when the type
@ -1517,7 +1526,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds: &GenericBounds,
fn_kind: Option<FnDeclKind>,
itctx: ImplTraitContext,
precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>,
) -> hir::TyKind<'hir> {
// Make sure we know that some funky desugaring has been going on here.
// This is a first: there is code in other places like for loop
@ -1526,59 +1534,64 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
let captured_lifetimes_to_duplicate =
if let Some((precise_capturing, _)) = precise_capturing_args {
// We'll actually validate these later on; all we need is the list of
// lifetimes to duplicate during this portion of lowering.
precise_capturing
.iter()
.filter_map(|arg| match arg {
PreciseCapturingArg::Lifetime(lt) => Some(*lt),
PreciseCapturingArg::Arg(..) => None,
})
// Add in all the lifetimes mentioned in the bounds. We will error
// them out later, but capturing them here is important to make sure
// they actually get resolved in resolve_bound_vars.
.chain(lifetime_collector::lifetimes_in_bounds(self.resolver, bounds))
.collect()
} else {
match origin {
hir::OpaqueTyOrigin::TyAlias { .. } => {
// type alias impl trait and associated type position impl trait were
// decided to capture all in-scope lifetimes, which we collect for
// all opaques during resolution.
let captured_lifetimes_to_duplicate = if let Some(args) =
// We only look for one `use<...>` syntax since we syntactially reject more than one.
bounds.iter().find_map(
|bound| match bound {
ast::GenericBound::Use(a, _) => Some(a),
_ => None,
},
) {
// We'll actually validate these later on; all we need is the list of
// lifetimes to duplicate during this portion of lowering.
args.iter()
.filter_map(|arg| match arg {
PreciseCapturingArg::Lifetime(lt) => Some(*lt),
PreciseCapturingArg::Arg(..) => None,
})
// Add in all the lifetimes mentioned in the bounds. We will error
// them out later, but capturing them here is important to make sure
// they actually get resolved in resolve_bound_vars.
.chain(lifetime_collector::lifetimes_in_bounds(self.resolver, bounds))
.collect()
} else {
match origin {
hir::OpaqueTyOrigin::TyAlias { .. } => {
// type alias impl trait and associated type position impl trait were
// decided to capture all in-scope lifetimes, which we collect for
// all opaques during resolution.
self.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
}
hir::OpaqueTyOrigin::FnReturn(..) => {
if matches!(
fn_kind.expect("expected RPITs to be lowered with a FnKind"),
FnDeclKind::Impl | FnDeclKind::Trait
) || self.tcx.features().lifetime_capture_rules_2024
|| span.at_least_rust_2024()
{
// return-position impl trait in trait was decided to capture all
// in-scope lifetimes, which we collect for all opaques during resolution.
self.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
}
hir::OpaqueTyOrigin::FnReturn(..) => {
if matches!(
fn_kind.expect("expected RPITs to be lowered with a FnKind"),
FnDeclKind::Impl | FnDeclKind::Trait
) || self.tcx.features().lifetime_capture_rules_2024
|| span.at_least_rust_2024()
{
// return-position impl trait in trait was decided to capture all
// in-scope lifetimes, which we collect for all opaques during resolution.
self.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
} else {
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
// example, we only need to duplicate lifetimes that appear in the
// bounds, since those are the only ones that are captured by the opaque.
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
}
}
hir::OpaqueTyOrigin::AsyncFn(..) => {
unreachable!("should be using `lower_async_fn_ret_ty`")
} else {
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
// example, we only need to duplicate lifetimes that appear in the
// bounds, since those are the only ones that are captured by the opaque.
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
}
}
};
hir::OpaqueTyOrigin::AsyncFn(..) => {
unreachable!("should be using `lower_async_fn_ret_ty`")
}
}
};
debug!(?captured_lifetimes_to_duplicate);
self.lower_opaque_inner(
@ -1588,7 +1601,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
captured_lifetimes_to_duplicate,
span,
opaque_ty_span,
precise_capturing_args,
|this| this.lower_param_bounds(bounds, itctx),
)
}
@ -1601,7 +1613,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>,
span: Span,
opaque_ty_span: Span,
precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>,
lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
) -> hir::TyKind<'hir> {
let opaque_ty_def_id = self.create_def(
@ -1688,18 +1699,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Install the remapping from old to new (if any). This makes sure that
// any lifetimes that would have resolved to the def-id of captured
// lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
let (bounds, precise_capturing_args) =
this.with_remapping(captured_to_synthesized_mapping, |this| {
(
lower_item_bounds(this),
precise_capturing_args.map(|(precise_capturing, span)| {
(
this.lower_precise_capturing_args(precise_capturing),
this.lower_span(span),
)
}),
)
});
let bounds = this
.with_remapping(captured_to_synthesized_mapping, |this| lower_item_bounds(this));
let generic_params =
this.arena.alloc_from_iter(synthesized_lifetime_definitions.iter().map(
@ -1744,7 +1745,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
origin,
lifetime_mapping,
in_trait,
precise_capturing_args,
};
// Generate an `type Foo = impl Trait;` declaration.
@ -1955,7 +1955,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
captured_lifetimes,
span,
opaque_ty_span,
None,
|this| {
let bound = this.lower_coroutine_fn_output_type_to_bound(
output,
@ -2038,6 +2037,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericBound::Outlives(lifetime) => {
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
}
GenericBound::Use(args, span) => hir::GenericBound::Use(
self.lower_precise_capturing_args(args),
self.lower_span(*span),
),
}
}

View file

@ -215,6 +215,11 @@ ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer t
ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
.label = pattern not allowed in foreign function
ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax
.label = second `use<...>` here
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
ast_passes_show_span = {$msg}
ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library

View file

@ -12,6 +12,7 @@ use rustc_ast::visit::{walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::DiagCtxtHandle;
use rustc_feature::Features;
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
@ -193,8 +194,24 @@ impl<'a> AstValidator<'a> {
// Mirrors `visit::walk_ty`, but tracks relevant state.
fn walk_ty(&mut self, t: &'a Ty) {
match &t.kind {
TyKind::ImplTrait(..) => {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
TyKind::ImplTrait(_, bounds) => {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t));
// FIXME(precise_capturing): If we were to allow `use` in other positions
// (e.g. GATs), then we must validate those as well. However, we don't have
// a good way of doing this with the current `Visitor` structure.
let mut use_bounds = bounds
.iter()
.filter_map(|bound| match bound {
GenericBound::Use(_, span) => Some(span),
_ => None,
})
.copied();
if let Some(bound1) = use_bounds.next()
&& let Some(bound2) = use_bounds.next()
{
self.dcx().emit_err(errors::DuplicatePreciseCapturing { bound1, bound2 });
}
}
TyKind::TraitObject(..) => self
.with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
@ -253,7 +270,7 @@ impl<'a> AstValidator<'a> {
}
}
fn dcx(&self) -> &rustc_errors::DiagCtxt {
fn dcx(&self) -> DiagCtxtHandle<'a> {
self.session.dcx()
}
@ -751,7 +768,7 @@ impl<'a> AstValidator<'a> {
}
}
}
TyKind::ImplTrait(_, bounds, _) => {
TyKind::ImplTrait(_, bounds) => {
if self.is_impl_trait_banned {
self.dcx().emit_err(errors::ImplTraitPath { span: ty.span });
}
@ -793,11 +810,7 @@ impl<'a> AstValidator<'a> {
/// Checks that generic parameters are in the correct order,
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
fn validate_generic_param_order(
dcx: &rustc_errors::DiagCtxt,
generics: &[GenericParam],
span: Span,
) {
fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericParam], span: Span) {
let mut max_param: Option<ParamKindOrd> = None;
let mut out_of_order = FxIndexMap::default();
let mut param_idents = Vec::with_capacity(generics.len());
@ -1304,6 +1317,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
GenericBound::Outlives(_) => {}
GenericBound::Use(..) => {}
}
}
}
@ -1322,95 +1336,110 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
if let GenericBound::Trait(poly, modifiers) = bound {
match (ctxt, modifiers.constness, modifiers.polarity) {
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
self.dcx().emit_err(errors::OptionalTraitSupertrait {
span: poly.span,
path_str: pprust::path_to_string(&poly.trait_ref.path),
});
match bound {
GenericBound::Trait(trait_ref, modifiers) => {
match (ctxt, modifiers.constness, modifiers.polarity) {
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
self.dcx().emit_err(errors::OptionalTraitSupertrait {
span: trait_ref.span,
path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
});
}
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
self.dcx().emit_err(errors::OptionalTraitObject { span: trait_ref.span });
}
(
BoundKind::TraitObject,
BoundConstness::Always(_),
BoundPolarity::Positive,
) => {
self.dcx().emit_err(errors::ConstBoundTraitObject { span: trait_ref.span });
}
(_, BoundConstness::Maybe(span), BoundPolarity::Positive)
if let Some(reason) = &self.disallow_tilde_const =>
{
let reason = match reason {
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
errors::TildeConstReason::Closure
}
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
errors::TildeConstReason::Function { ident: ident.span }
}
&DisallowTildeConstContext::Trait(span) => {
errors::TildeConstReason::Trait { span }
}
&DisallowTildeConstContext::TraitImpl(span) => {
errors::TildeConstReason::TraitImpl { span }
}
&DisallowTildeConstContext::Impl(span) => {
// FIXME(effects): Consider providing a help message or even a structured
// suggestion for moving such bounds to the assoc const fns if available.
errors::TildeConstReason::Impl { span }
}
&DisallowTildeConstContext::TraitAssocTy(span) => {
errors::TildeConstReason::TraitAssocTy { span }
}
&DisallowTildeConstContext::TraitImplAssocTy(span) => {
errors::TildeConstReason::TraitImplAssocTy { span }
}
&DisallowTildeConstContext::InherentAssocTy(span) => {
errors::TildeConstReason::InherentAssocTy { span }
}
DisallowTildeConstContext::TraitObject => {
errors::TildeConstReason::TraitObject
}
DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
};
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
}
(
_,
BoundConstness::Always(_) | BoundConstness::Maybe(_),
BoundPolarity::Negative(_) | BoundPolarity::Maybe(_),
) => {
self.dcx().emit_err(errors::IncompatibleTraitBoundModifiers {
span: bound.span(),
left: modifiers.constness.as_str(),
right: modifiers.polarity.as_str(),
});
}
_ => {}
}
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
self.dcx().emit_err(errors::OptionalTraitObject { span: poly.span });
}
(BoundKind::TraitObject, BoundConstness::Always(_), BoundPolarity::Positive) => {
self.dcx().emit_err(errors::ConstBoundTraitObject { span: poly.span });
}
(_, BoundConstness::Maybe(span), BoundPolarity::Positive)
if let Some(reason) = &self.disallow_tilde_const =>
{
let reason = match reason {
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
errors::TildeConstReason::Closure
}
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
errors::TildeConstReason::Function { ident: ident.span }
}
&DisallowTildeConstContext::Trait(span) => {
errors::TildeConstReason::Trait { span }
}
&DisallowTildeConstContext::TraitImpl(span) => {
errors::TildeConstReason::TraitImpl { span }
}
&DisallowTildeConstContext::Impl(span) => {
// FIXME(effects): Consider providing a help message or even a structured
// suggestion for moving such bounds to the assoc const fns if available.
errors::TildeConstReason::Impl { span }
}
&DisallowTildeConstContext::TraitAssocTy(span) => {
errors::TildeConstReason::TraitAssocTy { span }
}
&DisallowTildeConstContext::TraitImplAssocTy(span) => {
errors::TildeConstReason::TraitImplAssocTy { span }
}
&DisallowTildeConstContext::InherentAssocTy(span) => {
errors::TildeConstReason::InherentAssocTy { span }
}
DisallowTildeConstContext::TraitObject => {
errors::TildeConstReason::TraitObject
}
DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
};
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
}
(
_,
BoundConstness::Always(_) | BoundConstness::Maybe(_),
BoundPolarity::Negative(_) | BoundPolarity::Maybe(_),
) => {
self.dcx().emit_err(errors::IncompatibleTraitBoundModifiers {
span: bound.span(),
left: modifiers.constness.as_str(),
right: modifiers.polarity.as_str(),
});
}
_ => {}
}
}
// Negative trait bounds are not allowed to have associated constraints
if let GenericBound::Trait(trait_ref, modifiers) = bound
&& let BoundPolarity::Negative(_) = modifiers.polarity
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
{
match segment.args.as_deref() {
Some(ast::GenericArgs::AngleBracketed(args)) => {
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
self.dcx().emit_err(errors::ConstraintOnNegativeBound {
span: constraint.span,
// Negative trait bounds are not allowed to have associated constraints
if let BoundPolarity::Negative(_) = modifiers.polarity
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
{
match segment.args.as_deref() {
Some(ast::GenericArgs::AngleBracketed(args)) => {
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
self.dcx().emit_err(errors::ConstraintOnNegativeBound {
span: constraint.span,
});
}
}
}
// The lowered form of parenthesized generic args contains an associated type binding.
Some(ast::GenericArgs::Parenthesized(args)) => {
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
span: args.span,
});
}
None => {}
}
}
// The lowered form of parenthesized generic args contains an associated type binding.
Some(ast::GenericArgs::Parenthesized(args)) => {
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
span: args.span,
}
GenericBound::Outlives(_) => {}
GenericBound::Use(_, span) => match ctxt {
BoundKind::Impl => {}
BoundKind::Bound | BoundKind::TraitObject | BoundKind::SuperTraits => {
self.dcx().emit_err(errors::PreciseCapturingNotAllowedHere {
loc: ctxt.descr(),
span: *span,
});
}
None => {}
}
},
}
visit::walk_param_bound(self, bound)

View file

@ -844,3 +844,20 @@ pub struct MatchArmWithNoBody {
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
pub suggestion: Span,
}
#[derive(Diagnostic)]
#[diag(ast_passes_precise_capturing_not_allowed_here)]
pub struct PreciseCapturingNotAllowedHere {
#[primary_span]
pub span: Span,
pub loc: &'static str,
}
#[derive(Diagnostic)]
#[diag(ast_passes_precise_capturing_duplicated)]
pub struct DuplicatePreciseCapturing {
#[primary_span]
pub bound1: Span,
#[label]
pub bound2: Span,
}

View file

@ -8,6 +8,7 @@ use std::str::FromStr;
use rustc_ast as ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
use rustc_errors::DiagCtxtHandle;
use crate::errors;
@ -31,7 +32,7 @@ impl FromStr for Mode {
}
struct ShowSpanVisitor<'a> {
dcx: &'a rustc_errors::DiagCtxt,
dcx: DiagCtxtHandle<'a>,
mode: Mode,
}
@ -58,7 +59,7 @@ impl<'a> Visitor<'a> for ShowSpanVisitor<'a> {
}
}
pub fn run(dcx: &rustc_errors::DiagCtxt, mode: &str, krate: &ast::Crate) {
pub fn run(dcx: DiagCtxtHandle<'_>, mode: &str, krate: &ast::Crate) {
let Ok(mode) = mode.parse() else {
return;
};

View file

@ -1187,17 +1187,8 @@ impl<'a> State<'a> {
}
self.print_type_bounds(bounds);
}
ast::TyKind::ImplTrait(_, bounds, precise_capturing_args) => {
ast::TyKind::ImplTrait(_, bounds) => {
self.word_nbsp("impl");
if let Some((precise_capturing_args, ..)) = precise_capturing_args.as_deref() {
self.word("use");
self.word("<");
self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg {
ast::PreciseCapturingArg::Arg(p, _) => s.print_path(p, false, 0),
ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt),
});
self.word(">")
}
self.print_type_bounds(bounds);
}
ast::TyKind::Array(ty, length) => {
@ -1800,6 +1791,15 @@ impl<'a> State<'a> {
self.print_poly_trait_ref(tref);
}
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
GenericBound::Use(args, _) => {
self.word("use");
self.word("<");
self.commasep(Inconsistent, args, |s, arg| match arg {
ast::PreciseCapturingArg::Arg(p, _) => s.print_path(p, false, 0),
ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt),
});
self.word(">")
}
}
}
}

View file

@ -596,7 +596,7 @@ pub fn eval_condition(
features: Option<&Features>,
eval: &mut impl FnMut(Condition) -> bool,
) -> bool {
let dcx = &sess.psess.dcx;
let dcx = sess.dcx();
match &cfg.kind {
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
try_gate_cfg(sym::version, cfg.span, sess, features);

View file

@ -1,7 +1,8 @@
use std::num::IntErrorKind;
use rustc_ast as ast;
use rustc_errors::{codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::DiagCtxtHandle;
use rustc_errors::{codes::*, Applicability, Diag, Diagnostic, EmissionGuarantee, Level};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
@ -49,7 +50,7 @@ pub(crate) struct UnknownMetaItem<'a> {
// Manual implementation to be able to format `expected` items correctly.
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> {
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
Diag::new(dcx, level, fluent::attr_unknown_meta_item)
.with_span(self.span)
@ -202,7 +203,7 @@ pub(crate) struct UnsupportedLiteral {
}
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let mut diag = Diag::new(
dcx,
level,

View file

@ -1,13 +1,13 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxt};
use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxtHandle};
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub fn dcx(&self) -> &'tcx DiagCtxt {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.infcx.dcx()
}

View file

@ -228,7 +228,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
seen_spans.insert(move_span);
}
use_spans.var_path_only_subdiag(self.dcx(), &mut err, desired_action);
use_spans.var_path_only_subdiag(&mut err, desired_action);
if !is_loop_move {
err.span_label(
@ -303,24 +303,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if needs_note {
if let Some(local) = place.as_local() {
let span = self.body.local_decls[local].source_info.span;
err.subdiagnostic(
self.dcx(),
crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move,
ty,
place: &note_msg,
span,
},
);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move,
ty,
place: &note_msg,
span,
});
} else {
err.subdiagnostic(
self.dcx(),
crate::session_diagnostics::TypeNoCopy::Note {
is_partial_move,
ty,
place: &note_msg,
},
);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note {
is_partial_move,
ty,
place: &note_msg,
});
};
}
@ -597,7 +591,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
E0381,
"{used} binding {desc}{isnt_initialized}"
);
use_spans.var_path_only_subdiag(self.dcx(), &mut err, desired_action);
use_spans.var_path_only_subdiag(&mut err, desired_action);
if let InitializationRequiringAction::PartialAssignment
| InitializationRequiringAction::Assignment = desired_action
@ -996,7 +990,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self,
err: &mut Diag<'_>,
ty: Ty<'tcx>,
expr: &'cx hir::Expr<'cx>,
expr: &hir::Expr<'_>,
) {
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
let hir::ExprKind::Struct(struct_qpath, fields, Some(base)) = expr.kind else { return };
@ -1084,8 +1078,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self,
err: &mut Diag<'_>,
ty: Ty<'tcx>,
mut expr: &'cx hir::Expr<'cx>,
mut other_expr: Option<&'cx hir::Expr<'cx>>,
mut expr: &'tcx hir::Expr<'tcx>,
mut other_expr: Option<&'tcx hir::Expr<'tcx>>,
use_spans: Option<UseSpans<'tcx>>,
) {
if let hir::ExprKind::Struct(_, _, Some(_)) = expr.kind {
@ -1410,13 +1404,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&value_msg,
);
borrow_spans.var_path_only_subdiag(
self.dcx(),
&mut err,
crate::InitializationRequiringAction::Borrow,
);
borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
move_spans.var_subdiag(self.dcx(), &mut err, None, |kind, var_span| {
move_spans.var_subdiag(&mut err, None, |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => MoveUseInCoroutine { var_span },
@ -1468,7 +1458,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_span,
&self.describe_any_place(borrow.borrowed_place.as_ref()),
);
borrow_spans.var_subdiag(self.dcx(), &mut err, Some(borrow.kind), |kind, var_span| {
borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
let place = &borrow.borrowed_place;
let desc_place = self.describe_any_place(place.as_ref());
@ -1633,7 +1623,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
"mutably borrow",
);
borrow_spans.var_subdiag(
self.dcx(),
&mut err,
Some(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }),
|kind, var_span| {
@ -1730,64 +1719,45 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
if issued_spans == borrow_spans {
borrow_spans.var_subdiag(
self.dcx(),
&mut err,
Some(gen_borrow_kind),
|kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
place: desc_place,
var_span,
is_single_var: false,
},
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
BorrowUsePlaceClosure {
place: desc_place,
var_span,
is_single_var: false,
}
}
borrow_spans.var_subdiag(&mut err, Some(gen_borrow_kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
place: desc_place,
var_span,
is_single_var: false,
},
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false }
}
},
);
}
});
} else {
issued_spans.var_subdiag(
self.dcx(),
&mut err,
Some(issued_borrow.kind),
|kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
let borrow_place = &issued_borrow.borrowed_place;
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
match kind {
hir::ClosureKind::Coroutine(_) => {
FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
}
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span }
}
issued_spans.var_subdiag(&mut err, Some(issued_borrow.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
let borrow_place = &issued_borrow.borrowed_place;
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
match kind {
hir::ClosureKind::Coroutine(_) => {
FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
}
},
);
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span }
}
}
});
borrow_spans.var_subdiag(
self.dcx(),
&mut err,
Some(gen_borrow_kind),
|kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => {
SecondBorrowUsePlaceCoroutine { place: desc_place, var_span }
}
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
SecondBorrowUsePlaceClosure { place: desc_place, var_span }
}
borrow_spans.var_subdiag(&mut err, Some(gen_borrow_kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => {
SecondBorrowUsePlaceCoroutine { place: desc_place, var_span }
}
},
);
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
SecondBorrowUsePlaceClosure { place: desc_place, var_span }
}
}
});
}
if union_type_name != "" {
@ -2016,7 +1986,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}
pub(crate) fn find_expr(&self, span: Span) -> Option<&hir::Expr<'_>> {
pub(crate) fn find_expr(&self, span: Span) -> Option<&'tcx hir::Expr<'tcx>> {
let tcx = self.infcx.tcx;
let body_id = tcx.hir_node(self.mir_hir_id()).body_id()?;
let mut expr_finder = FindExprBySpan::new(span, tcx);
@ -2961,7 +2931,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.span_label(borrow_span, "borrowed value does not live long enough");
err.span_label(drop_span, format!("`{name}` dropped here while still borrowed"));
borrow_spans.args_subdiag(self.dcx(), &mut err, |args_span| {
borrow_spans.args_subdiag(&mut err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::Capture {
is_within: borrow_spans.for_coroutine(),
args_span,
@ -3219,7 +3189,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
None,
);
borrow_spans.args_subdiag(self.dcx(), &mut err, |args_span| {
borrow_spans.args_subdiag(&mut err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::Capture {
is_within: borrow_spans.for_coroutine(),
args_span,
@ -3680,7 +3650,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
"assign",
);
loan_spans.var_subdiag(self.dcx(), &mut err, Some(loan.kind), |kind, var_span| {
loan_spans.var_subdiag(&mut err, Some(loan.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
@ -3698,7 +3668,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place);
loan_spans.var_subdiag(self.dcx(), &mut err, Some(loan.kind), |kind, var_span| {
loan_spans.var_subdiag(&mut err, Some(loan.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },

View file

@ -4,8 +4,8 @@ use crate::session_diagnostics::{
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
};
use rustc_errors::MultiSpan;
use rustc_errors::{Applicability, Diag};
use rustc_errors::{DiagCtxt, MultiSpan};
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::CoroutineKind;
use rustc_hir::{self as hir, LangItem};
@ -130,16 +130,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() {
let did = did.expect_local();
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
diag.subdiagnostic(
self.dcx(),
OnClosureNote::InvokedTwice {
place_name: &ty::place_to_string_for_capture(
self.infcx.tcx,
hir_place,
),
span: *span,
},
);
diag.subdiagnostic(OnClosureNote::InvokedTwice {
place_name: &ty::place_to_string_for_capture(
self.infcx.tcx,
hir_place,
),
span: *span,
});
return true;
}
}
@ -152,13 +149,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() {
let did = did.expect_local();
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
diag.subdiagnostic(
self.dcx(),
OnClosureNote::MovedTwice {
place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
span: *span,
},
);
diag.subdiagnostic(OnClosureNote::MovedTwice {
place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
span: *span,
});
return true;
}
}
@ -591,14 +585,9 @@ impl UseSpans<'_> {
/// Add a span label to the arguments of the closure, if it exists.
#[allow(rustc::diagnostic_outside_of_impl)]
pub(super) fn args_subdiag(
self,
dcx: &DiagCtxt,
err: &mut Diag<'_>,
f: impl FnOnce(Span) -> CaptureArgLabel,
) {
pub(super) fn args_subdiag(self, err: &mut Diag<'_>, f: impl FnOnce(Span) -> CaptureArgLabel) {
if let UseSpans::ClosureUse { args_span, .. } = self {
err.subdiagnostic(dcx, f(args_span));
err.subdiagnostic(f(args_span));
}
}
@ -607,7 +596,6 @@ impl UseSpans<'_> {
#[allow(rustc::diagnostic_outside_of_impl)]
pub(super) fn var_path_only_subdiag(
self,
dcx: &DiagCtxt,
err: &mut Diag<'_>,
action: crate::InitializationRequiringAction,
) {
@ -616,26 +604,20 @@ impl UseSpans<'_> {
if let UseSpans::ClosureUse { closure_kind, path_span, .. } = self {
match closure_kind {
hir::ClosureKind::Coroutine(_) => {
err.subdiagnostic(
dcx,
match action {
Borrow => BorrowInCoroutine { path_span },
MatchOn | Use => UseInCoroutine { path_span },
Assignment => AssignInCoroutine { path_span },
PartialAssignment => AssignPartInCoroutine { path_span },
},
);
err.subdiagnostic(match action {
Borrow => BorrowInCoroutine { path_span },
MatchOn | Use => UseInCoroutine { path_span },
Assignment => AssignInCoroutine { path_span },
PartialAssignment => AssignPartInCoroutine { path_span },
});
}
hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => {
err.subdiagnostic(
dcx,
match action {
Borrow => BorrowInClosure { path_span },
MatchOn | Use => UseInClosure { path_span },
Assignment => AssignInClosure { path_span },
PartialAssignment => AssignPartInClosure { path_span },
},
);
err.subdiagnostic(match action {
Borrow => BorrowInClosure { path_span },
MatchOn | Use => UseInClosure { path_span },
Assignment => AssignInClosure { path_span },
PartialAssignment => AssignPartInClosure { path_span },
});
}
}
}
@ -645,32 +627,28 @@ impl UseSpans<'_> {
#[allow(rustc::diagnostic_outside_of_impl)]
pub(super) fn var_subdiag(
self,
dcx: &DiagCtxt,
err: &mut Diag<'_>,
kind: Option<rustc_middle::mir::BorrowKind>,
f: impl FnOnce(hir::ClosureKind, Span) -> CaptureVarCause,
) {
if let UseSpans::ClosureUse { closure_kind, capture_kind_span, path_span, .. } = self {
if capture_kind_span != path_span {
err.subdiagnostic(
dcx,
match kind {
Some(kd) => match kd {
rustc_middle::mir::BorrowKind::Shared
| rustc_middle::mir::BorrowKind::Fake(_) => {
CaptureVarKind::Immut { kind_span: capture_kind_span }
}
err.subdiagnostic(match kind {
Some(kd) => match kd {
rustc_middle::mir::BorrowKind::Shared
| rustc_middle::mir::BorrowKind::Fake(_) => {
CaptureVarKind::Immut { kind_span: capture_kind_span }
}
rustc_middle::mir::BorrowKind::Mut { .. } => {
CaptureVarKind::Mut { kind_span: capture_kind_span }
}
},
None => CaptureVarKind::Move { kind_span: capture_kind_span },
rustc_middle::mir::BorrowKind::Mut { .. } => {
CaptureVarKind::Mut { kind_span: capture_kind_span }
}
},
);
None => CaptureVarKind::Move { kind_span: capture_kind_span },
});
};
let diag = f(closure_kind, path_span);
err.subdiagnostic(dcx, diag);
err.subdiagnostic(diag);
}
}
@ -1042,15 +1020,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
CallKind::FnCall { fn_trait_id, self_ty }
if self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce) =>
{
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::Call {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::Call {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
});
// Check if the move occurs on a value because of a call on a closure that comes
// from a type parameter `F: FnOnce()`. If so, we provide a targeted `note`:
// ```
@ -1119,27 +1094,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
err.span_note(span, fluent::borrowck_moved_a_fn_once_in_call_call);
} else {
err.subdiagnostic(
self.dcx(),
CaptureReasonNote::FnOnceMoveInCall { var_span },
);
err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span });
}
}
CallKind::Operator { self_arg, trait_id, .. } => {
let self_arg = self_arg.unwrap();
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::OperatorUse {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::OperatorUse {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
});
if self.fn_self_span_reported.insert(fn_span) {
let lang = self.infcx.tcx.lang_items();
err.subdiagnostic(
self.dcx(),
if [lang.not_trait(), lang.deref_trait(), lang.neg_trait()]
.contains(&Some(trait_id))
{
@ -1164,14 +1132,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
let func = tcx.def_path_str(method_did);
err.subdiagnostic(
self.dcx(),
CaptureReasonNote::FuncTakeSelf {
func,
place_name: place_name.clone(),
span: self_arg.span,
},
);
err.subdiagnostic(CaptureReasonNote::FuncTakeSelf {
func,
place_name: place_name.clone(),
span: self_arg.span,
});
}
let parent_did = tcx.parent(method_did);
let parent_self_ty =
@ -1185,10 +1150,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
});
if is_option_or_result && maybe_reinitialized_locations_is_empty {
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::BorrowContent { var_span },
);
err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span });
}
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
let ty = moved_place.ty(self.body, tcx).ty;
@ -1202,24 +1164,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => false,
};
if suggest {
err.subdiagnostic(
self.dcx(),
CaptureReasonSuggest::IterateSlice {
ty,
span: move_span.shrink_to_lo(),
},
);
err.subdiagnostic(CaptureReasonSuggest::IterateSlice {
ty,
span: move_span.shrink_to_lo(),
});
}
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::ImplicitCall {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::ImplicitCall {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
});
// If the moved place was a `&mut` ref, then we can
// suggest to reborrow it where it was moved, so it
// will still be valid by the time we get to the usage.
@ -1243,25 +1199,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
} else {
if let Some((CallDesugaringKind::Await, _)) = desugaring {
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::Await {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::Await {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
});
} else {
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::MethodCall {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::MethodCall {
fn_call_span,
place_name: &place_name,
is_partial,
is_loop_message,
});
}
// Erase and shadow everything that could be passed to the new infcx.
let ty = moved_place.ty(self.body, tcx).ty;
@ -1276,12 +1226,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
)
&& self.infcx.can_eq(self.param_env, ty, self_ty)
{
err.subdiagnostic(
self.dcx(),
CaptureReasonSuggest::FreshReborrow {
span: move_span.shrink_to_hi(),
},
);
err.subdiagnostic(CaptureReasonSuggest::FreshReborrow {
span: move_span.shrink_to_hi(),
});
has_sugg = true;
}
if let Some(clone_trait) = tcx.lang_items().clone_trait() {
@ -1368,20 +1315,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
} else {
if move_span != span || is_loop_message {
err.subdiagnostic(
self.dcx(),
CaptureReasonLabel::MovedHere {
move_span,
is_partial,
is_move_msg,
is_loop_message,
},
);
err.subdiagnostic(CaptureReasonLabel::MovedHere {
move_span,
is_partial,
is_move_msg,
is_loop_message,
});
}
// If the move error occurs due to a loop, don't show
// another message for the same span
if !is_loop_message {
move_spans.var_subdiag(self.dcx(), err, None, |kind, var_span| match kind {
move_spans.var_subdiag(err, None, |kind, var_span| match kind {
hir::ClosureKind::Coroutine(_) => {
CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial }
}

View file

@ -579,15 +579,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span), None);
}
err.subdiagnostic(
self.dcx(),
crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
place: &place_desc,
span,
},
);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
place: &place_desc,
span,
});
} else {
binds_to.sort();
binds_to.dedup();
@ -620,17 +617,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
);
}
err.subdiagnostic(
self.dcx(),
crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
place: &place_desc,
span: use_span,
},
);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
place: &place_desc,
span: use_span,
});
use_spans.args_subdiag(self.dcx(), err, |args_span| {
use_spans.args_subdiag(err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
place: place_desc,
args_span,
@ -733,15 +727,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.suggest_cloning(err, bind_to.ty, expr, None, None);
}
err.subdiagnostic(
self.dcx(),
crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: bind_to.ty,
place: place_desc,
span: binding_span,
},
);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: bind_to.ty,
place: place_desc,
span: binding_span,
});
}
}

View file

@ -230,7 +230,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
if suggest {
borrow_spans.var_subdiag(
self.dcx(),
&mut err,
Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }),
|_kind, var_span| {

View file

@ -631,13 +631,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
let upvar_def_span = self.infcx.tcx.hir().span(def_hir);
let upvar_span = upvars_map.get(&def_hir).unwrap().span;
diag.subdiagnostic(self.dcx(), VarHereDenote::Defined { span: upvar_def_span });
diag.subdiagnostic(self.dcx(), VarHereDenote::Captured { span: upvar_span });
diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span });
diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span });
}
}
if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
diag.subdiagnostic(self.dcx(), VarHereDenote::FnMutInferred { span: fr_span });
diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span });
}
self.suggest_move_on_borrowing_closure(&mut diag);
@ -810,7 +810,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
},
};
diag.subdiagnostic(self.dcx(), err_category);
diag.subdiagnostic(err_category);
self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr);
@ -1008,7 +1008,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ident.span,
"calling this method introduces the `impl`'s `'static` requirement",
);
err.subdiagnostic(self.dcx(), RequireStaticErr::UsedImpl { multi_span });
err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
err.span_suggestion_verbose(
span.shrink_to_hi(),
"consider relaxing the implicit `'static` requirement",

View file

@ -46,7 +46,7 @@ pub fn parse_asm_args<'a>(
sp: Span,
is_global_asm: bool,
) -> PResult<'a, AsmArgs> {
let dcx = &p.psess.dcx;
let dcx = p.dcx();
if p.token == token::Eof {
return Err(dcx.create_err(errors::AsmRequiresTemplate { span: sp }));
@ -307,7 +307,7 @@ pub fn parse_asm_args<'a>(
fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
// Tool-only output
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
p.psess.dcx.emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
}
/// Try to set the provided option in the provided `AsmArgs`.
@ -379,7 +379,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
return Err(p.psess.dcx.create_err(errors::NonABI { span: p.token.span }));
return Err(p.dcx().create_err(errors::NonABI { span: p.token.span }));
}
let mut new_abis = Vec::new();
@ -390,7 +390,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
}
Err(opt_lit) => {
let span = opt_lit.map_or(p.token.span, |lit| lit.span);
let mut err = p.psess.dcx.struct_span_err(span, "expected string literal");
let mut err = p.dcx().struct_span_err(span, "expected string literal");
err.span_label(span, "not a string literal");
return Err(err);
}

View file

@ -26,7 +26,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
};
let end_span = parser.token.span;
if parser.token != token::Eof {
psess.dcx.emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
psess.dcx().emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
continue;
}

View file

@ -1,5 +1,5 @@
use rustc_errors::{
codes::*, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level, MultiSpan,
codes::*, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan,
SingleLabelManySpans, SubdiagMessageOp, Subdiagnostic,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
@ -434,7 +434,7 @@ pub(crate) struct EnvNotDefinedWithUserMessage {
// Hand-written implementation to support custom user messages.
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessage {
#[track_caller]
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
#[expect(
rustc::untranslatable_diagnostic,
reason = "cannot translate user-provided messages"
@ -801,7 +801,7 @@ pub(crate) struct AsmClobberNoReg {
}
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AsmClobberNoReg {
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
// eager translation as `span_labels` takes `AsRef<str>`
let lbl1 = dcx.eagerly_translate_to_string(
crate::fluent_generated::builtin_macros_asm_clobber_abi,

View file

@ -3,6 +3,7 @@ use rustc_ast::ptr::P;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{self as ast, attr, NodeId};
use rustc_ast_pretty::pprust;
use rustc_errors::DiagCtxtHandle;
use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
@ -38,7 +39,7 @@ enum ProcMacro {
struct CollectProcMacros<'a> {
macros: Vec<ProcMacro>,
in_root: bool,
dcx: &'a rustc_errors::DiagCtxt,
dcx: DiagCtxtHandle<'a>,
source_map: &'a SourceMap,
is_proc_macro_crate: bool,
is_test_crate: bool,
@ -52,7 +53,7 @@ pub fn inject(
is_proc_macro_crate: bool,
has_proc_macro_decls: bool,
is_test_crate: bool,
dcx: &rustc_errors::DiagCtxt,
dcx: DiagCtxtHandle<'_>,
) {
let ecfg = ExpansionConfig::default("proc_macro".to_string(), features);
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);

View file

@ -6,6 +6,7 @@ use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::visit::{walk_item, Visitor};
use rustc_ast::{attr, ModKind};
use rustc_errors::DiagCtxtHandle;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
@ -391,7 +392,7 @@ fn get_test_name(i: &ast::Item) -> Option<Symbol> {
attr::first_attr_value_str_by_name(&i.attrs, sym::rustc_test_marker)
}
fn get_test_runner(dcx: &rustc_errors::DiagCtxt, krate: &ast::Crate) -> Option<ast::Path> {
fn get_test_runner(dcx: DiagCtxtHandle<'_>, krate: &ast::Crate) -> Option<ast::Path> {
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
let meta_list = test_attr.meta_item_list()?;
let span = test_attr.span;

View file

@ -1,6 +1,7 @@
use std::sync::{Arc, Condvar, Mutex};
use jobserver::HelperThread;
use rustc_errors::DiagCtxtHandle;
use rustc_session::Session;
// FIXME don't panic when a worker thread panics
@ -46,7 +47,7 @@ impl ConcurrencyLimiter {
}
}
pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken {
pub(super) fn acquire(&self, dcx: DiagCtxtHandle<'_>) -> ConcurrencyLimiterToken {
let mut state = self.state.lock().unwrap();
loop {
state.assert_invariants();

View file

@ -28,7 +28,7 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::memmap::Mmap;
use rustc_errors::{DiagCtxt, FatalError};
use rustc_errors::{DiagCtxtHandle, FatalError};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
@ -59,7 +59,7 @@ struct LtoData {
fn prepare_lto(
cgcx: &CodegenContext<GccCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
) -> Result<LtoData, FatalError> {
let export_threshold = match cgcx.lto {
// We're just doing LTO for our one crate
@ -179,12 +179,13 @@ pub(crate) fn run_fat(
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
let dcx = cgcx.create_dcx();
let lto_data = prepare_lto(cgcx, &dcx)?;
let dcx = dcx.handle();
let lto_data = prepare_lto(cgcx, dcx)?;
/*let symbols_below_threshold =
lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
fat_lto(
cgcx,
&dcx,
dcx,
modules,
cached_modules,
lto_data.upstream_modules,
@ -195,7 +196,7 @@ pub(crate) fn run_fat(
fn fat_lto(
cgcx: &CodegenContext<GccCodegenBackend>,
_dcx: &DiagCtxt,
_dcx: DiagCtxtHandle<'_>,
modules: Vec<FatLtoInput<GccCodegenBackend>>,
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,

View file

@ -4,7 +4,7 @@ use gccjit::OutputKind;
use rustc_codegen_ssa::back::link::ensure_removed;
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
use rustc_errors::DiagCtxt;
use rustc_errors::DiagCtxtHandle;
use rustc_fs_util::link_or_copy;
use rustc_session::config::OutputType;
use rustc_span::fatal_error::FatalError;
@ -15,7 +15,7 @@ use crate::{GccCodegenBackend, GccContext};
pub(crate) unsafe fn codegen(
cgcx: &CodegenContext<GccCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<GccContext>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError> {
@ -166,7 +166,7 @@ pub(crate) unsafe fn codegen(
pub(crate) fn link(
_cgcx: &CodegenContext<GccCodegenBackend>,
_dcx: &DiagCtxt,
_dcx: DiagCtxtHandle<'_>,
mut _modules: Vec<ModuleCodegen<GccContext>>,
) -> Result<ModuleCodegen<GccContext>, FatalError> {
unimplemented!();

View file

@ -1,4 +1,4 @@
use rustc_errors::{Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;
@ -90,13 +90,13 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> {
pub(crate) struct MissingFeatures;
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> {
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable);
if let Some(span) = self.span {
diag.span(span);
};
if let Some(missing_features) = self.missing_features {
diag.subdiagnostic(dcx, missing_features);
diag.subdiagnostic(missing_features);
}
diag.arg("features", self.features.join(", "));
diag

View file

@ -16,13 +16,7 @@
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![feature(
rustc_private,
decl_macro,
never_type,
trusted_len,
hash_raw_entry
)]
#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry)]
#![allow(broken_intra_doc_links)]
#![recursion_limit = "256"]
#![warn(rust_2018_idioms)]
@ -104,7 +98,7 @@ use rustc_codegen_ssa::traits::{
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::IntoDynSyncSend;
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::TyCtxt;
@ -386,7 +380,7 @@ impl WriteBackendMethods for GccCodegenBackend {
unsafe fn optimize(
_cgcx: &CodegenContext<Self>,
_dcx: &DiagCtxt,
_dcx: DiagCtxtHandle<'_>,
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
@ -411,14 +405,17 @@ impl WriteBackendMethods for GccCodegenBackend {
unsafe fn codegen(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError> {
back::write::codegen(cgcx, dcx, module, config)
}
fn prepare_thin(_module: ModuleCodegen<Self::Module>, _emit_summary: bool) -> (String, Self::ThinBuffer) {
fn prepare_thin(
_module: ModuleCodegen<Self::Module>,
_emit_summary: bool,
) -> (String, Self::ThinBuffer) {
unimplemented!();
}
@ -428,7 +425,7 @@ impl WriteBackendMethods for GccCodegenBackend {
fn run_link(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
modules: Vec<ModuleCodegen<Self::Module>>,
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
back::write::link(cgcx, dcx, modules)

View file

@ -14,7 +14,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::memmap::Mmap;
use rustc_errors::{DiagCtxt, FatalError};
use rustc_errors::{DiagCtxtHandle, FatalError};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_middle::dep_graph::WorkProduct;
@ -49,7 +49,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
fn prepare_lto(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
) -> Result<(Vec<CString>, Vec<(SerializedModule<ModuleBuffer>, CString)>), FatalError> {
let export_threshold = match cgcx.lto {
// We're just doing LTO for our one crate
@ -203,10 +203,11 @@ pub(crate) fn run_fat(
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
) -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError> {
let dcx = cgcx.create_dcx();
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &dcx)?;
let dcx = dcx.handle();
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, dcx)?;
let symbols_below_threshold =
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
fat_lto(cgcx, &dcx, modules, cached_modules, upstream_modules, &symbols_below_threshold)
fat_lto(cgcx, dcx, modules, cached_modules, upstream_modules, &symbols_below_threshold)
}
/// Performs thin LTO by performing necessary global analysis and returning two
@ -218,7 +219,8 @@ pub(crate) fn run_thin(
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
) -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError> {
let dcx = cgcx.create_dcx();
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &dcx)?;
let dcx = dcx.handle();
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, dcx)?;
let symbols_below_threshold =
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
if cgcx.opts.cg.linker_plugin_lto.enabled() {
@ -227,7 +229,7 @@ pub(crate) fn run_thin(
is deferred to the linker"
);
}
thin_lto(cgcx, &dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
thin_lto(cgcx, dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
}
pub(crate) fn prepare_thin(
@ -241,7 +243,7 @@ pub(crate) fn prepare_thin(
fn fat_lto(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
modules: Vec<FatLtoInput<LlvmCodegenBackend>>,
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
@ -436,7 +438,7 @@ impl Drop for Linker<'_> {
/// they all go out of scope.
fn thin_lto(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
modules: Vec<(String, ThinBuffer)>,
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
@ -593,7 +595,7 @@ fn thin_lto(
pub(crate) fn run_pass_manager(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: &mut ModuleCodegen<ModuleLlvm>,
thin: bool,
) -> Result<(), FatalError> {
@ -714,10 +716,11 @@ pub unsafe fn optimize_thin_module(
cgcx: &CodegenContext<LlvmCodegenBackend>,
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
let dcx = cgcx.create_dcx();
let dcx = dcx.handle();
let module_name = &thin_module.shared.module_names[thin_module.idx];
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(dcx, e))?;
// Right now the implementation we've got only works over serialized
// modules, so we create a fresh new LLVM context and parse the module
@ -725,7 +728,7 @@ pub unsafe fn optimize_thin_module(
// crates but for locally codegened modules we may be able to reuse
// that LLVM Context and Module.
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &dcx)? as *const _;
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _;
let mut module = ModuleCodegen {
module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
name: thin_module.name().to_string(),
@ -748,7 +751,7 @@ pub unsafe fn optimize_thin_module(
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) {
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
}
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
}
@ -758,7 +761,7 @@ pub unsafe fn optimize_thin_module(
.prof
.generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
}
save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve");
}
@ -768,7 +771,7 @@ pub unsafe fn optimize_thin_module(
.prof
.generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
}
save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize");
}
@ -777,7 +780,7 @@ pub unsafe fn optimize_thin_module(
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) {
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
}
save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
}
@ -789,7 +792,7 @@ pub unsafe fn optimize_thin_module(
// little differently.
{
info!("running thin lto passes over {}", module.name);
run_pass_manager(cgcx, &dcx, &mut module, true)?;
run_pass_manager(cgcx, dcx, &mut module, true)?;
save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
}
}
@ -859,7 +862,7 @@ pub fn parse_module<'a>(
cx: &'a llvm::Context,
name: &CStr,
data: &[u8],
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
) -> Result<&'a llvm::Module, FatalError> {
unsafe {
llvm::LLVMRustParseBitcodeForLTO(cx, data.as_ptr(), data.len(), name.as_ptr())

View file

@ -26,7 +26,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{DiagCtxt, FatalError, Level};
use rustc_errors::{DiagCtxtHandle, FatalError, Level};
use rustc_fs_util::{link_or_copy, path_to_c_string};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, Lto, OutputType, Passes};
@ -47,7 +47,7 @@ use std::slice;
use std::str;
use std::sync::Arc;
pub fn llvm_err<'a>(dcx: &rustc_errors::DiagCtxt, err: LlvmError<'a>) -> FatalError {
pub fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError {
match llvm::last_error() {
Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)),
None => dcx.emit_almost_fatal(err),
@ -55,7 +55,7 @@ pub fn llvm_err<'a>(dcx: &rustc_errors::DiagCtxt, err: LlvmError<'a>) -> FatalEr
}
pub fn write_output_file<'ll>(
dcx: &rustc_errors::DiagCtxt,
dcx: DiagCtxtHandle<'_>,
target: &'ll llvm::TargetMachine,
pm: &llvm::PassManager<'ll>,
m: &'ll llvm::Module,
@ -331,7 +331,7 @@ pub enum CodegenDiagnosticsStage {
}
pub struct DiagnosticHandlers<'a> {
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, &'a DiagCtxt),
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'a>),
llcx: &'a llvm::Context,
old_handler: Option<&'a llvm::DiagnosticHandler>,
}
@ -339,7 +339,7 @@ pub struct DiagnosticHandlers<'a> {
impl<'a> DiagnosticHandlers<'a> {
pub fn new(
cgcx: &'a CodegenContext<LlvmCodegenBackend>,
dcx: &'a DiagCtxt,
dcx: DiagCtxtHandle<'a>,
llcx: &'a llvm::Context,
module: &ModuleCodegen<ModuleLlvm>,
stage: CodegenDiagnosticsStage,
@ -428,7 +428,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
if user.is_null() {
return;
}
let (cgcx, dcx) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &DiagCtxt));
let (cgcx, dcx) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'_>));
match llvm::diagnostic::Diagnostic::unpack(info) {
llvm::diagnostic::InlineAsm(inline) => {
@ -506,7 +506,7 @@ fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
pub(crate) unsafe fn llvm_optimize(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: &ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
opt_level: config::OptLevel,
@ -604,7 +604,7 @@ pub(crate) unsafe fn llvm_optimize(
// Unsafe due to LLVM calls.
pub(crate) unsafe fn optimize(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: &ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
@ -637,7 +637,7 @@ pub(crate) unsafe fn optimize(
pub(crate) fn link(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
mut modules: Vec<ModuleCodegen<ModuleLlvm>>,
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
use super::lto::{Linker, ModuleBuffer};
@ -660,7 +660,7 @@ pub(crate) fn link(
pub(crate) unsafe fn codegen(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError> {

View file

@ -4,7 +4,7 @@ use std::path::Path;
use crate::fluent_generated as fluent;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;
@ -100,7 +100,7 @@ pub(crate) struct DynamicLinkingWithLTO;
pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>);
impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let diag: Diag<'_, G> = self.0.into_diag(dcx, level);
let (message, _) = diag.messages.first().expect("`LlvmError` with no message");
let message = dcx.eagerly_translate_to_string(message.clone(), diag.args.iter());
@ -120,13 +120,13 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> {
pub(crate) struct MissingFeatures;
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> {
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::codegen_llvm_target_feature_disable_or_enable);
if let Some(span) = self.span {
diag.span(span);
};
if let Some(missing_features) = self.missing_features {
diag.subdiagnostic(dcx, missing_features);
diag.subdiagnostic(missing_features);
}
diag.arg("features", self.features.join(", "));
diag
@ -180,7 +180,7 @@ pub enum LlvmError<'a> {
pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String);
impl<G: EmissionGuarantee> Diagnostic<'_, G> for WithLlvmError<'_> {
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
use LlvmError::*;
let msg_with_llvm_err = match &self.0 {
WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err,

View file

@ -31,7 +31,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagCtxt, ErrorGuaranteed, FatalError};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::TyCtxt;
@ -191,7 +191,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
}
fn run_link(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
modules: Vec<ModuleCodegen<Self::Module>>,
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
back::write::link(cgcx, dcx, modules)
@ -212,7 +212,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
}
unsafe fn optimize(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
@ -223,7 +223,8 @@ impl WriteBackendMethods for LlvmCodegenBackend {
module: &mut ModuleCodegen<Self::Module>,
) -> Result<(), FatalError> {
let dcx = cgcx.create_dcx();
back::lto::run_pass_manager(cgcx, &dcx, module, false)
let dcx = dcx.handle();
back::lto::run_pass_manager(cgcx, dcx, module, false)
}
unsafe fn optimize_thin(
cgcx: &CodegenContext<Self>,
@ -233,7 +234,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
}
unsafe fn codegen(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError> {
@ -441,7 +442,7 @@ impl ModuleLlvm {
cgcx: &CodegenContext<LlvmCodegenBackend>,
name: &CStr,
buffer: &[u8],
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
) -> Result<Self, FatalError> {
unsafe {
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);

View file

@ -3,7 +3,7 @@ use rustc_ast::CRATE_NODE_ID;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{DiagCtxt, ErrorGuaranteed, FatalError};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
@ -54,7 +54,7 @@ use std::process::{ExitStatus, Output, Stdio};
use std::{env, fmt, fs, io, mem, str};
use tracing::{debug, info, warn};
pub fn ensure_removed(dcx: &DiagCtxt, path: &Path) {
pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
if let Err(e) = fs::remove_file(path) {
if e.kind() != io::ErrorKind::NotFound {
dcx.err(format!("failed to remove {}: {}", path.display(), e));

View file

@ -891,9 +891,10 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
module_config: &ModuleConfig,
) -> Result<WorkItemResult<B>, FatalError> {
let dcx = cgcx.create_dcx();
let dcx = dcx.handle();
unsafe {
B::optimize(cgcx, &dcx, &module, module_config)?;
B::optimize(cgcx, dcx, &module, module_config)?;
}
// After we've done the initial round of optimizations we need to
@ -954,7 +955,11 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
match link_or_copy(&source_file, &output_path) {
Ok(_) => Some(output_path),
Err(error) => {
cgcx.create_dcx().emit_err(errors::CopyPathBuf { source_file, output_path, error });
cgcx.create_dcx().handle().emit_err(errors::CopyPathBuf {
source_file,
output_path,
error,
});
None
}
}
@ -987,7 +992,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode);
let object = load_from_incr_cache(should_emit_obj, OutputType::Object);
if should_emit_obj && object.is_none() {
cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
cgcx.create_dcx().handle().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
}
WorkItemResult::Finished(CompiledModule {
@ -1016,12 +1021,13 @@ fn finish_intra_module_work<B: ExtraBackendMethods>(
module_config: &ModuleConfig,
) -> Result<WorkItemResult<B>, FatalError> {
let dcx = cgcx.create_dcx();
let dcx = dcx.handle();
if !cgcx.opts.unstable_opts.combine_cgu
|| module.kind == ModuleKind::Metadata
|| module.kind == ModuleKind::Allocator
{
let module = unsafe { B::codegen(cgcx, &dcx, module, module_config)? };
let module = unsafe { B::codegen(cgcx, dcx, module, module_config)? };
Ok(WorkItemResult::Finished(module))
} else {
Ok(WorkItemResult::NeedsLink(module))
@ -1692,9 +1698,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
if !needs_link.is_empty() {
assert!(compiled_modules.is_empty());
let dcx = cgcx.create_dcx();
let module = B::run_link(&cgcx, &dcx, needs_link).map_err(|_| ())?;
let dcx = dcx.handle();
let module = B::run_link(&cgcx, dcx, needs_link).map_err(|_| ())?;
let module = unsafe {
B::codegen(&cgcx, &dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?
B::codegen(&cgcx, dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?
};
compiled_modules.push(module);
}

View file

@ -4,7 +4,7 @@ use crate::assert_module_sources::CguReuse;
use crate::back::command::Command;
use crate::fluent_generated as fluent;
use rustc_errors::{
codes::*, Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
codes::*, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
};
use rustc_macros::Diagnostic;
use rustc_middle::ty::layout::LayoutError;
@ -215,7 +215,7 @@ pub enum LinkRlibError {
pub struct ThorinErrorWrapper(pub thorin::Error);
impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
fn into_diag(self, dcx: &DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let build = |msg| Diag::new(dcx, level, msg);
match self.0 {
thorin::Error::ReadInput(_) => build(fluent::codegen_ssa_thorin_read_input_failure),
@ -348,7 +348,7 @@ pub struct LinkingFailed<'a> {
}
impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
fn into_diag(self, dcx: &DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed);
diag.arg("linker_path", format!("{}", self.linker_path.display()));
diag.arg("exit_status", format!("{}", self.exit_status));

View file

@ -2,7 +2,7 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig};
use crate::{CompiledModule, ModuleCodegen};
use rustc_errors::{DiagCtxt, FatalError};
use rustc_errors::{DiagCtxtHandle, FatalError};
use rustc_middle::dep_graph::WorkProduct;
pub trait WriteBackendMethods: 'static + Sized + Clone {
@ -16,7 +16,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
/// Merge all modules into main_module and returning it
fn run_link(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
modules: Vec<ModuleCodegen<Self::Module>>,
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
/// Performs fat LTO by merging all modules into a single one and returning it
@ -38,7 +38,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
fn print_statistics(&self);
unsafe fn optimize(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError>;
@ -52,7 +52,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
unsafe fn codegen(
cgcx: &CodegenContext<Self>,
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError>;

View file

@ -5,7 +5,7 @@
//! it finds operations that are invalid in a certain context.
use rustc_attr as attr;
use rustc_errors::DiagCtxt;
use rustc_errors::DiagCtxtHandle;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::bug;
@ -46,7 +46,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
ConstCx { body, tcx, param_env, const_kind }
}
pub(crate) fn dcx(&self) -> &'tcx DiagCtxt {
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.tcx.dcx()
}

View file

@ -138,7 +138,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
// FIXME(effects) revisit this
if !tcx.is_const_trait_impl_raw(data.impl_def_id) {
let span = tcx.def_span(data.impl_def_id);
err.subdiagnostic(tcx.dcx(), errors::NonConstImplNote { span });
err.subdiagnostic(errors::NonConstImplNote { span });
}
}
}

View file

@ -2,7 +2,7 @@ use std::borrow::Cow;
use either::Either;
use rustc_errors::{
codes::*, Diag, DiagArgValue, DiagCtxt, DiagMessage, Diagnostic, EmissionGuarantee, Level,
codes::*, Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
};
use rustc_hir::ConstContext;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@ -453,7 +453,7 @@ pub trait ReportErrorExt {
}
}
fn bad_pointer_message(msg: CheckInAllocMsg, dcx: &DiagCtxt) -> String {
fn bad_pointer_message(msg: CheckInAllocMsg, dcx: DiagCtxtHandle<'_>) -> String {
use crate::fluent_generated::*;
let msg = match msg {

View file

@ -4,7 +4,7 @@ use std::{fmt, mem};
use either::{Either, Left, Right};
use tracing::{debug, info, info_span, instrument, trace};
use rustc_errors::DiagCtxt;
use rustc_errors::DiagCtxtHandle;
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::IndexVec;
use rustc_middle::mir;
@ -474,7 +474,7 @@ pub(super) fn from_known_layout<'tcx>(
///
/// This is NOT the preferred way to render an error; use `report` from `const_eval` instead.
/// However, this is useful when error messages appear in ICEs.
pub fn format_interp_error<'tcx>(dcx: &DiagCtxt, e: InterpErrorInfo<'tcx>) -> String {
pub fn format_interp_error<'tcx>(dcx: DiagCtxtHandle<'_>, e: InterpErrorInfo<'tcx>) -> String {
let (e, backtrace) = e.into_parts();
backtrace.print_backtrace();
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the

View file

@ -1444,6 +1444,7 @@ fn report_ice(
fallback_bundle,
));
let dcx = rustc_errors::DiagCtxt::new(emitter);
let dcx = dcx.handle();
// a .span_bug or .bug call has already printed what
// it wants to print.
@ -1509,7 +1510,7 @@ fn report_ice(
let num_frames = if backtrace { None } else { Some(2) };
interface::try_print_query_stack(&dcx, num_frames, file);
interface::try_print_query_stack(dcx, num_frames, file);
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
// printed all the relevant info.

View file

@ -1,7 +1,7 @@
use crate::snippet::Style;
use crate::{
CodeSuggestion, DiagCtxt, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level, MultiSpan,
StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
};
use rustc_data_structures::fx::FxIndexMap;
use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
@ -133,7 +133,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
pub trait Diagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
/// Write out as a diagnostic out of `DiagCtxt`.
#[must_use]
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G>;
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G>;
}
impl<'a, T, G> Diagnostic<'a, G> for Spanned<T>
@ -141,7 +141,7 @@ where
T: Diagnostic<'a, G>,
G: EmissionGuarantee,
{
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
self.node.into_diag(dcx, level).with_span(self.span)
}
}
@ -490,7 +490,7 @@ pub struct Subdiag {
/// the methods of `Diag` here, consider extending `DiagCtxtFlags`.
#[must_use]
pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
pub dcx: &'a DiagCtxt,
pub dcx: DiagCtxtHandle<'a>,
/// Why the `Option`? It is always `Some` until the `Diag` is consumed via
/// `emit`, `cancel`, etc. At that point it is consumed and replaced with
@ -578,13 +578,13 @@ macro_rules! with_fn {
impl<'a, G: EmissionGuarantee> Diag<'a, G> {
#[rustc_lint_diagnostics]
#[track_caller]
pub fn new(dcx: &'a DiagCtxt, level: Level, message: impl Into<DiagMessage>) -> Self {
pub fn new(dcx: DiagCtxtHandle<'a>, level: Level, message: impl Into<DiagMessage>) -> Self {
Self::new_diagnostic(dcx, DiagInner::new(level, message))
}
/// Creates a new `Diag` with an already constructed diagnostic.
#[track_caller]
pub(crate) fn new_diagnostic(dcx: &'a DiagCtxt, diag: DiagInner) -> Self {
pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self {
debug!("Created new diagnostic");
Self { dcx, diag: Some(Box::new(diag)), _marker: PhantomData }
}
@ -1192,11 +1192,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
/// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
/// interpolated variables).
#[rustc_lint_diagnostics]
pub fn subdiagnostic(
&mut self,
dcx: &crate::DiagCtxt,
subdiagnostic: impl Subdiagnostic,
) -> &mut Self {
pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self {
let dcx = self.dcx;
subdiagnostic.add_to_diag_with(self, &|diag, msg| {
let args = diag.args.iter();
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
@ -1341,7 +1338,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
/// See `DiagCtxt::stash_diagnostic` for details.
pub fn stash(mut self, span: Span, key: StashKey) -> Option<ErrorGuaranteed> {
self.dcx.stash_diagnostic(span, key, self.take_diag())
let diag = self.take_diag();
self.dcx.stash_diagnostic(span, key, diag)
}
/// Delay emission of this diagnostic as a bug.

View file

@ -1,7 +1,7 @@
use crate::diagnostic::DiagLocation;
use crate::{fluent_generated as fluent, Subdiagnostic};
use crate::{fluent_generated as fluent, DiagCtxtHandle, Subdiagnostic};
use crate::{
Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level,
Diag, DiagArgValue, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level,
SubdiagMessageOp,
};
use rustc_ast as ast;
@ -315,7 +315,7 @@ impl IntoDiagArg for DiagSymbolList {
}
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
fn into_diag(self, dcx: &DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
match self {
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
Diag::new(dcx, level, fluent::errors_target_invalid_address_space)

View file

@ -567,7 +567,7 @@ impl Emitter for SilentEmitter {
if let Some(fatal_note) = &self.fatal_note {
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
}
self.fatal_dcx.emit_diagnostic(diag);
self.fatal_dcx.handle().emit_diagnostic(diag);
}
}
}

View file

@ -55,8 +55,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
);
let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
let dcx = DiagCtxt::new(Box::new(je));
dcx.span_err(span, "foo");
DiagCtxt::new(Box::new(je)).handle().span_err(span, "foo");
let bytes = output.lock().unwrap();
let actual_output = str::from_utf8(&bytes).unwrap();

View file

@ -414,6 +414,19 @@ pub struct DiagCtxt {
inner: Lock<DiagCtxtInner>,
}
#[derive(Copy, Clone)]
pub struct DiagCtxtHandle<'a> {
dcx: &'a DiagCtxt,
}
impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
type Target = &'a DiagCtxt;
fn deref(&self) -> &Self::Target {
&self.dcx
}
}
/// This inner struct exists to keep it all behind a single lock;
/// this is done to prevent possible deadlocks in a multi-threaded compiler,
/// as well as inconsistent state observation.
@ -608,7 +621,7 @@ impl DiagCtxt {
}
pub fn make_silent(
&mut self,
&self,
fallback_bundle: LazyFallbackBundle,
fatal_note: Option<String>,
emit_fatal_diagnostic: bool,
@ -623,7 +636,7 @@ impl DiagCtxt {
});
}
fn wrap_emitter<F>(&mut self, f: F)
fn wrap_emitter<F>(&self, f: F)
where
F: FnOnce(DiagCtxtInner) -> Box<DynEmitter>,
{
@ -738,6 +751,12 @@ impl DiagCtxt {
*fulfilled_expectations = Default::default();
}
pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
DiagCtxtHandle { dcx: self }
}
}
impl<'a> DiagCtxtHandle<'a> {
/// Stashes a diagnostic for possible later improvement in a different,
/// later stage of the compiler. Possible actions depend on the diagnostic
/// level:
@ -745,8 +764,8 @@ impl DiagCtxt {
/// - Level::Error: immediately counted as an error that has occurred, because it
/// is guaranteed to be emitted eventually. Can be later accessed with the
/// provided `span` and `key` through
/// [`DiagCtxt::try_steal_modify_and_emit_err`] or
/// [`DiagCtxt::try_steal_replace_and_emit_err`]. These do not allow
/// [`DiagCtxtHandle::try_steal_modify_and_emit_err`] or
/// [`DiagCtxtHandle::try_steal_replace_and_emit_err`]. These do not allow
/// cancellation or downgrading of the error. Returns
/// `Some(ErrorGuaranteed)`.
/// - Level::DelayedBug: this does happen occasionally with errors that are
@ -757,7 +776,7 @@ impl DiagCtxt {
/// user-facing error. Returns `Some(ErrorGuaranteed)` as is normal for
/// delayed bugs.
/// - Level::Warning and lower (i.e. !is_error()): can be accessed with the
/// provided `span` and `key` through [`DiagCtxt::steal_non_err()`]. This
/// provided `span` and `key` through [`DiagCtxtHandle::steal_non_err()`]. This
/// allows cancelling and downgrading of the diagnostic. Returns `None`.
pub fn stash_diagnostic(
&self,
@ -793,7 +812,7 @@ impl DiagCtxt {
/// Steal a previously stashed non-error diagnostic with the given `Span`
/// and [`StashKey`] as the key. Panics if the found diagnostic is an
/// error.
pub fn steal_non_err(&self, span: Span, key: StashKey) -> Option<Diag<'_, ()>> {
pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key)?;
@ -807,7 +826,7 @@ impl DiagCtxt {
/// no matching diagnostic is found. Panics if the found diagnostic's level
/// isn't `Level::Error`.
pub fn try_steal_modify_and_emit_err<F>(
&self,
self,
span: Span,
key: StashKey,
mut modify_err: F,
@ -833,7 +852,7 @@ impl DiagCtxt {
/// [`StashKey`] as the key, cancels it if found, and emits `new_err`.
/// Panics if the found diagnostic's level isn't `Level::Error`.
pub fn try_steal_replace_and_emit_err(
&self,
self,
span: Span,
key: StashKey,
new_err: Diag<'_>,
@ -1106,18 +1125,18 @@ impl DiagCtxt {
//
// Functions beginning with `struct_`/`create_` create a diagnostic. Other
// functions create and emit a diagnostic all in one go.
impl DiagCtxt {
impl<'a> DiagCtxtHandle<'a> {
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
// user-facing.
#[track_caller]
pub fn struct_bug(&self, msg: impl Into<Cow<'static, str>>) -> Diag<'_, BugAbort> {
pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
Diag::new(self, Bug, msg.into())
}
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
// user-facing.
#[track_caller]
pub fn bug(&self, msg: impl Into<Cow<'static, str>>) -> ! {
pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
self.struct_bug(msg).emit()
}
@ -1125,111 +1144,108 @@ impl DiagCtxt {
// user-facing.
#[track_caller]
pub fn struct_span_bug(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<Cow<'static, str>>,
) -> Diag<'_, BugAbort> {
) -> Diag<'a, BugAbort> {
self.struct_bug(msg).with_span(span)
}
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
// user-facing.
#[track_caller]
pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
self.struct_span_bug(span, msg.into()).emit()
}
#[track_caller]
pub fn create_bug<'a>(&'a self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
bug.into_diag(self, Bug)
}
#[track_caller]
pub fn emit_bug<'a>(&'a self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
self.create_bug(bug).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_fatal(&self, msg: impl Into<DiagMessage>) -> Diag<'_, FatalAbort> {
pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
Diag::new(self, Fatal, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn fatal(&self, msg: impl Into<DiagMessage>) -> ! {
pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
self.struct_fatal(msg).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_fatal(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
) -> Diag<'_, FatalAbort> {
) -> Diag<'a, FatalAbort> {
self.struct_fatal(msg).with_span(span)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
self.struct_span_fatal(span, msg).emit()
}
#[track_caller]
pub fn create_fatal<'a>(
&'a self,
fatal: impl Diagnostic<'a, FatalAbort>,
) -> Diag<'a, FatalAbort> {
pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
fatal.into_diag(self, Fatal)
}
#[track_caller]
pub fn emit_fatal<'a>(&'a self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
self.create_fatal(fatal).emit()
}
#[track_caller]
pub fn create_almost_fatal<'a>(
&'a self,
pub fn create_almost_fatal(
self,
fatal: impl Diagnostic<'a, FatalError>,
) -> Diag<'a, FatalError> {
fatal.into_diag(self, Fatal)
}
#[track_caller]
pub fn emit_almost_fatal<'a>(&'a self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
self.create_almost_fatal(fatal).emit()
}
// FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_err(&self, msg: impl Into<DiagMessage>) -> Diag<'_> {
pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
Diag::new(self, Error, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn err(&self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
self.struct_err(msg).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_err(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
) -> Diag<'_> {
) -> Diag<'a> {
self.struct_err(msg).with_span(span)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn span_err(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
) -> ErrorGuaranteed {
@ -1237,12 +1253,12 @@ impl DiagCtxt {
}
#[track_caller]
pub fn create_err<'a>(&'a self, err: impl Diagnostic<'a>) -> Diag<'a> {
pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
err.into_diag(self, Error)
}
#[track_caller]
pub fn emit_err<'a>(&'a self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
self.create_err(err).emit()
}
@ -1251,7 +1267,7 @@ impl DiagCtxt {
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
// user-facing.
#[track_caller]
pub fn delayed_bug(&self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
}
@ -1264,7 +1280,7 @@ impl DiagCtxt {
// user-facing.
#[track_caller]
pub fn span_delayed_bug(
&self,
self,
sp: impl Into<MultiSpan>,
msg: impl Into<Cow<'static, str>>,
) -> ErrorGuaranteed {
@ -1273,45 +1289,45 @@ impl DiagCtxt {
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_warn(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> {
pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
Diag::new(self, Warning, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn warn(&self, msg: impl Into<DiagMessage>) {
pub fn warn(self, msg: impl Into<DiagMessage>) {
self.struct_warn(msg).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_warn(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
) -> Diag<'_, ()> {
) -> Diag<'a, ()> {
self.struct_warn(msg).with_span(span)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
self.struct_span_warn(span, msg).emit()
}
#[track_caller]
pub fn create_warn<'a>(&'a self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
warning.into_diag(self, Warning)
}
#[track_caller]
pub fn emit_warn<'a>(&'a self, warning: impl Diagnostic<'a, ()>) {
pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
self.create_warn(warning).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_note(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> {
pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
Diag::new(self, Note, msg)
}
@ -1324,54 +1340,50 @@ impl DiagCtxt {
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_note(
&self,
self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
) -> Diag<'_, ()> {
) -> Diag<'a, ()> {
self.struct_note(msg).with_span(span)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
self.struct_span_note(span, msg).emit()
}
#[track_caller]
pub fn create_note<'a>(&'a self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
note.into_diag(self, Note)
}
#[track_caller]
pub fn emit_note<'a>(&'a self, note: impl Diagnostic<'a, ()>) {
pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
self.create_note(note).emit()
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_help(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> {
pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
Diag::new(self, Help, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_failure_note(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> {
pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
Diag::new(self, FailureNote, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_allow(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> {
pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
Diag::new(self, Allow, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_expect(
&self,
msg: impl Into<DiagMessage>,
id: LintExpectationId,
) -> Diag<'_, ()> {
pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
Diag::new(self, Expect(id), msg)
}
}

View file

@ -12,7 +12,7 @@ use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind
use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{self, Lrc};
use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult};
use rustc_feature::Features;
use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
use rustc_parse::{parser::Parser, MACRO_ARGUMENTS};
@ -1135,7 +1135,7 @@ impl<'a> ExtCtxt<'a> {
}
}
pub fn dcx(&self) -> &'a DiagCtxt {
pub fn dcx(&self) -> DiagCtxtHandle<'a> {
self.sess.dcx()
}
@ -1256,7 +1256,7 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
}
pub fn parse_macro_name_and_helper_attrs(
dcx: &rustc_errors::DiagCtxt,
dcx: DiagCtxtHandle<'_>,
attr: &Attribute,
macro_type: &str,
) -> Option<(Symbol, Vec<Symbol>)> {
@ -1358,7 +1358,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) {
if crate_matches {
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
sess.psess.dcx.emit_fatal(errors::ProcMacroBackCompat {
sess.dcx().emit_fatal(errors::ProcMacroBackCompat {
crate_name: "rental".to_string(),
fixed_version: "0.5.6".to_string(),
});

View file

@ -7,7 +7,7 @@ use crate::mbe::{
use rustc_ast::token::{self, Token, TokenKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, Diag, DiagCtxt, DiagMessage};
use rustc_errors::{Applicability, Diag, DiagMessage};
use rustc_macros::Subdiagnostic;
use rustc_parse::parser::{Parser, Recovery};
use rustc_span::source_map::SourceMap;
@ -61,7 +61,7 @@ pub(super) fn failed_to_match_macro<'cx>(
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
}
annotate_doc_comment(cx.sess.dcx(), &mut err, psess.source_map(), span);
annotate_doc_comment(&mut err, psess.source_map(), span);
if let Some(span) = remaining_matcher.span() {
err.span_note(span, format!("while trying to match {remaining_matcher}"));
@ -324,12 +324,12 @@ enum ExplainDocComment {
},
}
pub(super) fn annotate_doc_comment(dcx: &DiagCtxt, err: &mut Diag<'_>, sm: &SourceMap, span: Span) {
pub(super) fn annotate_doc_comment(err: &mut Diag<'_>, sm: &SourceMap, span: Span) {
if let Ok(src) = sm.span_to_snippet(span) {
if src.starts_with("///") || src.starts_with("/**") {
err.subdiagnostic(dcx, ExplainDocComment::Outer { span });
err.subdiagnostic(ExplainDocComment::Outer { span });
} else if src.starts_with("//!") || src.starts_with("/*!") {
err.subdiagnostic(dcx, ExplainDocComment::Inner { span });
err.subdiagnostic(ExplainDocComment::Inner { span });
}
}
}

View file

@ -206,7 +206,7 @@ pub(super) fn check_meta_variables(
rhses: &[TokenTree],
) -> Result<(), ErrorGuaranteed> {
if lhses.len() != rhses.len() {
psess.dcx.span_bug(span, "length mismatch between LHSes and RHSes")
psess.dcx().span_bug(span, "length mismatch between LHSes and RHSes")
}
let mut guar = None;
for (lhs, rhs) in iter::zip(lhses, rhses) {
@ -245,7 +245,7 @@ fn check_binders(
// MetaVar(fragment) and not as MetaVarDecl(y, fragment).
TokenTree::MetaVar(span, name) => {
if macros.is_empty() {
psess.dcx.span_bug(span, "unexpected MetaVar in lhs");
psess.dcx().span_bug(span, "unexpected MetaVar in lhs");
}
let name = MacroRulesNormalizedIdent::new(name);
// There are 3 possibilities:
@ -276,7 +276,7 @@ fn check_binders(
);
}
if !macros.is_empty() {
psess.dcx.span_bug(span, "unexpected MetaVarDecl in nested lhs");
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");
}
let name = MacroRulesNormalizedIdent::new(name);
if let Some(prev_info) = get_binder_info(macros, binders, name) {
@ -284,7 +284,7 @@ fn check_binders(
// for nested macro definitions.
*guar = Some(
psess
.dcx
.dcx()
.emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span }),
);
} else {
@ -344,7 +344,7 @@ fn check_occurrences(
match *rhs {
TokenTree::Token(..) => {}
TokenTree::MetaVarDecl(span, _name, _kind) => {
psess.dcx.span_bug(span, "unexpected MetaVarDecl in rhs")
psess.dcx().span_bug(span, "unexpected MetaVarDecl in rhs")
}
TokenTree::MetaVar(span, name) => {
let name = MacroRulesNormalizedIdent::new(name);

View file

@ -383,7 +383,7 @@ pub fn compile_declarative_macro(
};
let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new());
let dcx = &sess.psess.dcx;
let dcx = sess.dcx();
let lhs_nm = Ident::new(sym::lhs, def.span);
let rhs_nm = Ident::new(sym::rhs, def.span);
let tt_spec = Some(NonterminalKind::TT);
@ -463,7 +463,7 @@ pub fn compile_declarative_macro(
let sp = token.span.substitute_dummy(def.span);
let mut err = sess.dcx().struct_span_err(sp, s);
err.span_label(sp, msg);
annotate_doc_comment(sess.dcx(), &mut err, sess.source_map(), sp);
annotate_doc_comment(&mut err, sess.source_map(), sp);
let guar = err.emit();
return dummy_syn_ext(guar);
}

View file

@ -42,7 +42,7 @@ impl MetaVarExpr {
let ident = parse_ident(&mut tts, psess, outer_span)?;
let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = tts.next() else {
let msg = "meta-variable expression parameter must be wrapped in parentheses";
return Err(psess.dcx.struct_span_err(ident.span, msg));
return Err(psess.dcx().struct_span_err(ident.span, msg));
};
check_trailing_token(&mut tts, psess)?;
let mut iter = args.trees();
@ -62,12 +62,12 @@ impl MetaVarExpr {
break;
}
if !try_eat_comma(&mut iter) {
return Err(psess.dcx.struct_span_err(outer_span, "expected comma"));
return Err(psess.dcx().struct_span_err(outer_span, "expected comma"));
}
}
if result.len() < 2 {
return Err(psess
.dcx
.dcx()
.struct_span_err(ident.span, "`concat` must have at least two elements"));
}
MetaVarExpr::Concat(result.into())
@ -81,7 +81,7 @@ impl MetaVarExpr {
"len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?),
_ => {
let err_msg = "unrecognized meta-variable expression";
let mut err = psess.dcx.struct_span_err(ident.span, err_msg);
let mut err = psess.dcx().struct_span_err(ident.span, err_msg);
err.span_suggestion(
ident.span,
"supported expressions are count, ignore, index and len",
@ -120,7 +120,7 @@ fn check_trailing_token<'psess>(
) -> PResult<'psess, ()> {
if let Some(tt) = iter.next() {
let mut diag = psess
.dcx
.dcx()
.struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt)));
diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens");
Err(diag)
@ -139,7 +139,7 @@ fn parse_count<'psess>(
let ident = parse_ident(iter, psess, span)?;
let depth = if try_eat_comma(iter) {
if iter.look_ahead(0).is_none() {
return Err(psess.dcx.struct_span_err(
return Err(psess.dcx().struct_span_err(
span,
"`count` followed by a comma must have an associated index indicating its depth",
));
@ -160,7 +160,7 @@ fn parse_depth<'psess>(
let Some(tt) = iter.next() else { return Ok(0) };
let TokenTree::Token(token::Token { kind: token::TokenKind::Literal(lit), .. }, _) = tt else {
return Err(psess
.dcx
.dcx()
.struct_span_err(span, "meta-variable expression depth must be a literal"));
};
if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
@ -170,7 +170,7 @@ fn parse_depth<'psess>(
Ok(n_usize)
} else {
let msg = "only unsuffixes integer literals are supported in meta-variable expressions";
Err(psess.dcx.struct_span_err(span, msg))
Err(psess.dcx().struct_span_err(span, msg))
}
}
@ -181,20 +181,21 @@ fn parse_ident<'psess>(
fallback_span: Span,
) -> PResult<'psess, Ident> {
let Some(tt) = iter.next() else {
return Err(psess.dcx.struct_span_err(fallback_span, "expected identifier"));
return Err(psess.dcx().struct_span_err(fallback_span, "expected identifier"));
};
let TokenTree::Token(token, _) = tt else {
return Err(psess.dcx.struct_span_err(tt.span(), "expected identifier"));
return Err(psess.dcx().struct_span_err(tt.span(), "expected identifier"));
};
if let Some((elem, is_raw)) = token.ident() {
if let IdentIsRaw::Yes = is_raw {
return Err(psess.dcx.struct_span_err(elem.span, RAW_IDENT_ERR));
return Err(psess.dcx().struct_span_err(elem.span, RAW_IDENT_ERR));
}
return Ok(elem);
}
let token_str = pprust::token_to_string(token);
let mut err =
psess.dcx.struct_span_err(token.span, format!("expected identifier, found `{token_str}`"));
let mut err = psess
.dcx()
.struct_span_err(token.span, format!("expected identifier, found `{token_str}`"));
err.span_suggestion(
token.span,
format!("try removing `{token_str}`"),
@ -236,7 +237,7 @@ fn eat_dollar<'psess>(
let _ = iter.next();
return Ok(());
}
Err(psess.dcx.struct_span_err(
Err(psess.dcx().struct_span_err(
span,
"meta-variables within meta-variable expressions must be referenced using a dollar sign",
))

View file

@ -10,7 +10,7 @@ use rustc_ast::token::IdentIsRaw;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, Diag, DiagCtxt, PResult};
use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult};
use rustc_parse::parser::ParseNtResult;
use rustc_session::parse::ParseSess;
use rustc_span::hygiene::{LocalExpnId, Transparency};
@ -141,7 +141,7 @@ pub(super) fn transcribe<'a>(
let mut result_stack = Vec::new();
let mut marker = Marker(expand_id, transparency, Default::default());
let dcx = &psess.dcx;
let dcx = psess.dcx();
loop {
// Look at the last frame on the stack.
// If it still has a TokenTree we have not looked at yet, use that tree.
@ -571,7 +571,7 @@ fn lockstep_iter_size(
/// * `[ $( ${count(foo, 1)} ),* ]` will return an error because `${count(foo, 1)}` is
/// declared inside a single repetition and the index `1` implies two nested repetitions.
fn count_repetitions<'a>(
dcx: &'a DiagCtxt,
dcx: DiagCtxtHandle<'a>,
depth_user: usize,
mut matched: &NamedMatch,
repeats: &[(usize, usize)],
@ -632,7 +632,7 @@ fn count_repetitions<'a>(
/// Returns a `NamedMatch` item declared on the LHS given an arbitrary [Ident]
fn matched_from_ident<'ctx, 'interp, 'rslt>(
dcx: &'ctx DiagCtxt,
dcx: DiagCtxtHandle<'ctx>,
ident: Ident,
interp: &'interp FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
) -> PResult<'ctx, &'rslt NamedMatch>
@ -646,7 +646,7 @@ where
/// Used by meta-variable expressions when an user input is out of the actual declared bounds. For
/// example, index(999999) in an repetition of only three elements.
fn out_of_bounds_err<'a>(dcx: &'a DiagCtxt, max: usize, span: Span, ty: &str) -> Diag<'a> {
fn out_of_bounds_err<'a>(dcx: DiagCtxtHandle<'a>, max: usize, span: Span, ty: &str) -> Diag<'a> {
let msg = if max == 0 {
format!(
"meta-variable expression `{ty}` with depth parameter \
@ -662,7 +662,7 @@ fn out_of_bounds_err<'a>(dcx: &'a DiagCtxt, max: usize, span: Span, ty: &str) ->
}
fn transcribe_metavar_expr<'a>(
dcx: &'a DiagCtxt,
dcx: DiagCtxtHandle<'a>,
expr: &MetaVarExpr,
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
marker: &mut Marker,
@ -730,7 +730,7 @@ fn transcribe_metavar_expr<'a>(
/// Extracts an identifier that can be originated from a `$var:ident` variable or from a token tree.
fn extract_ident<'a>(
dcx: &'a DiagCtxt,
dcx: DiagCtxtHandle<'a>,
ident: Ident,
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
) -> PResult<'a, String> {

View file

@ -522,7 +522,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
let message = rustc_errors::DiagMessage::from(diagnostic.message);
let mut diag: Diag<'_, ()> =
Diag::new(&self.psess().dcx, diagnostic.level.to_internal(), message);
Diag::new(self.psess().dcx(), diagnostic.level.to_internal(), message);
diag.span(MultiSpan::from_spans(diagnostic.spans));
for child in diagnostic.children {
// This message comes from another diagnostic, and we are just reconstructing the

View file

@ -567,8 +567,8 @@ declare_features! (
(unstable, optimize_attribute, "1.34.0", Some(54882)),
/// Allows postfix match `expr.match { ... }`
(unstable, postfix_match, "1.79.0", Some(121618)),
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.
(incomplete, precise_capturing, "1.79.0", Some(123432)),
/// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args.
(unstable, precise_capturing, "1.79.0", Some(123432)),
/// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.

View file

@ -463,6 +463,7 @@ pub enum TraitBoundModifier {
pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
Outlives(&'hir Lifetime),
Use(&'hir [PreciseCapturingArg<'hir>], Span),
}
impl GenericBound<'_> {
@ -477,6 +478,7 @@ impl GenericBound<'_> {
match self {
GenericBound::Trait(t, ..) => t.span,
GenericBound::Outlives(l) => l.ident.span,
GenericBound::Use(_, span) => *span,
}
}
}
@ -2689,8 +2691,6 @@ pub struct OpaqueTy<'hir> {
/// originating from a trait method. This makes it so that the opaque is
/// lowered as an associated type.
pub in_trait: bool,
/// List of arguments captured via `impl use<'a, P, ...> Trait` syntax.
pub precise_capturing_args: Option<(&'hir [PreciseCapturingArg<'hir>], Span)>,
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]

View file

@ -532,15 +532,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
try_visit!(visitor.visit_ty(ty));
try_visit!(visitor.visit_generics(generics));
}
ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, precise_capturing_args, .. }) => {
ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => {
try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(walk_generics(visitor, generics));
walk_list!(visitor, visit_param_bound, bounds);
if let Some((precise_capturing_args, _)) = precise_capturing_args {
for arg in precise_capturing_args {
try_visit!(visitor.visit_precise_capturing_arg(arg));
}
}
}
ItemKind::Enum(ref enum_definition, ref generics) => {
try_visit!(visitor.visit_generics(generics));
@ -1147,6 +1142,10 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(
match *bound {
GenericBound::Trait(ref typ, _modifier) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
GenericBound::Use(args, _) => {
walk_list!(visitor, visit_precise_capturing_arg, args);
V::Result::output()
}
}
}

View file

@ -481,9 +481,12 @@ fn sanity_check_found_hidden_type<'tcx>(
/// 2. Checking that all lifetimes that are implicitly captured are mentioned.
/// 3. Asserting that all parameters mentioned in the captures list are invariant.
fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
let hir::OpaqueTy { precise_capturing_args, .. } =
let hir::OpaqueTy { bounds, .. } =
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
let Some((precise_capturing_args, _)) = precise_capturing_args else {
let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
hir::GenericBound::Use(bounds, ..) => Some(bounds),
_ => None,
}) else {
// No precise capturing args; nothing to validate
return;
};

View file

@ -63,7 +63,7 @@ fn handle_static_mut_ref(
} else {
(errors::StaticMutRefSugg::Shared { span, var }, "shared")
};
tcx.sess.psess.dcx.emit_err(errors::StaticMutRef { span, sugg, shared });
tcx.dcx().emit_err(errors::StaticMutRef { span, sugg, shared });
} else {
let (sugg, shared) = if mutable == Mutability::Mut {
(errors::RefOfMutStaticSugg::Mut { span, var }, "mutable")

View file

@ -403,74 +403,56 @@ fn emit_orphan_check_error<'tcx>(
match *ty.kind() {
ty::Slice(_) => {
if is_foreign {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsForeign { span },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
} else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "slices" },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsName {
span,
name: "slices",
});
}
}
ty::Array(..) => {
if is_foreign {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsForeign { span },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
} else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "arrays" },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsName {
span,
name: "arrays",
});
}
}
ty::Tuple(..) => {
if is_foreign {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsForeign { span },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
} else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "tuples" },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsName {
span,
name: "tuples",
});
}
}
ty::Alias(ty::Opaque, ..) => {
diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
diag.subdiagnostic(errors::OnlyCurrentTraitsOpaque { span });
}
ty::RawPtr(ptr_ty, mutbl) => {
if !trait_ref.self_ty().has_param() {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsPointerSugg {
wrapper_span: impl_.self_ty.span,
struct_span: item.span.shrink_to_lo(),
mut_key: mutbl.prefix_str(),
ptr_ty,
},
);
diag.subdiagnostic(errors::OnlyCurrentTraitsPointerSugg {
wrapper_span: impl_.self_ty.span,
struct_span: item.span.shrink_to_lo(),
mut_key: mutbl.prefix_str(),
ptr_ty,
});
}
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsPointer { span, pointer: ty },
);
diag.subdiagnostic(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
}
ty::Adt(adt_def, _) => {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsAdt {
span,
name: tcx.def_path_str(adt_def.did()),
},
);
diag.subdiagnostic(errors::OnlyCurrentTraitsAdt {
span,
name: tcx.def_path_str(adt_def.did()),
});
}
_ => {
diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsTy { span, ty });
diag.subdiagnostic(errors::OnlyCurrentTraitsTy { span, ty });
}
}
}

View file

@ -2,7 +2,7 @@
use crate::fluent_generated as fluent;
use rustc_errors::{
codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level, MultiSpan,
codes::*, Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan,
};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
@ -424,7 +424,7 @@ pub struct MissingTypeParams {
// Manual implementation of `Diagnostic` to be able to call `span_to_snippet`.
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams {
#[track_caller]
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let mut err = Diag::new(dcx, level, fluent::hir_analysis_missing_type_params);
err.span(self.span);
err.code(E0393);

View file

@ -178,6 +178,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
lifetime.ident.span,
);
}
hir::GenericBound::Use(..) => {
// We don't actually lower `use` into the type layer.
}
}
}
}

View file

@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir;
use rustc_hir::{
BindingMode, ByRef, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId,
LifetimeParamKind, Node, PatKind, RangeEnd, Term, TraitBoundModifier,
LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TraitBoundModifier,
};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, Symbol};
@ -2100,10 +2100,24 @@ impl<'a> State<'a> {
GenericBound::Outlives(lt) => {
self.print_lifetime(lt);
}
GenericBound::Use(args, _) => {
self.word("use <");
self.commasep(Inconsistent, args, |s, arg| s.print_precise_capturing_arg(*arg));
self.word(">");
}
}
}
}
fn print_precise_capturing_arg(&mut self, arg: PreciseCapturingArg<'_>) {
match arg {
PreciseCapturingArg::Lifetime(lt) => self.print_lifetime(lt),
PreciseCapturingArg::Param(arg) => self.print_ident(arg.ident),
}
}
fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) {
if !generic_params.is_empty() {
self.word("<");

View file

@ -246,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let semi = expr.span.shrink_to_hi().with_hi(semi_span.hi());
let sugg = crate::errors::RemoveSemiForCoerce { expr: expr.span, ret, semi };
diag.subdiagnostic(self.dcx(), sugg);
diag.subdiagnostic(sugg);
}
/// When the previously checked expression (the scrutinee) diverges,

View file

@ -1005,25 +1005,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
if let Some((deref_ty, _)) = derefed {
// Give a note about what the expr derefs to.
if deref_ty != self.expr_ty.peel_refs() {
err.subdiagnostic(
fcx.dcx(),
errors::DerefImplsIsEmpty {
span: self.expr_span,
deref_ty: fcx.ty_to_string(deref_ty),
},
);
err.subdiagnostic(errors::DerefImplsIsEmpty {
span: self.expr_span,
deref_ty: fcx.ty_to_string(deref_ty),
});
}
// Create a multipart suggestion: add `!` and `.is_empty()` in
// place of the cast.
err.subdiagnostic(
fcx.dcx(),
errors::UseIsEmpty {
lo: self.expr_span.shrink_to_lo(),
hi: self.span.with_lo(self.expr_span.hi()),
expr_ty: fcx.ty_to_string(self.expr_ty),
},
);
err.subdiagnostic(errors::UseIsEmpty {
lo: self.expr_span.shrink_to_lo(),
hi: self.span.with_lo(self.expr_span.hi()),
expr_ty: fcx.ty_to_string(self.expr_ty),
});
}
}
}

View file

@ -1782,20 +1782,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
let rpid_def_span = fcx.tcx.def_span(rpit_def_id);
err.subdiagnostic(
fcx.tcx.dcx(),
SuggestBoxingForReturnImplTrait::ChangeReturnType {
start_sp: rpid_def_span.with_hi(rpid_def_span.lo() + BytePos(4)),
end_sp: rpid_def_span.shrink_to_hi(),
},
);
err.subdiagnostic(SuggestBoxingForReturnImplTrait::ChangeReturnType {
start_sp: rpid_def_span.with_hi(rpid_def_span.lo() + BytePos(4)),
end_sp: rpid_def_span.shrink_to_hi(),
});
let (starts, ends) =
arm_spans.map(|span| (span.shrink_to_lo(), span.shrink_to_hi())).unzip();
err.subdiagnostic(
fcx.tcx.dcx(),
SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends },
);
err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends });
}
fn report_return_mismatched_types<'a>(

View file

@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(sp) =
tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp)
{
err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp));
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
oprnd_t = Ty::new_error(tcx, err.emit());
}
@ -2018,10 +2018,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.shrink_to_hi()
.to(range_end.span);
err.subdiagnostic(
self.dcx(),
TypeMismatchFruTypo { expr_span: range_start.span, fru_span, expr },
);
err.subdiagnostic(TypeMismatchFruTypo { expr_span: range_start.span, fru_span, expr });
// Suppress any range expr type mismatches
self.dcx().try_steal_replace_and_emit_err(

View file

@ -1435,7 +1435,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
// The user provided `ptr::null()`, but the function expects
// `ptr::null_mut()`.
err.subdiagnostic(self.dcx(), SuggestPtrNullMut { span: arg.span });
err.subdiagnostic(SuggestPtrNullMut { span: arg.span });
}
}

View file

@ -5,14 +5,13 @@ mod checks;
mod inspect_obligations;
mod suggestions;
use rustc_errors::ErrorGuaranteed;
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
use crate::coercion::DynamicCoerceMany;
use crate::fallback::DivergingFallbackBehavior;
use crate::fn_ctxt::checks::DivergingBlockBehavior;
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt};
use hir::def_id::CRATE_DEF_ID;
use rustc_errors::DiagCtxt;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
@ -145,8 +144,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
pub(crate) fn dcx(&self) -> &'tcx DiagCtxt {
self.tcx.dcx()
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.infcx.dcx()
}
pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {

View file

@ -460,16 +460,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// but those checks need to be a bit more delicate and the benefit is diminishing.
if self.can_eq(self.param_env, found_ty_inner, peeled) && error_tys_equate_as_ref {
let sugg = prefix_wrap(".as_ref()");
err.subdiagnostic(
self.dcx(),
errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
},
);
err.subdiagnostic(errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
});
return true;
} else if let Some((deref_ty, _)) =
self.autoderef(expr.span, found_ty_inner).silence_errors().nth(1)
@ -477,16 +474,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& error_tys_equate_as_ref
{
let sugg = prefix_wrap(".as_deref()");
err.subdiagnostic(
self.dcx(),
errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
},
);
err.subdiagnostic(errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
});
return true;
} else if let ty::Adt(adt, _) = found_ty_inner.peel_refs().kind()
&& self.tcx.is_lang_item(adt.did(), LangItem::String)
@ -573,7 +567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
end: span.shrink_to_hi(),
},
};
err.subdiagnostic(self.dcx(), suggest_boxing);
err.subdiagnostic(suggest_boxing);
true
} else {
@ -814,28 +808,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match &fn_decl.output {
&hir::FnRetTy::DefaultReturn(span) if expected.is_unit() && !can_suggest => {
// `fn main()` must return `()`, do not suggest changing return type
err.subdiagnostic(self.dcx(), errors::ExpectedReturnTypeLabel::Unit { span });
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Unit { span });
return true;
}
&hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => {
if let Some(found) = found.make_suggestable(self.tcx, false, None) {
err.subdiagnostic(
self.dcx(),
errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() },
);
err.subdiagnostic(errors::AddReturnTypeSuggestion::Add {
span,
found: found.to_string(),
});
return true;
} else if let Some(sugg) = suggest_impl_trait(self, self.param_env, found) {
err.subdiagnostic(
self.dcx(),
errors::AddReturnTypeSuggestion::Add { span, found: sugg },
);
err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span, found: sugg });
return true;
} else {
// FIXME: if `found` could be `impl Iterator` we should suggest that.
err.subdiagnostic(
self.dcx(),
errors::AddReturnTypeSuggestion::MissingHere { span },
);
err.subdiagnostic(errors::AddReturnTypeSuggestion::MissingHere { span });
return true;
}
}
@ -856,19 +844,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!(?found);
if found.is_suggestable(self.tcx, false) {
if ty.span.is_empty() {
err.subdiagnostic(
self.dcx(),
errors::AddReturnTypeSuggestion::Add {
span: ty.span,
found: found.to_string(),
},
);
err.subdiagnostic(errors::AddReturnTypeSuggestion::Add {
span: ty.span,
found: found.to_string(),
});
return true;
} else {
err.subdiagnostic(
self.dcx(),
errors::ExpectedReturnTypeLabel::Other { span: ty.span, expected },
);
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other {
span: ty.span,
expected,
});
}
}
} else {
@ -883,10 +868,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = self.normalize(hir_ty.span, ty);
let ty = self.tcx.instantiate_bound_regions_with_erased(ty);
if self.can_coerce(expected, ty) {
err.subdiagnostic(
self.dcx(),
errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected },
);
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other {
span: hir_ty.span,
expected,
});
self.try_suggest_return_impl_trait(err, expected, found, fn_id);
self.note_caller_chooses_ty_for_ty_param(err, expected, found);
return true;
@ -905,13 +890,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
found: Ty<'tcx>,
) {
if let ty::Param(expected_ty_as_param) = expected.kind() {
diag.subdiagnostic(
self.dcx(),
errors::NoteCallerChoosesTyForTyParam {
ty_param_name: expected_ty_as_param.name,
found_ty: found,
},
);
diag.subdiagnostic(errors::NoteCallerChoosesTyForTyParam {
ty_param_name: expected_ty_as_param.name,
found_ty: found,
});
}
}
@ -1136,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let sp = self.tcx.sess.source_map().start_point(expr.span).with_parent(None);
if let Some(sp) = self.tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) {
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp));
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
true
} else {
false
@ -1250,7 +1232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
return false;
};
diag.subdiagnostic(self.dcx(), subdiag);
diag.subdiagnostic(subdiag);
return true;
}
}

View file

@ -2788,32 +2788,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
errors: Vec<FulfillmentError<'tcx>>,
suggest_derive: bool,
) {
let all_local_types_needing_impls =
errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
match pred.self_ty().kind() {
ty::Adt(def, _) => def.did().is_local(),
_ => false,
}
}
_ => false,
});
let mut preds: Vec<_> = errors
let preds: Vec<_> = errors
.iter()
.filter_map(|e| match e.obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred),
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
match pred.self_ty().kind() {
ty::Adt(_, _) => Some(pred),
_ => None,
}
}
_ => None,
})
.collect();
preds.sort_by_key(|pred| pred.trait_ref.to_string());
let def_ids = preds
// Note for local items and foreign items respectively.
let (mut local_preds, mut foreign_preds): (Vec<_>, Vec<_>) =
preds.iter().partition(|&pred| {
if let ty::Adt(def, _) = pred.self_ty().kind() {
def.did().is_local()
} else {
false
}
});
local_preds.sort_by_key(|pred: &&ty::TraitPredicate<'_>| pred.trait_ref.to_string());
let local_def_ids = local_preds
.iter()
.filter_map(|pred| match pred.self_ty().kind() {
ty::Adt(def, _) => Some(def.did()),
_ => None,
})
.collect::<FxIndexSet<_>>();
let mut spans: MultiSpan = def_ids
let mut local_spans: MultiSpan = local_def_ids
.iter()
.filter_map(|def_id| {
let span = self.tcx.def_span(*def_id);
@ -2821,11 +2827,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
.collect::<Vec<_>>()
.into();
for pred in &preds {
for pred in &local_preds {
match pred.self_ty().kind() {
ty::Adt(def, _) if def.did().is_local() => {
spans.push_span_label(
ty::Adt(def, _) => {
local_spans.push_span_label(
self.tcx.def_span(def.did()),
format!("must implement `{}`", pred.trait_ref.print_trait_sugared()),
);
@ -2833,24 +2838,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => {}
}
}
if all_local_types_needing_impls && spans.primary_span().is_some() {
let msg = if preds.len() == 1 {
if local_spans.primary_span().is_some() {
let msg = if local_preds.len() == 1 {
format!(
"an implementation of `{}` might be missing for `{}`",
preds[0].trait_ref.print_trait_sugared(),
preds[0].self_ty()
local_preds[0].trait_ref.print_trait_sugared(),
local_preds[0].self_ty()
)
} else {
format!(
"the following type{} would have to `impl` {} required trait{} for this \
operation to be valid",
pluralize!(def_ids.len()),
if def_ids.len() == 1 { "its" } else { "their" },
pluralize!(preds.len()),
pluralize!(local_def_ids.len()),
if local_def_ids.len() == 1 { "its" } else { "their" },
pluralize!(local_preds.len()),
)
};
err.span_note(spans, msg);
err.span_note(local_spans, msg);
}
foreign_preds.sort_by_key(|pred: &&ty::TraitPredicate<'_>| pred.trait_ref.to_string());
let foreign_def_ids = foreign_preds
.iter()
.filter_map(|pred| match pred.self_ty().kind() {
ty::Adt(def, _) => Some(def.did()),
_ => None,
})
.collect::<FxIndexSet<_>>();
let mut foreign_spans: MultiSpan = foreign_def_ids
.iter()
.filter_map(|def_id| {
let span = self.tcx.def_span(*def_id);
if span.is_dummy() { None } else { Some(span) }
})
.collect::<Vec<_>>()
.into();
for pred in &foreign_preds {
match pred.self_ty().kind() {
ty::Adt(def, _) => {
foreign_spans.push_span_label(
self.tcx.def_span(def.did()),
format!("not implement `{}`", pred.trait_ref.print_trait_sugared()),
);
}
_ => {}
}
}
if foreign_spans.primary_span().is_some() {
let msg = if foreign_preds.len() == 1 {
format!(
"the foreign item type `{}` doesn't implement `{}`",
foreign_preds[0].self_ty(),
foreign_preds[0].trait_ref.print_trait_sugared()
)
} else {
format!(
"the foreign item type{} {} implement required trait{} for this \
operation to be valid",
pluralize!(foreign_def_ids.len()),
if foreign_def_ids.len() > 1 { "don't" } else { "doesn't" },
pluralize!(foreign_preds.len()),
)
};
err.span_note(foreign_spans, msg);
}
let preds: Vec<_> = errors
@ -3729,22 +3779,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if impls_trait(trait_info.def_id) {
self.suggest_valid_traits(err, item_name, vec![trait_info.def_id], false);
} else {
err.subdiagnostic(
self.dcx(),
CandidateTraitNote {
span: self.tcx.def_span(trait_info.def_id),
trait_name: self.tcx.def_path_str(trait_info.def_id),
item_name,
action_or_ty: if trait_missing_method {
"NONE".to_string()
} else {
param_type.map_or_else(
|| "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
|p| p.to_string(),
)
},
err.subdiagnostic(CandidateTraitNote {
span: self.tcx.def_span(trait_info.def_id),
trait_name: self.tcx.def_path_str(trait_info.def_id),
item_name,
action_or_ty: if trait_missing_method {
"NONE".to_string()
} else {
param_type.map_or_else(
|| "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
|p| p.to_string(),
)
},
);
});
}
}
trait_infos => {

View file

@ -820,7 +820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If the previous expression was a block expression, suggest parentheses
// (turning this into a binary subtraction operation instead.)
// for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp));
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
} else {
match actual.kind() {
Uint(_) if op == hir::UnOp::Neg => {

View file

@ -61,8 +61,8 @@ use crate::traits::{
use crate::infer::relate::{self, RelateResult, TypeRelation};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
ErrorGuaranteed, IntoDiagArg, StringPart,
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxtHandle,
DiagStyledString, ErrorGuaranteed, IntoDiagArg, StringPart,
};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
@ -139,8 +139,8 @@ pub struct TypeErrCtxt<'a, 'tcx> {
}
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub fn dcx(&self) -> &'tcx DiagCtxt {
self.infcx.tcx.dcx()
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.infcx.dcx()
}
/// This is just to avoid a potential footgun of accidentally
@ -892,7 +892,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
arm_ty,
arm_span,
) {
err.subdiagnostic(self.dcx(), subdiag);
err.subdiagnostic(subdiag);
}
}
},
@ -918,7 +918,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
else_ty,
else_span,
) {
err.subdiagnostic(self.dcx(), subdiag);
err.subdiagnostic(subdiag);
}
}
ObligationCauseCode::LetElse => {

View file

@ -369,7 +369,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
trait_predicates: trait_predicates.join(", "),
}
};
err.subdiagnostic(self.dcx(), suggestion);
err.subdiagnostic(suggestion);
}
pub(super) fn report_placeholder_failure(

View file

@ -121,7 +121,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span_low: cause.span.shrink_to_lo(),
span_high: cause.span.shrink_to_hi(),
};
diag.subdiagnostic(self.dcx(), sugg);
diag.subdiagnostic(sugg);
}
_ => {
// More than one matching variant.
@ -130,7 +130,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause_span: cause.span,
compatible_variants,
};
diag.subdiagnostic(self.dcx(), sugg);
diag.subdiagnostic(sugg);
}
}
}
@ -202,10 +202,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
},
(_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => {
// FIXME: Seems like we can't have a suggestion and a note with different spans in a single subdiagnostic
diag.subdiagnostic(
self.dcx(),
ConsiderAddingAwait::FutureSugg { span: exp_span.shrink_to_hi() },
);
diag.subdiagnostic(ConsiderAddingAwait::FutureSugg {
span: exp_span.shrink_to_hi(),
});
Some(ConsiderAddingAwait::FutureSuggNote { span: exp_span })
}
(Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
@ -233,7 +232,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_ => None,
};
if let Some(subdiag) = subdiag {
diag.subdiagnostic(self.dcx(), subdiag);
diag.subdiagnostic(subdiag);
}
}
@ -269,7 +268,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} else {
return;
};
diag.subdiagnostic(self.dcx(), suggestion);
diag.subdiagnostic(suggestion);
}
}
}
@ -401,15 +400,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
(true, true) => {
diag.subdiagnostic(self.dcx(), FnItemsAreDistinct);
diag.subdiagnostic(FnItemsAreDistinct);
FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig }
}
(false, false) => {
diag.subdiagnostic(self.dcx(), FnItemsAreDistinct);
diag.subdiagnostic(FnItemsAreDistinct);
FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig }
}
};
diag.subdiagnostic(self.dcx(), sugg);
diag.subdiagnostic(sugg);
}
(ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => {
let expected_sig =
@ -418,7 +417,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2));
if self.same_type_modulo_infer(*expected_sig, *found_sig) {
diag.subdiagnostic(self.dcx(), FnUniqTypes);
diag.subdiagnostic(FnUniqTypes);
}
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
@ -447,7 +446,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
};
diag.subdiagnostic(self.dcx(), sug);
diag.subdiagnostic(sug);
}
(ty::FnDef(did, args), ty::FnPtr(sig)) => {
let expected_sig =
@ -466,7 +465,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
format!("{fn_name} as {found_sig}")
};
diag.subdiagnostic(self.dcx(), FnConsiderCasting { casting });
diag.subdiagnostic(FnConsiderCasting { casting });
}
_ => {
return;
@ -889,7 +888,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let diag = self.consider_returning_binding_diag(blk, expected_ty);
match diag {
Some(diag) => {
err.subdiagnostic(self.dcx(), diag);
err.subdiagnostic(diag);
true
}
None => false,

View file

@ -4,13 +4,14 @@ pub use lexical_region_resolve::RegionResolutionError;
pub use relate::combine::CombineFields;
pub use relate::combine::PredicateEmittingRelation;
pub use relate::StructurallyRelateAliases;
use rustc_errors::DiagCtxtHandle;
pub use rustc_macros::{TypeFoldable, TypeVisitable};
pub use rustc_middle::ty::IntVarValue;
pub use BoundRegionConversionTime::*;
pub use RegionVariableOrigin::*;
pub use SubregionOrigin::*;
use crate::infer::relate::{Relate, RelateResult};
use crate::infer::relate::RelateResult;
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
use error_reporting::TypeErrCtxt;
use free_regions::RegionRelations;
@ -23,7 +24,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::undo_log::Rollback;
use rustc_data_structures::unify as ut;
use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed};
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::extension;
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
@ -44,7 +45,7 @@ use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use rustc_span::Span;
use snapshot::undo_log::InferCtxtUndoLogs;
use std::cell::{Cell, RefCell};
use std::fmt;
@ -334,149 +335,6 @@ pub struct InferCtxt<'tcx> {
pub obligation_inspector: Cell<Option<ObligationInspector<'tcx>>>,
}
impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
type Interner = TyCtxt<'tcx>;
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn universe_of_ty(&self, vid: TyVid) -> Option<ty::UniverseIndex> {
// FIXME(BoxyUwU): this is kind of jank and means that printing unresolved
// ty infers will give you the universe of the var it resolved to not the universe
// it actually had. It also means that if you have a `?0.1` and infer it to `u8` then
// try to print out `?0.1` it will just print `?0`.
match self.probe_ty_var(vid) {
Err(universe) => Some(universe),
Ok(_) => None,
}
}
fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
Err(universe) => Some(universe),
Ok(_) => None,
}
}
fn universe_of_ct(&self, ct: ConstVid) -> Option<ty::UniverseIndex> {
// Same issue as with `universe_of_ty`
match self.probe_const_var(ct) {
Err(universe) => Some(universe),
Ok(_) => None,
}
}
fn root_ty_var(&self, var: TyVid) -> TyVid {
self.root_var(var)
}
fn root_const_var(&self, var: ConstVid) -> ConstVid {
self.root_const_var(var)
}
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
match self.probe_ty_var(vid) {
Ok(ty) => ty,
Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
}
}
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'tcx> {
self.opportunistic_resolve_int_var(vid)
}
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'tcx> {
self.opportunistic_resolve_float_var(vid)
}
fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> ty::Const<'tcx> {
match self.probe_const_var(vid) {
Ok(ct) => ct,
Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
}
}
fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> ty::Const<'tcx> {
match self.probe_effect_var(vid) {
Some(ct) => ct,
None => {
ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)))
}
}
}
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
}
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
self.defining_opaque_types
}
fn next_ty_infer(&self) -> Ty<'tcx> {
self.next_ty_var(DUMMY_SP)
}
fn next_const_infer(&self) -> ty::Const<'tcx> {
self.next_const_var(DUMMY_SP)
}
fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
self.fresh_args_for_item(DUMMY_SP, def_id)
}
fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
&self,
value: ty::Binder<'tcx, T>,
) -> T {
self.instantiate_binder_with_fresh_vars(
DUMMY_SP,
BoundRegionConversionTime::HigherRankedType,
value,
)
}
fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
&self,
value: ty::Binder<'tcx, T>,
f: impl FnOnce(T) -> U,
) -> U {
self.enter_forall(value, f)
}
fn relate<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
variance: ty::Variance,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
}
fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env)
.eq_structurally_relating_aliases_no_trace(lhs, rhs)
}
fn resolve_vars_if_possible<T>(&self, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
self.resolve_vars_if_possible(value)
}
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
self.probe(|_| probe())
}
}
/// See the `error_reporting` module for more details.
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
pub enum ValuePairs<'tcx> {
@ -826,10 +684,14 @@ impl<'tcx> InferOk<'tcx, ()> {
}
impl<'tcx> InferCtxt<'tcx> {
pub fn dcx(&self) -> &'tcx DiagCtxt {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.tcx.dcx()
}
pub fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
self.defining_opaque_types
}
pub fn next_trait_solver(&self) -> bool {
self.next_trait_solver
}

View file

@ -9,7 +9,7 @@ use rustc_data_structures::jobserver;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_errors::registry::Registry;
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
use rustc_lint::LintStore;
use rustc_middle::ty;
use rustc_middle::ty::CurrentGcx;
@ -46,7 +46,7 @@ pub struct Compiler {
}
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
cfgs.into_iter()
.map(|s| {
let psess = ParseSess::with_silent_emitter(
@ -105,7 +105,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
}
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> CheckCfg {
// If any --check-cfg is passed then exhaustive_values and exhaustive_names
// are enabled by default.
let exhaustive_names = !specs.is_empty();
@ -451,12 +451,12 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
codegen_backend.init(&sess);
let cfg = parse_cfg(&sess.dcx(), config.crate_cfg);
let cfg = parse_cfg(sess.dcx(), config.crate_cfg);
let mut cfg = config::build_configuration(&sess, cfg);
util::add_configuration(&mut cfg, &mut sess, &*codegen_backend);
sess.psess.config = cfg;
let mut check_cfg = parse_check_cfg(&sess.dcx(), config.crate_check_cfg);
let mut check_cfg = parse_check_cfg(sess.dcx(), config.crate_check_cfg);
check_cfg.fill_well_known(&sess.target);
sess.psess.check_config = check_cfg;
@ -529,7 +529,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
}
pub fn try_print_query_stack(
dcx: &DiagCtxt,
dcx: DiagCtxtHandle<'_>,
num_frames: Option<usize>,
file: Option<std::fs::File>,
) {

View file

@ -70,7 +70,7 @@ where
Arc::default(),
Default::default(),
);
let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg"));
let cfg = parse_cfg(sess.dcx(), matches.opt_strs("cfg"));
let cfg = build_configuration(&sess, cfg);
f(sess, cfg)
});
@ -761,7 +761,7 @@ fn test_unstable_options_tracking_hash() {
})
);
tracked!(codegen_backend, Some("abc".to_string()));
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc });
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc, no_mir_spans: true });
tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true);

View file

@ -11,7 +11,7 @@ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::{sym, BytePos, Span};
use rustc_span::{sym, Span};
use crate::fluent_generated as fluent;
use crate::{LateContext, LateLintPass};
@ -53,7 +53,7 @@ declare_lint! {
/// while the `impl Display` is live.
///
/// To fix this, we can explicitly state that the `impl Display` doesn't
/// capture any lifetimes, using `impl use<> Display`.
/// capture any lifetimes, using `impl Display + use<>`.
pub IMPL_TRAIT_OVERCAPTURES,
Allow,
"`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
@ -79,7 +79,7 @@ declare_lint! {
/// # #![feature(precise_capturing, lifetime_capture_rules_2024)]
/// # #![allow(incomplete_features)]
/// # #![deny(impl_trait_redundant_captures)]
/// fn test<'a>(x: &'a i32) -> impl use<'a> Sized { x }
/// fn test<'a>(x: &'a i32) -> impl Sized + use<'a> { x }
/// ```
///
/// {{produces}}
@ -249,7 +249,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
// If we have uncaptured args, and if the opaque doesn't already have
// `use<>` syntax on it, and we're < edition 2024, then warn the user.
if !new_capture_rules
&& opaque.precise_capturing_args.is_none()
&& !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..)))
&& !uncaptured_spans.is_empty()
{
let suggestion = if let Ok(snippet) =
@ -268,8 +268,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
// Make sure that we're not trying to name any APITs
if generics.iter().all(|name| !name.starts_with("impl ")) {
Some((
format!(" use<{}>", generics.join(", ")),
opaque_span.with_lo(opaque_span.lo() + BytePos(4)).shrink_to_lo(),
format!(" + use<{}>", generics.join(", ")),
opaque_span.shrink_to_hi(),
))
} else {
None
@ -294,7 +294,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
// have no uncaptured args, then we should warn to the user that
// it's redundant to capture all args explicitly.
else if new_capture_rules
&& let Some((captured_args, capturing_span)) = opaque.precise_capturing_args
&& let Some((captured_args, capturing_span)) =
opaque.bounds.iter().find_map(|bound| match *bound {
hir::GenericBound::Use(a, s) => Some((a, s)),
_ => None,
})
{
let mut explicitly_captured = UnordSet::default();
for arg in captured_args {

View file

@ -1405,7 +1405,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
diag.note(fluent::lint_macro_to_change);
}
if let Some(cargo_update) = cargo_update {
diag.subdiagnostic(&diag.dcx, cargo_update);
diag.subdiagnostic(cargo_update);
}
if has_trait {
@ -1471,7 +1471,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
diag.note(fluent::lint_non_local_definitions_deprecation);
if let Some(cargo_update) = cargo_update {
diag.subdiagnostic(&diag.dcx, cargo_update);
diag.subdiagnostic(cargo_update);
}
}
}
@ -1957,7 +1957,7 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
diag.note(note.to_string());
}
if let Some(sugg) = self.suggestion {
diag.subdiagnostic(diag.dcx, sugg);
diag.subdiagnostic(sugg);
}
}
}

View file

@ -1268,7 +1268,7 @@ impl EarlyLintPass for UnusedParens {
ast::TyKind::TraitObject(..) => {}
ast::TyKind::BareFn(b)
if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
ast::TyKind::ImplTrait(_, bounds, _) if bounds.len() > 1 => {}
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
_ => {
let spans = if !ty.span.from_expansion() {
r.span

View file

@ -78,7 +78,7 @@ impl<'a> DiagnosticDerive<'a> {
#[track_caller]
fn into_diag(
self,
dcx: &'_sess rustc_errors::DiagCtxt,
dcx: rustc_errors::DiagCtxtHandle<'_sess>,
level: rustc_errors::Level
) -> rustc_errors::Diag<'_sess, G> {
#implementation

View file

@ -335,7 +335,7 @@ impl DiagnosticDeriveVariantBuilder {
}
}
(Meta::Path(_), "subdiagnostic") => {
return Ok(quote! { diag.subdiagnostic(diag.dcx, #binding); });
return Ok(quote! { diag.subdiagnostic(#binding); });
}
_ => (),
}

View file

@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard};
use rustc_errors::DiagCtxt;
use rustc_errors::DiagCtxtHandle;
use rustc_expand::base::SyntaxExtension;
use rustc_fs_util::try_canonicalize;
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
@ -91,8 +91,8 @@ impl<'a, 'tcx> std::ops::Deref for CrateLoader<'a, 'tcx> {
}
impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
fn dcx(&self) -> &'tcx DiagCtxt {
&self.tcx.dcx()
fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.tcx.dcx()
}
}

View file

@ -3,7 +3,7 @@ use std::{
path::{Path, PathBuf},
};
use rustc_errors::{codes::*, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::{codes::*, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{sym, Span, Symbol};
use rustc_target::spec::{PanicStrategy, TargetTriple};
@ -503,7 +503,7 @@ pub(crate) struct MultipleCandidates {
}
impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_multiple_candidates);
diag.arg("crate_name", self.crate_name);
diag.arg("flavor", self.flavor);
@ -602,7 +602,7 @@ pub struct InvalidMetadataFiles {
impl<G: EmissionGuarantee> Diagnostic<'_, G> for InvalidMetadataFiles {
#[track_caller]
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_invalid_meta_files);
diag.arg("crate_name", self.crate_name);
diag.arg("add_info", self.add_info);
@ -631,7 +631,7 @@ pub struct CannotFindCrate {
impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
#[track_caller]
fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_cannot_find_crate);
diag.arg("crate_name", self.crate_name);
diag.arg("current_crate", self.current_crate);

View file

@ -111,7 +111,7 @@ macro_rules! arena_types {
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
>,
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<rustc_middle::ty::TyCtxt<'tcx>>,
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
[] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
[] mod_child: rustc_middle::metadata::ModChild,

View file

@ -4,10 +4,10 @@
///
/// If you have a span available, you should use [`span_bug`] instead.
///
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxt::span_delayed_bug`]
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`]
/// may be useful.
///
/// [`DiagCtxt::span_delayed_bug`]: rustc_errors::DiagCtxt::span_delayed_bug
/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug
/// [`span_bug`]: crate::span_bug
#[macro_export]
macro_rules! bug {
@ -30,10 +30,10 @@ macro_rules! bug {
/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger
/// ICEs.
///
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxt::span_delayed_bug`]
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`]
/// may be useful.
///
/// [`DiagCtxt::span_delayed_bug`]: rustc_errors::DiagCtxt::span_delayed_bug
/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug
#[macro_export]
macro_rules! span_bug {
($span:expr, $msg:expr) => (

View file

@ -176,7 +176,7 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate
diag.arg("has_note", false);
}
if let Some(sub) = self.sub {
diag.subdiagnostic(diag.dcx, sub);
diag.subdiagnostic(sub);
}
}
}

View file

@ -52,7 +52,7 @@ impl AllocBytes for Box<[u8]> {
}
fn zeroed(size: Size, _align: Align) -> Option<Self> {
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes_usize()).ok()?;
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes().try_into().ok()?).ok()?;
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
let bytes = unsafe { bytes.assume_init() };
Some(bytes)
@ -323,7 +323,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
/// first call this function and then call write_scalar to fill in the right data.
pub fn uninit(size: Size, align: Align) -> Self {
match Self::uninit_inner(size, align, || {
panic!("Allocation::uninit called with panic_on_fail had allocation failure");
panic!(
"interpreter ran out of memory: cannot create allocation of {} bytes",
size.bytes()
);
}) {
Ok(x) => x,
Err(x) => x,

View file

@ -5,12 +5,12 @@ use rustc_type_ir as ir;
pub use rustc_type_ir::solve::*;
use crate::ty::{
self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
};
mod cache;
pub use cache::{CacheData, EvaluationCache};
pub use cache::EvaluationCache;
pub type Goal<'tcx, P> = ir::solve::Goal<TyCtxt<'tcx>, P>;
pub type QueryInput<'tcx, P> = ir::solve::QueryInput<TyCtxt<'tcx>, P>;
@ -19,17 +19,11 @@ pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>;
pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>;
/// Additional constraints returned on success.
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default)]
pub struct PredefinedOpaquesData<'tcx> {
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<'tcx>>);
pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>);
impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
type Target = PredefinedOpaquesData<'tcx>;
type Target = PredefinedOpaquesData<TyCtxt<'tcx>>;
fn deref(&self) -> &Self::Target {
&self.0

View file

@ -5,6 +5,8 @@ use rustc_data_structures::sync::Lock;
use rustc_query_system::cache::WithDepNode;
use rustc_query_system::dep_graph::DepNodeIndex;
use rustc_session::Limit;
use rustc_type_ir::solve::CacheData;
/// The trait solver cache used by `-Znext-solver`.
///
/// FIXME(@lcnr): link to some official documentation of how
@ -14,17 +16,9 @@ pub struct EvaluationCache<'tcx> {
map: Lock<FxHashMap<CanonicalInput<'tcx>, CacheEntry<'tcx>>>,
}
#[derive(Debug, PartialEq, Eq)]
pub struct CacheData<'tcx> {
pub result: QueryResult<'tcx>,
pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>>,
pub additional_depth: usize,
pub encountered_overflow: bool,
}
impl<'tcx> EvaluationCache<'tcx> {
impl<'tcx> rustc_type_ir::inherent::EvaluationCache<TyCtxt<'tcx>> for &'tcx EvaluationCache<'tcx> {
/// Insert a final result into the global cache.
pub fn insert(
fn insert(
&self,
tcx: TyCtxt<'tcx>,
key: CanonicalInput<'tcx>,
@ -48,7 +42,7 @@ impl<'tcx> EvaluationCache<'tcx> {
if cfg!(debug_assertions) {
drop(map);
let expected = CacheData { result, proof_tree, additional_depth, encountered_overflow };
let actual = self.get(tcx, key, [], Limit(additional_depth));
let actual = self.get(tcx, key, [], additional_depth);
if !actual.as_ref().is_some_and(|actual| expected == *actual) {
bug!("failed to lookup inserted element for {key:?}: {expected:?} != {actual:?}");
}
@ -59,13 +53,13 @@ impl<'tcx> EvaluationCache<'tcx> {
/// and handling root goals of coinductive cycles.
///
/// If this returns `Some` the cache result can be used.
pub fn get(
fn get(
&self,
tcx: TyCtxt<'tcx>,
key: CanonicalInput<'tcx>,
stack_entries: impl IntoIterator<Item = CanonicalInput<'tcx>>,
available_depth: Limit,
) -> Option<CacheData<'tcx>> {
available_depth: usize,
) -> Option<CacheData<TyCtxt<'tcx>>> {
let map = self.map.borrow();
let entry = map.get(&key)?;
@ -76,7 +70,7 @@ impl<'tcx> EvaluationCache<'tcx> {
}
if let Some(ref success) = entry.success {
if available_depth.value_within_limit(success.additional_depth) {
if Limit(available_depth).value_within_limit(success.additional_depth) {
let QueryData { result, proof_tree } = success.data.get(tcx);
return Some(CacheData {
result,
@ -87,12 +81,12 @@ impl<'tcx> EvaluationCache<'tcx> {
}
}
entry.with_overflow.get(&available_depth.0).map(|e| {
entry.with_overflow.get(&available_depth).map(|e| {
let QueryData { result, proof_tree } = e.get(tcx);
CacheData {
result,
proof_tree,
additional_depth: available_depth.0,
additional_depth: available_depth,
encountered_overflow: true,
}
})

View file

@ -205,6 +205,14 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
self.did()
}
fn is_struct(self) -> bool {
self.is_struct()
}
fn struct_tail_ty(self, interner: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
Some(interner.type_of(self.non_enum_variant().tail_opt()?.did))
}
fn is_phantom_data(self) -> bool {
self.is_phantom_data()
}
@ -212,7 +220,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
fn all_field_tys(
self,
tcx: TyCtxt<'tcx>,
) -> ty::EarlyBinder<'tcx, impl Iterator<Item = Ty<'tcx>>> {
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = Ty<'tcx>>> {
ty::EarlyBinder::bind(
self.all_fields().map(move |field| tcx.type_of(field.did).skip_binder()),
)

View file

@ -16,8 +16,8 @@ mod valtree;
pub use int::*;
pub use kind::*;
use rustc_span::Span;
use rustc_span::DUMMY_SP;
use rustc_span::{ErrorGuaranteed, Span};
pub use valtree::*;
pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
@ -176,6 +176,10 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
fn new_expr(interner: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Self {
Const::new_expr(interner, expr)
}
fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
Const::new_error(interner, guar)
}
}
impl<'tcx> Const<'tcx> {

View file

@ -47,7 +47,9 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work
#[cfg(parallel_compiler)]
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan};
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
@ -71,6 +73,7 @@ use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx}
use rustc_target::spec::abi;
use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::SolverMode;
use rustc_type_ir::TyKind::*;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo};
use tracing::{debug, instrument};
@ -89,46 +92,65 @@ use std::ops::{Bound, Deref};
impl<'tcx> Interner for TyCtxt<'tcx> {
type DefId = DefId;
type LocalDefId = LocalDefId;
type AdtDef = ty::AdtDef<'tcx>;
type GenericArgs = ty::GenericArgsRef<'tcx>;
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'tcx>;
type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
type BoundVarKind = ty::BoundVariableKind;
type CanonicalVars = CanonicalVarInfos<'tcx>;
type BoundVarKind = ty::BoundVariableKind;
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
fn mk_predefined_opaques_in_body(
self,
data: PredefinedOpaquesData<Self>,
) -> Self::PredefinedOpaques {
self.mk_predefined_opaques_in_body(data)
}
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
type ExternalConstraints = ExternalConstraints<'tcx>;
type CanonicalGoalEvaluationStepRef =
&'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>;
type CanonicalVars = CanonicalVarInfos<'tcx>;
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
type ExternalConstraints = ExternalConstraints<'tcx>;
fn mk_external_constraints(
self,
data: ExternalConstraintsData<Self>,
) -> ExternalConstraints<'tcx> {
self.mk_external_constraints(data)
}
type DepNodeIndex = DepNodeIndex;
fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
}
type Ty = Ty<'tcx>;
type Tys = &'tcx List<Ty<'tcx>>;
type FnInputTys = &'tcx [Ty<'tcx>];
type ParamTy = ParamTy;
type BoundTy = ty::BoundTy;
type PlaceholderTy = ty::PlaceholderType;
type PlaceholderTy = ty::PlaceholderType;
type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
type AllocId = crate::mir::interpret::AllocId;
type AllocId = crate::mir::interpret::AllocId;
type Pat = Pattern<'tcx>;
type Safety = hir::Safety;
type Abi = abi::Abi;
type Const = ty::Const<'tcx>;
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
type BoundConst = ty::BoundVar;
type ValueConst = ty::ValTree<'tcx>;
type ExprConst = ty::Expr<'tcx>;
type Region = Region<'tcx>;
type EarlyParamRegion = ty::EarlyParamRegion;
type LateParamRegion = ty::LateParamRegion;
type BoundRegion = ty::BoundRegion;
@ -136,15 +158,21 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;
type Clause = Clause<'tcx>;
type Clauses = ty::Clauses<'tcx>;
fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_abstract_consts(t)
type EvaluationCache = &'tcx solve::EvaluationCache<'tcx>;
fn evaluation_cache(self, mode: SolverMode) -> &'tcx solve::EvaluationCache<'tcx> {
match mode {
SolverMode::Normal => &self.new_solver_evaluation_cache,
SolverMode::Coherence => &self.new_solver_coherence_evaluation_cache,
}
}
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_abstract_consts(t)
}
type GenericsOf = &'tcx ty::Generics;
@ -163,6 +191,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.type_of(def_id)
}
type AdtDef = ty::AdtDef<'tcx>;
fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
self.adt_def(adt_def_id)
}
fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
@ -200,8 +233,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn trait_ref_and_own_args_for_alias(
self,
def_id: DefId,
args: Self::GenericArgs,
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
args: ty::GenericArgsRef<'tcx>,
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
let trait_def_id = self.parent(def_id);
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
@ -212,18 +245,22 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
)
}
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
self.mk_args(args)
}
fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Self::GenericArg, Self::GenericArgs>,
T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
{
self.mk_args_from_iter(args)
}
fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
self.check_args_compatible(def_id, args)
}
fn check_and_mk_args(
self,
def_id: DefId,
@ -242,7 +279,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Self::Ty, Self::Tys>,
T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
{
self.mk_type_list_from_iter(args)
}
@ -291,6 +328,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
ty::EarlyBinder::bind(
self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
)
}
fn own_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
ty::EarlyBinder::bind(
self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
)
}
fn super_predicates_of(
self,
def_id: DefId,
@ -305,15 +360,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
}
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
self.require_lang_item(
match lang_item {
TraitSolverLangItem::Future => hir::LangItem::Future,
TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput,
TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars,
},
None,
)
self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
}
fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
}
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
@ -322,6 +373,257 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
.filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
.map(|assoc_item| assoc_item.def_id)
}
fn args_may_unify_deep(
self,
obligation_args: ty::GenericArgsRef<'tcx>,
impl_args: ty::GenericArgsRef<'tcx>,
) -> bool {
ty::fast_reject::DeepRejectCtxt {
treat_obligation_params: ty::fast_reject::TreatParams::ForLookup,
}
.args_may_unify(obligation_args, impl_args)
}
// This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
// since we want to skip over blanket impls for non-rigid aliases, and also we
// only want to consider types that *actually* unify with float/int vars.
fn for_each_relevant_impl(
self,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
mut f: impl FnMut(DefId),
) {
let tcx = self;
let trait_impls = tcx.trait_impls_of(trait_def_id);
let mut consider_impls_for_simplified_type = |simp| {
if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
for &impl_def_id in impls_for_type {
f(impl_def_id);
}
}
};
match self_ty.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Adt(_, _)
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
| ty::Dynamic(_, _, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::Never
| ty::Tuple(_) => {
let simp = ty::fast_reject::simplify_type(
tcx,
self_ty,
ty::fast_reject::TreatParams::ForLookup,
)
.unwrap();
consider_impls_for_simplified_type(simp);
}
// HACK: For integer and float variables we have to manually look at all impls
// which have some integer or float as a self type.
ty::Infer(ty::IntVar(_)) => {
use ty::IntTy::*;
use ty::UintTy::*;
// This causes a compiler error if any new integer kinds are added.
let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
let possible_integers = [
// signed integers
ty::SimplifiedType::Int(I8),
ty::SimplifiedType::Int(I16),
ty::SimplifiedType::Int(I32),
ty::SimplifiedType::Int(I64),
ty::SimplifiedType::Int(I128),
ty::SimplifiedType::Int(Isize),
// unsigned integers
ty::SimplifiedType::Uint(U8),
ty::SimplifiedType::Uint(U16),
ty::SimplifiedType::Uint(U32),
ty::SimplifiedType::Uint(U64),
ty::SimplifiedType::Uint(U128),
ty::SimplifiedType::Uint(Usize),
];
for simp in possible_integers {
consider_impls_for_simplified_type(simp);
}
}
ty::Infer(ty::FloatVar(_)) => {
// This causes a compiler error if any new float kinds are added.
let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
let possible_floats = [
ty::SimplifiedType::Float(ty::FloatTy::F16),
ty::SimplifiedType::Float(ty::FloatTy::F32),
ty::SimplifiedType::Float(ty::FloatTy::F64),
ty::SimplifiedType::Float(ty::FloatTy::F128),
];
for simp in possible_floats {
consider_impls_for_simplified_type(simp);
}
}
// The only traits applying to aliases and placeholders are blanket impls.
//
// Impls which apply to an alias after normalization are handled by
// `assemble_candidates_after_normalizing_self_ty`.
ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
// FIXME: These should ideally not exist as a self type. It would be nice for
// the builtin auto trait impls of coroutines to instead directly recurse
// into the witness.
ty::CoroutineWitness(..) => (),
// These variants should not exist as a self type.
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
| ty::Param(_)
| ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
}
let trait_impls = tcx.trait_impls_of(trait_def_id);
for &impl_def_id in trait_impls.blanket_impls() {
f(impl_def_id);
}
}
fn has_item_definition(self, def_id: DefId) -> bool {
self.defaultness(def_id).has_value()
}
fn impl_is_default(self, impl_def_id: DefId) -> bool {
self.defaultness(impl_def_id).is_default()
}
fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
self.impl_trait_ref(impl_def_id).unwrap()
}
fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
self.impl_polarity(impl_def_id)
}
fn trait_is_auto(self, trait_def_id: DefId) -> bool {
self.trait_is_auto(trait_def_id)
}
fn trait_is_alias(self, trait_def_id: DefId) -> bool {
self.trait_is_alias(trait_def_id)
}
fn trait_is_object_safe(self, trait_def_id: DefId) -> bool {
self.is_object_safe(trait_def_id)
}
fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).implement_via_object
}
fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
self.fn_trait_kind_from_def_id(trait_def_id)
}
fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
self.async_fn_trait_kind_from_def_id(trait_def_id)
}
fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.supertrait_def_ids(trait_def_id)
}
fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
}
fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
self.is_general_coroutine(coroutine_def_id)
}
fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_async(coroutine_def_id)
}
fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_gen(coroutine_def_id)
}
fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_async_gen(coroutine_def_id)
}
fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
self.layout_of(self.erase_regions(param_env.and(ty)))
.is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
}
type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>;
fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
self.unsizing_params_for_adt(adt_def_id)
}
fn find_const_ty_from_env(
self,
param_env: ty::ParamEnv<'tcx>,
placeholder: Self::PlaceholderConst,
) -> Ty<'tcx> {
placeholder.find_const_ty_from_env(param_env)
}
}
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
match lang_item {
TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct,
TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars,
TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator,
TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture,
TraitSolverLangItem::Clone => LangItem::Clone,
TraitSolverLangItem::Copy => LangItem::Copy,
TraitSolverLangItem::Coroutine => LangItem::Coroutine,
TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield,
TraitSolverLangItem::Destruct => LangItem::Destruct,
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
TraitSolverLangItem::FusedIterator => LangItem::FusedIterator,
TraitSolverLangItem::Future => LangItem::Future,
TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
TraitSolverLangItem::Iterator => LangItem::Iterator,
TraitSolverLangItem::Metadata => LangItem::Metadata,
TraitSolverLangItem::Option => LangItem::Option,
TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
TraitSolverLangItem::PointerLike => LangItem::PointerLike,
TraitSolverLangItem::Poll => LangItem::Poll,
TraitSolverLangItem::Sized => LangItem::Sized,
TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait,
TraitSolverLangItem::Tuple => LangItem::Tuple,
TraitSolverLangItem::Unpin => LangItem::Unpin,
TraitSolverLangItem::Unsize => LangItem::Unsize,
}
}
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
fn as_local(self) -> Option<LocalDefId> {
self.as_local()
}
}
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
@ -356,6 +658,10 @@ impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_featu
fn coroutine_clone(self) -> bool {
self.coroutine_clone
}
fn associated_const_equality(self) -> bool {
self.associated_const_equality
}
}
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
@ -384,7 +690,7 @@ pub struct CtxtInterners<'tcx> {
layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>,
adt_def: InternedSet<'tcx, AdtDefData>,
external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
fields: InternedSet<'tcx, List<FieldIdx>>,
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
@ -1415,7 +1721,7 @@ impl<'tcx> TyCtxt<'tcx> {
)
}
pub fn dcx(self) -> &'tcx DiagCtxt {
pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
self.sess.dcx()
}
}
@ -2096,7 +2402,7 @@ direct_interners! {
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
ExternalConstraints -> ExternalConstraints<'tcx>,
predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>):
predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
PredefinedOpaques -> PredefinedOpaques<'tcx>,
}

View file

@ -44,10 +44,27 @@ pub struct GenericArg<'tcx> {
impl<'tcx> rustc_type_ir::inherent::GenericArg<TyCtxt<'tcx>> for GenericArg<'tcx> {}
impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
fn rebase_onto(
self,
tcx: TyCtxt<'tcx>,
source_ancestor: DefId,
target_args: GenericArgsRef<'tcx>,
) -> GenericArgsRef<'tcx> {
self.rebase_onto(tcx, source_ancestor, target_args)
}
fn type_at(self, i: usize) -> Ty<'tcx> {
self.type_at(i)
}
fn region_at(self, i: usize) -> ty::Region<'tcx> {
self.region_at(i)
}
fn const_at(self, i: usize) -> ty::Const<'tcx> {
self.const_at(i)
}
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
GenericArgs::identity_for_item(tcx, def_id)
}
@ -281,6 +298,7 @@ impl<'tcx> GenericArg<'tcx> {
pub fn is_non_region_infer(self) -> bool {
match self.unpack() {
GenericArgKind::Lifetime(_) => false,
// FIXME: This shouldn't return numerical/float.
GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(),
GenericArgKind::Const(ct) => ct.is_ct_infer(),
}

View file

@ -392,6 +392,10 @@ impl<'tcx> GenericPredicates<'tcx> {
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
}
pub fn instantiate_own_identity(&self) -> impl Iterator<Item = (Clause<'tcx>, Span)> {
EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied()
}
#[instrument(level = "debug", skip(self, tcx))]
fn instantiate_into(
&self,

View file

@ -5,7 +5,7 @@ use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};
use rustc_error_messages::DiagMessage;
use rustc_errors::{
Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@ -1256,7 +1256,7 @@ pub enum FnAbiError<'tcx> {
}
impl<'a, 'b, G: EmissionGuarantee> Diagnostic<'a, G> for FnAbiError<'b> {
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
match self {
Self::Layout(e) => e.into_diagnostic().into_diag(dcx, level),
Self::AdjustForForeignAbi(call::AdjustForForeignAbiError::Unsupported {

View file

@ -990,6 +990,16 @@ pub struct ParamEnv<'tcx> {
packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>,
}
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
fn reveal(self) -> Reveal {
self.reveal()
}
fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
self.caller_bounds()
}
}
#[derive(Copy, Clone)]
struct ParamTag {
reveal: traits::Reveal,

View file

@ -175,6 +175,14 @@ pub struct Clause<'tcx>(
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {}
impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
fn kind(self) -> Self::Kind {
self.kind()
}
}
impl<'tcx> Clause<'tcx> {
pub fn as_predicate(self) -> Predicate<'tcx> {
Predicate(self.0)
@ -251,6 +259,28 @@ impl<'tcx> ExistentialPredicate<'tcx> {
pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
{
fn principal_def_id(self) -> Option<DefId> {
self.principal_def_id()
}
fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
self.principal()
}
fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
self.auto_traits()
}
fn projection_bounds(
self,
) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
self.projection_bounds()
}
}
impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
/// Returns the "principal `DefId`" of this set of existential predicates.
///
@ -481,12 +511,6 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
}
}
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for TraitPredicate<'tcx> {
fn upcast_from(from: TraitRef<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
}
}
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
let p: Predicate<'tcx> = from.upcast(tcx);
@ -543,6 +567,12 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> {
}
}
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
fn upcast_from(from: RegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
}
}
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx)

Some files were not shown because too many files have changed in this diff Show more