Skip to content

Commit 59ce96f

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 a858e4b commit 59ce96f

37 files changed

Lines changed: 935 additions & 975 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 & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ use hir_def::{
1515
};
1616
use hir_expand::{HirFileId, InFile, mod_path::ModPath, name::Name};
1717
use hir_ty::{
18-
CastError, InferenceDiagnostic, InferenceTyDiagnosticSource, ParamEnvAndCrate,
19-
PathGenericsSource, PathLoweringDiagnostic, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
18+
CastError, InferenceDiagnostic, InferenceTyDiagnosticSource, PathGenericsSource,
19+
PathLoweringDiagnostic, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
2020
db::HirDatabase,
2121
diagnostics::{BodyValidationDiagnostic, UnsafetyReason},
2222
display::{DisplayTarget, HirDisplay},
23-
next_solver::DbInterner,
23+
next_solver::{DbInterner, EarlyBinder},
2424
solver_errors::SolverDiagnosticKind,
2525
};
2626
use stdx::{impl_from, never};
@@ -31,7 +31,7 @@ use syntax::{
3131
};
3232
use triomphe::Arc;
3333

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

3636
pub use hir_def::VariantId;
3737
pub use hir_ty::{
@@ -726,7 +726,7 @@ impl<'db> AnyDiagnostic<'db> {
726726
d: &'db InferenceDiagnostic,
727727
source_map: &hir_def::expr_store::BodySourceMap,
728728
sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
729-
env: ParamEnvAndCrate<'db>,
729+
type_owner: TypeOwnerId,
730730
) -> Option<AnyDiagnostic<'db>> {
731731
let expr_syntax = |expr| {
732732
source_map
@@ -750,6 +750,7 @@ impl<'db> AnyDiagnostic<'db> {
750750
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
751751
ExprOrPatId::PatId(pat) => pat_syntax(pat),
752752
};
753+
let generic_def = || def.generic_def(db);
753754
let span_syntax = |span| match span {
754755
hir_ty::Span::ExprId(idx) => expr_syntax(idx).map(|it| it.upcast()),
755756
hir_ty::Span::PatId(idx) => pat_syntax(idx).map(|it| it.upcast()),
@@ -801,8 +802,11 @@ impl<'db> AnyDiagnostic<'db> {
801802
}
802803
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
803804
let call_expr = expr_syntax(*call_expr)?;
804-
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) }
805-
.into()
805+
ExpectedFunction {
806+
call: call_expr,
807+
found: Type::new(generic_def(), found.as_ref()),
808+
}
809+
.into()
806810
}
807811
InferenceDiagnostic::UnresolvedField {
808812
expr,
@@ -814,7 +818,7 @@ impl<'db> AnyDiagnostic<'db> {
814818
UnresolvedField {
815819
expr,
816820
name: name.clone(),
817-
receiver: Type::new(db, def, receiver.as_ref()),
821+
receiver: Type::new(generic_def(), receiver.as_ref()),
818822
method_with_same_name_exists: *method_with_same_name_exists,
819823
}
820824
.into()
@@ -830,10 +834,10 @@ impl<'db> AnyDiagnostic<'db> {
830834
UnresolvedMethodCall {
831835
expr,
832836
name: name.clone(),
833-
receiver: Type::new(db, def, receiver.as_ref()),
837+
receiver: Type::new(generic_def(), receiver.as_ref()),
834838
field_with_same_name: field_with_same_name
835839
.as_ref()
836-
.map(|ty| Type::new(db, def, ty.as_ref())),
840+
.map(|ty| Type::new(generic_def(), ty.as_ref())),
837841
assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
838842
}
839843
.into()
@@ -866,7 +870,7 @@ impl<'db> AnyDiagnostic<'db> {
866870
}
867871
InferenceDiagnostic::TypedHole { expr, expected } => {
868872
let expr = expr_syntax(*expr)?;
869-
TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into()
873+
TypedHole { expr, expected: Type::new(generic_def(), expected.as_ref()) }.into()
870874
}
871875
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
872876
let InFile { file_id, value } = pat_syntax(pat)?;
@@ -877,12 +881,12 @@ impl<'db> AnyDiagnostic<'db> {
877881
}
878882
InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
879883
let expr = expr_syntax(*expr)?;
880-
CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into()
884+
CastToUnsized { expr, cast_ty: Type::new(generic_def(), cast_ty.as_ref()) }.into()
881885
}
882886
InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
883887
let expr = expr_syntax(*expr)?;
884-
let expr_ty = Type::new(db, def, expr_ty.as_ref());
885-
let cast_ty = Type::new(db, def, cast_ty.as_ref());
888+
let expr_ty = Type::new(generic_def(), expr_ty.as_ref());
889+
let cast_ty = Type::new(generic_def(), cast_ty.as_ref());
886890
InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
887891
}
888892
InferenceDiagnostic::TyDiagnostic { source, diag } => {
@@ -955,10 +959,9 @@ impl<'db> AnyDiagnostic<'db> {
955959
&InferenceDiagnostic::TypeMustBeKnown { at_point, ref top_term } => {
956960
let at_point = span_syntax(at_point)?;
957961
let top_term = top_term.as_ref().map(|top_term| match top_term.as_ref().kind() {
958-
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(Type {
959-
ty,
960-
env: crate::body_param_env_from_has_crate(db, def),
961-
}),
962+
rustc_type_ir::GenericArgKind::Type(ty) => {
963+
Either::Left(Type::new(generic_def(), ty))
964+
}
962965
// FIXME: Printing the const to string is definitely not the correct thing to do here.
963966
rustc_type_ir::GenericArgKind::Const(konst) => Either::Right(
964967
konst.display(db, DisplayTarget::from_crate(db, def.krate(db))).to_string(),
@@ -977,14 +980,14 @@ impl<'db> AnyDiagnostic<'db> {
977980
let expr_or_pat = expr_or_pat_syntax(*node)?;
978981
TypeMismatch {
979982
expr_or_pat,
980-
expected: Type { env, ty: expected.as_ref() },
981-
actual: Type { env, ty: found.as_ref() },
983+
expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) },
984+
actual: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
982985
}
983986
.into()
984987
}
985988
InferenceDiagnostic::SolverDiagnostic(d) => {
986989
let span = span_syntax(d.span)?;
987-
Self::solver_diagnostic(db, &d.kind, span, env)?
990+
Self::solver_diagnostic(db, &d.kind, span, type_owner)?
988991
}
989992
})
990993
}
@@ -993,16 +996,21 @@ impl<'db> AnyDiagnostic<'db> {
993996
db: &'db dyn HirDatabase,
994997
d: &'db SolverDiagnosticKind,
995998
span: SpanSyntax,
996-
env: ParamEnvAndCrate<'db>,
999+
type_owner: TypeOwnerId,
9971000
) -> Option<AnyDiagnostic<'db>> {
9981001
let interner = DbInterner::new_no_crate(db);
9991002
Some(match d {
10001003
SolverDiagnosticKind::TraitUnimplemented { trait_predicate, root_trait_predicate } => {
1001-
let trait_predicate =
1002-
crate::TraitPredicate { inner: trait_predicate.get(interner), env };
1004+
let trait_predicate = crate::TraitPredicate {
1005+
inner: trait_predicate.get(interner),
1006+
owner: type_owner,
1007+
};
10031008
let root_trait_predicate =
10041009
root_trait_predicate.as_ref().map(|root_trait_predicate| {
1005-
crate::TraitPredicate { inner: root_trait_predicate.get(interner), env }
1010+
crate::TraitPredicate {
1011+
inner: root_trait_predicate.get(interner),
1012+
owner: type_owner,
1013+
}
10061014
});
10071015
UnimplementedTrait { span, trait_predicate, root_trait_predicate }.into()
10081016
}

crates/hir/src/display.rs

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

3838
fn write_builtin_derive_impl_method<'db>(
@@ -533,13 +533,7 @@ impl<'db> HirDisplay<'db> for EnumVariant {
533533

534534
impl<'db> HirDisplay<'db> for Type<'db> {
535535
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
536-
self.ty.hir_fmt(f)
537-
}
538-
}
539-
540-
impl<'db> HirDisplay<'db> for TypeNs<'db> {
541-
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
542-
self.ty.hir_fmt(f)
536+
self.ty.skip_binder().hir_fmt(f)
543537
}
544538
}
545539

@@ -579,7 +573,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
579573
let params = GenericParams::of(f.db, self.id.parent());
580574
let param_data = &params[self.id.local_id()];
581575
let krate = self.id.parent().krate(f.db).id;
582-
let ty = self.ty(f.db).ty;
576+
let ty = self.ty(f.db).ty.skip_binder();
583577
let predicates = GenericPredicates::query_all(f.db, self.id.parent());
584578
let predicates = predicates
585579
.iter_identity()

0 commit comments

Comments
 (0)