@@ -83,6 +83,8 @@ pub(super) fn check<'tcx>(
83
83
method_span : Span ,
84
84
self_expr : & hir:: Expr < ' _ > ,
85
85
arg : & ' tcx hir:: Expr < ' _ > ,
86
+ // `Some` if fn has second argument
87
+ second_arg : Option < & hir:: Expr < ' _ > > ,
86
88
span : Span ,
87
89
// None if lambda is required
88
90
fun_span : Option < Span > ,
@@ -109,30 +111,40 @@ pub(super) fn check<'tcx>(
109
111
if poss. contains( & name) ;
110
112
111
113
then {
112
- let macro_expanded_snipped;
113
- let sugg: Cow <' _, str > = {
114
+ let sugg = {
114
115
let ( snippet_span, use_lambda) = match ( fn_has_arguments, fun_span) {
115
116
( false , Some ( fun_span) ) => ( fun_span, false ) ,
116
117
_ => ( arg. span, true ) ,
117
118
} ;
118
- let snippet = {
119
- let not_macro_argument_snippet = snippet_with_macro_callsite( cx, snippet_span, ".." ) ;
120
- if not_macro_argument_snippet == "vec![]" {
121
- macro_expanded_snipped = snippet( cx, snippet_span, ".." ) ;
119
+
120
+ let format_span = |span: Span | {
121
+ let not_macro_argument_snippet = snippet_with_macro_callsite( cx, span, ".." ) ;
122
+ let snip = if not_macro_argument_snippet == "vec![]" {
123
+ let macro_expanded_snipped = snippet( cx, snippet_span, ".." ) ;
122
124
match macro_expanded_snipped. strip_prefix( "$crate::vec::" ) {
123
- Some ( stripped) => Cow :: from ( stripped) ,
125
+ Some ( stripped) => Cow :: Owned ( stripped. to_owned ( ) ) ,
124
126
None => macro_expanded_snipped,
125
127
}
126
128
} else {
127
129
not_macro_argument_snippet
128
- }
130
+ } ;
131
+
132
+ snip. to_string( )
129
133
} ;
130
134
131
- if use_lambda {
135
+ let snip = format_span( snippet_span) ;
136
+ let snip = if use_lambda {
132
137
let l_arg = if fn_has_arguments { "_" } else { "" } ;
133
- format!( "|{l_arg}| {snippet}" ) . into ( )
138
+ format!( "|{l_arg}| {snip}" )
134
139
} else {
135
- snippet
140
+ snip
141
+ } ;
142
+
143
+ if let Some ( f) = second_arg {
144
+ let f = format_span( f. span) ;
145
+ format!( "{snip}, {f}" )
146
+ } else {
147
+ snip
136
148
}
137
149
} ;
138
150
let span_replace_word = method_span. with_hi( span. hi( ) ) ;
@@ -149,8 +161,8 @@ pub(super) fn check<'tcx>(
149
161
}
150
162
}
151
163
152
- if let [ arg ] = args {
153
- let inner_arg = if let hir:: ExprKind :: Block (
164
+ let extract_inner_arg = | arg : & ' tcx hir :: Expr < ' _ > | {
165
+ if let hir:: ExprKind :: Block (
154
166
hir:: Block {
155
167
stmts : [ ] ,
156
168
expr : Some ( expr) ,
@@ -162,19 +174,32 @@ pub(super) fn check<'tcx>(
162
174
expr
163
175
} else {
164
176
arg
165
- } ;
177
+ }
178
+ } ;
179
+
180
+ if let [ arg] = args {
181
+ let inner_arg = extract_inner_arg ( arg) ;
166
182
match inner_arg. kind {
167
183
hir:: ExprKind :: Call ( fun, or_args) => {
168
184
let or_has_args = !or_args. is_empty ( ) ;
169
185
if !check_unwrap_or_default ( cx, name, fun, arg, or_has_args, expr. span , method_span) {
170
186
let fun_span = if or_has_args { None } else { Some ( fun. span ) } ;
171
- check_general_case ( cx, name, method_span, receiver, arg, expr. span , fun_span) ;
187
+ check_general_case ( cx, name, method_span, receiver, arg, None , expr. span , fun_span) ;
172
188
}
173
189
} ,
174
190
hir:: ExprKind :: Index ( ..) | hir:: ExprKind :: MethodCall ( ..) => {
175
- check_general_case ( cx, name, method_span, receiver, arg, expr. span , None ) ;
191
+ check_general_case ( cx, name, method_span, receiver, arg, None , expr. span , None ) ;
176
192
} ,
177
193
_ => ( ) ,
178
194
}
179
195
}
196
+
197
+ // `map_or` takes two arguments
198
+ if let [ arg, lambda] = args {
199
+ let inner_arg = extract_inner_arg ( arg) ;
200
+ if let hir:: ExprKind :: Call ( fun, or_args) = inner_arg. kind {
201
+ let fun_span = if or_args. is_empty ( ) { Some ( fun. span ) } else { None } ;
202
+ check_general_case ( cx, name, method_span, receiver, arg, Some ( lambda) , expr. span , fun_span) ;
203
+ }
204
+ }
180
205
}
0 commit comments