Skip to content

Commit fbe801a

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 c6786ca commit fbe801a

38 files changed

Lines changed: 950 additions & 994 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: 33 additions & 28 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::{
@@ -791,7 +790,7 @@ impl<'db> AnyDiagnostic<'db> {
791790
d: &'db InferenceDiagnostic,
792791
source_map: &hir_def::expr_store::BodySourceMap,
793792
sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
794-
env: ParamEnvAndCrate<'db>,
793+
type_owner: TypeOwnerId,
795794
) -> Option<AnyDiagnostic<'db>> {
796795
let expr_syntax = |expr| {
797796
source_map
@@ -815,6 +814,7 @@ impl<'db> AnyDiagnostic<'db> {
815814
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
816815
ExprOrPatId::PatId(pat) => pat_syntax(pat),
817816
};
817+
let new_ty = |ty| Type { owner: type_owner, ty: EarlyBinder::bind(ty) };
818818
let span_syntax = |span| match span {
819819
hir_ty::Span::ExprId(idx) => expr_syntax(idx).map(|it| it.upcast()),
820820
hir_ty::Span::PatId(idx) => pat_syntax(idx).map(|it| it.upcast()),
@@ -848,7 +848,11 @@ impl<'db> AnyDiagnostic<'db> {
848848
}
849849
InferenceDiagnostic::ExpectedArrayOrSlicePat { pat, found } => {
850850
let pat = pat_syntax(*pat)?.map(Into::into);
851-
ExpectedArrayOrSlicePat { pat, found: Type::new(db, def, found.as_ref()) }.into()
851+
ExpectedArrayOrSlicePat {
852+
pat,
853+
found: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
854+
}
855+
.into()
852856
}
853857
&InferenceDiagnostic::InvalidRangePatType { pat } => {
854858
let pat = pat_syntax(pat)?.map(Into::into);
@@ -878,8 +882,7 @@ impl<'db> AnyDiagnostic<'db> {
878882
}
879883
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
880884
let call_expr = expr_syntax(*call_expr)?;
881-
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) }
882-
.into()
885+
ExpectedFunction { call: call_expr, found: new_ty(found.as_ref()) }.into()
883886
}
884887
InferenceDiagnostic::UnresolvedField {
885888
expr,
@@ -891,7 +894,7 @@ impl<'db> AnyDiagnostic<'db> {
891894
UnresolvedField {
892895
expr,
893896
name: name.clone(),
894-
receiver: Type::new(db, def, receiver.as_ref()),
897+
receiver: new_ty(receiver.as_ref()),
895898
method_with_same_name_exists: *method_with_same_name_exists,
896899
}
897900
.into()
@@ -907,10 +910,10 @@ impl<'db> AnyDiagnostic<'db> {
907910
UnresolvedMethodCall {
908911
expr,
909912
name: name.clone(),
910-
receiver: Type::new(db, def, receiver.as_ref()),
913+
receiver: new_ty(receiver.as_ref()),
911914
field_with_same_name: field_with_same_name
912915
.as_ref()
913-
.map(|ty| Type::new(db, def, ty.as_ref())),
916+
.map(|ty| new_ty(ty.as_ref())),
914917
assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
915918
}
916919
.into()
@@ -947,7 +950,7 @@ impl<'db> AnyDiagnostic<'db> {
947950
}
948951
InferenceDiagnostic::TypedHole { expr, expected } => {
949952
let expr = expr_syntax(*expr)?;
950-
TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into()
953+
TypedHole { expr, expected: new_ty(expected.as_ref()) }.into()
951954
}
952955
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
953956
let InFile { file_id, value } = pat_syntax(pat)?;
@@ -958,21 +961,21 @@ impl<'db> AnyDiagnostic<'db> {
958961
}
959962
InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
960963
let expr = expr_syntax(*expr)?;
961-
CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into()
964+
CastToUnsized { expr, cast_ty: new_ty(cast_ty.as_ref()) }.into()
962965
}
963966
InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
964967
let expr = expr_syntax(*expr)?;
965-
let expr_ty = Type::new(db, def, expr_ty.as_ref());
966-
let cast_ty = Type::new(db, def, cast_ty.as_ref());
968+
let expr_ty = new_ty(expr_ty.as_ref());
969+
let cast_ty = new_ty(cast_ty.as_ref());
967970
InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
968971
}
969972
InferenceDiagnostic::CannotBeDereferenced { expr, found } => {
970973
let expr = expr_syntax(*expr)?;
971-
CannotBeDereferenced { expr, found: Type::new(db, def, found.as_ref()) }.into()
974+
CannotBeDereferenced { expr, found: new_ty(found.as_ref()) }.into()
972975
}
973976
InferenceDiagnostic::CannotIndexInto { expr, found } => {
974977
let expr = expr_syntax(*expr)?;
975-
CannotIndexInto { expr, found: Type::new(db, def, found.as_ref()) }.into()
978+
CannotIndexInto { expr, found: new_ty(found.as_ref()) }.into()
976979
}
977980
InferenceDiagnostic::TyDiagnostic { source, diag } => {
978981
let source_map = match source {
@@ -1047,10 +1050,7 @@ impl<'db> AnyDiagnostic<'db> {
10471050
&InferenceDiagnostic::TypeMustBeKnown { at_point, ref top_term } => {
10481051
let at_point = span_syntax(at_point)?;
10491052
let top_term = top_term.as_ref().map(|top_term| match top_term.as_ref().kind() {
1050-
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(Type {
1051-
ty,
1052-
env: crate::body_param_env_from_has_crate(db, def),
1053-
}),
1053+
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(new_ty(ty)),
10541054
// FIXME: Printing the const to string is definitely not the correct thing to do here.
10551055
rustc_type_ir::GenericArgKind::Const(konst) => Either::Right(
10561056
konst.display(db, DisplayTarget::from_crate(db, def.krate(db))).to_string(),
@@ -1069,14 +1069,14 @@ impl<'db> AnyDiagnostic<'db> {
10691069
let expr_or_pat = expr_or_pat_syntax(*node)?;
10701070
TypeMismatch {
10711071
expr_or_pat,
1072-
expected: Type { env, ty: expected.as_ref() },
1073-
actual: Type { env, ty: found.as_ref() },
1072+
expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) },
1073+
actual: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
10741074
}
10751075
.into()
10761076
}
10771077
InferenceDiagnostic::SolverDiagnostic(d) => {
10781078
let span = span_syntax(d.span)?;
1079-
Self::solver_diagnostic(db, &d.kind, span, env)?
1079+
Self::solver_diagnostic(db, &d.kind, span, type_owner)?
10801080
}
10811081
InferenceDiagnostic::ExplicitDropMethodUse { kind } => {
10821082
let expr_or_path = match kind {
@@ -1108,16 +1108,21 @@ impl<'db> AnyDiagnostic<'db> {
11081108
db: &'db dyn HirDatabase,
11091109
d: &'db SolverDiagnosticKind,
11101110
span: SpanSyntax,
1111-
env: ParamEnvAndCrate<'db>,
1111+
type_owner: TypeOwnerId,
11121112
) -> Option<AnyDiagnostic<'db>> {
11131113
let interner = DbInterner::new_no_crate(db);
11141114
Some(match d {
11151115
SolverDiagnosticKind::TraitUnimplemented { trait_predicate, root_trait_predicate } => {
1116-
let trait_predicate =
1117-
crate::TraitPredicate { inner: trait_predicate.get(interner), env };
1116+
let trait_predicate = crate::TraitPredicate {
1117+
inner: trait_predicate.get(interner),
1118+
owner: type_owner,
1119+
};
11181120
let root_trait_predicate =
11191121
root_trait_predicate.as_ref().map(|root_trait_predicate| {
1120-
crate::TraitPredicate { inner: root_trait_predicate.get(interner), env }
1122+
crate::TraitPredicate {
1123+
inner: root_trait_predicate.get(interner),
1124+
owner: type_owner,
1125+
}
11211126
});
11221127
UnimplementedTrait { span, trait_predicate, root_trait_predicate }.into()
11231128
}

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)