@@ -1430,3 +1430,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
1430
1430
}
1431
1431
}
1432
1432
}
1433
+
1434
+ /// Lint constants that are erroneous.
1435
+ /// Without this lint, we might not get any diagnostic if the constant is
1436
+ /// unused within this crate, even though downstream crates can't use it
1437
+ /// without producing an error.
1438
+ pub struct UnusedBrokenConst ;
1439
+
1440
+ impl LintPass for UnusedBrokenConst {
1441
+ fn get_lints ( & self ) -> LintArray {
1442
+ lint_array ! ( )
1443
+ }
1444
+ }
1445
+
1446
+ fn check_const ( cx : & LateContext , body_id : hir:: BodyId , what : & str ) {
1447
+ let def_id = cx. tcx . hir . body_owner_def_id ( body_id) ;
1448
+ let param_env = cx. tcx . param_env ( def_id) ;
1449
+ let cid = :: rustc:: mir:: interpret:: GlobalId {
1450
+ instance : ty:: Instance :: mono ( cx. tcx , def_id) ,
1451
+ promoted : None
1452
+ } ;
1453
+ if let Err ( err) = cx. tcx . const_eval ( param_env. and ( cid) ) {
1454
+ let span = cx. tcx . def_span ( def_id) ;
1455
+ let mut diag = cx. struct_span_lint (
1456
+ CONST_ERR ,
1457
+ span,
1458
+ & format ! ( "this {} cannot be used" , what) ,
1459
+ ) ;
1460
+ use rustc:: middle:: const_val:: ConstEvalErrDescription ;
1461
+ match err. description ( ) {
1462
+ ConstEvalErrDescription :: Simple ( message) => {
1463
+ diag. span_label ( span, message) ;
1464
+ }
1465
+ ConstEvalErrDescription :: Backtrace ( miri, frames) => {
1466
+ diag. span_label ( span, format ! ( "{}" , miri) ) ;
1467
+ for frame in frames {
1468
+ diag. span_label ( frame. span , format ! ( "inside call to `{}`" , frame. location) ) ;
1469
+ }
1470
+ }
1471
+ }
1472
+ diag. emit ( )
1473
+ }
1474
+ }
1475
+
1476
+ struct UnusedBrokenConstVisitor < ' a , ' tcx : ' a > ( & ' a LateContext < ' a , ' tcx > ) ;
1477
+
1478
+ impl < ' a , ' tcx , ' v > hir:: intravisit:: Visitor < ' v > for UnusedBrokenConstVisitor < ' a , ' tcx > {
1479
+ fn visit_nested_body ( & mut self , id : hir:: BodyId ) {
1480
+ check_const ( self . 0 , id, "array length" ) ;
1481
+ }
1482
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> hir:: intravisit:: NestedVisitorMap < ' this , ' v > {
1483
+ hir:: intravisit:: NestedVisitorMap :: None
1484
+ }
1485
+ }
1486
+
1487
+ impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for UnusedBrokenConst {
1488
+ fn check_item ( & mut self , cx : & LateContext , it : & hir:: Item ) {
1489
+ match it. node {
1490
+ hir:: ItemConst ( _, body_id) => {
1491
+ check_const ( cx, body_id, "constant" ) ;
1492
+ } ,
1493
+ hir:: ItemTy ( ref ty, _) => hir:: intravisit:: walk_ty (
1494
+ & mut UnusedBrokenConstVisitor ( cx) ,
1495
+ ty
1496
+ ) ,
1497
+ _ => { } ,
1498
+ }
1499
+ }
1500
+ }
0 commit comments