Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/builtin_derive_macro.rs')
| -rw-r--r-- | crates/hir-expand/src/builtin_derive_macro.rs | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs index 2795487514..66dec7d89e 100644 --- a/crates/hir-expand/src/builtin_derive_macro.rs +++ b/crates/hir-expand/src/builtin_derive_macro.rs @@ -10,10 +10,12 @@ use crate::{ hygiene::span_with_def_site_ctxt, name::{AsName, Name}, quote::dollar_crate, - span_map::SpanMapRef, + span_map::ExpansionSpanMap, tt, }; -use syntax::ast::{self, AstNode, FieldList, HasAttrs, HasGenericParams, HasName, HasTypeBounds}; +use syntax::ast::{ + self, AstNode, FieldList, HasAttrs, HasGenericParams, HasModuleItem, HasName, HasTypeBounds, +}; use crate::{db::ExpandDatabase, name, quote, ExpandError, ExpandResult}; @@ -25,20 +27,10 @@ macro_rules! register_builtin { } impl BuiltinDeriveExpander { - pub fn expand( - &self, - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &ast::Adt, - token_map: SpanMapRef<'_>, - ) -> ExpandResult<tt::Subtree> { - let expander = match *self { + pub fn expander(&self) -> fn(Span, &tt::Subtree) -> ExpandResult<tt::Subtree> { + match *self { $( BuiltinDeriveExpander::$trait => $expand, )* - }; - - let span = db.lookup_intern_macro_call(id).call_site; - let span = span_with_def_site_ctxt(db, span, id); - expander(span, tt, token_map) + } } fn find_by_name(name: &name::Name) -> Option<Self> { @@ -52,6 +44,19 @@ macro_rules! register_builtin { }; } +impl BuiltinDeriveExpander { + pub fn expand( + &self, + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> ExpandResult<tt::Subtree> { + let span = db.lookup_intern_macro_call(id).call_site; + let span = span_with_def_site_ctxt(db, span, id); + self.expander()(span, tt) + } +} + register_builtin! { Copy => copy_expand, Clone => clone_expand, @@ -122,7 +127,7 @@ impl VariantShape { } } - fn from(tm: SpanMapRef<'_>, value: Option<FieldList>) -> Result<Self, ExpandError> { + fn from(tm: &ExpansionSpanMap, value: Option<FieldList>) -> Result<Self, ExpandError> { let r = match value { None => VariantShape::Unit, Some(FieldList::RecordFieldList(it)) => VariantShape::Struct( @@ -198,11 +203,13 @@ struct BasicAdtInfo { associated_types: Vec<tt::Subtree>, } -fn parse_adt( - tm: SpanMapRef<'_>, - adt: &ast::Adt, - call_site: Span, -) -> Result<BasicAdtInfo, ExpandError> { +fn parse_adt(tt: &tt::Subtree, call_site: Span) -> Result<BasicAdtInfo, ExpandError> { + let (parsed, tm) = &mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MacroItems); + let macro_items = ast::MacroItems::cast(parsed.syntax_node()) + .ok_or_else(|| ExpandError::other("invalid item definition"))?; + let item = macro_items.items().next().ok_or_else(|| ExpandError::other("no item found"))?; + let adt = &ast::Adt::cast(item.syntax().clone()) + .ok_or_else(|| ExpandError::other("expected struct, enum or union"))?; let (name, generic_param_list, where_clause, shape) = match adt { ast::Adt::Struct(it) => ( it.name(), @@ -318,14 +325,14 @@ fn parse_adt( } fn name_to_token( - token_map: SpanMapRef<'_>, + token_map: &ExpansionSpanMap, name: Option<ast::Name>, ) -> Result<tt::Ident, ExpandError> { let name = name.ok_or_else(|| { debug!("parsed item has no name"); ExpandError::other("missing name") })?; - let span = token_map.span_for_range(name.syntax().text_range()); + let span = token_map.span_at(name.syntax().text_range().start()); let name_token = tt::Ident { span, text: name.text().into() }; Ok(name_token) } @@ -362,14 +369,12 @@ fn name_to_token( /// where B1, ..., BN are the bounds given by `bounds_paths`. Z is a phantom type, and /// therefore does not get bound by the derived trait. fn expand_simple_derive( - // FIXME: use invoc_span: Span, - tt: &ast::Adt, - tm: SpanMapRef<'_>, + tt: &tt::Subtree, trait_path: tt::Subtree, make_trait_body: impl FnOnce(&BasicAdtInfo) -> tt::Subtree, ) -> ExpandResult<tt::Subtree> { - let info = match parse_adt(tm, tt, invoc_span) { + let info = match parse_adt(tt, invoc_span) { Ok(info) => info, Err(e) => { return ExpandResult::new( @@ -412,14 +417,14 @@ fn expand_simple_derive( ExpandResult::ok(expanded) } -fn copy_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn copy_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::marker::Copy }, |_| quote! {span =>}) + expand_simple_derive(span, tt, quote! {span => #krate::marker::Copy }, |_| quote! {span =>}) } -fn clone_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn clone_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::clone::Clone }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::clone::Clone }, |adt| { if matches!(adt.shape, AdtShape::Union) { let star = tt::Punct { char: '*', spacing: ::tt::Spacing::Alone, span }; return quote! {span => @@ -468,9 +473,9 @@ fn and_and(span: Span) -> tt::Subtree { quote! {span => #and& } } -fn default_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn default_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = &dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::default::Default }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::default::Default }, |adt| { let body = match &adt.shape { AdtShape::Struct(fields) => { let name = &adt.name; @@ -507,9 +512,9 @@ fn default_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult }) } -fn debug_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn debug_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = &dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::fmt::Debug }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::fmt::Debug }, |adt| { let for_variant = |name: String, v: &VariantShape| match v { VariantShape::Struct(fields) => { let for_fields = fields.iter().map(|it| { @@ -579,9 +584,9 @@ fn debug_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<t }) } -fn hash_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn hash_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = &dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::hash::Hash }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::hash::Hash }, |adt| { if matches!(adt.shape, AdtShape::Union) { // FIXME: Return expand error here return quote! {span =>}; @@ -626,14 +631,14 @@ fn hash_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt }) } -fn eq_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn eq_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::Eq }, |_| quote! {span =>}) + expand_simple_derive(span, tt, quote! {span => #krate::cmp::Eq }, |_| quote! {span =>}) } -fn partial_eq_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn partial_eq_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::PartialEq }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::cmp::PartialEq }, |adt| { if matches!(adt.shape, AdtShape::Union) { // FIXME: Return expand error here return quote! {span =>}; @@ -703,9 +708,9 @@ fn self_and_other_patterns( (self_patterns, other_patterns) } -fn ord_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn ord_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = &dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::Ord }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::cmp::Ord }, |adt| { fn compare( krate: &tt::Ident, left: tt::Subtree, @@ -761,9 +766,9 @@ fn ord_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt: }) } -fn partial_ord_expand(span: Span, tt: &ast::Adt, tm: SpanMapRef<'_>) -> ExpandResult<tt::Subtree> { +fn partial_ord_expand(span: Span, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> { let krate = &dollar_crate(span); - expand_simple_derive(span, tt, tm, quote! {span => #krate::cmp::PartialOrd }, |adt| { + expand_simple_derive(span, tt, quote! {span => #krate::cmp::PartialOrd }, |adt| { fn compare( krate: &tt::Ident, left: tt::Subtree, |