@@ -13,9 +13,8 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
13
13
14
14
use hir:: def_id:: DefId ;
15
15
use rustc:: traits:: { self , ObligationCauseCode } ;
16
- use rustc:: ty:: { self , Lift , Ty , TyCtxt , TyKind , GenericParamDefKind , TypeFoldable } ;
16
+ use rustc:: ty:: { self , Lift , Ty , TyCtxt , TyKind , GenericParamDefKind , TypeFoldable , ToPredicate } ;
17
17
use rustc:: ty:: subst:: { Subst , Substs } ;
18
- use rustc:: ty:: util:: ExplicitSelf ;
19
18
use rustc:: util:: nodemap:: { FxHashSet , FxHashMap } ;
20
19
use rustc:: middle:: lang_items;
21
20
use rustc:: infer:: opaque_types:: may_define_existential_type;
@@ -749,72 +748,149 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
749
748
& ty:: Binder :: bind ( self_ty)
750
749
) ;
751
750
752
- let self_arg_ty = sig. inputs ( ) [ 0 ] ;
751
+ let receiver_ty = sig. inputs ( ) [ 0 ] ;
753
752
754
- let cause = fcx. cause ( span, ObligationCauseCode :: MethodReceiver ) ;
755
- let self_arg_ty = fcx. normalize_associated_types_in ( span, & self_arg_ty) ;
756
- let self_arg_ty = fcx. tcx . liberate_late_bound_regions (
753
+ let receiver_ty = fcx. normalize_associated_types_in ( span, & receiver_ty) ;
754
+ let receiver_ty = fcx. tcx . liberate_late_bound_regions (
757
755
method. def_id ,
758
- & ty:: Binder :: bind ( self_arg_ty )
756
+ & ty:: Binder :: bind ( receiver_ty )
759
757
) ;
760
758
761
- let mut autoderef = fcx. autoderef ( span, self_arg_ty) . include_raw_pointers ( ) ;
759
+ if fcx. tcx . features ( ) . arbitrary_self_types {
760
+ if !receiver_is_valid ( fcx, span, receiver_ty, self_ty, true ) {
761
+ // report error, arbitrary_self_types was enabled
762
+ fcx. tcx . sess . diagnostic ( ) . mut_span_err (
763
+ span, & format ! ( "invalid method receiver type: {:?}" , receiver_ty)
764
+ ) . note ( "type of `self` must be `Self` or a type that dereferences to it" )
765
+ . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
766
+ . code ( DiagnosticId :: Error ( "E0307" . into ( ) ) )
767
+ . emit ( ) ;
768
+ }
769
+ } else {
770
+ if !receiver_is_valid ( fcx, span, receiver_ty, self_ty, false ) {
771
+ if receiver_is_valid ( fcx, span, receiver_ty, self_ty, true ) {
772
+ // report error, would have worked with arbitrary_self_types
773
+ feature_gate:: feature_err (
774
+ & fcx. tcx . sess . parse_sess ,
775
+ "arbitrary_self_types" ,
776
+ span,
777
+ GateIssue :: Language ,
778
+ & format ! (
779
+ "`{}` cannot be used as the type of `self` without \
780
+ the `arbitrary_self_types` feature",
781
+ receiver_ty,
782
+ ) ,
783
+ ) . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
784
+ . emit ( ) ;
785
+ } else {
786
+ // report error, would not have worked with arbitrary_self_types
787
+ fcx. tcx . sess . diagnostic ( ) . mut_span_err (
788
+ span, & format ! ( "invalid method receiver type: {:?}" , receiver_ty)
789
+ ) . note ( "type must be `Self` or a type that dereferences to it" )
790
+ . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
791
+ . code ( DiagnosticId :: Error ( "E0307" . into ( ) ) )
792
+ . emit ( ) ;
793
+ }
794
+ }
795
+ }
796
+ }
797
+
798
+ /// returns true if `receiver_ty` would be considered a valid receiver type for `self_ty`. If
799
+ /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
800
+ /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
801
+ /// strict: `receiver_ty` must implement `Receiver` and directly implement `Deref<Target=self_ty>`.
802
+ ///
803
+ /// NB: there are cases this function returns `true` but causes an error to be emitted,
804
+ /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
805
+ /// wrong lifetime. Be careful of this if you are calling this function speculatively.
806
+ fn receiver_is_valid < ' fcx , ' tcx , ' gcx > (
807
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
808
+ span : Span ,
809
+ receiver_ty : Ty < ' tcx > ,
810
+ self_ty : Ty < ' tcx > ,
811
+ arbitrary_self_types_enabled : bool ,
812
+ ) -> bool {
813
+ let cause = fcx. cause ( span, traits:: ObligationCauseCode :: MethodReceiver ) ;
814
+
815
+ let can_eq_self = |ty| fcx. infcx . can_eq ( fcx. param_env , self_ty, ty) . is_ok ( ) ;
816
+
817
+ // `self: Self` is always valid
818
+ if can_eq_self ( receiver_ty) {
819
+ if let Some ( mut err) = fcx. demand_eqtype_with_origin ( & cause, self_ty, receiver_ty) {
820
+ err. emit ( ) ;
821
+ }
822
+ return true
823
+ }
824
+
825
+ let mut autoderef = fcx. autoderef ( span, receiver_ty) ;
826
+
827
+ // the `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`
828
+ if arbitrary_self_types_enabled {
829
+ autoderef = autoderef. include_raw_pointers ( ) ;
830
+ }
831
+
832
+ // the first type is `receiver_ty`, which we know its not equal to `self_ty`. skip it.
833
+ autoderef. next ( ) ;
762
834
835
+ // keep dereferencing `receiver_ty` until we get to `self_ty`
763
836
loop {
764
837
if let Some ( ( potential_self_ty, _) ) = autoderef. next ( ) {
765
- debug ! ( "check_method_receiver : potential self type `{:?}` to match `{:?}`" ,
838
+ debug ! ( "receiver_is_valid : potential self type `{:?}` to match `{:?}`" ,
766
839
potential_self_ty, self_ty) ;
767
840
768
- if fcx . infcx . can_eq ( fcx . param_env , self_ty , potential_self_ty) . is_ok ( ) {
841
+ if can_eq_self ( potential_self_ty) {
769
842
autoderef. finalize ( fcx) ;
843
+
770
844
if let Some ( mut err) = fcx. demand_eqtype_with_origin (
771
- & cause, self_ty, potential_self_ty) {
845
+ & cause, self_ty, potential_self_ty
846
+ ) {
772
847
err. emit ( ) ;
773
848
}
849
+
774
850
break
775
851
}
776
852
} else {
777
- fcx. tcx . sess . diagnostic ( ) . mut_span_err (
778
- span, & format ! ( "invalid `self` type: {:?}" , self_arg_ty) )
779
- . note ( & format ! ( "type must be `{:?}` or a type that dereferences to it" , self_ty) )
780
- . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
781
- . code ( DiagnosticId :: Error ( "E0307" . into ( ) ) )
782
- . emit ( ) ;
783
- return
853
+ debug ! ( "receiver_is_valid: type `{:?}` does not deref to `{:?}`" ,
854
+ receiver_ty, self_ty) ;
855
+ return false
856
+ }
857
+
858
+ // without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to
859
+ // `self_ty`. Enforce this by only doing one iteration of the loop
860
+ if !arbitrary_self_types_enabled {
861
+ return false
784
862
}
785
863
}
786
864
787
- let is_self_ty = |ty| fcx. infcx . can_eq ( fcx. param_env , self_ty, ty) . is_ok ( ) ;
788
- let self_kind = ExplicitSelf :: determine ( self_arg_ty, is_self_ty) ;
865
+ // without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`
866
+ if !arbitrary_self_types_enabled {
867
+ let trait_def_id = match fcx. tcx . lang_items ( ) . receiver_trait ( ) {
868
+ Some ( did) => did,
869
+ None => {
870
+ debug ! ( "receiver_is_valid: missing Receiver trait" ) ;
871
+ return false
872
+ }
873
+ } ;
789
874
790
- if !fcx. tcx . features ( ) . arbitrary_self_types {
791
- match self_kind {
792
- ExplicitSelf :: ByValue |
793
- ExplicitSelf :: ByReference ( _, _) |
794
- ExplicitSelf :: ByBox => ( ) ,
875
+ let trait_ref = ty:: TraitRef {
876
+ def_id : trait_def_id,
877
+ substs : fcx. tcx . mk_substs_trait ( receiver_ty, & [ ] ) ,
878
+ } ;
795
879
796
- ExplicitSelf :: ByRawPointer ( _) => {
797
- feature_gate:: feature_err (
798
- & fcx. tcx . sess . parse_sess ,
799
- "arbitrary_self_types" ,
800
- span,
801
- GateIssue :: Language ,
802
- "raw pointer `self` is unstable" )
803
- . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
804
- . emit ( ) ;
805
- }
880
+ let obligation = traits:: Obligation :: new (
881
+ cause. clone ( ) ,
882
+ fcx. param_env ,
883
+ trait_ref. to_predicate ( )
884
+ ) ;
806
885
807
- ExplicitSelf :: Other => {
808
- feature_gate:: feature_err (
809
- & fcx. tcx . sess . parse_sess ,
810
- "arbitrary_self_types" ,
811
- span,
812
- GateIssue :: Language , "arbitrary `self` types are unstable" )
813
- . help ( "consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`" )
814
- . emit ( ) ;
815
- }
886
+ if !fcx. predicate_must_hold ( & obligation) {
887
+ debug ! ( "receiver_is_valid: type `{:?}` does not implement `Receiver` trait" ,
888
+ receiver_ty) ;
889
+ return false
816
890
}
817
891
}
892
+
893
+ true
818
894
}
819
895
820
896
fn check_variances_for_type_defn < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
0 commit comments