@@ -1441,3 +1441,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
14411441 }
14421442 }
14431443}
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