Skip to content

Commit 5495bcb

Browse files
Refactor handling of generic params in hir::Type
The essence of the new handling is that `hir::Type` now remembers its owner (and not `ParamEnv`; we could remember both but that is unnecessary) and refuse (panics) to work with types not from the same owner. It would be best if we could enforce this statically, but unfortunately we can't.
1 parent 6916b0f commit 5495bcb

38 files changed

Lines changed: 948 additions & 992 deletions

crates/hir-ty/src/traits.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub fn implements_trait_unique<'db>(
121121
env: ParamEnvAndCrate<'db>,
122122
trait_: TraitId,
123123
) -> bool {
124-
implements_trait_unique_impl(db, env, trait_, &mut |infcx| {
124+
implements_trait_unique_with_infcx(db, env, trait_, &mut |infcx| {
125125
infcx.fill_rest_fresh_args(Span::Dummy, trait_.into(), [ty.into()])
126126
})
127127
}
@@ -133,10 +133,10 @@ pub fn implements_trait_unique_with_args<'db>(
133133
trait_: TraitId,
134134
args: GenericArgs<'db>,
135135
) -> bool {
136-
implements_trait_unique_impl(db, env, trait_, &mut |_| args)
136+
implements_trait_unique_with_infcx(db, env, trait_, &mut |_| args)
137137
}
138138

139-
fn implements_trait_unique_impl<'db>(
139+
pub fn implements_trait_unique_with_infcx<'db>(
140140
db: &'db dyn HirDatabase,
141141
env: ParamEnvAndCrate<'db>,
142142
trait_: TraitId,

crates/hir/src/attrs.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use stdx::never;
2626

2727
use crate::{
2828
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, EnumVariant,
29-
ExternCrateDecl, Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro,
30-
Module, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant,
29+
ExternCrateDecl, Field, Function, GenericParam, Impl, LangItem, LifetimeParam, Macro, Module,
30+
ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant,
3131
};
3232

3333
#[derive(Debug, Clone, Copy)]
@@ -487,27 +487,28 @@ fn resolve_impl_trait_item<'db>(
487487
ns: Option<Namespace>,
488488
) -> Option<DocLinkDef> {
489489
let krate = ty.krate(db);
490-
let environment = crate::param_env_from_resolver(db, &resolver);
490+
let param_env = ty.param_env(db);
491491
let traits_in_scope = resolver.traits_in_scope(db);
492492

493493
// `ty.iterate_path_candidates()` require a scope, which is not available when resolving
494494
// attributes here. Use path resolution directly instead.
495495
//
496496
// FIXME: resolve type aliases (which are not yielded by iterate_path_candidates)
497-
let interner = DbInterner::new_with(db, environment.krate);
497+
let interner = DbInterner::new_with(db, param_env.krate);
498498
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
499499
let features = resolver.top_level_def_map().features();
500500
let ctx = MethodResolutionContext {
501501
infcx: &infcx,
502502
resolver: &resolver,
503-
param_env: environment.param_env,
503+
param_env: param_env.param_env,
504504
traits_in_scope: &traits_in_scope,
505-
edition: krate.edition(db),
505+
edition: krate.data(db).edition,
506506
features,
507507
call_span: hir_ty::Span::Dummy,
508508
receiver_span: hir_ty::Span::Dummy,
509509
};
510-
let resolution = ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), ty.ty);
510+
let resolution =
511+
ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), ty.ty.skip_binder());
511512
let resolution = match resolution {
512513
Ok(resolution) => resolution.item,
513514
Err(MethodError::PrivateMatch(resolution)) => resolution.item,

crates/hir/src/diagnostics.rs

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ use hir_def::{
1616
use hir_expand::{HirFileId, InFile, mod_path::ModPath, name::Name};
1717
use hir_ty::{
1818
CastError, ExplicitDropMethodUseKind, InferenceDiagnostic, InferenceTyDiagnosticSource,
19-
ParamEnvAndCrate, PathGenericsSource, PathLoweringDiagnostic, TyLoweringDiagnostic,
20-
TyLoweringDiagnosticKind,
19+
PathGenericsSource, PathLoweringDiagnostic, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
2120
db::HirDatabase,
2221
diagnostics::{BodyValidationDiagnostic, UnsafetyReason},
2322
display::{DisplayTarget, HirDisplay},
24-
next_solver::DbInterner,
23+
next_solver::{DbInterner, EarlyBinder},
2524
solver_errors::SolverDiagnosticKind,
2625
};
2726
use stdx::{impl_from, never};
@@ -32,7 +31,7 @@ use syntax::{
3231
};
3332
use triomphe::Arc;
3433

35-
use crate::{AssocItem, Field, Function, GenericDef, Local, Trait, Type, Variant};
34+
use crate::{AssocItem, Field, Function, GenericDef, Local, Trait, Type, TypeOwnerId, Variant};
3635

3736
pub use hir_def::VariantId;
3837
pub use hir_ty::{
@@ -772,7 +771,7 @@ impl<'db> AnyDiagnostic<'db> {
772771
d: &'db InferenceDiagnostic,
773772
source_map: &hir_def::expr_store::BodySourceMap,
774773
sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
775-
env: ParamEnvAndCrate<'db>,
774+
type_owner: TypeOwnerId,
776775
) -> Option<AnyDiagnostic<'db>> {
777776
let expr_syntax = |expr| {
778777
source_map
@@ -796,6 +795,7 @@ impl<'db> AnyDiagnostic<'db> {
796795
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
797796
ExprOrPatId::PatId(pat) => pat_syntax(pat),
798797
};
798+
let new_ty = |ty| Type { owner: type_owner, ty: EarlyBinder::bind(ty) };
799799
let span_syntax = |span| match span {
800800
hir_ty::Span::ExprId(idx) => expr_syntax(idx).map(|it| it.upcast()),
801801
hir_ty::Span::PatId(idx) => pat_syntax(idx).map(|it| it.upcast()),
@@ -825,7 +825,11 @@ impl<'db> AnyDiagnostic<'db> {
825825
}
826826
InferenceDiagnostic::ExpectedArrayOrSlicePat { pat, found } => {
827827
let pat = pat_syntax(*pat)?.map(Into::into);
828-
ExpectedArrayOrSlicePat { pat, found: Type::new(db, def, found.as_ref()) }.into()
828+
ExpectedArrayOrSlicePat {
829+
pat,
830+
found: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
831+
}
832+
.into()
829833
}
830834
&InferenceDiagnostic::InvalidRangePatType { pat } => {
831835
let pat = pat_syntax(pat)?.map(Into::into);
@@ -855,8 +859,7 @@ impl<'db> AnyDiagnostic<'db> {
855859
}
856860
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
857861
let call_expr = expr_syntax(*call_expr)?;
858-
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) }
859-
.into()
862+
ExpectedFunction { call: call_expr, found: new_ty(found.as_ref()) }.into()
860863
}
861864
InferenceDiagnostic::UnresolvedField {
862865
expr,
@@ -868,7 +871,7 @@ impl<'db> AnyDiagnostic<'db> {
868871
UnresolvedField {
869872
expr,
870873
name: name.clone(),
871-
receiver: Type::new(db, def, receiver.as_ref()),
874+
receiver: new_ty(receiver.as_ref()),
872875
method_with_same_name_exists: *method_with_same_name_exists,
873876
}
874877
.into()
@@ -884,10 +887,10 @@ impl<'db> AnyDiagnostic<'db> {
884887
UnresolvedMethodCall {
885888
expr,
886889
name: name.clone(),
887-
receiver: Type::new(db, def, receiver.as_ref()),
890+
receiver: new_ty(receiver.as_ref()),
888891
field_with_same_name: field_with_same_name
889892
.as_ref()
890-
.map(|ty| Type::new(db, def, ty.as_ref())),
893+
.map(|ty| new_ty(ty.as_ref())),
891894
assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
892895
}
893896
.into()
@@ -924,7 +927,7 @@ impl<'db> AnyDiagnostic<'db> {
924927
}
925928
InferenceDiagnostic::TypedHole { expr, expected } => {
926929
let expr = expr_syntax(*expr)?;
927-
TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into()
930+
TypedHole { expr, expected: new_ty(expected.as_ref()) }.into()
928931
}
929932
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
930933
let InFile { file_id, value } = pat_syntax(pat)?;
@@ -935,17 +938,17 @@ impl<'db> AnyDiagnostic<'db> {
935938
}
936939
InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
937940
let expr = expr_syntax(*expr)?;
938-
CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into()
941+
CastToUnsized { expr, cast_ty: new_ty(cast_ty.as_ref()) }.into()
939942
}
940943
InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
941944
let expr = expr_syntax(*expr)?;
942-
let expr_ty = Type::new(db, def, expr_ty.as_ref());
943-
let cast_ty = Type::new(db, def, cast_ty.as_ref());
945+
let expr_ty = new_ty(expr_ty.as_ref());
946+
let cast_ty = new_ty(cast_ty.as_ref());
944947
InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
945948
}
946949
InferenceDiagnostic::CannotBeDereferenced { expr, found } => {
947950
let expr = expr_syntax(*expr)?;
948-
CannotBeDereferenced { expr, found: Type::new(db, def, found.as_ref()) }.into()
951+
CannotBeDereferenced { expr, found: new_ty(found.as_ref()) }.into()
949952
}
950953
InferenceDiagnostic::TyDiagnostic { source, diag } => {
951954
let source_map = match source {
@@ -1020,10 +1023,7 @@ impl<'db> AnyDiagnostic<'db> {
10201023
&InferenceDiagnostic::TypeMustBeKnown { at_point, ref top_term } => {
10211024
let at_point = span_syntax(at_point)?;
10221025
let top_term = top_term.as_ref().map(|top_term| match top_term.as_ref().kind() {
1023-
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(Type {
1024-
ty,
1025-
env: crate::body_param_env_from_has_crate(db, def),
1026-
}),
1026+
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(new_ty(ty)),
10271027
// FIXME: Printing the const to string is definitely not the correct thing to do here.
10281028
rustc_type_ir::GenericArgKind::Const(konst) => Either::Right(
10291029
konst.display(db, DisplayTarget::from_crate(db, def.krate(db))).to_string(),
@@ -1042,14 +1042,14 @@ impl<'db> AnyDiagnostic<'db> {
10421042
let expr_or_pat = expr_or_pat_syntax(*node)?;
10431043
TypeMismatch {
10441044
expr_or_pat,
1045-
expected: Type { env, ty: expected.as_ref() },
1046-
actual: Type { env, ty: found.as_ref() },
1045+
expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) },
1046+
actual: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
10471047
}
10481048
.into()
10491049
}
10501050
InferenceDiagnostic::SolverDiagnostic(d) => {
10511051
let span = span_syntax(d.span)?;
1052-
Self::solver_diagnostic(db, &d.kind, span, env)?
1052+
Self::solver_diagnostic(db, &d.kind, span, type_owner)?
10531053
}
10541054
InferenceDiagnostic::ExplicitDropMethodUse { kind } => {
10551055
let expr_or_path = match kind {
@@ -1077,16 +1077,21 @@ impl<'db> AnyDiagnostic<'db> {
10771077
db: &'db dyn HirDatabase,
10781078
d: &'db SolverDiagnosticKind,
10791079
span: SpanSyntax,
1080-
env: ParamEnvAndCrate<'db>,
1080+
type_owner: TypeOwnerId,
10811081
) -> Option<AnyDiagnostic<'db>> {
10821082
let interner = DbInterner::new_no_crate(db);
10831083
Some(match d {
10841084
SolverDiagnosticKind::TraitUnimplemented { trait_predicate, root_trait_predicate } => {
1085-
let trait_predicate =
1086-
crate::TraitPredicate { inner: trait_predicate.get(interner), env };
1085+
let trait_predicate = crate::TraitPredicate {
1086+
inner: trait_predicate.get(interner),
1087+
owner: type_owner,
1088+
};
10871089
let root_trait_predicate =
10881090
root_trait_predicate.as_ref().map(|root_trait_predicate| {
1089-
crate::TraitPredicate { inner: root_trait_predicate.get(interner), env }
1091+
crate::TraitPredicate {
1092+
inner: root_trait_predicate.get(interner),
1093+
owner: type_owner,
1094+
}
10901095
});
10911096
UnimplementedTrait { span, trait_predicate, root_trait_predicate }.into()
10921097
}

crates/hir/src/display.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::{
3333
Adt, AnyFunctionId, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
3434
EnumVariant, ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl,
3535
LifetimeParam, Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitPredicate,
36-
TraitRef, TupleField, Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union,
36+
TraitRef, TupleField, Type, TypeAlias, TypeOrConstParam, TypeParam, Union,
3737
};
3838

3939
fn write_builtin_derive_impl_method<'db>(
@@ -552,13 +552,7 @@ impl<'db> HirDisplay<'db> for EnumVariant {
552552

553553
impl<'db> HirDisplay<'db> for Type<'db> {
554554
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
555-
self.ty.hir_fmt(f)
556-
}
557-
}
558-
559-
impl<'db> HirDisplay<'db> for TypeNs<'db> {
560-
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
561-
self.ty.hir_fmt(f)
555+
self.ty.skip_binder().hir_fmt(f)
562556
}
563557
}
564558

@@ -598,7 +592,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
598592
let params = GenericParams::of(f.db, self.id.parent());
599593
let param_data = &params[self.id.local_id()];
600594
let krate = self.id.parent().krate(f.db).id;
601-
let ty = self.ty(f.db).ty;
595+
let ty = self.ty(f.db).ty.skip_binder();
602596
let predicates = GenericPredicates::query_all(f.db, self.id.parent());
603597
let predicates = predicates
604598
.iter_identity()

0 commit comments

Comments
 (0)