@@ -13,7 +13,7 @@ use rustc_hir as hir;
13
13
use rustc_hir:: def:: DefKind ;
14
14
use rustc_hir:: def_id:: DefId ;
15
15
use rustc_hir:: lang_items:: LangItem ;
16
- use rustc_hir:: { is_range_literal , ExprKind , Node , QPath } ;
16
+ use rustc_hir:: { ExprKind , Node , QPath } ;
17
17
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
18
18
use rustc_middle:: traits:: util:: supertraits;
19
19
use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
@@ -1214,50 +1214,61 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1214
1214
ty_str : & str ,
1215
1215
) -> bool {
1216
1216
if let SelfSource :: MethodCall ( expr) = source {
1217
- let mut search_limit = 5 ;
1218
- for ( _, parent) in tcx. hir ( ) . parent_iter ( expr. hir_id ) {
1219
- search_limit -= 1 ;
1220
- if search_limit == 0 {
1221
- break ;
1222
- }
1217
+ for ( _, parent) in tcx. hir ( ) . parent_iter ( expr. hir_id ) . take ( 5 ) {
1218
+ if let Node :: Expr ( parent_expr) = parent {
1219
+ let lang_item = match parent_expr. kind {
1220
+ ExprKind :: Struct ( ref qpath, _, _) => match * * qpath {
1221
+ QPath :: LangItem ( LangItem :: Range , ..) => Some ( LangItem :: Range ) ,
1222
+ QPath :: LangItem ( LangItem :: RangeTo , ..) => Some ( LangItem :: RangeTo ) ,
1223
+ QPath :: LangItem ( LangItem :: RangeToInclusive , ..) => {
1224
+ Some ( LangItem :: RangeToInclusive )
1225
+ }
1226
+ _ => None ,
1227
+ } ,
1228
+ ExprKind :: Call ( ref func, _) => match func. kind {
1229
+ // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1230
+ ExprKind :: Path ( QPath :: LangItem ( LangItem :: RangeInclusiveNew , ..) ) => {
1231
+ Some ( LangItem :: RangeInclusiveStruct )
1232
+ }
1233
+ _ => None ,
1234
+ } ,
1235
+ _ => None ,
1236
+ } ;
1237
+
1238
+ if lang_item. is_none ( ) {
1239
+ continue ;
1240
+ }
1223
1241
1224
- if let Node :: Expr ( parent_expr) = parent && is_range_literal ( parent_expr) {
1225
1242
let span_included = match parent_expr. kind {
1226
- hir:: ExprKind :: Struct ( _, eps, _) =>
1227
- eps. len ( ) > 0 && eps. last ( ) . map_or ( false , |ep| ep. span . contains ( span) ) ,
1228
- // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1229
- hir:: ExprKind :: Call ( ref func, ..) => func. span . contains ( span) ,
1230
- _ => false ,
1243
+ hir:: ExprKind :: Struct ( _, eps, _) => {
1244
+ eps. len ( ) > 0 && eps. last ( ) . map_or ( false , |ep| ep. span . contains ( span) )
1245
+ }
1246
+ // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1247
+ hir:: ExprKind :: Call ( ref func, ..) => func. span . contains ( span) ,
1248
+ _ => false ,
1231
1249
} ;
1232
1250
1233
1251
if !span_included {
1234
1252
continue ;
1235
1253
}
1236
1254
1237
- let range_def_id = self . tcx . lang_items ( ) . range_struct ( ) . unwrap ( ) ;
1238
- let range_ty = self . tcx . bound_type_of ( range_def_id) . subst ( self . tcx , & [ actual. into ( ) ] ) ;
1239
-
1240
- // avoid suggesting when the method name is not implemented for a `range`
1241
- let pick = self . lookup_probe (
1242
- span,
1243
- item_name,
1244
- range_ty,
1245
- expr,
1246
- ProbeScope :: AllTraits
1247
- ) ;
1255
+ debug ! ( "lang_item: {:?}" , lang_item) ;
1256
+ let range_def_id = self . tcx . require_lang_item ( lang_item. unwrap ( ) , None ) ;
1257
+ let range_ty =
1258
+ self . tcx . bound_type_of ( range_def_id) . subst ( self . tcx , & [ actual. into ( ) ] ) ;
1248
1259
1260
+ let pick =
1261
+ self . lookup_probe ( span, item_name, range_ty, expr, ProbeScope :: AllTraits ) ;
1249
1262
if pick. is_ok ( ) {
1250
1263
let range_span = parent_expr. span . with_hi ( expr. span . hi ( ) ) ;
1251
1264
tcx. sess . emit_err ( errors:: MissingParentheseInRange {
1252
1265
span : span,
1253
1266
ty_str : ty_str. to_string ( ) ,
1254
- add_missing_parentheses : Some (
1255
- errors:: AddMissingParenthesesInRange {
1256
- func_name : item_name. name . as_str ( ) . to_string ( ) ,
1257
- left : range_span. shrink_to_lo ( ) ,
1258
- right : range_span. shrink_to_hi ( ) ,
1259
- }
1260
- )
1267
+ add_missing_parentheses : Some ( errors:: AddMissingParenthesesInRange {
1268
+ func_name : item_name. name . as_str ( ) . to_string ( ) ,
1269
+ left : range_span. shrink_to_lo ( ) ,
1270
+ right : range_span. shrink_to_hi ( ) ,
1271
+ } ) ,
1261
1272
} ) ;
1262
1273
return true ;
1263
1274
}
0 commit comments