@@ -45,15 +45,16 @@ use hir::map::{Definitions, DefKey, REGULAR_SPACE};
4545use hir:: map:: definitions:: DefPathData ;
4646use hir:: def_id:: { DefIndex , DefId , CRATE_DEF_INDEX } ;
4747use hir:: def:: { Def , PathResolution } ;
48+ use lint:: builtin:: PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES ;
4849use rustc_data_structures:: indexed_vec:: IndexVec ;
4950use session:: Session ;
51+ use util:: common:: FN_OUTPUT_NAME ;
5052use util:: nodemap:: { DefIdMap , FxHashMap , NodeMap } ;
5153
5254use std:: collections:: BTreeMap ;
5355use std:: fmt:: Debug ;
5456use std:: iter;
5557use std:: mem;
56-
5758use syntax:: attr;
5859use syntax:: ast:: * ;
5960use syntax:: errors;
@@ -160,6 +161,12 @@ struct LoweredNodeId {
160161 hir_id : hir:: HirId ,
161162}
162163
164+ enum ParenthesizedGenericArgs {
165+ Ok ,
166+ Warn ,
167+ Err ,
168+ }
169+
163170impl < ' a > LoweringContext < ' a > {
164171 fn lower_crate ( mut self , c : & Crate ) -> hir:: Crate {
165172 /// Full-crate AST visitor that inserts into a fresh
@@ -749,6 +756,21 @@ impl<'a> LoweringContext<'a> {
749756 Def :: Trait ( def_id) if i + 1 == proj_start => Some ( def_id) ,
750757 _ => None
751758 } ;
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+ } ;
752774
753775 let num_lifetimes = type_def_id. map_or ( 0 , |def_id| {
754776 if let Some ( & n) = self . type_def_lifetime_params . get ( & def_id) {
@@ -759,7 +781,8 @@ impl<'a> LoweringContext<'a> {
759781 self . type_def_lifetime_params . insert ( def_id, n) ;
760782 n
761783 } ) ;
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)
763786 } ) . collect ( ) ,
764787 span : p. span ,
765788 } ) ;
@@ -794,7 +817,8 @@ impl<'a> LoweringContext<'a> {
794817 // 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
795818 // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
796819 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 ) ) ;
798822 let qpath = hir:: QPath :: TypeRelative ( ty, segment) ;
799823
800824 // It's finished, return the extension of the right node type.
@@ -827,7 +851,8 @@ impl<'a> LoweringContext<'a> {
827851 hir:: Path {
828852 def : self . expect_full_def ( id) ,
829853 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 )
831856 } ) . chain ( name. map ( |name| {
832857 hir:: PathSegment {
833858 name,
@@ -851,29 +876,37 @@ impl<'a> LoweringContext<'a> {
851876 path_span : Span ,
852877 segment : & PathSegment ,
853878 param_mode : ParamMode ,
854- expected_lifetimes : usize )
879+ expected_lifetimes : usize ,
880+ parenthesized_generic_args : ParenthesizedGenericArgs )
855881 -> hir:: PathSegment {
856882 let mut parameters = if let Some ( ref parameters) = segment. parameters {
883+ let msg = "parenthesized parameters may only be used with a trait" ;
857884 match * * parameters {
858885 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)
861887 }
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+ }
864900 }
865901 }
866902 } 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)
869904 } ;
870905
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 ( ) ;
877910 }
878911
879912 hir:: PathSegment {
@@ -885,24 +918,38 @@ impl<'a> LoweringContext<'a> {
885918 fn lower_angle_bracketed_parameter_data ( & mut self ,
886919 data : & AngleBracketedParameterData ,
887920 param_mode : ParamMode )
888- -> hir:: AngleBracketedParameterData {
921+ -> hir:: PathParameters {
889922 let & AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
890- hir:: AngleBracketedParameterData {
923+ hir:: PathParameters {
891924 lifetimes : self . lower_lifetimes ( lifetimes) ,
892925 types : types. iter ( ) . map ( |ty| self . lower_ty ( ty) ) . collect ( ) ,
893926 infer_types : types. is_empty ( ) && param_mode == ParamMode :: Optional ,
894927 bindings : bindings. iter ( ) . map ( |b| self . lower_ty_binding ( b) ) . collect ( ) ,
928+ parenthesized : false ,
895929 }
896930 }
897931
898932 fn lower_parenthesized_parameter_data ( & mut self ,
899933 data : & ParenthesizedParameterData )
900- -> hir:: ParenthesizedParameterData {
934+ -> hir:: PathParameters {
901935 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 ,
906953 }
907954 }
908955
@@ -1877,7 +1924,8 @@ impl<'a> LoweringContext<'a> {
18771924 hir:: ExprCall ( f, args. iter ( ) . map ( |x| self . lower_expr ( x) ) . collect ( ) )
18781925 }
18791926 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 ) ;
18811929 let args = args. iter ( ) . map ( |x| self . lower_expr ( x) ) . collect ( ) ;
18821930 hir:: ExprMethodCall ( hir_seg, seg. span , args)
18831931 }
0 commit comments