1
Fork 0

Split UserTypeAnnotation to have a kind

This commit is contained in:
Michael Goulet 2024-12-11 20:10:47 +00:00
parent 4a204bebdf
commit 1da411e750
13 changed files with 60 additions and 36 deletions

View file

@ -275,7 +275,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
user_ty: ty::UserType<'tcx>,
span: Span,
) {
let ty::UserType::Ty(user_ty) = user_ty else { bug!() };
let ty::UserTypeKind::Ty(user_ty) = user_ty.kind else { bug!() };
// A fast path for a common case with closure input/output types.
if let ty::Infer(_) = user_ty.kind() {

View file

@ -110,7 +110,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
) {
self.ascribe_user_type_skip_wf(
arg_decl.ty,
ty::UserType::Ty(user_ty),
ty::UserType::new(ty::UserTypeKind::Ty(user_ty)),
arg_decl.source_info.span,
);
}
@ -119,7 +119,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let output_decl = &body.local_decls[RETURN_PLACE];
self.ascribe_user_type_skip_wf(
output_decl.ty,
ty::UserType::Ty(user_provided_sig.output()),
ty::UserType::new(ty::UserTypeKind::Ty(user_provided_sig.output())),
output_decl.source_info.span,
);
}

View file

@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserArgs,
UserType, UserTypeAnnotationIndex,
UserTypeAnnotationIndex,
};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::ResultsCursor;
@ -370,7 +370,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} else {
self.cx.ascribe_user_type(
constant.const_.ty(),
UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
ty::UserType::new(ty::UserTypeKind::TypeOf(uv.def, UserArgs {
args: uv.args,
user_self_ty: None,
})),
locations.span(self.cx.body),
);
}
@ -991,9 +994,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let annotation = self.instantiate_canonical(span, user_ty);
if let ty::UserType::TypeOf(def, args) = annotation
if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind
&& let DefKind::InlineConst = tcx.def_kind(def)
{
// TODO:
self.check_inline_const(inferred_ty, def.expect_local(), args, span);
} else {
self.ascribe_user_type(inferred_ty, annotation, span);

View file

@ -25,7 +25,7 @@ use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{
self, AdtKind, CanonicalUserType, GenericArgKind, GenericArgsRef, GenericParamDefKind,
IsIdentity, Ty, TyCtxt, UserArgs, UserSelfTy, UserType,
IsIdentity, Ty, TyCtxt, UserArgs, UserSelfTy,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
@ -216,11 +216,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("fcx {}", self.tag());
if Self::can_contain_user_lifetime_bounds((args, user_self_ty)) {
let canonicalized =
self.canonicalize_user_type_annotation(UserType::TypeOf(def_id, UserArgs {
args,
user_self_ty,
}));
let canonicalized = self.canonicalize_user_type_annotation(ty::UserType::new(
ty::UserTypeKind::TypeOf(def_id, UserArgs { args, user_self_ty }),
));
debug!(?canonicalized);
self.write_user_type_annotation(hir_id, canonicalized);
}
@ -468,7 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!(?ty);
if Self::can_contain_user_lifetime_bounds(ty.raw) {
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
let c_ty = self.canonicalize_response(ty::UserType::new(ty::UserTypeKind::Ty(ty.raw)));
debug!(?c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(hir_ty.hir_id, c_ty);
}

View file

@ -2,7 +2,7 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{HirId, PatKind};
use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::ty::{Ty, UserType};
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
use tracing::debug;
@ -92,7 +92,9 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
Some(ref ty) => {
let o_ty = self.fcx.lower_ty(ty);
let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));
let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
ty::UserTypeKind::Ty(o_ty.raw),
));
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
self.fcx
.typeck_results

View file

@ -17,7 +17,6 @@ use rustc_middle::ty::adjustment::{
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, UserArgs,
UserType,
};
use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Span};
@ -491,9 +490,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
user_self_ty: None, // not relevant here
};
self.fcx.canonicalize_user_type_annotation(UserType::TypeOf(
pick.item.def_id,
user_args,
self.fcx.canonicalize_user_type_annotation(ty::UserType::new(
ty::UserTypeKind::TypeOf(pick.item.def_id, user_args),
))
});

View file

@ -476,7 +476,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
for (local_id, c_ty) in sorted_user_provided_types {
let hir_id = HirId { owner: common_hir_owner, local_id };
if let ty::UserType::TypeOf(_, user_args) = c_ty.value {
if let ty::UserTypeKind::TypeOf(_, user_args) = c_ty.value.kind {
// This is a unit-testing mechanism.
let span = self.tcx().hir().span(hir_id);
// We need to buffer the errors in order to guarantee a consistent

View file

@ -95,7 +95,7 @@ pub use self::sty::{
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
TypeckResults, UserType, UserTypeAnnotationIndex,
TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
};
pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};

View file

@ -700,12 +700,24 @@ pub struct CanonicalUserTypeAnnotation<'tcx> {
/// Canonical user type annotation.
pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UserType<'tcx> {
pub kind: UserTypeKind<'tcx>,
}
impl<'tcx> UserType<'tcx> {
pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
UserType { kind }
}
}
/// A user-given type annotation attached to a constant. These arise
/// from constants that are named via paths, like `Foo::<A>::new` and
/// so forth.
#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum UserType<'tcx> {
pub enum UserTypeKind<'tcx> {
Ty(Ty<'tcx>),
/// The canonical type is the result of `type_of(def_id)` with the
@ -721,9 +733,11 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
/// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
/// i.e., each thing is mapped to a canonical variable with the same index.
fn is_identity(&self) -> bool {
match self.value {
UserType::Ty(_) => false,
UserType::TypeOf(_, user_args) => {
// TODO:
match self.value.kind {
UserTypeKind::Ty(_) => false,
UserTypeKind::TypeOf(_, user_args) => {
if user_args.user_self_ty.is_some() {
return false;
}
@ -764,6 +778,14 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
}
impl<'tcx> std::fmt::Display for UserType<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// TODO:
self.kind.fmt(f)
}
}
impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Ty(arg0) => {

View file

@ -176,9 +176,8 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
ty: cx.infcx.next_ty_var(span),
})
.args;
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
def_id,
ty::UserArgs { args, user_self_ty: None },
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
ty::UserTypeKind::TypeOf(def_id, ty::UserArgs { args, user_self_ty: None }),
));
let annotation = ty::CanonicalUserTypeAnnotation {
inferred_ty: pattern.ty,

View file

@ -15,7 +15,6 @@ use rustc_middle::ty::adjustment::{
};
use rustc_middle::ty::{
self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs,
UserType,
};
use rustc_middle::{bug, span_bug};
use rustc_span::{Span, sym};
@ -443,7 +442,9 @@ impl<'tcx> Cx<'tcx> {
let user_provided_types = self.typeck_results().user_provided_types();
let user_ty =
user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
if let ty::UserTypeKind::TypeOf(ref mut did, _) =
&mut u_ty.value.kind
{
*did = adt_def.did();
}
Box::new(u_ty)

View file

@ -1,6 +1,6 @@
use rustc_hir as hir;
use rustc_middle::bug;
use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType};
use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
use tracing::debug;
pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
@ -21,7 +21,7 @@ pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
let ty = self.typeck_results().node_type(hir_id);
match ty.kind() {
ty::Adt(adt_def, ..) => {
if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
*did = adt_def.did();
}
Some(user_ty)

View file

@ -3,7 +3,7 @@ use rustc_infer::traits::Obligation;
use rustc_middle::traits::query::NoSolution;
pub use rustc_middle::traits::query::type_op::AscribeUserType;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserType};
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserTypeKind};
use rustc_span::{DUMMY_SP, Span};
use tracing::{debug, instrument};
@ -46,9 +46,9 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
let (param_env, AscribeUserType { mir_ty, user_ty }) = key.into_parts();
debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty);
let span = span.unwrap_or(DUMMY_SP);
match user_ty {
UserType::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
UserType::TypeOf(def_id, user_args) => {
match user_ty.kind {
UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
UserTypeKind::TypeOf(def_id, user_args) => {
relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
}
};