From 4634bfb332897f8478ed885970e7cb21bb9c4fce Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 2 Dec 2020 17:03:18 +0100 Subject: Give better diagnostic if `OUT_DIR` is unset --- crates/hir_def/src/body/tests.rs | 3 +++ crates/hir_expand/src/builtin_macro.rs | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs index f2b57aebe..c7003f2a6 100644 --- a/crates/hir_def/src/body/tests.rs +++ b/crates/hir_def/src/body/tests.rs @@ -100,6 +100,9 @@ fn f() { env!(invalid); //^^^^^^^^^^^^^ could not convert tokens + env!("OUT_DIR"); + //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix + // Lazy: format_args!(); diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index 7f4db106d..7bb42be6c 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs @@ -417,17 +417,25 @@ fn env_expand( Err(e) => return ExpandResult::only_err(e), }; - // FIXME: - // If the environment variable is not defined int rustc, then a compilation error will be emitted. - // We might do the same if we fully support all other stuffs. - // But for now on, we should return some dummy string for better type infer purpose. - // However, we cannot use an empty string here, because for - // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become - // `include!("foo.rs"), which might go to infinite loop - let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| "__RA_UNIMPLEMENTED__".to_string()); + let mut err = None; + let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| { + // The only variable rust-analyzer ever sets is `OUT_DIR`, so only diagnose that to avoid + // unnecessary diagnostics for eg. `CARGO_PKG_NAME`. + if key == "OUT_DIR" { + err = Some(mbe::ExpandError::Other( + r#"`OUT_DIR` not set, enable "load out dirs from check" to fix"#.into(), + )); + } + + // If the variable is unset, still return a dummy string to help type inference along. + // We cannot use an empty string here, because for + // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become + // `include!("foo.rs"), which might go to infinite loop + "__RA_UNIMPLEMENTED__".to_string() + }); let expanded = quote! { #s }; - ExpandResult::ok(Some((expanded, FragmentKind::Expr))) + ExpandResult { value: Some((expanded, FragmentKind::Expr)), err } } fn option_env_expand( -- cgit v1.2.3