@@ -19,16 +19,17 @@ use metadata::csearch::{get_impls_for_mod};
19
19
use metadata:: cstore:: { CStore , iter_crate_data} ;
20
20
use metadata:: decoder:: { dl_def, dl_field, dl_impl} ;
21
21
use middle:: resolve:: { Impl , MethodInfo } ;
22
- use middle:: ty:: { ProvidedMethodSource ,
23
- ProvidedMethodInfo , get } ;
24
- use middle:: ty:: { lookup_item_type , subst , t , ty_bot, ty_box, ty_struct } ;
25
- use middle:: ty:: { ty_bool , ty_enum , ty_int , ty_nil , ty_ptr , ty_rptr , ty_uint } ;
26
- use middle:: ty:: { ty_float , ty_estr , ty_evec , ty_rec , ty_uniq } ;
27
- use middle:: ty:: { ty_err , ty_fn , ty_trait , ty_tup , ty_infer } ;
28
- use middle:: ty:: { ty_param , ty_self , ty_type , ty_opaque_box } ;
29
- use middle:: ty:: { ty_opaque_closure_ptr , ty_unboxed_vec , type_is_ty_var} ;
22
+ use middle:: ty:: { ProvidedMethodSource , ProvidedMethodInfo , bound_copy , get } ;
23
+ use middle :: ty :: { kind_can_be_copied , lookup_item_type , param_bounds , subst } ;
24
+ use middle:: ty:: { t , ty_bool , ty_bot, ty_box, ty_enum , ty_err , ty_estr } ;
25
+ use middle:: ty:: { ty_evec , ty_float , ty_fn , ty_infer , ty_int , ty_nil , ty_ptr } ;
26
+ use middle:: ty:: { ty_rec , ty_rptr , ty_struct , ty_trait , ty_tup , ty_uint } ;
27
+ use middle:: ty:: { ty_param , ty_self , ty_type , ty_opaque_box , ty_uniq } ;
28
+ use middle:: ty:: { ty_opaque_closure_ptr , ty_unboxed_vec , type_kind_ext } ;
29
+ use middle:: ty:: { type_is_ty_var} ;
30
30
use middle:: typeck:: infer:: { infer_ctxt, can_mk_subty} ;
31
- use middle:: typeck:: infer:: { new_infer_ctxt, resolve_ivar, resolve_type} ;
31
+ use middle:: typeck:: infer:: { new_infer_ctxt, resolve_ivar} ;
32
+ use middle:: typeck:: infer:: { resolve_nested_tvar, resolve_type} ;
32
33
use syntax:: ast:: { crate , def_id, def_mod, def_ty} ;
33
34
use syntax:: ast:: { item, item_struct, item_const, item_enum, item_fn} ;
34
35
use syntax:: ast:: { item_foreign_mod, item_impl, item_mac, item_mod} ;
@@ -49,6 +50,12 @@ use std::map::HashMap;
49
50
use core:: uint:: range;
50
51
use core:: vec:: { len, push} ;
51
52
53
+ struct UniversalQuantificationResult {
54
+ monotype : t ,
55
+ type_variables : ~[ ty:: t ] ,
56
+ bounds : @~[ param_bounds ]
57
+ }
58
+
52
59
fn get_base_type ( inference_context : infer_ctxt , span : span , original_type : t )
53
60
-> Option < t > {
54
61
@@ -465,19 +472,21 @@ impl CoherenceChecker {
465
472
fn polytypes_unify ( polytype_a : ty_param_bounds_and_ty ,
466
473
polytype_b : ty_param_bounds_and_ty )
467
474
-> bool {
468
-
469
- let monotype_a = self . universally_quantify_polytype ( polytype_a) ;
470
- let monotype_b = self . universally_quantify_polytype ( polytype_b) ;
471
- return can_mk_subty ( self . inference_context ,
472
- monotype_a, monotype_b) . is_ok ( )
473
- || can_mk_subty ( self . inference_context ,
474
- monotype_b, monotype_a) . is_ok ( ) ;
475
+ let universally_quantified_a =
476
+ self . universally_quantify_polytype ( polytype_a) ;
477
+ let universally_quantified_b =
478
+ self . universally_quantify_polytype ( polytype_b) ;
479
+
480
+ return self . can_unify_universally_quantified (
481
+ & universally_quantified_a, & universally_quantified_b) ||
482
+ self . can_unify_universally_quantified (
483
+ & universally_quantified_b, & universally_quantified_a) ;
475
484
}
476
485
477
486
// Converts a polytype to a monotype by replacing all parameters with
478
- // type variables.
479
-
480
- fn universally_quantify_polytype ( polytype : ty_param_bounds_and_ty ) -> t {
487
+ // type variables. Returns the monotype and the type variables created.
488
+ fn universally_quantify_polytype ( polytype : ty_param_bounds_and_ty )
489
+ -> UniversalQuantificationResult {
481
490
// NDM--this span is bogus.
482
491
let self_region =
483
492
polytype. region_param . map (
@@ -493,7 +502,67 @@ impl CoherenceChecker {
493
502
tps: type_parameters
494
503
} ;
495
504
496
- return subst ( self . crate_context . tcx , & substitutions, polytype. ty ) ;
505
+ let monotype = subst ( self . crate_context . tcx ,
506
+ & substitutions,
507
+ polytype. ty ) ;
508
+ UniversalQuantificationResult {
509
+ monotype : monotype,
510
+ type_variables : move type_parameters,
511
+ bounds : polytype. bounds
512
+ }
513
+ }
514
+
515
+ fn can_unify_universally_quantified ( a : & a/UniversalQuantificationResult ,
516
+ b : & a/UniversalQuantificationResult )
517
+ -> bool {
518
+ let mut might_unify = true ;
519
+ let _ = do self . inference_context . probe {
520
+ let result = self . inference_context . sub ( true , dummy_sp ( ) )
521
+ . tys ( a. monotype , b. monotype ) ;
522
+ if result. is_ok ( ) {
523
+ // Check to ensure that each parameter binding respected its
524
+ // kind bounds.
525
+ for [ a, b ] . each |result| {
526
+ for vec:: each2( result. type_variables, * result. bounds)
527
+ |ty_var, bounds| {
528
+ match resolve_type( self . inference_context,
529
+ * ty_var,
530
+ resolve_nested_tvar) {
531
+ Ok ( resolved_ty) => {
532
+ for bounds. each |bound| {
533
+ match * bound {
534
+ bound_copy => {
535
+ let kind = type_kind_ext(
536
+ self . inference_context. tcx,
537
+ resolved_ty,
538
+ true) ;
539
+ if !kind_can_be_copied ( kind) {
540
+ might_unify = false ;
541
+ break ;
542
+ }
543
+ }
544
+
545
+ // XXX: We could be smarter here.
546
+ // Check to see whether owned, send,
547
+ // const, trait param bounds could
548
+ // possibly unify.
549
+ _ => { }
550
+ }
551
+ }
552
+ }
553
+ Err ( * ) => {
554
+ // Conservatively assume it might unify.
555
+ }
556
+ }
557
+ }
558
+ }
559
+ } else {
560
+ might_unify = false ;
561
+ }
562
+
563
+ result
564
+ } ;
565
+ might_unify
497
566
}
498
567
499
568
fn get_self_type_for_implementation ( implementation : @Impl )
0 commit comments