Skip to content

Commit 0b7ef36

Browse files
committed
Factor out shared code for lowering assoc item paths
1 parent 1494041 commit 0b7ef36

File tree

4 files changed

+88
-105
lines changed

4 files changed

+88
-105
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 42 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use tracing::{debug, instrument};
4545

4646
use crate::check::intrinsic::intrinsic_operation_unsafety;
4747
use crate::errors;
48+
use crate::hir_ty_lowering::errors::assoc_kind_str;
4849
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
4950

5051
pub(crate) mod dump;
@@ -450,84 +451,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
450451
item_segment: &hir::PathSegment<'tcx>,
451452
poly_trait_ref: ty::PolyTraitRef<'tcx>,
452453
) -> Ty<'tcx> {
453-
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
454-
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
455-
span,
456-
item_def_id,
457-
item_segment,
458-
trait_ref.args,
459-
);
460-
Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
461-
} else {
462-
// There are no late-bound regions; we can just ignore the binder.
463-
let (mut mpart_sugg, mut inferred_sugg) = (None, None);
464-
let mut bound = String::new();
465-
466-
match self.node() {
467-
hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
468-
let item = self
469-
.tcx
470-
.hir()
471-
.expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
472-
match &item.kind {
473-
hir::ItemKind::Enum(_, generics)
474-
| hir::ItemKind::Struct(_, generics)
475-
| hir::ItemKind::Union(_, generics) => {
476-
let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
477-
let (lt_sp, sugg) = match generics.params {
478-
[] => (generics.span, format!("<{lt_name}>")),
479-
[bound, ..] => (bound.span.shrink_to_lo(), format!("{lt_name}, ")),
480-
};
481-
mpart_sugg = Some(errors::AssociatedItemTraitUninferredGenericParamsMultipartSuggestion {
482-
fspan: lt_sp,
483-
first: sugg,
484-
sspan: span.with_hi(item_segment.ident.span.lo()),
485-
second: format!(
486-
"{}::",
487-
// Replace the existing lifetimes with a new named lifetime.
488-
self.tcx.instantiate_bound_regions_uncached(
489-
poly_trait_ref,
490-
|_| {
491-
ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
492-
index: 0,
493-
name: Symbol::intern(&lt_name),
494-
})
495-
}
496-
),
497-
),
498-
});
499-
}
500-
_ => {}
501-
}
502-
}
503-
hir::Node::Item(hir::Item {
504-
kind:
505-
hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..),
506-
..
507-
}) => {}
508-
hir::Node::Item(_)
509-
| hir::Node::ForeignItem(_)
510-
| hir::Node::TraitItem(_)
511-
| hir::Node::ImplItem(_) => {
512-
inferred_sugg = Some(span.with_hi(item_segment.ident.span.lo()));
513-
bound = format!(
514-
"{}::",
515-
// Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
516-
self.tcx.anonymize_bound_vars(poly_trait_ref).skip_binder(),
517-
);
518-
}
519-
_ => {}
520-
}
521-
Ty::new_error(
522-
self.tcx(),
523-
self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
524-
span,
525-
inferred_sugg,
526-
bound,
527-
mpart_sugg,
528-
what: "type",
529-
}),
530-
)
454+
match self.lower_assoc_shared(
455+
span,
456+
item_def_id,
457+
item_segment,
458+
poly_trait_ref,
459+
ty::AssocKind::Type,
460+
) {
461+
Ok((def_id, args)) => Ty::new_projection_from_args(self.tcx(), def_id, args),
462+
Err(witness) => Ty::new_error(self.tcx(), witness),
531463
}
532464
}
533465

@@ -538,15 +470,37 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
538470
item_segment: &hir::PathSegment<'tcx>,
539471
poly_trait_ref: ty::PolyTraitRef<'tcx>,
540472
) -> Const<'tcx> {
473+
match self.lower_assoc_shared(
474+
span,
475+
item_def_id,
476+
item_segment,
477+
poly_trait_ref,
478+
ty::AssocKind::Const,
479+
) {
480+
Ok((def_id, args)) => {
481+
let uv = ty::UnevaluatedConst::new(def_id, args);
482+
Const::new_unevaluated(self.tcx(), uv)
483+
}
484+
Err(witness) => Const::new_error(self.tcx(), witness),
485+
}
486+
}
487+
488+
fn lower_assoc_shared(
489+
&self,
490+
span: Span,
491+
item_def_id: DefId,
492+
item_segment: &rustc_hir::PathSegment<'tcx>,
493+
poly_trait_ref: ty::PolyTraitRef<'tcx>,
494+
kind: ty::AssocKind,
495+
) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
541496
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
542497
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
543498
span,
544499
item_def_id,
545500
item_segment,
546501
trait_ref.args,
547502
);
548-
let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
549-
Const::new_unevaluated(self.tcx(), uv)
503+
Ok((item_def_id, item_args))
550504
} else {
551505
// There are no late-bound regions; we can just ignore the binder.
552506
let (mut mpart_sugg, mut inferred_sugg) = (None, None);
@@ -607,16 +561,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
607561
}
608562
_ => {}
609563
}
610-
Const::new_error(
611-
self.tcx(),
612-
self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
613-
span,
614-
inferred_sugg,
615-
bound,
616-
mpart_sugg,
617-
what: "const",
618-
}),
619-
)
564+
565+
Err(self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
566+
span,
567+
inferred_sugg,
568+
bound,
569+
mpart_sugg,
570+
what: assoc_kind_str(kind),
571+
}))
620572
}
621573
}
622574

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ fn generics_args_err_extend<'a>(
16141614
}
16151615
}
16161616

1617-
pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
1617+
pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
16181618
match kind {
16191619
ty::AssocKind::Fn => "function",
16201620
ty::AssocKind::Const => "constant",

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,18 @@ pub trait HirTyLowerer<'tcx> {
181181
poly_trait_ref: ty::PolyTraitRef<'tcx>,
182182
) -> Const<'tcx>;
183183

184+
/// Helper function; use [`Self::lower_assoc_ty`] or [`Self::lower_assoc_const`] instead.
185+
///
186+
/// The logic for lowering associated items that is the same between types and consts.
187+
fn lower_assoc_shared(
188+
&self,
189+
span: Span,
190+
item_def_id: DefId,
191+
item_segment: &hir::PathSegment<'tcx>,
192+
poly_trait_ref: ty::PolyTraitRef<'tcx>,
193+
kind: ty::AssocKind,
194+
) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
195+
184196
fn lower_fn_sig(
185197
&self,
186198
decl: &hir::FnDecl<'tcx>,

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_infer::infer;
1717
use rustc_infer::traits::Obligation;
1818
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
1919
use rustc_session::Session;
20-
use rustc_span::{self, DUMMY_SP, Ident, Span, sym};
20+
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
2121
use rustc_trait_selection::error_reporting::TypeErrCtxt;
2222
use rustc_trait_selection::error_reporting::infer::sub_relations::SubRelations;
2323
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
@@ -315,20 +315,16 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
315315
item_segment: &hir::PathSegment<'tcx>,
316316
poly_trait_ref: ty::PolyTraitRef<'tcx>,
317317
) -> Ty<'tcx> {
318-
let trait_ref = self.instantiate_binder_with_fresh_vars(
319-
span,
320-
infer::BoundRegionConversionTime::AssocTypeProjection(item_def_id),
321-
poly_trait_ref,
322-
);
323-
324-
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
318+
match self.lower_assoc_shared(
325319
span,
326320
item_def_id,
327321
item_segment,
328-
trait_ref.args,
329-
);
330-
331-
Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
322+
poly_trait_ref,
323+
ty::AssocKind::Type,
324+
) {
325+
Ok((def_id, args)) => Ty::new_projection_from_args(self.tcx(), def_id, args),
326+
Err(witness) => Ty::new_error(self.tcx(), witness),
327+
}
332328
}
333329

334330
fn lower_assoc_const(
@@ -338,9 +334,32 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
338334
item_segment: &hir::PathSegment<'tcx>,
339335
poly_trait_ref: ty::PolyTraitRef<'tcx>,
340336
) -> Const<'tcx> {
337+
match self.lower_assoc_shared(
338+
span,
339+
item_def_id,
340+
item_segment,
341+
poly_trait_ref,
342+
ty::AssocKind::Const,
343+
) {
344+
Ok((def_id, args)) => {
345+
let uv = ty::UnevaluatedConst::new(def_id, args);
346+
Const::new_unevaluated(self.tcx(), uv)
347+
}
348+
Err(witness) => Const::new_error(self.tcx(), witness),
349+
}
350+
}
351+
352+
fn lower_assoc_shared(
353+
&self,
354+
span: Span,
355+
item_def_id: DefId,
356+
item_segment: &rustc_hir::PathSegment<'tcx>,
357+
poly_trait_ref: ty::PolyTraitRef<'tcx>,
358+
_kind: ty::AssocKind,
359+
) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
341360
let trait_ref = self.instantiate_binder_with_fresh_vars(
342361
span,
343-
// FIXME(mgca): this should be assoc const not assoc type
362+
// FIXME(mgca): this should be assoc const if that is the `kind`
344363
infer::BoundRegionConversionTime::AssocTypeProjection(item_def_id),
345364
poly_trait_ref,
346365
);
@@ -352,7 +371,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
352371
trait_ref.args,
353372
);
354373

355-
Const::new_unevaluated(self.tcx(), ty::UnevaluatedConst::new(item_def_id, item_args))
374+
Ok((item_def_id, item_args))
356375
}
357376

358377
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {

0 commit comments

Comments
 (0)