@@ -45,15 +45,16 @@ use hir::map::{Definitions, DefKey, REGULAR_SPACE};
45
45
use hir:: map:: definitions:: DefPathData ;
46
46
use hir:: def_id:: { DefIndex , DefId , CRATE_DEF_INDEX } ;
47
47
use hir:: def:: { Def , PathResolution } ;
48
+ use lint:: builtin:: PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES ;
48
49
use rustc_data_structures:: indexed_vec:: IndexVec ;
49
50
use session:: Session ;
51
+ use util:: common:: FN_OUTPUT_NAME ;
50
52
use util:: nodemap:: { DefIdMap , FxHashMap , NodeMap } ;
51
53
52
54
use std:: collections:: BTreeMap ;
53
55
use std:: fmt:: Debug ;
54
56
use std:: iter;
55
57
use std:: mem;
56
-
57
58
use syntax:: attr;
58
59
use syntax:: ast:: * ;
59
60
use syntax:: errors;
@@ -160,6 +161,12 @@ struct LoweredNodeId {
160
161
hir_id : hir:: HirId ,
161
162
}
162
163
164
+ enum ParenthesizedGenericArgs {
165
+ Ok ,
166
+ Warn ,
167
+ Err ,
168
+ }
169
+
163
170
impl < ' a > LoweringContext < ' a > {
164
171
fn lower_crate ( mut self , c : & Crate ) -> hir:: Crate {
165
172
/// Full-crate AST visitor that inserts into a fresh
@@ -749,6 +756,21 @@ impl<'a> LoweringContext<'a> {
749
756
Def :: Trait ( def_id) if i + 1 == proj_start => Some ( def_id) ,
750
757
_ => None
751
758
} ;
759
+ let parenthesized_generic_args = match resolution. base_def ( ) {
760
+ // `a::b::Trait(Args)`
761
+ Def :: Trait ( ..) if i + 1 == proj_start => ParenthesizedGenericArgs :: Ok ,
762
+ // `a::b::Trait(Args)::TraitItem`
763
+ Def :: Method ( ..) |
764
+ Def :: AssociatedConst ( ..) |
765
+ Def :: AssociatedTy ( ..) if i + 2 == proj_start => ParenthesizedGenericArgs :: Ok ,
766
+ // Avoid duplicated errors
767
+ Def :: Err => ParenthesizedGenericArgs :: Ok ,
768
+ // An error
769
+ Def :: Struct ( ..) | Def :: Enum ( ..) | Def :: Union ( ..) | Def :: TyAlias ( ..) |
770
+ Def :: Variant ( ..) if i + 1 == proj_start => ParenthesizedGenericArgs :: Err ,
771
+ // A warning for now, for compatibility reasons
772
+ _ => ParenthesizedGenericArgs :: Warn ,
773
+ } ;
752
774
753
775
let num_lifetimes = type_def_id. map_or ( 0 , |def_id| {
754
776
if let Some ( & n) = self . type_def_lifetime_params . get ( & def_id) {
@@ -759,7 +781,8 @@ impl<'a> LoweringContext<'a> {
759
781
self . type_def_lifetime_params . insert ( def_id, n) ;
760
782
n
761
783
} ) ;
762
- self . lower_path_segment ( p. span , segment, param_mode, num_lifetimes)
784
+ self . lower_path_segment ( p. span , segment, param_mode, num_lifetimes,
785
+ parenthesized_generic_args)
763
786
} ) . collect ( ) ,
764
787
span : p. span ,
765
788
} ) ;
@@ -794,7 +817,8 @@ impl<'a> LoweringContext<'a> {
794
817
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
795
818
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
796
819
for ( i, segment) in p. segments . iter ( ) . enumerate ( ) . skip ( proj_start) {
797
- let segment = P ( self . lower_path_segment ( p. span , segment, param_mode, 0 ) ) ;
820
+ let segment = P ( self . lower_path_segment ( p. span , segment, param_mode, 0 ,
821
+ ParenthesizedGenericArgs :: Warn ) ) ;
798
822
let qpath = hir:: QPath :: TypeRelative ( ty, segment) ;
799
823
800
824
// It's finished, return the extension of the right node type.
@@ -827,7 +851,8 @@ impl<'a> LoweringContext<'a> {
827
851
hir:: Path {
828
852
def : self . expect_full_def ( id) ,
829
853
segments : segments. map ( |segment| {
830
- self . lower_path_segment ( p. span , segment, param_mode, 0 )
854
+ self . lower_path_segment ( p. span , segment, param_mode, 0 ,
855
+ ParenthesizedGenericArgs :: Err )
831
856
} ) . chain ( name. map ( |name| {
832
857
hir:: PathSegment {
833
858
name,
@@ -851,29 +876,37 @@ impl<'a> LoweringContext<'a> {
851
876
path_span : Span ,
852
877
segment : & PathSegment ,
853
878
param_mode : ParamMode ,
854
- expected_lifetimes : usize )
879
+ expected_lifetimes : usize ,
880
+ parenthesized_generic_args : ParenthesizedGenericArgs )
855
881
-> hir:: PathSegment {
856
882
let mut parameters = if let Some ( ref parameters) = segment. parameters {
883
+ let msg = "parenthesized parameters may only be used with a trait" ;
857
884
match * * parameters {
858
885
PathParameters :: AngleBracketed ( ref data) => {
859
- let data = self . lower_angle_bracketed_parameter_data ( data, param_mode) ;
860
- hir:: AngleBracketedParameters ( data)
886
+ self . lower_angle_bracketed_parameter_data ( data, param_mode)
861
887
}
862
- PathParameters :: Parenthesized ( ref data) => {
863
- hir:: ParenthesizedParameters ( self . lower_parenthesized_parameter_data ( data) )
888
+ PathParameters :: Parenthesized ( ref data) => match parenthesized_generic_args {
889
+ ParenthesizedGenericArgs :: Ok => self . lower_parenthesized_parameter_data ( data) ,
890
+ ParenthesizedGenericArgs :: Warn => {
891
+ self . sess . buffer_lint ( PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES ,
892
+ CRATE_NODE_ID , data. span , msg. into ( ) ) ;
893
+ hir:: PathParameters :: none ( )
894
+ }
895
+ ParenthesizedGenericArgs :: Err => {
896
+ struct_span_err ! ( self . sess, data. span, E0214 , "{}" , msg)
897
+ . span_label ( data. span , "only traits may use parentheses" ) . emit ( ) ;
898
+ hir:: PathParameters :: none ( )
899
+ }
864
900
}
865
901
}
866
902
} else {
867
- let data = self . lower_angle_bracketed_parameter_data ( & Default :: default ( ) , param_mode) ;
868
- hir:: AngleBracketedParameters ( data)
903
+ self . lower_angle_bracketed_parameter_data ( & Default :: default ( ) , param_mode)
869
904
} ;
870
905
871
- if let hir:: AngleBracketedParameters ( ref mut data) = parameters {
872
- if data. lifetimes . is_empty ( ) {
873
- data. lifetimes = ( 0 ..expected_lifetimes) . map ( |_| {
874
- self . elided_lifetime ( path_span)
875
- } ) . collect ( ) ;
876
- }
906
+ if !parameters. parenthesized && parameters. lifetimes . is_empty ( ) {
907
+ parameters. lifetimes = ( 0 ..expected_lifetimes) . map ( |_| {
908
+ self . elided_lifetime ( path_span)
909
+ } ) . collect ( ) ;
877
910
}
878
911
879
912
hir:: PathSegment {
@@ -885,24 +918,38 @@ impl<'a> LoweringContext<'a> {
885
918
fn lower_angle_bracketed_parameter_data ( & mut self ,
886
919
data : & AngleBracketedParameterData ,
887
920
param_mode : ParamMode )
888
- -> hir:: AngleBracketedParameterData {
921
+ -> hir:: PathParameters {
889
922
let & AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
890
- hir:: AngleBracketedParameterData {
923
+ hir:: PathParameters {
891
924
lifetimes : self . lower_lifetimes ( lifetimes) ,
892
925
types : types. iter ( ) . map ( |ty| self . lower_ty ( ty) ) . collect ( ) ,
893
926
infer_types : types. is_empty ( ) && param_mode == ParamMode :: Optional ,
894
927
bindings : bindings. iter ( ) . map ( |b| self . lower_ty_binding ( b) ) . collect ( ) ,
928
+ parenthesized : false ,
895
929
}
896
930
}
897
931
898
932
fn lower_parenthesized_parameter_data ( & mut self ,
899
933
data : & ParenthesizedParameterData )
900
- -> hir:: ParenthesizedParameterData {
934
+ -> hir:: PathParameters {
901
935
let & ParenthesizedParameterData { ref inputs, ref output, span } = data;
902
- hir:: ParenthesizedParameterData {
903
- inputs : inputs. iter ( ) . map ( |ty| self . lower_ty ( ty) ) . collect ( ) ,
904
- output : output. as_ref ( ) . map ( |ty| self . lower_ty ( ty) ) ,
905
- span,
936
+ let inputs = inputs. iter ( ) . map ( |ty| self . lower_ty ( ty) ) . collect ( ) ;
937
+ let mk_tup = |this : & mut Self , tys, span| {
938
+ P ( hir:: Ty { node : hir:: TyTup ( tys) , id : this. next_id ( ) . node_id , span } )
939
+ } ;
940
+
941
+ hir:: PathParameters {
942
+ lifetimes : hir:: HirVec :: new ( ) ,
943
+ types : hir_vec ! [ mk_tup( self , inputs, span) ] ,
944
+ infer_types : false ,
945
+ bindings : hir_vec ! [ hir:: TypeBinding {
946
+ id: self . next_id( ) . node_id,
947
+ name: Symbol :: intern( FN_OUTPUT_NAME ) ,
948
+ ty: output. as_ref( ) . map( |ty| self . lower_ty( & ty) )
949
+ . unwrap_or_else( || mk_tup( self , hir:: HirVec :: new( ) , span) ) ,
950
+ span: output. as_ref( ) . map_or( span, |ty| ty. span) ,
951
+ } ] ,
952
+ parenthesized : true ,
906
953
}
907
954
}
908
955
@@ -1877,7 +1924,8 @@ impl<'a> LoweringContext<'a> {
1877
1924
hir:: ExprCall ( f, args. iter ( ) . map ( |x| self . lower_expr ( x) ) . collect ( ) )
1878
1925
}
1879
1926
ExprKind :: MethodCall ( ref seg, ref args) => {
1880
- let hir_seg = self . lower_path_segment ( e. span , seg, ParamMode :: Optional , 0 ) ;
1927
+ let hir_seg = self . lower_path_segment ( e. span , seg, ParamMode :: Optional , 0 ,
1928
+ ParenthesizedGenericArgs :: Err ) ;
1881
1929
let args = args. iter ( ) . map ( |x| self . lower_expr ( x) ) . collect ( ) ;
1882
1930
hir:: ExprMethodCall ( hir_seg, seg. span , args)
1883
1931
}
0 commit comments