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.rs95
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,