@@ -93,62 +93,96 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
93
93
span : Span ,
94
94
trait_def_id : DefId ,
95
95
trait_segment : & ' _ hir:: PathSegment < ' _ > ,
96
+ is_impl : bool ,
96
97
) {
98
+ if self . tcx ( ) . features ( ) . unboxed_closures {
99
+ return ;
100
+ }
101
+
97
102
let trait_def = self . tcx ( ) . trait_def ( trait_def_id) ;
103
+ if !trait_def. paren_sugar {
104
+ if trait_segment. args ( ) . parenthesized {
105
+ // For now, require that parenthetical notation be used only with `Fn()` etc.
106
+ let mut err = feature_err (
107
+ & self . tcx ( ) . sess . parse_sess ,
108
+ sym:: unboxed_closures,
109
+ span,
110
+ "parenthetical notation is only stable when used with `Fn`-family traits" ,
111
+ ) ;
112
+ err. emit ( ) ;
113
+ }
98
114
99
- if !self . tcx ( ) . features ( ) . unboxed_closures
100
- && trait_segment. args ( ) . parenthesized != trait_def. paren_sugar
101
- {
102
- let sess = & self . tcx ( ) . sess . parse_sess ;
115
+ return ;
116
+ }
117
+
118
+ let sess = self . tcx ( ) . sess ;
119
+
120
+ if !trait_segment. args ( ) . parenthesized {
103
121
// For now, require that parenthetical notation be used only with `Fn()` etc.
104
- let ( msg, sugg) = if trait_def. paren_sugar {
105
- (
106
- "the precise format of `Fn`-family traits' type parameters is subject to \
107
- change",
108
- Some ( format ! (
109
- "{}{} -> {}" ,
110
- trait_segment. ident,
111
- trait_segment
112
- . args
113
- . as_ref( )
114
- . and_then( |args| args. args. get( 0 ) )
115
- . and_then( |arg| match arg {
116
- hir:: GenericArg :: Type ( ty) => match ty. kind {
117
- hir:: TyKind :: Tup ( t) => t
118
- . iter( )
119
- . map( |e| sess. source_map( ) . span_to_snippet( e. span) )
120
- . collect:: <Result <Vec <_>, _>>( )
121
- . map( |a| a. join( ", " ) ) ,
122
- _ => sess. source_map( ) . span_to_snippet( ty. span) ,
123
- }
124
- . map( |s| format!( "({})" , s) )
125
- . ok( ) ,
126
- _ => None ,
127
- } )
128
- . unwrap_or_else( || "()" . to_string( ) ) ,
129
- trait_segment
130
- . args( )
131
- . bindings
132
- . iter( )
133
- . find_map( |b| match ( b. ident. name == sym:: Output , & b. kind) {
134
- ( true , hir:: TypeBindingKind :: Equality { ty } ) => {
135
- sess. source_map( ) . span_to_snippet( ty. span) . ok( )
136
- }
137
- _ => None ,
138
- } )
139
- . unwrap_or_else( || "()" . to_string( ) ) ,
140
- ) ) ,
141
- )
142
- } else {
143
- ( "parenthetical notation is only stable when used with `Fn`-family traits" , None )
144
- } ;
145
- let mut err = feature_err ( sess, sym:: unboxed_closures, span, msg) ;
146
- if let Some ( sugg) = sugg {
147
- let msg = "use parenthetical notation instead" ;
148
- err. span_suggestion ( span, msg, sugg, Applicability :: MaybeIncorrect ) ;
122
+ let mut err = feature_err (
123
+ & sess. parse_sess ,
124
+ sym:: unboxed_closures,
125
+ span,
126
+ "the precise format of `Fn`-family traits' type parameters is subject to change" ,
127
+ ) ;
128
+ // Do not suggest the other syntax if we are in trait impl:
129
+ // the desugaring would contain an associated type constrait.
130
+ if !is_impl {
131
+ let args = trait_segment
132
+ . args
133
+ . as_ref ( )
134
+ . and_then ( |args| args. args . get ( 0 ) )
135
+ . and_then ( |arg| match arg {
136
+ hir:: GenericArg :: Type ( ty) => match ty. kind {
137
+ hir:: TyKind :: Tup ( t) => t
138
+ . iter ( )
139
+ . map ( |e| sess. source_map ( ) . span_to_snippet ( e. span ) )
140
+ . collect :: < Result < Vec < _ > , _ > > ( )
141
+ . map ( |a| a. join ( ", " ) ) ,
142
+ _ => sess. source_map ( ) . span_to_snippet ( ty. span ) ,
143
+ }
144
+ . map ( |s| format ! ( "({})" , s) )
145
+ . ok ( ) ,
146
+ _ => None ,
147
+ } )
148
+ . unwrap_or_else ( || "()" . to_string ( ) ) ;
149
+ let ret = trait_segment
150
+ . args ( )
151
+ . bindings
152
+ . iter ( )
153
+ . find_map ( |b| match ( b. ident . name == sym:: Output , & b. kind ) {
154
+ ( true , hir:: TypeBindingKind :: Equality { ty } ) => {
155
+ sess. source_map ( ) . span_to_snippet ( ty. span ) . ok ( )
156
+ }
157
+ _ => None ,
158
+ } )
159
+ . unwrap_or_else ( || "()" . to_string ( ) ) ;
160
+ err. span_suggestion (
161
+ span,
162
+ "use parenthetical notation instead" ,
163
+ format ! ( "{}{} -> {}" , trait_segment. ident, args, ret) ,
164
+ Applicability :: MaybeIncorrect ,
165
+ ) ;
149
166
}
150
167
err. emit ( ) ;
151
168
}
169
+
170
+ if is_impl {
171
+ let trait_name = self . tcx ( ) . def_path_str ( trait_def_id) ;
172
+ struct_span_err ! (
173
+ self . tcx( ) . sess,
174
+ span,
175
+ E0183 ,
176
+ "manual implementations of `{}` are experimental" ,
177
+ trait_name,
178
+ )
179
+ . span_label (
180
+ span,
181
+ format ! ( "manual implementations of `{}` are experimental" , trait_name) ,
182
+ )
183
+ . help ( "add `#![feature(unboxed_closures)]` to the crate attributes to enable" )
184
+ . emit ( ) ;
185
+ }
152
186
}
153
187
154
188
pub ( crate ) fn complain_about_assoc_type_not_found < I > (
0 commit comments