@@ -54,7 +54,9 @@ struct AstValidator<'a> {
54
54
extern_mod : Option < & ' a Item > ,
55
55
56
56
/// Are we inside a trait impl?
57
- in_trait_impl : bool ,
57
+ ///
58
+ /// If so, this is the trait ref together with its polarity.
59
+ in_trait_impl : Option < ( ImplPolarity , & ' a TraitRef ) > ,
58
60
59
61
/// Are we inside a const trait defn or impl?
60
62
///
@@ -80,15 +82,17 @@ struct AstValidator<'a> {
80
82
impl < ' a > AstValidator < ' a > {
81
83
fn with_in_trait_impl (
82
84
& mut self ,
83
- is_in : bool ,
84
- constness : Option < Const > ,
85
+ trait_ref : Option < ( Const , ImplPolarity , & ' a TraitRef ) > ,
85
86
f : impl FnOnce ( & mut Self ) ,
86
87
) {
87
- let old = mem:: replace ( & mut self . in_trait_impl , is_in) ;
88
+ let old = mem:: replace (
89
+ & mut self . in_trait_impl ,
90
+ trait_ref. map ( |( _, polarity, trait_ref) | ( polarity, trait_ref) ) ,
91
+ ) ;
88
92
let old_const = mem:: replace (
89
93
& mut self . in_const_trait_or_impl ,
90
- match constness {
91
- Some ( Const :: Yes ( span) ) => Some ( span) ,
94
+ match trait_ref {
95
+ Some ( ( Const :: Yes ( span) , .. ) ) => Some ( span) ,
92
96
_ => None ,
93
97
} ,
94
98
) ;
@@ -301,11 +305,20 @@ impl<'a> AstValidator<'a> {
301
305
return ;
302
306
} ;
303
307
304
- // FIXME(const_trait_impl): If the trait or impl is not const and feature `const_trait_impl`
305
- // is enabled, provide a structured suggestion to make the trait (impl) const.
308
+ let make_impl_const_sugg = if self . in_const_trait_or_impl . is_none ( )
309
+ && let Some ( ( ImplPolarity :: Positive , trait_ref) ) = self . in_trait_impl
310
+ && self . features . const_trait_impl
311
+ {
312
+ Some ( trait_ref. path . span . shrink_to_lo ( ) )
313
+ } else {
314
+ None
315
+ } ;
316
+
317
+ // FIXME(const_trait_impl): If the trait is not const and feature `const_trait_impl`
318
+ // is enabled, provide a structured suggestion to make the trait const.
306
319
self . dcx ( ) . emit_err ( errors:: TraitFnConst {
307
320
span,
308
- in_impl : self . in_trait_impl ,
321
+ in_impl : self . in_trait_impl . is_some ( ) ,
309
322
const_context_label : self . in_const_trait_or_impl ,
310
323
remove_const_sugg : (
311
324
self . session . source_map ( ) . span_extend_while ( span, |c| c == ' ' ) . unwrap_or ( span) ,
@@ -314,6 +327,7 @@ impl<'a> AstValidator<'a> {
314
327
None => rustc_errors:: Applicability :: MaybeIncorrect ,
315
328
} ,
316
329
) ,
330
+ make_impl_const_sugg,
317
331
} ) ;
318
332
}
319
333
@@ -837,7 +851,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
837
851
self_ty,
838
852
items,
839
853
} ) => {
840
- self . with_in_trait_impl ( true , Some ( * constness) , |this| {
854
+ self . with_in_trait_impl ( Some ( ( * constness, * polarity , t ) ) , |this| {
841
855
this. visibility_not_permitted (
842
856
& item. vis ,
843
857
errors:: VisibilityNotPermittedNote :: TraitImpl ,
@@ -1376,7 +1390,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1376
1390
self . check_nomangle_item_asciionly ( item. ident , item. span ) ;
1377
1391
}
1378
1392
1379
- if ctxt == AssocCtxt :: Trait || ! self . in_trait_impl {
1393
+ if ctxt == AssocCtxt :: Trait || self . in_trait_impl . is_none ( ) {
1380
1394
self . check_defaultness ( item. span , item. kind . defaultness ( ) ) ;
1381
1395
}
1382
1396
@@ -1424,7 +1438,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1424
1438
) ;
1425
1439
}
1426
1440
1427
- if ctxt == AssocCtxt :: Trait || self . in_trait_impl {
1441
+ if ctxt == AssocCtxt :: Trait || self . in_trait_impl . is_some ( ) {
1428
1442
self . visibility_not_permitted ( & item. vis , errors:: VisibilityNotPermittedNote :: TraitImpl ) ;
1429
1443
if let AssocItemKind :: Fn ( box Fn { sig, .. } ) = & item. kind {
1430
1444
self . check_trait_fn_not_const ( sig. header . constness ) ;
@@ -1453,8 +1467,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1453
1467
) ;
1454
1468
self . visit_fn ( kind, item. span , item. id ) ;
1455
1469
}
1456
- _ => self
1457
- . with_in_trait_impl ( false , None , |this| visit:: walk_assoc_item ( this, item, ctxt) ) ,
1470
+ _ => self . with_in_trait_impl ( None , |this| visit:: walk_assoc_item ( this, item, ctxt) ) ,
1458
1471
}
1459
1472
}
1460
1473
}
@@ -1570,7 +1583,7 @@ pub fn check_crate(
1570
1583
session,
1571
1584
features,
1572
1585
extern_mod : None ,
1573
- in_trait_impl : false ,
1586
+ in_trait_impl : None ,
1574
1587
in_const_trait_or_impl : None ,
1575
1588
has_proc_macro_decls : false ,
1576
1589
outer_impl_trait : None ,
0 commit comments