@@ -837,3 +837,230 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
837
837
}
838
838
}
839
839
}
840
+
841
+ /// CoerceMany encapsulates the pattern you should use when you have
842
+ /// many expressions that are all getting coerced to a common
843
+ /// type. This arises, for example, when you have a match (the result
844
+ /// of each arm is coerced to a common type). It also arises in less
845
+ /// obvious places, such as when you have many `break foo` expressions
846
+ /// that target the same loop, or the various `return` expressions in
847
+ /// a function.
848
+ ///
849
+ /// The basic protocol is as follows:
850
+ ///
851
+ /// - Instantiate the `CoerceMany` with an initial `expected_ty`.
852
+ /// This will also serve as the "starting LUB". The expectation is
853
+ /// that this type is something which all of the expressions *must*
854
+ /// be coercible to. Use a fresh type variable if needed.
855
+ /// - For each expression whose result is to be coerced, invoke `coerce()` with.
856
+ /// - In some cases we wish to coerce "non-expressions" whose types are implicitly
857
+ /// unit. This happens for example if you have a `break` with no expression,
858
+ /// or an `if` with no `else`. In that case, invoke `coerce_forced_unit()`.
859
+ /// - `coerce()` and `coerce_forced_unit()` may report errors. They hide this
860
+ /// from you so that you don't have to worry your pretty head about it.
861
+ /// But if an error is reported, the final type will be `err`.
862
+ /// - Invoking `coerce()` may cause us to go and adjust the "adjustments" on
863
+ /// previously coerced expressions.
864
+ /// - When all done, invoke `complete()`. This will return the LUB of
865
+ /// all your expressions.
866
+ /// - WARNING: I don't believe this final type is guaranteed to be
867
+ /// related to your initial `expected_ty` in any particular way,
868
+ /// although it will typically be a subtype, so you should check it.
869
+ /// - Invoking `complete()` may cause us to go and adjust the "adjustments" on
870
+ /// previously coerced expressions.
871
+ ///
872
+ /// Example:
873
+ ///
874
+ /// ```
875
+ /// let mut coerce = CoerceMany::new(expected_ty);
876
+ /// for expr in exprs {
877
+ /// let expr_ty = fcx.check_expr_with_expectation(expr, expected);
878
+ /// coerce.coerce(fcx, &cause, expr, expr_ty);
879
+ /// }
880
+ /// let final_ty = coerce.complete(fcx);
881
+ /// ```
882
+ #[ derive( Clone ) ] // (*)
883
+ pub struct CoerceMany < ' gcx : ' tcx , ' tcx > {
884
+ expected_ty : Ty < ' tcx > ,
885
+ final_ty : Option < Ty < ' tcx > > ,
886
+ expressions : Vec < & ' gcx hir:: Expr > ,
887
+ }
888
+
889
+ // (*) this is clone because `FnCtxt` is clone, but it seems dubious -- nmatsakis
890
+
891
+ impl < ' gcx , ' tcx > CoerceMany < ' gcx , ' tcx > {
892
+ pub fn new ( expected_ty : Ty < ' tcx > ) -> Self {
893
+ CoerceMany {
894
+ expected_ty,
895
+ final_ty : None ,
896
+ expressions : vec ! [ ] ,
897
+ }
898
+ }
899
+
900
+ pub fn is_empty ( & self ) -> bool {
901
+ self . expressions . is_empty ( )
902
+ }
903
+
904
+ /// Return the "expected type" with which this coercion was
905
+ /// constructed. This represents the "downward propagated" type
906
+ /// that was given to us at the start of typing whatever construct
907
+ /// we are typing (e.g., the match expression).
908
+ ///
909
+ /// Typically, this is used as the expected type when
910
+ /// type-checking each of the alternative expressions whose types
911
+ /// we are trying to merge.
912
+ pub fn expected_ty ( & self ) -> Ty < ' tcx > {
913
+ self . expected_ty
914
+ }
915
+
916
+ /// Returns the current "merged type", representing our best-guess
917
+ /// at the LUB of the expressions we've seen so far (if any). This
918
+ /// isn't *final* until you call `self.final()`, which will return
919
+ /// the merged type.
920
+ pub fn merged_ty ( & self ) -> Ty < ' tcx > {
921
+ self . final_ty . unwrap_or ( self . expected_ty )
922
+ }
923
+
924
+ /// Indicates that the value generated by `expression`, which is
925
+ /// of type `expression_ty`, is one of the possibility that we
926
+ /// could coerce from. This will record `expression` and later
927
+ /// calls to `coerce` may come back and add adjustments and things
928
+ /// if necessary.
929
+ pub fn coerce < ' a > ( & mut self ,
930
+ fcx : & FnCtxt < ' a , ' gcx , ' tcx > ,
931
+ cause : & ObligationCause < ' tcx > ,
932
+ expression : & ' gcx hir:: Expr ,
933
+ expression_ty : Ty < ' tcx > )
934
+ {
935
+ self . coerce_inner ( fcx, cause, Some ( expression) , expression_ty)
936
+ }
937
+
938
+ /// Indicates that one of the inputs is a "forced unit". This
939
+ /// occurs in a case like `if foo { ... };`, where the issing else
940
+ /// generates a "forced unit". Another example is a `loop { break;
941
+ /// }`, where the `break` has no argument expression. We treat
942
+ /// these cases slightly differently for error-reporting
943
+ /// purposes. Note that these tend to correspond to cases where
944
+ /// the `()` expression is implicit in the source, and hence we do
945
+ /// not take an expression argument.
946
+ pub fn coerce_forced_unit < ' a > ( & mut self ,
947
+ fcx : & FnCtxt < ' a , ' gcx , ' tcx > ,
948
+ cause : & ObligationCause < ' tcx > )
949
+ {
950
+ self . coerce_inner ( fcx,
951
+ cause,
952
+ None ,
953
+ fcx. tcx . mk_nil ( ) )
954
+ }
955
+
956
+ /// The inner coercion "engine". If `expression` is `None`, this
957
+ /// is a forced-unit case, and hence `expression_ty` must be
958
+ /// `Nil`.
959
+ fn coerce_inner < ' a > ( & mut self ,
960
+ fcx : & FnCtxt < ' a , ' gcx , ' tcx > ,
961
+ cause : & ObligationCause < ' tcx > ,
962
+ expression : Option < & ' gcx hir:: Expr > ,
963
+ mut expression_ty : Ty < ' tcx > )
964
+ {
965
+ // Incorporate whatever type inference information we have
966
+ // until now; in principle we might also want to process
967
+ // pending obligations, but doing so should only improve
968
+ // compatibility (hopefully that is true) by helping us
969
+ // uncover never types better.
970
+ if expression_ty. is_ty_var ( ) {
971
+ expression_ty = fcx. infcx . shallow_resolve ( expression_ty) ;
972
+ }
973
+
974
+ // If we see any error types, just propagate that error
975
+ // upwards.
976
+ if expression_ty. references_error ( ) || self . merged_ty ( ) . references_error ( ) {
977
+ self . final_ty = Some ( fcx. tcx . types . err ) ;
978
+ return ;
979
+ }
980
+
981
+ // Handle the actual type unification etc.
982
+ let result = if let Some ( expression) = expression {
983
+ if self . expressions . is_empty ( ) {
984
+ // Special-case the first expression we are coercing.
985
+ // To be honest, I'm not entirely sure why we do this.
986
+ fcx. try_coerce ( expression, expression_ty, self . expected_ty )
987
+ } else {
988
+ fcx. try_find_coercion_lub ( cause,
989
+ || self . expressions . iter ( ) . cloned ( ) ,
990
+ self . merged_ty ( ) ,
991
+ expression,
992
+ expression_ty)
993
+ }
994
+ } else {
995
+ // this is a hack for cases where we default to `()` because
996
+ // the expression etc has been omitted from the source. An
997
+ // example is an `if let` without an else:
998
+ //
999
+ // if let Some(x) = ... { }
1000
+ //
1001
+ // we wind up with a second match arm that is like `_ =>
1002
+ // ()`. That is the case we are considering here. We take
1003
+ // a different path to get the right "expected, found"
1004
+ // message and so forth (and because we know that
1005
+ // `expression_ty` will be unit).
1006
+ //
1007
+ // Another example is `break` with no argument expression.
1008
+ assert ! ( expression_ty. is_nil( ) ) ;
1009
+ assert ! ( expression_ty. is_nil( ) , "if let hack without unit type" ) ;
1010
+ fcx. eq_types ( true , cause, expression_ty, self . merged_ty ( ) )
1011
+ . map ( |infer_ok| {
1012
+ fcx. register_infer_ok_obligations ( infer_ok) ;
1013
+ expression_ty
1014
+ } )
1015
+ } ;
1016
+
1017
+ match result {
1018
+ Ok ( v) => {
1019
+ self . final_ty = Some ( v) ;
1020
+ self . expressions . extend ( expression) ;
1021
+ }
1022
+ Err ( err) => {
1023
+ let ( expected, found) = if expression. is_none ( ) {
1024
+ // In the case where this is a "forced unit", like
1025
+ // `break`, we want to call the `()` "expected"
1026
+ // since it is implied by the syntax.
1027
+ assert ! ( expression_ty. is_nil( ) ) ;
1028
+ ( expression_ty, self . final_ty . unwrap_or ( self . expected_ty ) )
1029
+ } else {
1030
+ // Otherwise, the "expected" type for error
1031
+ // reporting is the current unification type,
1032
+ // which is basically the LUB of the expressions
1033
+ // we've seen so far (combined with the expected
1034
+ // type)
1035
+ ( self . final_ty . unwrap_or ( self . expected_ty ) , expression_ty)
1036
+ } ;
1037
+
1038
+ match cause. code {
1039
+ ObligationCauseCode :: ReturnNoExpression => {
1040
+ struct_span_err ! ( fcx. tcx. sess, cause. span, E0069 ,
1041
+ "`return;` in a function whose return type is not `()`" )
1042
+ . span_label ( cause. span , & format ! ( "return type is not ()" ) )
1043
+ . emit ( ) ;
1044
+ }
1045
+ _ => {
1046
+ fcx. report_mismatched_types ( cause, expected, found, err)
1047
+ . emit ( ) ;
1048
+ }
1049
+ }
1050
+
1051
+ self . final_ty = Some ( fcx. tcx . types . err ) ;
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ pub fn complete < ' a > ( self , fcx : & FnCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
1057
+ if let Some ( final_ty) = self . final_ty {
1058
+ final_ty
1059
+ } else {
1060
+ // If we only had inputs that were of type `!` (or no
1061
+ // inputs at all), then the final type is `!`.
1062
+ assert ! ( self . expressions. is_empty( ) ) ;
1063
+ fcx. tcx . types . never
1064
+ }
1065
+ }
1066
+ }
0 commit comments