@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List,
16
16
use rustc_middle:: { bug, mir, span_bug} ;
17
17
use rustc_span:: def_id:: DefId ;
18
18
use rustc_span:: symbol:: { Ident , Symbol } ;
19
- use rustc_span:: SyntaxContext ;
19
+ use rustc_span:: { sym , SyntaxContext } ;
20
20
use rustc_target:: abi:: Size ;
21
21
use std:: cmp:: Ordering ;
22
22
use std:: hash:: { Hash , Hasher } ;
@@ -303,6 +303,8 @@ pub enum ConstantSource {
303
303
Local ,
304
304
/// The value is dependent on a defined constant.
305
305
Constant ,
306
+ /// The value is dependent on a constant defined in current crate of `core` crate.
307
+ LocalOrCoreCrateConstant ,
306
308
}
307
309
impl ConstantSource {
308
310
pub fn is_local ( & self ) -> bool {
@@ -416,9 +418,18 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
416
418
ExprKind :: ConstBlock ( ConstBlock { body, .. } ) => self . expr ( self . lcx . tcx . hir ( ) . body ( body) . value ) ,
417
419
ExprKind :: DropTemps ( e) => self . expr ( e) ,
418
420
ExprKind :: Path ( ref qpath) => {
421
+ let is_local_or_core_crate = if let Some ( def_id) = self . lcx . qpath_res ( qpath, e. hir_id ( ) ) . opt_def_id ( ) {
422
+ def_id. is_local ( ) || self . lcx . tcx . crate_name ( def_id. krate ) == sym:: core
423
+ } else {
424
+ false
425
+ } ;
419
426
self . fetch_path_and_apply ( qpath, e. hir_id , self . typeck_results . expr_ty ( e) , |this, result| {
420
427
let result = mir_to_const ( this. lcx , result) ?;
421
- this. source = ConstantSource :: Constant ;
428
+ this. source = if is_local_or_core_crate {
429
+ ConstantSource :: LocalOrCoreCrateConstant
430
+ } else {
431
+ ConstantSource :: Constant
432
+ } ;
422
433
Some ( result)
423
434
} )
424
435
} ,
@@ -530,59 +541,6 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
530
541
}
531
542
}
532
543
533
- /// Simple constant folding to determine if an expression depends on an external crate
534
- /// excluding crates listed in exceptions
535
- pub fn expr_is_external ( & mut self , e : & Expr < ' _ > , exceptions : & [ Symbol ] ) -> bool {
536
- match e. kind {
537
- ExprKind :: ConstBlock ( ConstBlock { body, .. } ) => {
538
- self . expr_is_external ( self . lcx . tcx . hir ( ) . body ( body) . value , exceptions)
539
- } ,
540
- ExprKind :: DropTemps ( e) => self . expr_is_external ( e, exceptions) ,
541
- ExprKind :: Path ( ref qpath) => {
542
- if let Some ( def_id) = self . lcx . qpath_res ( qpath, e. hir_id ( ) ) . opt_def_id ( ) {
543
- def_id. is_local ( ) || exceptions. iter ( ) . all ( |e| self . lcx . tcx . crate_name ( def_id. krate ) != * e)
544
- } else {
545
- true
546
- }
547
- } ,
548
- ExprKind :: Block ( block, _) => {
549
- if block. stmts . is_empty ( )
550
- && let Some ( expr) = block. expr
551
- {
552
- self . expr_is_external ( expr, exceptions)
553
- } else {
554
- false
555
- }
556
- } ,
557
- ExprKind :: Array ( vec) => vec. iter ( ) . any ( |elem| self . expr_is_external ( elem, exceptions) ) ,
558
- ExprKind :: Tup ( tup) => tup. iter ( ) . any ( |elem| self . expr_is_external ( elem, exceptions) ) ,
559
- ExprKind :: Repeat ( value, _) => self . expr_is_external ( value, exceptions) ,
560
- ExprKind :: Unary ( _, operand) => self . expr_is_external ( operand, exceptions) ,
561
- ExprKind :: If ( cond, then, ref otherwise) => {
562
- if let Some ( Constant :: Bool ( b) ) = self . expr ( cond) {
563
- if b {
564
- self . expr_is_external ( then, exceptions)
565
- } else {
566
- otherwise
567
- . as_ref ( )
568
- . is_some_and ( |expr| self . expr_is_external ( expr, exceptions) )
569
- }
570
- } else {
571
- false
572
- }
573
- } ,
574
- ExprKind :: Binary ( _, left, right) => {
575
- self . expr_is_external ( left, exceptions) || self . expr_is_external ( right, exceptions)
576
- } ,
577
- ExprKind :: Index ( arr, index, _) => {
578
- self . expr_is_external ( arr, exceptions) || self . expr_is_external ( index, exceptions)
579
- } ,
580
- ExprKind :: AddrOf ( _, _, inner) => self . expr_is_external ( inner, exceptions) ,
581
- ExprKind :: Field ( local_expr, _) => self . expr_is_external ( local_expr, exceptions) ,
582
- _ => false ,
583
- }
584
- }
585
-
586
544
#[ expect( clippy:: cast_possible_wrap) ]
587
545
fn constant_not ( & self , o : & Constant < ' tcx > , ty : Ty < ' _ > ) -> Option < Constant < ' tcx > > {
588
546
use self :: Constant :: { Bool , Int } ;
0 commit comments