@@ -1430,3 +1430,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
14301430 }
14311431 }
14321432}
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