@@ -53,7 +53,7 @@ pub fn expand_env<'cx>(
53
53
tts : TokenStream ,
54
54
) -> Box < dyn base:: MacResult + ' cx > {
55
55
let mut exprs = match get_exprs_from_tts ( cx, tts) {
56
- Some ( exprs) if exprs. is_empty ( ) => {
56
+ Some ( exprs) if exprs. is_empty ( ) || exprs . len ( ) > 2 => {
57
57
cx. span_err ( sp, "env! takes 1 or 2 arguments" ) ;
58
58
return DummyResult :: any ( sp) ;
59
59
}
@@ -64,28 +64,48 @@ pub fn expand_env<'cx>(
64
64
let Some ( ( var, _style) ) = expr_to_string ( cx, exprs. next ( ) . unwrap ( ) , "expected string literal" ) else {
65
65
return DummyResult :: any ( sp) ;
66
66
} ;
67
- let msg = match exprs. next ( ) {
68
- None => Symbol :: intern ( & format ! ( "environment variable `{}` not defined" , var) ) ,
67
+
68
+ let custom_msg = match exprs. next ( ) {
69
+ None => None ,
69
70
Some ( second) => match expr_to_string ( cx, second, "expected string literal" ) {
70
71
None => return DummyResult :: any ( sp) ,
71
- Some ( ( s, _style) ) => s ,
72
+ Some ( ( s, _style) ) => Some ( s ) ,
72
73
} ,
73
74
} ;
74
75
75
- if exprs. next ( ) . is_some ( ) {
76
- cx. span_err ( sp, "env! takes 1 or 2 arguments" ) ;
77
- return DummyResult :: any ( sp) ;
78
- }
79
-
80
76
let sp = cx. with_def_site_ctxt ( sp) ;
81
77
let value = env:: var ( var. as_str ( ) ) . ok ( ) . as_deref ( ) . map ( Symbol :: intern) ;
82
78
cx. sess . parse_sess . env_depinfo . borrow_mut ( ) . insert ( ( var, value) ) ;
83
79
let e = match value {
84
80
None => {
85
- cx. span_err ( sp, msg. as_str ( ) ) ;
81
+ let ( msg, help) = match custom_msg {
82
+ None => (
83
+ format ! ( "environment variable `{var}` not defined at compile time" ) ,
84
+ Some ( help_for_missing_env_var ( var. as_str ( ) ) ) ,
85
+ ) ,
86
+ Some ( s) => ( s. to_string ( ) , None ) ,
87
+ } ;
88
+ let mut diag = cx. struct_span_err ( sp, & msg) ;
89
+ if let Some ( help) = help {
90
+ diag. help ( help) ;
91
+ }
92
+ diag. emit ( ) ;
86
93
return DummyResult :: any ( sp) ;
87
94
}
88
95
Some ( value) => cx. expr_str ( sp, value) ,
89
96
} ;
90
97
MacEager :: expr ( e)
91
98
}
99
+
100
+ fn help_for_missing_env_var ( var : & str ) -> String {
101
+ if var. starts_with ( "CARGO_" )
102
+ || var. starts_with ( "DEP_" )
103
+ || matches ! ( var, "OUT_DIR" | "OPT_LEVEL" | "PROFILE" | "HOST" | "TARGET" )
104
+ {
105
+ format ! (
106
+ "Cargo sets build script variables at run time. Use `std::env::var(\" {var}\" )` instead"
107
+ )
108
+ } else {
109
+ format ! ( "Use `std::env::var(\" {var}\" )` to read the variable at run time" )
110
+ }
111
+ }
0 commit comments