Skip to content

Commit 0cc7d9e

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 f29cf63 commit 0cc7d9e

37 files changed

Lines changed: 896 additions & 967 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};
34+
use crate::{AssocItem, Field, Function, GenericDef, Local, Trait, Type, TypeOwnerId};
3535

3636
pub use hir_def::VariantId;
3737
pub use hir_ty::{
@@ -712,7 +712,7 @@ impl<'db> AnyDiagnostic<'db> {
712712
d: &'db InferenceDiagnostic,
713713
source_map: &hir_def::expr_store::BodySourceMap,
714714
sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
715-
env: ParamEnvAndCrate<'db>,
715+
type_owner: TypeOwnerId,
716716
) -> Option<AnyDiagnostic<'db>> {
717717
let expr_syntax = |expr| {
718718
source_map
@@ -736,6 +736,7 @@ impl<'db> AnyDiagnostic<'db> {
736736
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
737737
ExprOrPatId::PatId(pat) => pat_syntax(pat),
738738
};
739+
let generic_def = || def.generic_def(db);
739740
let span_syntax = |span| match span {
740741
hir_ty::Span::ExprId(idx) => expr_syntax(idx).map(|it| it.upcast()),
741742
hir_ty::Span::PatId(idx) => pat_syntax(idx).map(|it| it.upcast()),
@@ -778,8 +779,11 @@ impl<'db> AnyDiagnostic<'db> {
778779
}
779780
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
780781
let call_expr = expr_syntax(*call_expr)?;
781-
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) }
782-
.into()
782+
ExpectedFunction {
783+
call: call_expr,
784+
found: Type::new(generic_def(), found.as_ref()),
785+
}
786+
.into()
783787
}
784788
InferenceDiagnostic::UnresolvedField {
785789
expr,
@@ -791,7 +795,7 @@ impl<'db> AnyDiagnostic<'db> {
791795
UnresolvedField {
792796
expr,
793797
name: name.clone(),
794-
receiver: Type::new(db, def, receiver.as_ref()),
798+
receiver: Type::new(generic_def(), receiver.as_ref()),
795799
method_with_same_name_exists: *method_with_same_name_exists,
796800
}
797801
.into()
@@ -807,10 +811,10 @@ impl<'db> AnyDiagnostic<'db> {
807811
UnresolvedMethodCall {
808812
expr,
809813
name: name.clone(),
810-
receiver: Type::new(db, def, receiver.as_ref()),
814+
receiver: Type::new(generic_def(), receiver.as_ref()),
811815
field_with_same_name: field_with_same_name
812816
.as_ref()
813-
.map(|ty| Type::new(db, def, ty.as_ref())),
817+
.map(|ty| Type::new(generic_def(), ty.as_ref())),
814818
assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
815819
}
816820
.into()
@@ -840,7 +844,7 @@ impl<'db> AnyDiagnostic<'db> {
840844
}
841845
InferenceDiagnostic::TypedHole { expr, expected } => {
842846
let expr = expr_syntax(*expr)?;
843-
TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into()
847+
TypedHole { expr, expected: Type::new(generic_def(), expected.as_ref()) }.into()
844848
}
845849
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
846850
let InFile { file_id, value } = pat_syntax(pat)?;
@@ -851,12 +855,12 @@ impl<'db> AnyDiagnostic<'db> {
851855
}
852856
InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
853857
let expr = expr_syntax(*expr)?;
854-
CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into()
858+
CastToUnsized { expr, cast_ty: Type::new(generic_def(), cast_ty.as_ref()) }.into()
855859
}
856860
InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
857861
let expr = expr_syntax(*expr)?;
858-
let expr_ty = Type::new(db, def, expr_ty.as_ref());
859-
let cast_ty = Type::new(db, def, cast_ty.as_ref());
862+
let expr_ty = Type::new(generic_def(), expr_ty.as_ref());
863+
let cast_ty = Type::new(generic_def(), cast_ty.as_ref());
860864
InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
861865
}
862866
InferenceDiagnostic::TyDiagnostic { source, diag } => {
@@ -929,10 +933,9 @@ impl<'db> AnyDiagnostic<'db> {
929933
&InferenceDiagnostic::TypeMustBeKnown { at_point, ref top_term } => {
930934
let at_point = span_syntax(at_point)?;
931935
let top_term = top_term.as_ref().map(|top_term| match top_term.as_ref().kind() {
932-
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(Type {
933-
ty,
934-
env: crate::body_param_env_from_has_crate(db, def),
935-
}),
936+
rustc_type_ir::GenericArgKind::Type(ty) => {
937+
Either::Left(Type::new(generic_def(), ty))
938+
}
936939
// FIXME: Printing the const to string is definitely not the correct thing to do here.
937940
rustc_type_ir::GenericArgKind::Const(konst) => Either::Right(
938941
konst.display(db, DisplayTarget::from_crate(db, def.krate(db))).to_string(),
@@ -951,14 +954,14 @@ impl<'db> AnyDiagnostic<'db> {
951954
let expr_or_pat = expr_or_pat_syntax(*node)?;
952955
TypeMismatch {
953956
expr_or_pat,
954-
expected: Type { env, ty: expected.as_ref() },
955-
actual: Type { env, ty: found.as_ref() },
957+
expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) },
958+
actual: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
956959
}
957960
.into()
958961
}
959962
InferenceDiagnostic::SolverDiagnostic(d) => {
960963
let span = span_syntax(d.span)?;
961-
Self::solver_diagnostic(db, &d.kind, span, env)?
964+
Self::solver_diagnostic(db, &d.kind, span, type_owner)?
962965
}
963966
})
964967
}
@@ -967,16 +970,21 @@ impl<'db> AnyDiagnostic<'db> {
967970
db: &'db dyn HirDatabase,
968971
d: &'db SolverDiagnosticKind,
969972
span: SpanSyntax,
970-
env: ParamEnvAndCrate<'db>,
973+
type_owner: TypeOwnerId,
971974
) -> Option<AnyDiagnostic<'db>> {
972975
let interner = DbInterner::new_no_crate(db);
973976
Some(match d {
974977
SolverDiagnosticKind::TraitUnimplemented { trait_predicate, root_trait_predicate } => {
975-
let trait_predicate =
976-
crate::TraitPredicate { inner: trait_predicate.get(interner), env };
978+
let trait_predicate = crate::TraitPredicate {
979+
inner: trait_predicate.get(interner),
980+
owner: type_owner,
981+
};
977982
let root_trait_predicate =
978983
root_trait_predicate.as_ref().map(|root_trait_predicate| {
979-
crate::TraitPredicate { inner: root_trait_predicate.get(interner), env }
984+
crate::TraitPredicate {
985+
inner: root_trait_predicate.get(interner),
986+
owner: type_owner,
987+
}
980988
});
981989
UnimplementedTrait { span, trait_predicate, root_trait_predicate }.into()
982990
}

crates/hir/src/display.rs

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

3737
fn write_builtin_derive_impl_method<'db>(
@@ -532,13 +532,7 @@ impl<'db> HirDisplay<'db> for EnumVariant {
532532

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

@@ -578,7 +572,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
578572
let params = GenericParams::of(f.db, self.id.parent());
579573
let param_data = &params[self.id.local_id()];
580574
let krate = self.id.parent().krate(f.db).id;
581-
let ty = self.ty(f.db).ty;
575+
let ty = self.ty(f.db).ty.skip_binder();
582576
let predicates = GenericPredicates::query_all(f.db, self.id.parent());
583577
let predicates = predicates
584578
.iter_identity()

0 commit comments

Comments
 (0)