feat: make const_is_empty lint ignore external constants

This commit is contained in:
Samuel Tardieu 2024-02-26 09:47:13 +01:00
parent 1159e2c00f
commit 898ed8825d
2 changed files with 16 additions and 0 deletions

View File

@ -13,6 +13,7 @@
use rustc_middle::mir::ConstValue; use rustc_middle::mir::ConstValue;
use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List, ScalarInt, Ty, TyCtxt, UintTy}; use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List, ScalarInt, Ty, TyCtxt, UintTy};
use rustc_middle::{bug, mir, span_bug}; use rustc_middle::{bug, mir, span_bug};
use rustc_span::def_id::DefId;
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
use rustc_span::SyntaxContext; use rustc_span::SyntaxContext;
use rustc_target::abi::Size; use rustc_target::abi::Size;
@ -482,11 +483,21 @@ pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant<'tcx>> {
} }
/// Simple constant folding to determine if an expression is an empty slice, str, array, … /// Simple constant folding to determine if an expression is an empty slice, str, array, …
/// `None` will be returned if the constness cannot be determined, or if the resolution
/// leaves the local crate.
pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option<bool> { pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option<bool> {
match e.kind { match e.kind {
ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value),
ExprKind::DropTemps(e) => self.expr_is_empty(e), ExprKind::DropTemps(e) => self.expr_is_empty(e),
ExprKind::Path(ref qpath) => { ExprKind::Path(ref qpath) => {
if !self
.typeck_results
.qpath_res(qpath, e.hir_id)
.opt_def_id()
.is_some_and(DefId::is_local)
{
return None;
}
self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| { self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| {
mir_is_empty(this.lcx, result) mir_is_empty(this.lcx, result)
}) })

View File

@ -167,3 +167,8 @@ fn const_expressions() {
let _ = const_rand().is_empty(); let _ = const_rand().is_empty();
// Do not lint, we do not recurse into functions // Do not lint, we do not recurse into functions
} }
fn constant_from_external_crate() {
let _ = std::env::consts::EXE_EXTENSION.is_empty();
// Do not lint, `exe_ext` comes from the `std` crate
}