@@ -7,7 +7,7 @@ use syntax_pos::Span;
77use rustc:: hir;
88use rustc:: hir:: def:: Def ;
99use rustc:: hir:: Node ;
10- use rustc:: hir:: print;
10+ use rustc:: hir:: { print, lowering :: is_range_literal } ;
1111use rustc:: ty:: { self , Ty , AssociatedItem } ;
1212use rustc:: ty:: adjustment:: AllowTwoPhase ;
1313use errors:: { Applicability , DiagnosticBuilder } ;
@@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
380380 hir:: ExprKind :: Cast ( _, _) |
381381 hir:: ExprKind :: Binary ( _, _, _) => true ,
382382 // parenthesize borrows of range literals (Issue #54505)
383- _ if self . is_range_literal ( expr) => true ,
383+ _ if is_range_literal ( self . tcx . sess , expr) => true ,
384384 _ => false ,
385385 } ;
386386 let sugg_expr = if needs_parens {
@@ -479,70 +479,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
479479 None
480480 }
481481
482- /// This function checks if the specified expression is a built-in range literal.
483- /// (See: `LoweringContext::lower_expr()` in `src/librustc/hir/lowering.rs`).
484- fn is_range_literal ( & self , expr : & hir:: Expr ) -> bool {
485- use hir:: { Path , QPath , ExprKind , TyKind } ;
486-
487- // We support `::std::ops::Range` and `::core::ops::Range` prefixes
488- let is_range_path = |path : & Path | {
489- let mut segs = path. segments . iter ( )
490- . map ( |seg| seg. ident . as_str ( ) ) ;
491-
492- if let ( Some ( root) , Some ( std_core) , Some ( ops) , Some ( range) , None ) =
493- ( segs. next ( ) , segs. next ( ) , segs. next ( ) , segs. next ( ) , segs. next ( ) )
494- {
495- // "{{root}}" is the equivalent of `::` prefix in Path
496- root == "{{root}}" && ( std_core == "std" || std_core == "core" )
497- && ops == "ops" && range. starts_with ( "Range" )
498- } else {
499- false
500- }
501- } ;
502-
503- let span_is_range_literal = |span : & Span | {
504- // Check whether a span corresponding to a range expression
505- // is a range literal, rather than an explicit struct or `new()` call.
506- let source_map = self . tcx . sess . source_map ( ) ;
507- let end_point = source_map. end_point ( * span) ;
508-
509- if let Ok ( end_string) = source_map. span_to_snippet ( end_point) {
510- !( end_string. ends_with ( "}" ) || end_string. ends_with ( ")" ) )
511- } else {
512- false
513- }
514- } ;
515-
516- match expr. node {
517- // All built-in range literals but `..=` and `..` desugar to Structs
518- ExprKind :: Struct ( ref qpath, _, _) => {
519- if let QPath :: Resolved ( None , ref path) = * * qpath {
520- return is_range_path ( & path) && span_is_range_literal ( & expr. span ) ;
521- }
522- }
523- // `..` desugars to its struct path
524- ExprKind :: Path ( QPath :: Resolved ( None , ref path) ) => {
525- return is_range_path ( & path) && span_is_range_literal ( & expr. span ) ;
526- }
527-
528- // `..=` desugars into `::std::ops::RangeInclusive::new(...)`
529- ExprKind :: Call ( ref func, _) => {
530- if let ExprKind :: Path ( QPath :: TypeRelative ( ref ty, ref segment) ) = func. node {
531- if let TyKind :: Path ( QPath :: Resolved ( None , ref path) ) = ty. node {
532- let call_to_new = segment. ident . as_str ( ) == "new" ;
533-
534- return is_range_path ( & path) && span_is_range_literal ( & expr. span )
535- && call_to_new;
536- }
537- }
538- }
539-
540- _ => { }
541- }
542-
543- false
544- }
545-
546482 pub fn check_for_cast (
547483 & self ,
548484 err : & mut DiagnosticBuilder < ' tcx > ,
0 commit comments