Unify optional param info with object lifetime default boolean into an enum that exhaustively supports all call sites

This commit is contained in:
Oli Scherer 2024-06-04 13:36:28 +00:00
parent 4146b8280a
commit c8a331ac52
8 changed files with 75 additions and 53 deletions

View file

@ -44,7 +44,7 @@ use std::ops::Bound;
use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors; use crate::errors;
use crate::hir_ty_lowering::HirTyLowerer; use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
pub use type_of::test_opaque_hidden_types; pub use type_of::test_opaque_hidden_types;
mod generics_of; mod generics_of;
@ -374,13 +374,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
self.item_def_id self.item_def_id
} }
fn re_infer( fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
&self, if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
_: Option<&ty::GenericParamDef>,
span: Span,
object_lifetime_default: bool,
) -> ty::Region<'tcx> {
if object_lifetime_default {
let e = struct_span_code_err!( let e = struct_span_code_err!(
self.tcx().dcx(), self.tcx().dcx(),
span, span,

View file

@ -1,7 +1,7 @@
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::collect::ItemCtxt; use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp; 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 hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir; use rustc_hir as hir;
@ -243,12 +243,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
hir::WherePredicate::RegionPredicate(region_pred) => { 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| { predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound { let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => { hir::GenericBound::Outlives(lt) => (
(icx.lowerer().lower_lifetime(lt, None), lt.ident.span) icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
} lt.ident.span,
),
bound => { bound => {
span_bug!( span_bug!(
bound.span(), bound.span(),

View file

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

View file

@ -80,6 +80,20 @@ pub enum PredicateFilter {
SelfAndAssociatedTypeBounds, 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 /// A context which can lower type-system entities from the [HIR][hir] to
/// the [`rustc_middle::ty`] representation. /// the [`rustc_middle::ty`] representation.
/// ///
@ -91,14 +105,7 @@ pub trait HirTyLowerer<'tcx> {
fn item_def_id(&self) -> LocalDefId; fn item_def_id(&self) -> LocalDefId;
/// Returns the region to use when a lifetime is omitted (and not elided). /// Returns the region to use when a lifetime is omitted (and not elided).
/// fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
/// The `object_lifetime_default` argument states whether this lifetime is from a reference.
fn re_infer(
&self,
param: Option<&ty::GenericParamDef>,
span: Span,
object_lifetime_default: bool,
) -> ty::Region<'tcx>;
/// Returns the type to use when a type is omitted. /// Returns the type to use when a type is omitted.
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>; fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
@ -267,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub fn lower_lifetime( pub fn lower_lifetime(
&self, &self,
lifetime: &hir::Lifetime, lifetime: &hir::Lifetime,
def: Option<&ty::GenericParamDef>, reason: RegionInferReason<'_>,
) -> ty::Region<'tcx> { ) -> ty::Region<'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id)); let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
@ -301,7 +308,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar), Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar),
None => self.re_infer(def, lifetime.ident.span, false), None => self.re_infer(lifetime.ident.span, reason),
} }
} }
@ -466,7 +473,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
match (&param.kind, arg) { match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { (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)) => { (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
handle_ty_args(has_default, ty) handle_ty_args(has_default, ty)
@ -509,7 +516,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
} }
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
self.lowerer.re_infer(Some(param), self.span, false).into() self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
} }
GenericParamDefKind::Type { has_default, .. } => { GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default { if !infer_args && has_default {
@ -2041,7 +2048,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), 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::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
hir::TyKind::Ref(region, mt) => { hir::TyKind::Ref(region, mt) => {
let r = self.lower_lifetime(region, None); let r = self.lower_lifetime(region, RegionInferReason::Reference);
debug!(?r); debug!(?r);
let t = self.lower_ty_common(mt.ty, true, false); let t = self.lower_ty_common(mt.ty, true, false);
Ty::new_ref(tcx, r, t, mt.mutbl) Ty::new_ref(tcx, r, t, mt.mutbl)
@ -2270,7 +2277,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&lifetimes[i] &lifetimes[i]
) )
}; };
self.lower_lifetime(lifetime, None).into() self.lower_lifetime(lifetime, RegionInferReason::Param(&param)).into()
} else { } else {
tcx.mk_param_from_def(param) tcx.mk_param_from_def(param)
} }

View file

@ -1,5 +1,7 @@
use crate::bounds::Bounds; 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_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err}; use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir; use rustc_hir as hir;
@ -321,13 +323,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Use explicitly-specified region bound. // Use explicitly-specified region bound.
let region_bound = if !lifetime.is_elided() { let region_bound = if !lifetime.is_elided() {
self.lower_lifetime(lifetime, None) self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
} else { } else {
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
if tcx.named_bound_var(lifetime.hir_id).is_some() { if tcx.named_bound_var(lifetime.hir_id).is_some() {
self.lower_lifetime(lifetime, None) self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
} else { } else {
self.re_infer(None, span, !borrowed) self.re_infer(
span,
if borrowed {
RegionInferReason::ObjectLifetimeDefault
} else {
RegionInferReason::BorrowedObjectLifetimeDefault
},
)
} }
}) })
}; };

View file

@ -16,7 +16,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
}; };
use rustc_hir_analysis::hir_ty_lowering::{ use rustc_hir_analysis::hir_ty_lowering::{
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
GenericPathSegment, HirTyLowerer, IsMethodCall, GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
}; };
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
@ -1280,9 +1280,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
arg: &GenericArg<'tcx>, arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
match (&param.kind, arg) { match (&param.kind, arg) {
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
self.fcx.lowerer().lower_lifetime(lt, Some(param)).into() .fcx
} .lowerer()
.lower_lifetime(lt, RegionInferReason::Param(param))
.into(),
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.fcx.lower_ty(ty).raw.into() self.fcx.lower_ty(ty).raw.into()
} }
@ -1324,9 +1326,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
let tcx = self.fcx.tcx(); let tcx = self.fcx.tcx();
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => self
self.fcx.re_infer(Some(param), self.span, false).into() .fcx
} .re_infer(
self.span,
rustc_hir_analysis::hir_ty_lowering::RegionInferReason::Param(param),
)
.into(),
GenericParamDefKind::Type { has_default, .. } => { GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default { if !infer_args && has_default {
// If we have a default, then it doesn't matter that we're not // 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_errors::DiagCtxt;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; 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;
use rustc_infer::infer::error_reporting::sub_relations::SubRelations; use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::error_reporting::TypeErrCtxt;
@ -222,15 +222,10 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
self.body_id self.body_id
} }
fn re_infer( fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
&self, let v = match reason {
def: Option<&ty::GenericParamDef>, RegionInferReason::Param(def) => infer::RegionParameterDefinition(span, def.name),
span: Span, _ => infer::MiscVariable(span),
_object_lifetime_default: bool,
) -> ty::Region<'tcx> {
let v = match def {
Some(def) => infer::RegionParameterDefinition(span, def.name),
None => infer::MiscVariable(span),
}; };
self.next_region_var(v) self.next_region_var(v)
} }

View file

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