@@ -996,6 +996,7 @@ pub(crate) fn generic_predicates_for_param_query(
996
996
let ctx =
997
997
TyLoweringContext :: new ( db, & resolver) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
998
998
let generics = generics ( db. upcast ( ) , param_id. parent ) ;
999
+ // TODO(iDawer): add implicitly sized clauses?
999
1000
resolver
1000
1001
. where_predicates_in_scope ( )
1001
1002
// we have to filter out all other predicates *first*, before attempting to lower them
@@ -1036,7 +1037,7 @@ pub(crate) fn trait_environment_query(
1036
1037
traits_in_scope
1037
1038
. push ( ( tr. self_type_parameter ( & Interner ) . clone ( ) , tr. hir_trait_id ( ) ) ) ;
1038
1039
}
1039
- let program_clause: chalk_ir:: ProgramClause < Interner > = pred. clone ( ) . cast ( & Interner ) ;
1040
+ let program_clause: chalk_ir:: ProgramClause < Interner > = pred. cast ( & Interner ) ;
1040
1041
clauses. push ( program_clause. into_from_env_clause ( & Interner ) ) ;
1041
1042
}
1042
1043
}
@@ -1063,6 +1064,15 @@ pub(crate) fn trait_environment_query(
1063
1064
clauses. push ( program_clause. into_from_env_clause ( & Interner ) ) ;
1064
1065
}
1065
1066
1067
+ let subst = generics ( db. upcast ( ) , def) . type_params_subst ( db) ;
1068
+ let explicitly_unsized_tys = ctx. unsized_types . into_inner ( ) ;
1069
+ let implicitly_sized_clauses =
1070
+ implicitly_sized_clauses ( db, def, & explicitly_unsized_tys, & subst, & resolver) . map ( |pred| {
1071
+ let program_clause: chalk_ir:: ProgramClause < Interner > = pred. cast ( & Interner ) ;
1072
+ program_clause. into_from_env_clause ( & Interner )
1073
+ } ) ;
1074
+ clauses. extend ( implicitly_sized_clauses) ;
1075
+
1066
1076
let krate = def. module ( db. upcast ( ) ) . krate ( ) ;
1067
1077
1068
1078
let env = chalk_ir:: Environment :: new ( & Interner ) . add_clauses ( & Interner , clauses) ;
@@ -1085,34 +1095,43 @@ pub(crate) fn generic_predicates_query(
1085
1095
. flat_map ( |pred| ctx. lower_where_predicate ( pred, false ) . map ( |p| make_binders ( & generics, p) ) )
1086
1096
. collect :: < Vec < _ > > ( ) ;
1087
1097
1088
- // Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1089
- // Exception is Self of a trait.
1090
- let is_trait_def = matches ! ( def, GenericDefId :: TraitId ( ..) ) ;
1098
+ let subst = generics. bound_vars_subst ( DebruijnIndex :: INNERMOST ) ;
1091
1099
let explicitly_unsized_tys = ctx. unsized_types . into_inner ( ) ;
1092
- let subtsts = generics. bound_vars_subst ( DebruijnIndex :: INNERMOST ) ;
1093
- let generic_args = & subtsts. as_slice ( & Interner ) [ is_trait_def as usize ..] ;
1100
+ let implicitly_sized_predicates =
1101
+ implicitly_sized_clauses ( db, def, & explicitly_unsized_tys, & subst, & resolver)
1102
+ . map ( |p| make_binders ( & generics, crate :: wrap_empty_binders ( p) ) ) ;
1103
+ predicates. extend ( implicitly_sized_predicates) ;
1104
+ predicates. into ( )
1105
+ }
1106
+
1107
+ /// Generate implicit `: Sized` predicates for all generics that has no `?Sized` bound.
1108
+ /// Exception is Self of a trait def.
1109
+ fn implicitly_sized_clauses < ' a > (
1110
+ db : & dyn HirDatabase ,
1111
+ def : GenericDefId ,
1112
+ explicitly_unsized_tys : & ' a FxHashSet < Ty > ,
1113
+ substitution : & ' a Substitution ,
1114
+ resolver : & Resolver ,
1115
+ ) -> impl Iterator < Item = WhereClause > + ' a {
1116
+ let is_trait_def = matches ! ( def, GenericDefId :: TraitId ( ..) ) ;
1117
+ let generic_args = & substitution. as_slice ( & Interner ) [ is_trait_def as usize ..] ;
1094
1118
let sized_trait = resolver
1095
1119
. krate ( )
1096
1120
. and_then ( |krate| db. lang_item ( krate, "sized" . into ( ) ) )
1097
1121
. and_then ( |lang_item| lang_item. as_trait ( ) . map ( to_chalk_trait_id) ) ;
1098
- let sized_predicates = sized_trait
1099
- . into_iter ( )
1100
- . flat_map ( |sized_trait| {
1101
- let implicitly_sized_tys = generic_args
1102
- . iter ( )
1103
- . filter_map ( |generic_arg| generic_arg. ty ( & Interner ) )
1104
- . filter ( |& self_ty| !explicitly_unsized_tys. contains ( self_ty) ) ;
1105
- implicitly_sized_tys. map ( move |self_ty| {
1106
- WhereClause :: Implemented ( TraitRef {
1107
- trait_id : sized_trait,
1108
- substitution : Substitution :: from1 ( & Interner , self_ty. clone ( ) ) ,
1109
- } )
1122
+
1123
+ sized_trait. into_iter ( ) . flat_map ( move |sized_trait| {
1124
+ let implicitly_sized_tys = generic_args
1125
+ . iter ( )
1126
+ . filter_map ( |generic_arg| generic_arg. ty ( & Interner ) )
1127
+ . filter ( move |& self_ty| !explicitly_unsized_tys. contains ( self_ty) ) ;
1128
+ implicitly_sized_tys. map ( move |self_ty| {
1129
+ WhereClause :: Implemented ( TraitRef {
1130
+ trait_id : sized_trait,
1131
+ substitution : Substitution :: from1 ( & Interner , self_ty. clone ( ) ) ,
1110
1132
} )
1111
1133
} )
1112
- . map ( |p| make_binders ( & generics, crate :: wrap_empty_binders ( p) ) ) ;
1113
-
1114
- predicates. extend ( sized_predicates) ;
1115
- predicates. into ( )
1134
+ } )
1116
1135
}
1117
1136
1118
1137
/// Resolve the default type params from generics
0 commit comments