@@ -382,7 +382,7 @@ fn orphan_check_trait_ref<'tcx>(
382
382
ty : Ty < ' tcx > ,
383
383
in_crate : InCrate ,
384
384
) -> Vec < Ty < ' tcx > > {
385
- if fundamental_ty ( ty) && ty_is_non_local ( tcx , ty, in_crate) . is_some ( ) {
385
+ if fundamental_ty ( ty) && ty_is_non_local ( ty, in_crate) . is_some ( ) {
386
386
ty. walk_shallow ( ) . flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) ) . collect ( )
387
387
} else {
388
388
vec ! [ ty]
@@ -396,7 +396,7 @@ fn orphan_check_trait_ref<'tcx>(
396
396
. enumerate ( )
397
397
{
398
398
debug ! ( "orphan_check_trait_ref: check ty `{:?}`" , input_ty) ;
399
- let non_local_tys = ty_is_non_local ( tcx , input_ty, in_crate) ;
399
+ let non_local_tys = ty_is_non_local ( input_ty, in_crate) ;
400
400
if non_local_tys. is_none ( ) {
401
401
debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
402
402
return Ok ( ( ) ) ;
@@ -405,7 +405,7 @@ fn orphan_check_trait_ref<'tcx>(
405
405
let local_type = trait_ref
406
406
. input_types ( )
407
407
. flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) )
408
- . filter ( |ty| ty_is_non_local_constructor ( tcx , ty, in_crate) . is_none ( ) )
408
+ . filter ( |ty| ty_is_non_local_constructor ( ty, in_crate) . is_none ( ) )
409
409
. next ( ) ;
410
410
411
411
debug ! ( "orphan_check_trait_ref: uncovered ty local_type: `{:?}`" , local_type) ;
@@ -423,13 +423,13 @@ fn orphan_check_trait_ref<'tcx>(
423
423
Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans) )
424
424
}
425
425
426
- fn ty_is_non_local < ' t > ( tcx : TyCtxt < ' t > , ty : Ty < ' t > , in_crate : InCrate ) -> Option < Vec < Ty < ' t > > > {
427
- match ty_is_non_local_constructor ( tcx , ty, in_crate) {
426
+ fn ty_is_non_local < ' t > ( ty : Ty < ' t > , in_crate : InCrate ) -> Option < Vec < Ty < ' t > > > {
427
+ match ty_is_non_local_constructor ( ty, in_crate) {
428
428
Some ( ty) => if !fundamental_ty ( ty) {
429
429
Some ( vec ! [ ty] )
430
430
} else {
431
431
let tys: Vec < _ > = ty. walk_shallow ( )
432
- . filter_map ( |t| ty_is_non_local ( tcx , t, in_crate) )
432
+ . filter_map ( |t| ty_is_non_local ( t, in_crate) )
433
433
. flat_map ( |i| i)
434
434
. collect ( ) ;
435
435
if tys. is_empty ( ) {
@@ -460,7 +460,6 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
460
460
}
461
461
462
462
fn ty_is_non_local_constructor < ' tcx > (
463
- tcx : TyCtxt < ' tcx > ,
464
463
ty : Ty < ' tcx > ,
465
464
in_crate : InCrate ,
466
465
) -> Option < Ty < ' tcx > > {
@@ -503,14 +502,33 @@ fn ty_is_non_local_constructor<'tcx>(
503
502
} else {
504
503
Some ( ty)
505
504
} ,
506
- ty:: Opaque ( did, _) => {
507
- // Check the underlying type that this opaque
508
- // type resolves to.
509
- // This recursion will eventually terminate,
510
- // since we've already managed to successfully
511
- // resolve all opaque types by this point
512
- let real_ty = tcx. type_of ( did) ;
513
- ty_is_non_local_constructor ( tcx, real_ty, in_crate)
505
+ ty:: Opaque ( ..) => {
506
+ // This merits some explanation.
507
+ // Normally, opaque types are not involed when performing
508
+ // coherence checking, since it is illegal to directly
509
+ // implement a trait on an opaque type. However, we might
510
+ // end up looking at an opaque type during coherence checking
511
+ // if an opaque type gets used within another type (e.g. as
512
+ // a type parameter). This requires us to decide whether or
513
+ // not an opaque type should be considered 'local' or not.
514
+ //
515
+ // We choose to treat all opaque types as non-local, even
516
+ // those that appear within the same crate. This seems
517
+ // somewhat suprising at first, but makes sense when
518
+ // you consider that opaque types are supposed to hide
519
+ // the underlying type *within the same crate*. When an
520
+ // opaque type is used from outside the module
521
+ // where it is declared, it should be impossible to observe
522
+ // anyything about it other than the traits that it implements.
523
+ //
524
+ // The alternative would be to look at the underlying type
525
+ // to determine whether or not the opaque type itself should
526
+ // be considered local. However, this could make it a breaking change
527
+ // to switch the underlying ('defining') type from a local type
528
+ // to a remote type. This would violate the rule that opaque
529
+ // types should be completely opaque apart from the traits
530
+ // that they implement, so we don't use this behavior.
531
+ Some ( ty)
514
532
}
515
533
516
534
ty:: Dynamic ( ref tt, ..) => {
0 commit comments