diff options
| author | Lukas Wirth <me@lukaswirth.dev> | 2025-08-13 10:17:53 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-13 10:17:53 +0000 |
| commit | b7e4b28c3be2ac96db9dcb6594aecb84355ecd44 (patch) | |
| tree | 4c6b25b5de5ca29d111f329c91fe0624fd14c4b4 /src | |
| parent | 9b089011a0e8d1bfb44c995891fccd2c813d97e6 (diff) | |
| parent | 67b1e329080519085716c8e444a43eede0d196a6 (diff) | |
| download | rust-b7e4b28c3be2ac96db9dcb6594aecb84355ecd44.tar.gz rust-b7e4b28c3be2ac96db9dcb6594aecb84355ecd44.zip | |
Merge pull request #20446 from lcnr/kinda-unhelpful-3
next-solver fun time
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/layout.rs | 29 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs | 122 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/tests.rs | 2 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs (renamed from src/tools/rust-analyzer/crates/hir-ty/src/tests/type_alias_impl_traits.rs) | 16 |
4 files changed, 88 insertions, 81 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 819bd583dea..2d0471d7e55 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -182,7 +182,7 @@ pub fn layout_of_ty_ns_query<'db>( }; let dl = &*target; let cx = LayoutCx::new(dl); - let infer_ctxt = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); let ty = deeply_normalize(infer_ctxt.at(&cause, ParamEnv::empty()), ty).unwrap_or(ty); let result = match ty.kind() { @@ -335,27 +335,6 @@ pub fn layout_of_ty_ns_query<'db>( ptr.valid_range_mut().start = 1; Layout::scalar(dl, ptr) } - TyKind::Alias(_, ty) => match ty.def_id { - SolverDefId::TypeAliasId(_) => { - return Err(LayoutError::HasPlaceholder); - } - SolverDefId::InternedOpaqueTyId(opaque) => { - let impl_trait_id = db.lookup_intern_impl_trait_id(opaque); - match impl_trait_id { - crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { - let infer = db.infer(func.into()); - return db.layout_of_ty(infer.type_of_rpit[idx].clone(), trait_env); - } - crate::ImplTraitId::TypeAliasImplTrait(..) => { - return Err(LayoutError::NotImplemented); - } - crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => { - return Err(LayoutError::NotImplemented); - } - } - } - _ => unreachable!(), - }, TyKind::Closure(c, args) => { let id = match c { SolverDefId::InternedClosureId(id) => id, @@ -389,7 +368,11 @@ pub fn layout_of_ty_ns_query<'db>( } TyKind::Error(_) => return Err(LayoutError::HasErrorType), - TyKind::Placeholder(_) | TyKind::Bound(..) | TyKind::Infer(..) | TyKind::Param(..) => { + TyKind::Placeholder(_) + | TyKind::Bound(..) + | TyKind::Infer(..) + | TyKind::Param(..) + | TyKind::Alias(..) => { return Err(LayoutError::HasPlaceholder); } }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 26dc4ba2fd8..4fe0b54d684 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -22,8 +22,8 @@ use rustc_type_ir::inherent::{ use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ - AliasTerm, AliasTermKind, AliasTy, EarlyBinder, FlagComputation, Flags, ImplPolarity, InferTy, - ProjectionPredicate, TraitPredicate, TraitRef, Upcast, + AliasTerm, AliasTermKind, AliasTy, AliasTyKind, EarlyBinder, FlagComputation, Flags, + ImplPolarity, InferTy, ProjectionPredicate, TraitPredicate, TraitRef, Upcast, }; use salsa::plumbing::AsId; use smallvec::{SmallVec, smallvec}; @@ -626,12 +626,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef { fn struct_tail_ty( self, interner: DbInterner<'db>, - ) -> Option< - rustc_type_ir::EarlyBinder< - DbInterner<'db>, - <DbInterner<'db> as rustc_type_ir::Interner>::Ty, - >, - > { + ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> { let db = interner.db(); let hir_def::AdtId::StructId(struct_id) = self.inner().id else { return None; @@ -645,10 +640,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef { fn all_field_tys( self, interner: DbInterner<'db>, - ) -> rustc_type_ir::EarlyBinder< - DbInterner<'db>, - impl IntoIterator<Item = <DbInterner<'db> as rustc_type_ir::Interner>::Ty>, - > { + ) -> EarlyBinder<DbInterner<'db>, impl IntoIterator<Item = Ty<'db>>> { let db = interner.db(); // FIXME: this is disabled just to match the behavior with chalk right now let field_tys = |id: VariantId| { @@ -679,19 +671,14 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef { .collect(), }; - rustc_type_ir::EarlyBinder::bind(tys) + EarlyBinder::bind(tys) } fn sizedness_constraint( self, interner: DbInterner<'db>, sizedness: SizedTraitKind, - ) -> Option< - rustc_type_ir::EarlyBinder< - DbInterner<'db>, - <DbInterner<'db> as rustc_type_ir::Interner>::Ty, - >, - > { + ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> { if self.is_struct() { let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?; @@ -1024,8 +1011,8 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { false } - fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, t: T) -> T { - t + fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T { + unreachable!("only used by the old trait solver in rustc"); } fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf { @@ -1054,6 +1041,9 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { ), SolverDefId::InternedOpaqueTyId(_def_id) => { // FIXME(next-solver): track variances + // + // We compute them based on the only `Ty` level info in rustc, + // move `variances_of_opaque` into `rustc_next_trait_solver` for reuse. VariancesOf::new_from_iter( self, (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant), @@ -1063,7 +1053,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { } } - fn type_of(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder<Self, Self::Ty> { + fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> { let def_id = match def_id { SolverDefId::TypeAliasId(id) => { use hir_def::Lookup; @@ -1074,6 +1064,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { crate::TyDefId::TypeAliasId(id) } SolverDefId::AdtId(id) => crate::TyDefId::AdtId(id), + // FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc. + // + // We currently always use the type from HIR typeck which ignores regions. This + // should be fine. + SolverDefId::InternedOpaqueTyId(_) => { + return self.type_of_opaque_hir_typeck(def_id); + } _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"), }; self.db().ty_ns(def_id) @@ -1087,9 +1084,12 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { AdtDef::new(def_id, self) } - fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> rustc_type_ir::AliasTyKind { - // FIXME: not currently creating any others - rustc_type_ir::AliasTyKind::Projection + fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind { + match alias.def_id { + SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque, + SolverDefId::TypeAliasId(_) => AliasTyKind::Projection, + _ => unimplemented!("Unexpected alias: {:?}", alias.def_id), + } } fn alias_term_kind( @@ -1100,7 +1100,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy, SolverDefId::TypeAliasId(_) => AliasTermKind::ProjectionTy, SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst, - _ => unreachable!("Unexpected alias: {:?}", alias.def_id), + _ => unimplemented!("Unexpected alias: {:?}", alias.def_id), } } @@ -1194,8 +1194,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn fn_sig( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> - { + ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> { let id = match def_id { SolverDefId::FunctionId(id) => CallableDefId::FunctionId(id), SolverDefId::Ctor(ctor) => match ctor { @@ -1248,7 +1247,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn item_bounds( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { explicit_item_bounds(self, def_id).map_bound(|bounds| { Clauses::new_from_iter(self, elaborate(self, bounds).collect::<Vec<_>>()) }) @@ -1258,7 +1257,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn item_self_bounds( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { explicit_item_bounds(self, def_id).map_bound(|bounds| { Clauses::new_from_iter( self, @@ -1270,7 +1269,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn item_non_self_bounds( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect(); let own_bounds: FxHashSet<_> = self.item_self_bounds(def_id).skip_binder().into_iter().collect(); @@ -1288,7 +1287,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn predicates_of( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { let predicates = self.db().generic_predicates_ns(def_id.try_into().unwrap()); let predicates: Vec<_> = predicates.iter().cloned().collect(); EarlyBinder::bind(predicates.into_iter()) @@ -1298,7 +1297,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn own_predicates_of( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { let predicates = self.db().generic_predicates_without_parent_ns(def_id.try_into().unwrap()); let predicates: Vec<_> = predicates.iter().cloned().collect(); EarlyBinder::bind(predicates.into_iter()) @@ -1308,8 +1307,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn explicit_super_predicates_of( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> - { + ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> { let predicates: Vec<(Clause<'db>, Span)> = self .db() .generic_predicates_ns(def_id.try_into().unwrap()) @@ -1317,15 +1315,14 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { .cloned() .map(|p| (p, Span::dummy())) .collect(); - rustc_type_ir::EarlyBinder::bind(predicates) + EarlyBinder::bind(predicates) } #[tracing::instrument(skip(self), ret)] fn explicit_implied_predicates_of( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> - { + ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> { let predicates: Vec<(Clause<'db>, Span)> = self .db() .generic_predicates_ns(def_id.try_into().unwrap()) @@ -1333,13 +1330,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { .cloned() .map(|p| (p, Span::dummy())) .collect(); - rustc_type_ir::EarlyBinder::bind(predicates) + EarlyBinder::bind(predicates) } fn impl_super_outlives( self, impl_def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { + ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { let impl_id = match impl_def_id { SolverDefId::ImplId(id) => id, _ => unreachable!(), @@ -1362,11 +1359,11 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn const_conditions( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder< + ) -> EarlyBinder< Self, impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>, > { - rustc_type_ir::EarlyBinder::bind([unimplemented!()]) + EarlyBinder::bind([unimplemented!()]) } fn has_target_features(self, def_id: Self::DefId) -> bool { @@ -1740,7 +1737,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { } fn has_item_definition(self, def_id: Self::DefId) -> bool { - // FIXME: should check if has value + // FIXME(next-solver): should check if the associated item has a value. true } @@ -1753,7 +1750,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn impl_trait_ref( self, impl_def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> { + ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> { let impl_id = match impl_def_id { SolverDefId::ImplId(id) => id, _ => panic!("Unexpected SolverDefId in impl_trait_ref"), @@ -1815,7 +1812,8 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { } fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool { - // FIXME(next-solver) + // FIXME(next-solver): should check the `TraitFlags` for + // the `#[rustc_do_not_implement_via_object]` flag true } @@ -1954,12 +1952,12 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { fn explicit_implied_const_bounds( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder< + ) -> EarlyBinder< Self, impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>, > { // FIXME(next-solver) - rustc_type_ir::EarlyBinder::bind([]) + EarlyBinder::bind([]) } fn fn_is_const(self, def_id: Self::DefId) -> bool { @@ -1982,21 +1980,31 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> { None } - fn type_of_opaque_hir_typeck( - self, - def_id: Self::LocalDefId, - ) -> rustc_type_ir::EarlyBinder<Self, Self::Ty> { - // FIXME(next-solver) - unimplemented!() + fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> EarlyBinder<Self, Self::Ty> { + match def_id { + SolverDefId::InternedOpaqueTyId(opaque) => { + let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque); + match impl_trait_id { + crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { + let infer = self.db().infer(func.into()); + EarlyBinder::bind(infer.type_of_rpit[idx].to_nextsolver(self)) + } + crate::ImplTraitId::TypeAliasImplTrait(..) + | crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => { + // FIXME(next-solver) + EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed)) + } + } + } + _ => panic!("Unexpected SolverDefId in type_of_opaque_hir_typeck"), + } } fn coroutine_hidden_types( self, def_id: Self::DefId, - ) -> rustc_type_ir::EarlyBinder< - Self, - rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>, - > { + ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>> + { // FIXME(next-solver) unimplemented!() } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index c5f78e2f3ce..d98b6602efe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -6,12 +6,12 @@ mod incremental; mod macros; mod method_resolution; mod never_type; +mod opaque_types; mod patterns; mod regression; mod simple; mod trait_aliases; mod traits; -mod type_alias_impl_traits; use base_db::{Crate, SourceDatabase}; use expect_test::Expect; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/type_alias_impl_traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs index e2b7bf379cc..36578545a9f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/type_alias_impl_traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs @@ -159,3 +159,19 @@ static ALIAS: i32 = { "#]], ) } + +#[test] +fn leak_auto_traits() { + check_no_mismatches( + r#" +//- minicore: send +fn foo() -> impl Sized {} + +fn is_send<T: Send>(_: T) {} + +fn main() { + is_send(foo()); +} + "#, + ); +} |
