@@ -2209,9 +2209,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2209
2209
/// Adding a default to a type parameter that has none should be backwards compatible.
2210
2210
/// Therefore we take care to future-proof against conflicting defaults.
2211
2211
///
2212
- /// Currently we prioritize defaults from impls and fns over defaults in types,
2212
+ /// Currently we prioritize params from impls and fns over params in types,
2213
2213
/// this for example allows `fn foo<T=String>(x: Option<T>)` to work
2214
2214
/// even though `Option<T>` has no default for `T`.
2215
+ /// Lower priority defaults are considered when there are no higher priority params involved.
2215
2216
fn apply_user_type_parameter_fallback ( & self ) {
2216
2217
use self :: TypeVariableOrigin :: TypeParameterDefinition ;
2217
2218
use ty:: OriginOfTyParam ;
@@ -2253,51 +2254,42 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2253
2254
}
2254
2255
} ) ;
2255
2256
// Params from fns or impls have higher priority than those from type definitions.
2256
- // Consider the priority levels in order:
2257
- // Try again later if a default can't be normalized.
2258
- // Succeed if all defaults exist and agree.
2259
- // Fail if existing defaults agree but there are missing defaults.
2260
- // Skip the priority level if it's empty or there are disagreements.
2261
- let priority_levels: Vec < Vec < ty:: TyVid > > = vec ! [ fn_or_impl, ty_def] ;
2262
- ' priority_levels: for priority_level in priority_levels {
2263
- if priority_level. is_empty ( ) {
2264
- continue ;
2265
- }
2266
- let get_default = |& v| self . infcx . type_variables . borrow ( ) . default ( v) . as_user ( ) ;
2267
- let mut existing_defaults = Vec :: new ( ) ;
2268
- for default in priority_level. iter ( ) . filter_map ( & get_default) {
2257
+ // The first non-empty priority level is considered.
2258
+ let mut bag: Vec < ty:: TyVid > = fn_or_impl;
2259
+ if bag. is_empty ( ) {
2260
+ bag = ty_def;
2261
+ }
2262
+ // - Try again later if a default can't be normalized.
2263
+ // - Fail if there are conflicting or missing defaults.
2264
+ // - Succeess if all defaults exist and agree.
2265
+ let get_default = |& v| self . infcx . type_variables . borrow ( ) . default ( v) . as_user ( ) ;
2266
+ let mut normalized_defaults = Vec :: new ( ) ;
2267
+ for default in bag. iter ( ) . map ( & get_default) {
2268
+ if let Some ( default) = default {
2269
2269
match self . eager_normalize_in ( default. origin_span , & default. ty ) {
2270
- Some ( def ) => existing_defaults . push ( def ) ,
2270
+ Some ( default ) => normalized_defaults . push ( default ) ,
2271
2271
None => continue ' bags, // Try again later.
2272
2272
}
2273
- }
2274
- let mut existing_defaults = existing_defaults. iter ( ) ;
2275
- let equivalent_default = match existing_defaults. next ( ) {
2276
- Some ( default) => default,
2277
- None => break , // Failed, no params have defaults at this level.
2278
- } ;
2279
- // On conflicting defaults, skip this level.
2280
- if existing_defaults. any ( |& default| default. sty != equivalent_default. sty ) {
2281
- debug ! ( "apply_user_type_parameter_fallback: skipping priority level" ) ;
2282
- continue ;
2283
- }
2284
- // All existing defaults agree, but for future-proofing
2285
- // we must fail if there is a param with no default.
2286
- if priority_level. iter ( ) . any ( |vid| get_default ( vid) == None ) {
2287
- break ;
2288
- }
2289
- // All defaults exist and agree, apply the default and succeed.
2290
- for & vid in & priority_level {
2291
- let ty = self . tcx . mk_var ( vid) ;
2292
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , & ty, equivalent_default) ;
2293
- debug ! ( "apply_user_type_parameter_fallback: applied fallback to var: {:?} \
2294
- with ty: {:?} with default: {:?}", vid, ty, equivalent_default) ;
2295
- // Progress was made.
2296
- fixed_point = false ;
2273
+ } else {
2274
+ // Fail, missing default.
2297
2275
* done = true ;
2298
- break ' priority_levels ;
2276
+ continue ' bags ;
2299
2277
}
2300
2278
}
2279
+ let equivalent_default = normalized_defaults[ 0 ] ;
2280
+ // Fail on conflicting defaults.
2281
+ if normalized_defaults. iter ( ) . any ( |& d| d. sty != equivalent_default. sty ) {
2282
+ break ;
2283
+ }
2284
+ // All defaults exist and agree, success, apply the default.
2285
+ fixed_point = false ;
2286
+ * done = true ;
2287
+ for & vid in & bag {
2288
+ let ty = self . tcx . mk_var ( vid) ;
2289
+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , & ty, equivalent_default) ;
2290
+ debug ! ( "apply_user_type_parameter_fallback: applied fallback to var: {:?} \
2291
+ with ty: {:?} with default: {:?}", vid, ty, equivalent_default) ;
2292
+ }
2301
2293
}
2302
2294
if fixed_point {
2303
2295
break ;
0 commit comments