};
expander(db, id, tt)
}
+
+ fn by_name(ident: &name::Name) -> Option<BuiltinFnLikeExpander> {
+ match ident {
+ $( id if id == &name::name![$name] => Some(BuiltinFnLikeExpander::$kind), )*
+ _ => return None,
+ }
+ }
}
pub fn find_builtin_macro(
krate: CrateId,
ast_id: AstId<ast::MacroCall>,
) -> Option<MacroDefId> {
- let kind = match ident {
- $( id if id == &name::name![$name] => BuiltinFnLikeExpander::$kind, )*
- _ => return None,
- };
+ let kind = BuiltinFnLikeExpander::by_name(ident)?;
Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) })
}
(line, Line) => line_expand,
(stringify, Stringify) => stringify_expand,
(format_args, FormatArgs) => format_args_expand,
+ (env, Env) => env_expand,
+ (option_env, OptionEnv) => option_env_expand,
// format_args_nl only differs in that it adds a newline in the end,
// so we use the same stub expansion for now
(format_args_nl, FormatArgsNl) => format_args_expand
Ok(expanded)
}
+fn env_expand(
+ _db: &dyn AstDatabase,
+ _id: MacroCallId,
+ _tt: &tt::Subtree,
+) -> Result<tt::Subtree, mbe::ExpandError> {
+ // dummy implementation for type-checking purposes
+ let expanded = quote! { "" };
+
+ Ok(expanded)
+}
+
+fn option_env_expand(
+ _db: &dyn AstDatabase,
+ _id: MacroCallId,
+ _tt: &tt::Subtree,
+) -> Result<tt::Subtree, mbe::ExpandError> {
+ // dummy implementation for type-checking purposes
+ let expanded = quote! { std::option::Option::None::<&str> };
+
+ Ok(expanded)
+}
+
fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
// FIXME: Use expansion info
let file_id = file.original_file(db);
#[cfg(test)]
mod tests {
use super::*;
- use crate::{test_db::TestDB, MacroCallKind, MacroCallLoc};
+ use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc};
use ra_db::{fixture::WithFixture, SourceDatabase};
+ use ra_syntax::ast::NameOwner;
- fn expand_builtin_macro(s: &str, expander: BuiltinFnLikeExpander) -> String {
+ fn expand_builtin_macro(s: &str) -> String {
let (db, file_id) = TestDB::with_single_file(&s);
let parsed = db.parse(file_id);
let macro_calls: Vec<_> =
let ast_id_map = db.ast_id_map(file_id.into());
+ let expander =
+ BuiltinFnLikeExpander::by_name(¯o_calls[0].name().unwrap().as_name()).unwrap();
+
// the first one should be a macro_rules
let def = MacroDefId {
krate: Some(CrateId(0)),
fn test_column_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! column {() => {}}
- column!()
-"#,
- BuiltinFnLikeExpander::Column,
+ #[rustc_builtin_macro]
+ macro_rules! column {() => {}}
+ column!()
+ "#,
);
- assert_eq!(expanded, "9");
+ assert_eq!(expanded, "13");
}
#[test]
fn test_line_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! line {() => {}}
- line!()
-"#,
- BuiltinFnLikeExpander::Line,
+ #[rustc_builtin_macro]
+ macro_rules! line {() => {}}
+ line!()
+ "#,
);
assert_eq!(expanded, "4");
fn test_stringify_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! stringify {() => {}}
- stringify!(a b c)
-"#,
- BuiltinFnLikeExpander::Stringify,
+ #[rustc_builtin_macro]
+ macro_rules! stringify {() => {}}
+ stringify!(a b c)
+ "#,
);
assert_eq!(expanded, "\"a b c\"");
}
+ #[test]
+ fn test_env_expand() {
+ let expanded = expand_builtin_macro(
+ r#"
+ #[rustc_builtin_macro]
+ macro_rules! env {() => {}}
+ env!("TEST_ENV_VAR")
+ "#,
+ );
+
+ assert_eq!(expanded, "\"\"");
+ }
+
+ #[test]
+ fn test_option_env_expand() {
+ let expanded = expand_builtin_macro(
+ r#"
+ #[rustc_builtin_macro]
+ macro_rules! option_env {() => {}}
+ option_env!("TEST_ENV_VAR")
+ "#,
+ );
+
+ assert_eq!(expanded, "std::option::Option::None:: <&str>");
+ }
+
#[test]
fn test_file_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! file {() => {}}
- file!()
-"#,
- BuiltinFnLikeExpander::File,
+ #[rustc_builtin_macro]
+ macro_rules! file {() => {}}
+ file!()
+ "#,
);
assert_eq!(expanded, "\"\"");
fn test_compile_error_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! compile_error {
- ($msg:expr) => ({ /* compiler built-in */ });
- ($msg:expr,) => ({ /* compiler built-in */ })
- }
- compile_error!("error!");
-"#,
- BuiltinFnLikeExpander::CompileError,
+ #[rustc_builtin_macro]
+ macro_rules! compile_error {
+ ($msg:expr) => ({ /* compiler built-in */ });
+ ($msg:expr,) => ({ /* compiler built-in */ })
+ }
+ compile_error!("error!");
+ "#,
);
assert_eq!(expanded, r#"loop{"error!"}"#);
fn test_format_args_expand() {
let expanded = expand_builtin_macro(
r#"
- #[rustc_builtin_macro]
- macro_rules! format_args {
- ($fmt:expr) => ({ /* compiler built-in */ });
- ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
- }
- format_args!("{} {:?}", arg1(a, b, c), arg2);
-"#,
- BuiltinFnLikeExpander::FormatArgs,
+ #[rustc_builtin_macro]
+ macro_rules! format_args {
+ ($fmt:expr) => ({ /* compiler built-in */ });
+ ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+ }
+ format_args!("{} {:?}", arg1(a, b, c), arg2);
+ "#,
);
assert_eq!(