Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21059 from ChayimFriedman2/trait-env
fix: Derive ParamEnv from GenericPredicates
Shoyu Vanilla (Flint) 5 months ago
parent e8e02d5 · parent 9ceff9f · commit c904df0
-rw-r--r--crates/hir-ty/src/generics.rs5
-rw-r--r--crates/hir-ty/src/lower.rs112
-rw-r--r--crates/hir-ty/src/tests/incremental.rs19
-rw-r--r--crates/hir-ty/src/tests/traits.rs26
-rw-r--r--crates/ide-completion/src/tests/flyimport.rs2
5 files changed, 54 insertions, 110 deletions
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index 26e03aa01a..5f0261437b 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/crates/hir-ty/src/generics.rs
@@ -60,11 +60,6 @@ impl Generics {
self.params.where_predicates().iter()
}
- pub(crate) fn has_no_predicates(&self) -> bool {
- self.params.has_no_predicates()
- && self.parent_generics.as_ref().is_none_or(|g| g.params.has_no_predicates())
- }
-
pub(crate) fn is_empty(&self) -> bool {
self.params.is_empty() && self.parent_generics.as_ref().is_none_or(|g| g.params.is_empty())
}
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index adc48b57d5..a20c299d0c 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -1624,105 +1624,23 @@ pub(crate) fn trait_environment_query<'db>(
db: &'db dyn HirDatabase,
def: GenericDefId,
) -> Arc<TraitEnvironment<'db>> {
- let generics = generics(db, def);
- if generics.has_no_predicates() && generics.is_empty() {
- return TraitEnvironment::empty(def.krate(db));
- }
-
- let resolver = def.resolver(db);
- let mut ctx = TyLoweringContext::new(
- db,
- &resolver,
- generics.store(),
- def,
- LifetimeElisionKind::AnonymousReportError,
- );
- let mut traits_in_scope = Vec::new();
- let mut clauses = Vec::new();
- for maybe_parent_generics in
- std::iter::successors(Some(&generics), |generics| generics.parent_generics())
- {
- ctx.store = maybe_parent_generics.store();
- for pred in maybe_parent_generics.where_predicates() {
- for pred in ctx.lower_where_predicate(pred, false, &generics, PredicateFilter::All) {
- if let rustc_type_ir::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
- traits_in_scope.push((tr.self_ty(), tr.def_id().0));
- }
- clauses.push(pred);
- }
- }
-
- push_const_arg_has_type_predicates(db, &mut clauses, maybe_parent_generics);
- }
-
- if let Some(trait_id) = def.assoc_trait_container(db) {
- // add `Self: Trait<T1, T2, ...>` to the environment in trait
- // function default implementations (and speculative code
- // inside consts or type aliases)
- cov_mark::hit!(trait_self_implements_self);
- let trait_ref = TraitRef::identity(ctx.interner, trait_id.into());
- let clause = Clause(Predicate::new(
- ctx.interner,
- Binder::dummy(rustc_type_ir::PredicateKind::Clause(rustc_type_ir::ClauseKind::Trait(
- TraitPredicate { trait_ref, polarity: rustc_type_ir::PredicatePolarity::Positive },
- ))),
- ));
- clauses.push(clause);
- }
-
- let explicitly_unsized_tys = ctx.unsized_types;
-
- let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
- if let Some(sized_trait) = sized_trait {
- let (mut generics, mut def_id) =
- (crate::next_solver::generics::generics(db, def.into()), def);
- loop {
- let self_idx = trait_self_param_idx(db, def_id);
- for (idx, p) in generics.own_params.iter().enumerate() {
- if let Some(self_idx) = self_idx
- && p.index() as usize == self_idx
- {
- continue;
- }
- let GenericParamId::TypeParamId(param_id) = p.id else {
- continue;
- };
- let idx = idx as u32 + generics.parent_count as u32;
- let param_ty = Ty::new_param(ctx.interner, param_id, idx);
- if explicitly_unsized_tys.contains(&param_ty) {
- continue;
- }
- let trait_ref = TraitRef::new_from_args(
- ctx.interner,
- sized_trait.into(),
- GenericArgs::new_from_iter(ctx.interner, [param_ty.into()]),
- );
- let clause = Clause(Predicate::new(
- ctx.interner,
- Binder::dummy(rustc_type_ir::PredicateKind::Clause(
- rustc_type_ir::ClauseKind::Trait(TraitPredicate {
- trait_ref,
- polarity: rustc_type_ir::PredicatePolarity::Positive,
- }),
- )),
- ));
- clauses.push(clause);
- }
-
- if let Some(g) = generics.parent {
- generics = crate::next_solver::generics::generics(db, g.into());
- def_id = g;
- } else {
- break;
- }
- }
- }
-
- let clauses = rustc_type_ir::elaborate::elaborate(ctx.interner, clauses);
- let clauses = Clauses::new_from_iter(ctx.interner, clauses);
+ let module = def.module(db);
+ let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
+ let predicates = GenericPredicates::query_all(db, def);
+ let traits_in_scope = predicates
+ .iter_identity_copied()
+ .filter_map(|pred| match pred.kind().skip_binder() {
+ ClauseKind::Trait(tr) => Some((tr.self_ty(), tr.def_id().0)),
+ _ => None,
+ })
+ .collect();
+ let clauses = rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied());
+ let clauses = Clauses::new_from_iter(interner, clauses);
let env = ParamEnv { clauses };
- TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env)
+ // FIXME: We should normalize projections here, like rustc does.
+
+ TraitEnvironment::new(module.krate(), module.containing_block(), traits_in_scope, env)
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index 1b64bfddb8..e98e5e4828 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -44,10 +44,12 @@ fn foo() -> i32 {
"body_shim",
"body_with_source_map_shim",
"trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
+ "lang_item",
+ "crate_lang_items",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
"lang_item",
- "crate_lang_items",
]
"#]],
);
@@ -131,18 +133,21 @@ fn baz() -> i32 {
"body_shim",
"body_with_source_map_shim",
"trait_environment_shim",
- "ImplTraits < 'db >::return_type_impl_traits_",
- "expr_scopes_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"lang_item",
"crate_lang_items",
"attrs_shim",
"attrs_shim",
+ "ImplTraits < 'db >::return_type_impl_traits_",
+ "expr_scopes_shim",
+ "lang_item",
"infer_shim",
"function_signature_shim",
"function_signature_with_source_map_shim",
"body_shim",
"body_with_source_map_shim",
"trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
"infer_shim",
@@ -151,6 +156,7 @@ fn baz() -> i32 {
"body_shim",
"body_with_source_map_shim",
"trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
]
@@ -581,6 +587,7 @@ fn main() {
"body_shim",
"body_with_source_map_shim",
"trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"lang_item",
"crate_lang_items",
"attrs_shim",
@@ -591,6 +598,7 @@ fn main() {
"function_signature_shim",
"function_signature_with_source_map_shim",
"trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
"struct_signature_shim",
@@ -609,7 +617,6 @@ fn main() {
"impl_trait_with_diagnostics_shim",
"impl_self_ty_with_diagnostics_shim",
"GenericPredicates < 'db >::query_with_diagnostics_",
- "GenericPredicates < 'db >::query_with_diagnostics_",
"lang_item",
]
"#]],
@@ -677,7 +684,7 @@ fn main() {
"function_signature_shim",
"body_with_source_map_shim",
"body_shim",
- "trait_environment_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"crate_lang_items",
"attrs_shim",
"attrs_shim",
@@ -686,6 +693,7 @@ fn main() {
"ImplTraits < 'db >::return_type_impl_traits_",
"infer_shim",
"function_signature_with_source_map_shim",
+ "GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
"struct_signature_with_source_map_shim",
@@ -699,7 +707,6 @@ fn main() {
"impl_trait_with_diagnostics_shim",
"impl_self_ty_with_diagnostics_shim",
"GenericPredicates < 'db >::query_with_diagnostics_",
- "GenericPredicates < 'db >::query_with_diagnostics_",
]
"#]],
);
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 87f488f7aa..eb4ae5ec8a 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -349,7 +349,6 @@ fn test() {
#[test]
fn trait_default_method_self_bound_implements_trait() {
- cov_mark::check!(trait_self_implements_self);
check(
r#"
trait Trait {
@@ -5032,3 +5031,28 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn implicit_sized_bound_on_param() {
+ check(
+ r#"
+//- minicore: sized
+struct PBox<T, A>(T, A);
+
+impl<T, A> PBox<T, A> {
+ fn token_with(self) {}
+}
+
+trait MoveMessage {
+ fn token<A>(self, alloc: A)
+ where
+ Self: Sized,
+ {
+ let b = PBox::<Self, A>(self, alloc);
+ b.token_with();
+ // ^^^^^^^^^^^^^^ type: ()
+ }
+}
+ "#,
+ );
+}
diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs
index 155f0b5a98..e139a5e270 100644
--- a/crates/ide-completion/src/tests/flyimport.rs
+++ b/crates/ide-completion/src/tests/flyimport.rs
@@ -780,9 +780,9 @@ fn main() {
}
"#,
expect![[r#"
- me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED
fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
+ me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
"#]],
);
}