|
1 | 1 | //! Methods for lowering the HIR to types. There are two main cases here: |
2 | 2 | //! |
3 | 3 | //! - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a |
4 | | -//! type: The entry point for this is `Ty::from_hir`. |
5 | | -//! - Building the type for an item: This happens through the `type_for_def` query. |
| 4 | +//! type: The entry point for this is `TyLoweringContext::lower_ty`. |
| 5 | +//! - Building the type for an item: This happens through the `ty` query. |
6 | 6 | //! |
7 | 7 | //! This usually involves resolving names, collecting generic arguments etc. |
8 | 8 | use std::{ |
@@ -47,7 +47,7 @@ use crate::{ |
47 | 47 | consteval::{intern_const_scalar, path_to_const, unknown_const, unknown_const_as_generic}, |
48 | 48 | db::HirDatabase, |
49 | 49 | make_binders, |
50 | | - mapping::ToChalk, |
| 50 | + mapping::{from_chalk_trait_id, ToChalk}, |
51 | 51 | static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, |
52 | 52 | utils::Generics, |
53 | 53 | utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics}, |
@@ -969,13 +969,44 @@ impl<'a> TyLoweringContext<'a> { |
969 | 969 | fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty { |
970 | 970 | let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner); |
971 | 971 | let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
972 | | - QuantifiedWhereClauses::from_iter( |
| 972 | + let bounds = |
| 973 | + bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)); |
| 974 | + |
| 975 | + let mut auto_traits = SmallVec::<[_; 8]>::new(); |
| 976 | + let mut regular_traits = SmallVec::<[_; 2]>::new(); |
| 977 | + let mut other_bounds = SmallVec::<[_; 8]>::new(); |
| 978 | + for bound in bounds { |
| 979 | + if let Some(id) = bound.trait_id() { |
| 980 | + if ctx.db.trait_data(from_chalk_trait_id(id)).is_auto { |
| 981 | + auto_traits.push(bound); |
| 982 | + } else { |
| 983 | + regular_traits.push(bound); |
| 984 | + } |
| 985 | + } else { |
| 986 | + other_bounds.push(bound); |
| 987 | + } |
| 988 | + } |
| 989 | + |
| 990 | + if regular_traits.len() > 1 { |
| 991 | + return None; |
| 992 | + } |
| 993 | + |
| 994 | + auto_traits.sort_unstable_by_key(|b| b.trait_id().unwrap()); |
| 995 | + auto_traits.dedup(); |
| 996 | + |
| 997 | + Some(QuantifiedWhereClauses::from_iter( |
973 | 998 | Interner, |
974 | | - bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), |
975 | | - ) |
| 999 | + regular_traits.into_iter().chain(other_bounds).chain(auto_traits), |
| 1000 | + )) |
976 | 1001 | }); |
977 | | - let bounds = crate::make_single_type_binders(bounds); |
978 | | - TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner) |
| 1002 | + |
| 1003 | + if let Some(bounds) = bounds { |
| 1004 | + let bounds = crate::make_single_type_binders(bounds); |
| 1005 | + TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner) |
| 1006 | + } else { |
| 1007 | + // FIXME: report error (additional non-auto traits) |
| 1008 | + TyKind::Error.intern(Interner) |
| 1009 | + } |
979 | 1010 | } |
980 | 1011 |
|
981 | 1012 | fn lower_impl_trait( |
|
0 commit comments