Rollup merge of #125819 - oli-obk:localize, r=fmease

Various `HirTyLowerer` cleanups

Previously there was some ad-hoc specialization going on, because you could call `allows_infer`, which basically was deciding between whether the trait object was backed by `FnCtxt` or by `ItemCtxt`. I moved all the different logic into dedicated methods on `HirTyLowerer` and removed `allows_infer`

best reviewed commit-by-commit
This commit is contained in:
Matthias Krüger 2024-06-05 18:21:10 +02:00 committed by GitHub
commit 94c19c6522
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 221 additions and 210 deletions

View File

@ -18,11 +18,11 @@ use rustc_ast::Recovered;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_errors::{struct_span_code_err, Applicability, Diag, ErrorGuaranteed, StashKey, E0228};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::intravisit::{self, walk_generics, Visitor};
use rustc_hir::{self as hir};
use rustc_hir::{GenericParamKind, Node};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
@ -44,7 +44,7 @@ use std::ops::Bound;
use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
pub use type_of::test_opaque_hidden_types;
mod generics_of;
@ -370,16 +370,26 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
self.tcx
}
fn item_def_id(&self) -> DefId {
self.item_def_id.to_def_id()
fn item_def_id(&self) -> LocalDefId {
self.item_def_id
}
fn allow_infer(&self) -> bool {
false
}
fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
None
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
let e = struct_span_code_err!(
self.tcx().dcx(),
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
)
.emit();
self.set_tainted_by_errors(e);
ty::Region::new_error(self.tcx(), e)
} else {
// This indicates an illegal lifetime in a non-assoc-trait position
ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")
}
}
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
@ -510,6 +520,89 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
self.tainted_by_errors.set(Some(err));
}
fn lower_fn_sig(
&self,
decl: &hir::FnDecl<'tcx>,
generics: Option<&hir::Generics<'_>>,
hir_id: rustc_hir::HirId,
hir_ty: Option<&hir::Ty<'_>>,
) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
let tcx = self.tcx();
// We proactively collect all the inferred type params to emit a single error per fn def.
let mut visitor = HirPlaceholderCollector::default();
let mut infer_replacements = vec![];
if let Some(generics) = generics {
walk_generics(&mut visitor, generics);
}
let input_tys = decl
.inputs
.iter()
.enumerate()
.map(|(i, a)| {
if let hir::TyKind::Infer = a.kind {
if let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
{
infer_replacements.push((a.span, suggested_ty.to_string()));
return Ty::new_error_with_message(tcx, a.span, suggested_ty.to_string());
}
}
// Only visit the type looking for `_` if we didn't fix the type above
visitor.visit_ty(a);
self.lowerer().lower_arg_ty(a, None)
})
.collect();
let output_ty = match decl.output {
hir::FnRetTy::Return(output) => {
if let hir::TyKind::Infer = output.kind
&& let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
{
infer_replacements.push((output.span, suggested_ty.to_string()));
Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
} else {
visitor.visit_ty(output);
self.lower_ty(output)
}
}
hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
};
if !(visitor.0.is_empty() && infer_replacements.is_empty()) {
// We check for the presence of
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
let mut diag = crate::collect::placeholder_type_error_diag(
tcx,
generics,
visitor.0,
infer_replacements.iter().map(|(s, _)| *s).collect(),
true,
hir_ty,
"function",
);
if !infer_replacements.is_empty() {
diag.multipart_suggestion(
format!(
"try replacing `_` with the type{} in the corresponding trait method signature",
rustc_errors::pluralize!(infer_replacements.len()),
),
infer_replacements,
Applicability::MachineApplicable,
);
}
self.set_tainted_by_errors(diag.emit());
}
(input_tys, output_ty)
}
}
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.

View File

@ -1,7 +1,7 @@
use crate::bounds::Bounds;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
use hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
@ -117,7 +117,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
let mut is_trait = None;
let mut is_default_impl_trait = None;
// FIXME: Should ItemCtxt take a LocalDefId?
let icx = ItemCtxt::new(tcx, def_id);
const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
@ -244,12 +243,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
hir::WherePredicate::RegionPredicate(region_pred) => {
let r1 = icx.lowerer().lower_lifetime(region_pred.lifetime, None);
let r1 = icx
.lowerer()
.lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => {
(icx.lowerer().lower_lifetime(lt, None), lt.ident.span)
}
hir::GenericBound::Outlives(lt) => (
icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
lt.ident.span,
),
bound => {
span_bug!(
bound.span(),

View File

@ -18,6 +18,8 @@ use crate::bounds::Bounds;
use crate::errors;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use super::RegionInferReason;
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Add a `Sized` bound to the `bounds` if appropriate.
///
@ -166,7 +168,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
);
}
hir::GenericBound::Outlives(lifetime) => {
let region = self.lower_lifetime(lifetime, None);
let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
bounds.push_region_bound(
self.tcx(),
ty::Binder::bind_with_vars(

View File

@ -20,7 +20,6 @@ mod lint;
mod object_safety;
use crate::bounds::Bounds;
use crate::collect::HirPlaceholderCollector;
use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
@ -34,7 +33,6 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_generics, Visitor as _};
use rustc_hir::{GenericArg, GenericArgs, HirId};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
@ -82,6 +80,20 @@ pub enum PredicateFilter {
SelfAndAssociatedTypeBounds,
}
#[derive(Debug)]
pub enum RegionInferReason<'a> {
/// Lifetime on a trait object behind a reference.
/// This allows inferring information from the reference.
BorrowedObjectLifetimeDefault,
/// A trait object's lifetime.
ObjectLifetimeDefault,
/// Generic lifetime parameter
Param(&'a ty::GenericParamDef),
RegionPredicate,
Reference,
OutlivesBound,
}
/// A context which can lower type-system entities from the [HIR][hir] to
/// the [`rustc_middle::ty`] representation.
///
@ -89,15 +101,11 @@ pub enum PredicateFilter {
pub trait HirTyLowerer<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx>;
/// Returns the [`DefId`] of the overarching item whose constituents get lowered.
fn item_def_id(&self) -> DefId;
/// Returns `true` if the current context allows the use of inference variables.
fn allow_infer(&self) -> bool;
/// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
fn item_def_id(&self) -> LocalDefId;
/// Returns the region to use when a lifetime is omitted (and not elided).
fn re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span)
-> Option<ty::Region<'tcx>>;
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
/// Returns the type to use when a type is omitted.
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
@ -151,6 +159,14 @@ pub trait HirTyLowerer<'tcx> {
poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx>;
fn lower_fn_sig(
&self,
decl: &hir::FnDecl<'tcx>,
generics: Option<&hir::Generics<'_>>,
hir_id: HirId,
hir_ty: Option<&hir::Ty<'_>>,
) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
/// Returns `AdtDef` if `ty` is an ADT.
///
/// Note that `ty` might be a alias type that needs normalization.
@ -258,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub fn lower_lifetime(
&self,
lifetime: &hir::Lifetime,
def: Option<&ty::GenericParamDef>,
reason: RegionInferReason<'_>,
) -> ty::Region<'tcx> {
let tcx = self.tcx();
let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
@ -292,21 +308,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar),
None => {
self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
debug!(?lifetime, "unelided lifetime in signature");
// This indicates an illegal lifetime
// elision. `resolve_lifetime` should have
// reported an error in this case -- but if
// not, let's error out.
ty::Region::new_error_with_message(
tcx,
lifetime.ident.span,
"unelided lifetime in signature",
)
})
}
None => self.re_infer(lifetime.ident.span, reason),
}
}
@ -421,7 +423,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
def_id: DefId,
generic_args: &'a GenericArgs<'tcx>,
span: Span,
inferred_params: Vec<Span>,
infer_args: bool,
incorrect_args: &'a Result<(), GenericArgCountMismatch>,
}
@ -450,7 +451,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}
let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
if has_default {
tcx.check_optional_stability(
param.def_id,
@ -467,17 +468,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
},
);
}
if let (hir::TyKind::Infer, false) = (&ty.kind, self.lowerer.allow_infer()) {
self.inferred_params.push(ty.span);
Ty::new_misc_error(tcx).into()
} else {
self.lowerer.lower_ty(ty).into()
}
self.lowerer.lower_ty(ty).into()
};
match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
self.lowerer.lower_lifetime(lt, Some(param)).into()
self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
}
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
handle_ty_args(has_default, ty)
@ -496,12 +492,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.type_of(param.def_id)
.no_bound_vars()
.expect("const parameter types cannot be generic");
if self.lowerer.allow_infer() {
self.lowerer.ct_infer(ty, Some(param), inf.span).into()
} else {
self.inferred_params.push(inf.span);
ty::Const::new_misc_error(tcx, ty).into()
}
self.lowerer.ct_infer(ty, Some(param), inf.span).into()
}
(kind, arg) => span_bug!(
self.span,
@ -524,20 +515,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}
match param.kind {
GenericParamDefKind::Lifetime => self
.lowerer
.re_infer(Some(param), self.span)
.unwrap_or_else(|| {
debug!(?param, "unelided lifetime in signature");
// This indicates an illegal lifetime in a non-assoc-trait position
ty::Region::new_error_with_message(
tcx,
self.span,
"unelided lifetime in signature",
)
})
.into(),
GenericParamDefKind::Lifetime => {
self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
}
GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default {
// No type parameter provided, but a default exists.
@ -604,7 +584,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
def_id,
span,
generic_args: segment.args(),
inferred_params: vec![],
infer_args: segment.infer_args,
incorrect_args: &arg_count.correct,
};
@ -1493,16 +1472,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let def_id = self.item_def_id();
debug!(item_def_id = ?def_id);
let parent_def_id = def_id
.as_local()
.map(|def_id| tcx.local_def_id_to_hir_id(def_id))
.map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id());
// FIXME: document why/how this is different from `tcx.local_parent(def_id)`
let parent_def_id =
tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
debug!(?parent_def_id);
// If the trait in segment is the same as the trait defining the item,
// use the `<Self as ..>` syntax in the error.
let is_part_of_self_trait_constraints = def_id == trait_def_id;
let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id);
let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
vec!["Self".to_string()]
@ -1983,7 +1961,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
let sig_generics = self.tcx().generics_of(sig_id);
let parent = self.tcx().parent(self.item_def_id());
let parent = self.tcx().local_parent(self.item_def_id());
let parent_generics = self.tcx().generics_of(parent);
let parent_is_trait = (self.tcx().def_kind(parent) == DefKind::Trait) as usize;
@ -2022,7 +2000,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let sig = self.tcx().fn_sig(sig_id);
let sig_generics = self.tcx().generics_of(sig_id);
let parent = self.tcx().parent(self.item_def_id());
let parent = self.tcx().local_parent(self.item_def_id());
let parent_def_kind = self.tcx().def_kind(parent);
let sig = if let DefKind::Impl { .. } = parent_def_kind
@ -2070,7 +2048,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
hir::TyKind::Ref(region, mt) => {
let r = self.lower_lifetime(region, None);
let r = self.lower_lifetime(region, RegionInferReason::Reference);
debug!(?r);
let t = self.lower_ty_common(mt.ty, true, false);
Ty::new_ref(tcx, r, t, mt.mutbl)
@ -2299,7 +2277,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&lifetimes[i]
)
};
self.lower_lifetime(lifetime, None).into()
self.lower_lifetime(lifetime, RegionInferReason::Param(&param)).into()
} else {
tcx.mk_param_from_def(param)
}
@ -2338,92 +2316,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let bound_vars = tcx.late_bound_vars(hir_id);
debug!(?bound_vars);
// We proactively collect all the inferred type params to emit a single error per fn def.
let mut visitor = HirPlaceholderCollector::default();
let mut infer_replacements = vec![];
if let Some(generics) = generics {
walk_generics(&mut visitor, generics);
}
let input_tys: Vec<_> = decl
.inputs
.iter()
.enumerate()
.map(|(i, a)| {
if let hir::TyKind::Infer = a.kind
&& !self.allow_infer()
{
if let Some(suggested_ty) =
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
{
infer_replacements.push((a.span, suggested_ty.to_string()));
return Ty::new_error_with_message(
self.tcx(),
a.span,
suggested_ty.to_string(),
);
}
}
// Only visit the type looking for `_` if we didn't fix the type above
visitor.visit_ty(a);
self.lower_arg_ty(a, None)
})
.collect();
let output_ty = match decl.output {
hir::FnRetTy::Return(output) => {
if let hir::TyKind::Infer = output.kind
&& !self.allow_infer()
&& let Some(suggested_ty) =
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
{
infer_replacements.push((output.span, suggested_ty.to_string()));
Ty::new_error_with_message(self.tcx(), output.span, suggested_ty.to_string())
} else {
visitor.visit_ty(output);
self.lower_ty(output)
}
}
hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
};
let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
debug!(?output_ty);
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
if !self.allow_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
// We always collect the spans for placeholder types when evaluating `fn`s, but we
// only want to emit an error complaining about them if infer types (`_`) are not
// allowed. `allow_infer` gates this behavior. We check for the presence of
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
let mut diag = crate::collect::placeholder_type_error_diag(
tcx,
generics,
visitor.0,
infer_replacements.iter().map(|(s, _)| *s).collect(),
true,
hir_ty,
"function",
);
if !infer_replacements.is_empty() {
diag.multipart_suggestion(
format!(
"try replacing `_` with the type{} in the corresponding trait method signature",
rustc_errors::pluralize!(infer_replacements.len()),
),
infer_replacements,
Applicability::MachineApplicable,
);
}
self.set_tainted_by_errors(diag.emit());
}
// Find any late-bound regions declared in return type that do
// not appear in the arguments. These are not well-formed.
//
@ -2453,7 +2352,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// corresponding function in the trait that the impl implements, if it exists.
/// If arg_idx is Some, then it corresponds to an input type index, otherwise it
/// corresponds to the return type.
fn suggest_trait_fn_ty_for_impl_fn_infer(
pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
&self,
fn_hir_id: HirId,
arg_idx: Option<usize>,

View File

@ -1,5 +1,7 @@
use crate::bounds::Bounds;
use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use crate::hir_ty_lowering::{
GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds, RegionInferReason,
};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir;
@ -321,30 +323,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Use explicitly-specified region bound.
let region_bound = if !lifetime.is_elided() {
self.lower_lifetime(lifetime, None)
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
} else {
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
if tcx.named_bound_var(lifetime.hir_id).is_some() {
self.lower_lifetime(lifetime, None)
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
} else {
self.re_infer(None, span).unwrap_or_else(|| {
let err = struct_span_code_err!(
tcx.dcx(),
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
);
let e = if borrowed {
// We will have already emitted an error E0106 complaining about a
// missing named lifetime in `&dyn Trait`, so we elide this one.
err.delay_as_bug()
self.re_infer(
span,
if borrowed {
RegionInferReason::ObjectLifetimeDefault
} else {
err.emit()
};
self.set_tainted_by_errors(e);
ty::Region::new_error(tcx, e)
})
RegionInferReason::BorrowedObjectLifetimeDefault
},
)
}
})
};

View File

@ -16,7 +16,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
};
use rustc_hir_analysis::hir_ty_lowering::{
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
GenericPathSegment, HirTyLowerer, IsMethodCall,
GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
};
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
@ -1274,9 +1274,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
self.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
}
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
.fcx
.lowerer()
.lower_lifetime(lt, RegionInferReason::Param(param))
.into(),
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.fcx.lower_ty(ty).raw.into()
}
@ -1318,9 +1320,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> ty::GenericArg<'tcx> {
let tcx = self.fcx.tcx();
match param.kind {
GenericParamDefKind::Lifetime => {
self.fcx.re_infer(Some(param), self.span).unwrap().into()
}
GenericParamDefKind::Lifetime => self
.fcx
.re_infer(
self.span,
rustc_hir_analysis::hir_ty_lowering::RegionInferReason::Param(param),
)
.into(),
GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default {
// If we have a default, then it doesn't matter that we're not

View File

@ -15,7 +15,7 @@ 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;
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
use rustc_infer::infer;
use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
@ -213,25 +213,21 @@ impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
}
}
impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn item_def_id(&self) -> DefId {
self.body_id.to_def_id()
fn item_def_id(&self) -> LocalDefId {
self.body_id
}
fn allow_infer(&self) -> bool {
true
}
fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
let v = match def {
Some(def) => infer::RegionParameterDefinition(span, def.name),
None => infer::MiscVariable(span),
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
let v = match reason {
RegionInferReason::Param(def) => infer::RegionParameterDefinition(span, def.name),
_ => infer::MiscVariable(span),
};
Some(self.next_region_var(v))
self.next_region_var(v)
}
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
@ -350,6 +346,22 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
self.infcx.set_tainted_by_errors(e)
}
fn lower_fn_sig(
&self,
decl: &rustc_hir::FnDecl<'tcx>,
_generics: Option<&rustc_hir::Generics<'_>>,
_hir_id: rustc_hir::HirId,
_hir_ty: Option<&hir::Ty<'_>>,
) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
let input_tys = decl.inputs.iter().map(|a| self.lowerer().lower_arg_ty(a, None)).collect();
let output_ty = match decl.output {
hir::FnRetTy::Return(output) => self.lowerer().lower_ty(output),
hir::FnRetTy::DefaultReturn(..) => self.tcx().types.unit,
};
(input_tys, output_ty)
}
}
/// The `ty` representation of a user-provided type. Depending on the use-site

View File

@ -7,7 +7,9 @@ use rustc_hir::GenericArg;
use rustc_hir_analysis::hir_ty_lowering::generics::{
check_generic_arg_count_for_call, lower_generic_args,
};
use rustc_hir_analysis::hir_ty_lowering::{GenericArgsLowerer, HirTyLowerer, IsMethodCall};
use rustc_hir_analysis::hir_ty_lowering::{
GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
};
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@ -388,9 +390,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
self.cfcx.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
}
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
.cfcx
.fcx
.lowerer()
.lower_lifetime(lt, RegionInferReason::Param(param))
.into(),
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.cfcx.lower_ty(ty).raw.into()
}