Skip to content

Commit 2f34ce7

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 f73e9bf commit 2f34ce7

37 files changed

Lines changed: 944 additions & 984 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: 38 additions & 26 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::{
@@ -733,7 +733,7 @@ impl<'db> AnyDiagnostic<'db> {
733733
d: &'db InferenceDiagnostic,
734734
source_map: &hir_def::expr_store::BodySourceMap,
735735
sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
736-
env: ParamEnvAndCrate<'db>,
736+
type_owner: TypeOwnerId,
737737
) -> Option<AnyDiagnostic<'db>> {
738738
let expr_syntax = |expr| {
739739
source_map
@@ -757,6 +757,7 @@ impl<'db> AnyDiagnostic<'db> {
757757
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
758758
ExprOrPatId::PatId(pat) => pat_syntax(pat),
759759
};
760+
let generic_def = || def.generic_def(db);
760761
let span_syntax = |span| match span {
761762
hir_ty::Span::ExprId(idx) => expr_syntax(idx).map(|it| it.upcast()),
762763
hir_ty::Span::PatId(idx) => pat_syntax(idx).map(|it| it.upcast()),
@@ -786,7 +787,11 @@ impl<'db> AnyDiagnostic<'db> {
786787
}
787788
InferenceDiagnostic::ExpectedArrayOrSlicePat { pat, found } => {
788789
let pat = pat_syntax(*pat)?.map(Into::into);
789-
ExpectedArrayOrSlicePat { pat, found: Type::new(db, def, found.as_ref()) }.into()
790+
ExpectedArrayOrSlicePat {
791+
pat,
792+
found: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
793+
}
794+
.into()
790795
}
791796
&InferenceDiagnostic::DuplicateField { field: expr, variant } => {
792797
let expr_or_pat = match expr {
@@ -812,8 +817,11 @@ impl<'db> AnyDiagnostic<'db> {
812817
}
813818
InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
814819
let call_expr = expr_syntax(*call_expr)?;
815-
ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) }
816-
.into()
820+
ExpectedFunction {
821+
call: call_expr,
822+
found: Type::new(generic_def(), found.as_ref()),
823+
}
824+
.into()
817825
}
818826
InferenceDiagnostic::UnresolvedField {
819827
expr,
@@ -825,7 +833,7 @@ impl<'db> AnyDiagnostic<'db> {
825833
UnresolvedField {
826834
expr,
827835
name: name.clone(),
828-
receiver: Type::new(db, def, receiver.as_ref()),
836+
receiver: Type::new(generic_def(), receiver.as_ref()),
829837
method_with_same_name_exists: *method_with_same_name_exists,
830838
}
831839
.into()
@@ -841,10 +849,10 @@ impl<'db> AnyDiagnostic<'db> {
841849
UnresolvedMethodCall {
842850
expr,
843851
name: name.clone(),
844-
receiver: Type::new(db, def, receiver.as_ref()),
852+
receiver: Type::new(generic_def(), receiver.as_ref()),
845853
field_with_same_name: field_with_same_name
846854
.as_ref()
847-
.map(|ty| Type::new(db, def, ty.as_ref())),
855+
.map(|ty| Type::new(generic_def(), ty.as_ref())),
848856
assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
849857
}
850858
.into()
@@ -877,7 +885,7 @@ impl<'db> AnyDiagnostic<'db> {
877885
}
878886
InferenceDiagnostic::TypedHole { expr, expected } => {
879887
let expr = expr_syntax(*expr)?;
880-
TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into()
888+
TypedHole { expr, expected: Type::new(generic_def(), expected.as_ref()) }.into()
881889
}
882890
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
883891
let InFile { file_id, value } = pat_syntax(pat)?;
@@ -888,12 +896,12 @@ impl<'db> AnyDiagnostic<'db> {
888896
}
889897
InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
890898
let expr = expr_syntax(*expr)?;
891-
CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into()
899+
CastToUnsized { expr, cast_ty: Type::new(generic_def(), cast_ty.as_ref()) }.into()
892900
}
893901
InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
894902
let expr = expr_syntax(*expr)?;
895-
let expr_ty = Type::new(db, def, expr_ty.as_ref());
896-
let cast_ty = Type::new(db, def, cast_ty.as_ref());
903+
let expr_ty = Type::new(generic_def(), expr_ty.as_ref());
904+
let cast_ty = Type::new(generic_def(), cast_ty.as_ref());
897905
InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
898906
}
899907
InferenceDiagnostic::TyDiagnostic { source, diag } => {
@@ -966,10 +974,9 @@ impl<'db> AnyDiagnostic<'db> {
966974
&InferenceDiagnostic::TypeMustBeKnown { at_point, ref top_term } => {
967975
let at_point = span_syntax(at_point)?;
968976
let top_term = top_term.as_ref().map(|top_term| match top_term.as_ref().kind() {
969-
rustc_type_ir::GenericArgKind::Type(ty) => Either::Left(Type {
970-
ty,
971-
env: crate::body_param_env_from_has_crate(db, def),
972-
}),
977+
rustc_type_ir::GenericArgKind::Type(ty) => {
978+
Either::Left(Type::new(generic_def(), ty))
979+
}
973980
// FIXME: Printing the const to string is definitely not the correct thing to do here.
974981
rustc_type_ir::GenericArgKind::Const(konst) => Either::Right(
975982
konst.display(db, DisplayTarget::from_crate(db, def.krate(db))).to_string(),
@@ -988,14 +995,14 @@ impl<'db> AnyDiagnostic<'db> {
988995
let expr_or_pat = expr_or_pat_syntax(*node)?;
989996
TypeMismatch {
990997
expr_or_pat,
991-
expected: Type { env, ty: expected.as_ref() },
992-
actual: Type { env, ty: found.as_ref() },
998+
expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) },
999+
actual: Type { owner: type_owner, ty: EarlyBinder::bind(found.as_ref()) },
9931000
}
9941001
.into()
9951002
}
9961003
InferenceDiagnostic::SolverDiagnostic(d) => {
9971004
let span = span_syntax(d.span)?;
998-
Self::solver_diagnostic(db, &d.kind, span, env)?
1005+
Self::solver_diagnostic(db, &d.kind, span, type_owner)?
9991006
}
10001007
})
10011008
}
@@ -1004,16 +1011,21 @@ impl<'db> AnyDiagnostic<'db> {
10041011
db: &'db dyn HirDatabase,
10051012
d: &'db SolverDiagnosticKind,
10061013
span: SpanSyntax,
1007-
env: ParamEnvAndCrate<'db>,
1014+
type_owner: TypeOwnerId,
10081015
) -> Option<AnyDiagnostic<'db>> {
10091016
let interner = DbInterner::new_no_crate(db);
10101017
Some(match d {
10111018
SolverDiagnosticKind::TraitUnimplemented { trait_predicate, root_trait_predicate } => {
1012-
let trait_predicate =
1013-
crate::TraitPredicate { inner: trait_predicate.get(interner), env };
1019+
let trait_predicate = crate::TraitPredicate {
1020+
inner: trait_predicate.get(interner),
1021+
owner: type_owner,
1022+
};
10141023
let root_trait_predicate =
10151024
root_trait_predicate.as_ref().map(|root_trait_predicate| {
1016-
crate::TraitPredicate { inner: root_trait_predicate.get(interner), env }
1025+
crate::TraitPredicate {
1026+
inner: root_trait_predicate.get(interner),
1027+
owner: type_owner,
1028+
}
10171029
});
10181030
UnimplementedTrait { span, trait_predicate, root_trait_predicate }.into()
10191031
}

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)