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