@@ -558,25 +558,22 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
558
558
let prev = replace ( & mut self . diagnostic_metadata . currently_processing_generics , true ) ;
559
559
match arg {
560
560
GenericArg :: Type ( ref ty) => {
561
- // We parse const arguments as path types as we cannot distinguish them during
562
- // parsing. We try to resolve that ambiguity by attempting resolution the type
563
- // namespace first, and if that fails we try again in the value namespace. If
564
- // resolution in the value namespace succeeds, we have an generic const argument on
565
- // our hands.
566
- if let TyKind :: Path ( ref qself, ref path) = ty. kind {
567
- // We cannot disambiguate multi-segment paths right now as that requires type
568
- // checking.
569
- if path. segments . len ( ) == 1 && path. segments [ 0 ] . args . is_none ( ) {
570
- let mut check_ns = |ns| {
571
- self . resolve_ident_in_lexical_scope (
572
- path. segments [ 0 ] . ident ,
573
- ns,
574
- None ,
575
- path. span ,
576
- )
577
- . is_some ( )
578
- } ;
579
- if !check_ns ( TypeNS ) && check_ns ( ValueNS ) {
561
+ let mut check_ns = |path : & Path , ns| {
562
+ self . resolve_ident_in_lexical_scope ( path. segments [ 0 ] . ident , ns, None , path. span )
563
+ . is_some ( )
564
+ && path. segments . len ( ) == 1
565
+ && path. segments [ 0 ] . args . is_none ( )
566
+ } ;
567
+ match ty. kind {
568
+ // We parse const arguments as path types as we cannot distinguish them during
569
+ // parsing. We try to resolve that ambiguity by attempting resolution the type
570
+ // namespace first, and if that fails we try again in the value namespace. If
571
+ // resolution in the value namespace succeeds, we have an generic const argument
572
+ // on our hands.
573
+ TyKind :: Path ( ref qself, ref path) => {
574
+ // We cannot disambiguate multi-segment paths right now as that requires type
575
+ // checking.
576
+ if !check_ns ( path, TypeNS ) && check_ns ( path, ValueNS ) {
580
577
// This must be equivalent to `visit_anon_const`, but we cannot call it
581
578
// directly due to visitor lifetimes so we have to copy-paste some code.
582
579
self . with_constant_rib ( |this| {
@@ -597,6 +594,38 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
597
594
return ;
598
595
}
599
596
}
597
+
598
+ // Possible `a + b` expression that should be surrounded in braces but was
599
+ // parsed as trait bounds in a trait object. Suggest surrounding with braces.
600
+ TyKind :: TraitObject ( ref bounds, TraitObjectSyntax :: None ) => {
601
+ // We cannot disambiguate multi-segment paths right now as that requires
602
+ // type checking.
603
+ let const_expr_without_braces = bounds. iter ( ) . all ( |bound| match bound {
604
+ GenericBound :: Trait (
605
+ PolyTraitRef {
606
+ bound_generic_params,
607
+ trait_ref : TraitRef { path, .. } ,
608
+ ..
609
+ } ,
610
+ TraitBoundModifier :: None ,
611
+ ) if bound_generic_params. is_empty ( ) => {
612
+ !check_ns ( path, TypeNS ) && check_ns ( path, ValueNS )
613
+ }
614
+ _ => false ,
615
+ } ) ;
616
+ if const_expr_without_braces {
617
+ // This will be handled and emit an appropriate error in
618
+ // `rustc_ast_lowering::LoweringContext::lower_generic_arg`. We do not
619
+ // `visit_ty` in this case to avoid extra unnecessary output.
620
+ self . r . session . delay_span_bug (
621
+ ty. span ,
622
+ "`const` expression parsed as trait bounds" ,
623
+ ) ;
624
+ self . diagnostic_metadata . currently_processing_generics = prev;
625
+ return ;
626
+ }
627
+ }
628
+ _ => { }
600
629
}
601
630
602
631
self . visit_ty ( ty) ;
0 commit comments