@@ -1142,23 +1142,45 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1142
1142
} ) ;
1143
1143
}
1144
1144
1145
- match self_ty. sty {
1146
- ty:: ty_trait( ..) => { } ,
1147
- ty:: ty_infer( ty:: TyVar ( _) ) => {
1148
- // the defaulted impl might apply, we don't know
1149
- if ty:: trait_has_default_impl ( self . tcx ( ) , def_id) {
1145
+ if ty:: trait_has_default_impl ( self . tcx ( ) , def_id) {
1146
+ match self_ty. sty {
1147
+ ty:: ty_trait( ..) |
1148
+ ty:: ty_param( ..) |
1149
+ ty:: ty_projection( ..) => {
1150
+ // In these cases, we don't know what the actual
1151
+ // type is. Therefore, we cannot break it down
1152
+ // into its constituent types. So we don't
1153
+ // consider the `..` impl but instead just add no
1154
+ // candidates: this means that typeck will only
1155
+ // succeed if there is another reason to believe
1156
+ // that this obligation holds. That could be a
1157
+ // where-clause or, in the case of an object type,
1158
+ // it could be that the object type lists the
1159
+ // trait (e.g. `Foo+Send : Send`). See
1160
+ // `compile-fail/typeck-default-trait-impl-send-param.rs`
1161
+ // for an example of a test case that exercises
1162
+ // this path.
1163
+ }
1164
+ ty:: ty_infer( ty:: TyVar ( _) ) => {
1165
+ // the defaulted impl might apply, we don't know
1150
1166
candidates. ambiguous = true ;
1151
1167
}
1152
- }
1153
- _ => {
1154
- if ty:: trait_has_default_impl ( self . tcx ( ) , def_id) {
1155
- match self . constituent_types_for_ty ( self_ty) {
1156
- Some ( _) => {
1157
- candidates. vec . push ( DefaultImplCandidate ( def_id. clone ( ) ) )
1158
- }
1159
- None => {
1160
- candidates. ambiguous = true ;
1161
- }
1168
+ _ => {
1169
+ if self . constituent_types_for_ty ( self_ty) . is_some ( ) {
1170
+ candidates. vec . push ( DefaultImplCandidate ( def_id. clone ( ) ) )
1171
+ } else {
1172
+ // We don't yet know what the constituent
1173
+ // types are. So call it ambiguous for now,
1174
+ // though this is a bit stronger than
1175
+ // necessary: that is, we know that the
1176
+ // defaulted impl applies, but we can't
1177
+ // process the confirmation step without
1178
+ // knowing the constituent types. (Anyway, in
1179
+ // the particular case of defaulted impls, it
1180
+ // doesn't really matter much either way,
1181
+ // since we won't be aiding inference by
1182
+ // processing the confirmation step.)
1183
+ candidates. ambiguous = true ;
1162
1184
}
1163
1185
}
1164
1186
}
@@ -1632,6 +1654,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1632
1654
}
1633
1655
}
1634
1656
1657
+ /// For default impls, we need to break apart a type into its
1658
+ /// "constituent types" -- meaning, the types that it contains.
1659
+ ///
1660
+ /// Here are some (simple) examples:
1661
+ ///
1662
+ /// ```
1663
+ /// (i32, u32) -> [i32, u32]
1664
+ /// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
1665
+ /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
1666
+ /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
1667
+ /// ```
1635
1668
fn constituent_types_for_ty ( & self , t : Ty < ' tcx > ) -> Option < Vec < Ty < ' tcx > > > {
1636
1669
match t. sty {
1637
1670
ty:: ty_uint( _) |
@@ -1641,16 +1674,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1641
1674
ty:: ty_bare_fn( ..) |
1642
1675
ty:: ty_str |
1643
1676
ty:: ty_err |
1644
- ty:: ty_param( ..) |
1645
1677
ty:: ty_infer( ty:: IntVar ( _) ) |
1646
1678
ty:: ty_infer( ty:: FloatVar ( _) ) |
1647
1679
ty:: ty_char => {
1648
1680
Some ( Vec :: new ( ) )
1649
1681
}
1650
1682
1651
1683
ty:: ty_trait( ..) |
1684
+ ty:: ty_param( ..) |
1652
1685
ty:: ty_projection( ..) |
1653
- ty:: ty_infer( _ ) => {
1686
+ ty:: ty_infer( ty :: TyVar ( _ ) ) => {
1654
1687
self . tcx ( ) . sess . bug (
1655
1688
& format ! (
1656
1689
"asked to assemble constituent types of unexpected type: {}" ,
0 commit comments