macros: Expand macro invocation properly in type contexts
Macro invocations can be present where the language expects types. Thus, we need to add a new type of parsing context, a new transcriber, as well as a new way to extract types from the AST Fragments. This adds a lot of "expansion places" in the attribute visitor, as types can be present in a wide variety of constructs
This commit is contained in:
parent
3413f632ec
commit
6bf428379d
|
@ -35,13 +35,22 @@ AttrVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// expand sub-types of type, but can't strip type itself
|
// expand sub-types of type, but can't strip type itself
|
||||||
auto &type = field.get_field_type ();
|
auto &type = field.get_field_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
// if nothing else happens, increment
|
// if nothing else happens, increment
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +86,8 @@ AttrVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
|
||||||
void
|
void
|
||||||
AttrVisitor::expand_function_params (std::vector<AST::FunctionParam> ¶ms)
|
AttrVisitor::expand_function_params (std::vector<AST::FunctionParam> ¶ms)
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
for (auto it = params.begin (); it != params.end ();)
|
for (auto it = params.begin (); it != params.end ();)
|
||||||
{
|
{
|
||||||
auto ¶m = *it;
|
auto ¶m = *it;
|
||||||
|
@ -98,6 +109,11 @@ AttrVisitor::expand_function_params (std::vector<AST::FunctionParam> ¶ms)
|
||||||
|
|
||||||
auto &type = param.get_type ();
|
auto &type = param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
@ -105,27 +121,40 @@ AttrVisitor::expand_function_params (std::vector<AST::FunctionParam> ¶ms)
|
||||||
// increment
|
// increment
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AttrVisitor::expand_generic_args (AST::GenericArgs &args)
|
AttrVisitor::expand_generic_args (AST::GenericArgs &args)
|
||||||
{
|
{
|
||||||
// lifetime args can't be expanded
|
// lifetime args can't be expanded
|
||||||
|
// FIXME: Can we have macro invocations for lifetimes?
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// expand type args - strip sub-types only
|
// expand type args - strip sub-types only
|
||||||
for (auto &type : args.get_type_args ())
|
for (auto &type : args.get_type_args ())
|
||||||
{
|
{
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
|
// FIXME: Can we have macro invocations in generic type bindings?
|
||||||
// expand binding args - strip sub-types only
|
// expand binding args - strip sub-types only
|
||||||
for (auto &binding : args.get_binding_args ())
|
for (auto &binding : args.get_binding_args ())
|
||||||
{
|
{
|
||||||
auto &type = binding.get_type ();
|
auto &type = binding.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
@ -135,8 +164,17 @@ AttrVisitor::expand_generic_args (AST::GenericArgs &args)
|
||||||
void
|
void
|
||||||
AttrVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
|
AttrVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = path_type.get_type ();
|
auto &type = path_type.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
@ -174,11 +212,19 @@ AttrVisitor::AttrVisitor::expand_closure_params (
|
||||||
|
|
||||||
if (param.has_type_given ())
|
if (param.has_type_given ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
auto &type = param.get_type ();
|
auto &type = param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment if found nothing else so far
|
// increment if found nothing else so far
|
||||||
|
@ -191,11 +237,19 @@ AttrVisitor::expand_self_param (AST::SelfParam &self_param)
|
||||||
{
|
{
|
||||||
if (self_param.has_type ())
|
if (self_param.has_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
auto &type = self_param.get_type ();
|
auto &type = self_param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
/* TODO: maybe check for invariants being violated - e.g. both type and
|
/* TODO: maybe check for invariants being violated - e.g. both type and
|
||||||
* lifetime? */
|
* lifetime? */
|
||||||
|
@ -222,11 +276,20 @@ AttrVisitor::expand_trait_function_decl (AST::TraitFunctionDecl &decl)
|
||||||
|
|
||||||
if (decl.has_return_type ())
|
if (decl.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = decl.get_return_type ();
|
auto &return_type = decl.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto r_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (r_fragment.should_expand ())
|
||||||
|
return_type = r_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decl.has_where_clause ())
|
if (decl.has_where_clause ())
|
||||||
|
@ -251,11 +314,20 @@ AttrVisitor::expand_trait_method_decl (AST::TraitMethodDecl &decl)
|
||||||
|
|
||||||
if (decl.has_return_type ())
|
if (decl.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = decl.get_return_type ();
|
auto &return_type = decl.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto r_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (r_fragment.should_expand ())
|
||||||
|
return_type = r_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decl.has_where_clause ())
|
if (decl.has_where_clause ())
|
||||||
|
@ -368,11 +440,20 @@ AttrVisitor::visit (AST::TypePathSegmentFunction &segment)
|
||||||
|
|
||||||
if (type_path_function.has_return_type ())
|
if (type_path_function.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = type_path_function.get_return_type ();
|
auto &return_type = type_path_function.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto r_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (r_fragment.should_expand ())
|
||||||
|
return_type = r_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -1176,12 +1257,21 @@ AttrVisitor::visit (AST::ClosureExprInnerTyped &expr)
|
||||||
* allowed by spec */
|
* allowed by spec */
|
||||||
expand_closure_params (expr.get_params ());
|
expand_closure_params (expr.get_params ());
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// can't strip return type, but can strip sub-types
|
// can't strip return type, but can strip sub-types
|
||||||
auto &type = expr.get_return_type ();
|
auto &type = expr.get_return_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
// can't strip expression itself, but can strip sub-expressions
|
// can't strip expression itself, but can strip sub-expressions
|
||||||
auto &definition_block = expr.get_definition_block ();
|
auto &definition_block = expr.get_definition_block ();
|
||||||
definition_block->accept_vis (*this);
|
definition_block->accept_vis (*this);
|
||||||
|
@ -1928,11 +2018,19 @@ AttrVisitor::visit (AST::TypeParam ¶m)
|
||||||
|
|
||||||
if (param.has_type ())
|
if (param.has_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
auto &type = param.get_type ();
|
auto &type = param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -1945,11 +2043,20 @@ AttrVisitor::visit (AST::TypeBoundWhereClauseItem &item)
|
||||||
{
|
{
|
||||||
// for lifetimes shouldn't require
|
// for lifetimes shouldn't require
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = item.get_type ();
|
auto &type = item.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
// don't strip directly, only components of bounds
|
// don't strip directly, only components of bounds
|
||||||
for (auto &bound : item.get_type_param_bounds ())
|
for (auto &bound : item.get_type_param_bounds ())
|
||||||
bound->accept_vis (*this);
|
bound->accept_vis (*this);
|
||||||
|
@ -1980,11 +2087,20 @@ AttrVisitor::visit (AST::Method &method)
|
||||||
|
|
||||||
if (method.has_return_type ())
|
if (method.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = method.get_return_type ();
|
auto &return_type = method.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto r_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (r_fragment.should_expand ())
|
||||||
|
return_type = r_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method.has_where_clause ())
|
if (method.has_where_clause ())
|
||||||
|
@ -2093,11 +2209,20 @@ AttrVisitor::visit (AST::Function &function)
|
||||||
|
|
||||||
if (function.has_return_type ())
|
if (function.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = function.get_return_type ();
|
auto &return_type = function.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
return_type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function.has_where_clause ())
|
if (function.has_where_clause ())
|
||||||
|
@ -2297,12 +2422,21 @@ AttrVisitor::visit (AST::ConstantItem &const_item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// strip any sub-types
|
// strip any sub-types
|
||||||
auto &type = const_item.get_type ();
|
auto &type = const_item.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
/* strip any internal sub-expressions - expression itself isn't
|
/* strip any internal sub-expressions - expression itself isn't
|
||||||
* allowed to have external attributes in this position so can't be
|
* allowed to have external attributes in this position so can't be
|
||||||
* stripped. */
|
* stripped. */
|
||||||
|
@ -2324,12 +2458,21 @@ AttrVisitor::visit (AST::StaticItem &static_item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// strip any sub-types
|
// strip any sub-types
|
||||||
auto &type = static_item.get_type ();
|
auto &type = static_item.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
/* strip any internal sub-expressions - expression itself isn't
|
/* strip any internal sub-expressions - expression itself isn't
|
||||||
* allowed to have external attributes in this position so can't be
|
* allowed to have external attributes in this position so can't be
|
||||||
* stripped. */
|
* stripped. */
|
||||||
|
@ -2403,12 +2546,21 @@ AttrVisitor::visit (AST::TraitItemConst &item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
// strip any sub-types
|
// strip any sub-types
|
||||||
auto &type = item.get_type ();
|
auto &type = item.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
/* strip any internal sub-expressions - expression itself isn't
|
/* strip any internal sub-expressions - expression itself isn't
|
||||||
* allowed to have external attributes in this position so can't be
|
* allowed to have external attributes in this position so can't be
|
||||||
* stripped */
|
* stripped */
|
||||||
|
@ -2502,11 +2654,20 @@ AttrVisitor::visit (AST::InherentImpl &impl)
|
||||||
for (auto ¶m : impl.get_generic_params ())
|
for (auto ¶m : impl.get_generic_params ())
|
||||||
param->accept_vis (*this);
|
param->accept_vis (*this);
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = impl.get_type ();
|
auto &type = impl.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
if (impl.has_where_clause ())
|
if (impl.has_where_clause ())
|
||||||
expand_where_clause (impl.get_where_clause ());
|
expand_where_clause (impl.get_where_clause ());
|
||||||
|
|
||||||
|
@ -2539,11 +2700,20 @@ AttrVisitor::visit (AST::TraitImpl &impl)
|
||||||
for (auto ¶m : impl.get_generic_params ())
|
for (auto ¶m : impl.get_generic_params ())
|
||||||
param->accept_vis (*this);
|
param->accept_vis (*this);
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = impl.get_type ();
|
auto &type = impl.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
auto &trait_path = impl.get_trait_path ();
|
auto &trait_path = impl.get_trait_path ();
|
||||||
visit (trait_path);
|
visit (trait_path);
|
||||||
if (trait_path.is_marked_for_strip ())
|
if (trait_path.is_marked_for_strip ())
|
||||||
|
@ -2571,10 +2741,19 @@ AttrVisitor::visit (AST::ExternalStaticItem &item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = item.get_type ();
|
auto &type = item.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
rust_error_at (type->get_locus (), "cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
AttrVisitor::visit (AST::ExternalFunctionItem &item)
|
AttrVisitor::visit (AST::ExternalFunctionItem &item)
|
||||||
|
@ -2606,12 +2785,21 @@ AttrVisitor::visit (AST::ExternalFunctionItem &item)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = param.get_type ();
|
auto &type = param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
// increment if nothing else happens
|
// increment if nothing else happens
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -2624,16 +2812,26 @@ AttrVisitor::visit (AST::ExternalFunctionItem &item)
|
||||||
|
|
||||||
if (item.has_return_type ())
|
if (item.has_return_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &return_type = item.get_return_type ();
|
auto &return_type = item.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto r_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (r_fragment.should_expand ())
|
||||||
|
return_type = r_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
rust_error_at (return_type->get_locus (),
|
rust_error_at (return_type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.has_where_clause ())
|
if (item.has_where_clause ())
|
||||||
expand_where_clause (item.get_where_clause ());
|
expand_where_clause (item.get_where_clause ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AttrVisitor::visit (AST::ExternBlock &block)
|
AttrVisitor::visit (AST::ExternBlock &block)
|
||||||
{
|
{
|
||||||
|
@ -2991,11 +3189,20 @@ AttrVisitor::visit (AST::LetStmt &stmt)
|
||||||
// similar for type
|
// similar for type
|
||||||
if (stmt.has_type ())
|
if (stmt.has_type ())
|
||||||
{
|
{
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = stmt.get_type ();
|
auto &type = stmt.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* strip any internal sub-expressions - expression itself isn't
|
/* strip any internal sub-expressions - expression itself isn't
|
||||||
|
@ -3190,12 +3397,21 @@ AttrVisitor::visit (AST::BareFunctionType &type)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander.push_context (MacroExpander::ContextType::TYPE);
|
||||||
|
|
||||||
auto &type = param.get_type ();
|
auto &type = param.get_type ();
|
||||||
type->accept_vis (*this);
|
type->accept_vis (*this);
|
||||||
|
|
||||||
|
auto t_fragment = expander.take_expanded_fragment (*this);
|
||||||
|
if (t_fragment.should_expand ())
|
||||||
|
type = t_fragment.take_type_fragment ();
|
||||||
|
|
||||||
if (type->is_marked_for_strip ())
|
if (type->is_marked_for_strip ())
|
||||||
rust_error_at (type->get_locus (),
|
rust_error_at (type->get_locus (),
|
||||||
"cannot strip type in this position");
|
"cannot strip type in this position");
|
||||||
|
|
||||||
|
expander.pop_context ();
|
||||||
|
|
||||||
// increment if nothing else happens
|
// increment if nothing else happens
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -3205,6 +3421,9 @@ AttrVisitor::visit (AST::BareFunctionType &type)
|
||||||
|
|
||||||
if (type.has_return_type ())
|
if (type.has_return_type ())
|
||||||
{
|
{
|
||||||
|
// FIXME: Can we have type expansion in this position?
|
||||||
|
// In that case, we need to handle AST::TypeNoBounds on top of just
|
||||||
|
// AST::Types
|
||||||
auto &return_type = type.get_return_type ();
|
auto &return_type = type.get_return_type ();
|
||||||
return_type->accept_vis (*this);
|
return_type->accept_vis (*this);
|
||||||
if (return_type->is_marked_for_strip ())
|
if (return_type->is_marked_for_strip ())
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
// { dg-additional-options "-w" }
|
||||||
|
|
||||||
|
macro_rules! t {
|
||||||
|
() => {
|
||||||
|
i32
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! s {
|
||||||
|
() => {
|
||||||
|
*const i8
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn printf(s: s!(), ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn square(arg: t!()) -> t!() {
|
||||||
|
let input: t!() = arg;
|
||||||
|
|
||||||
|
input * input
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fn f() -> t!();
|
||||||
|
fn g(arg: t!());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrapper {
|
||||||
|
inner: t!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for Wrapper {
|
||||||
|
fn f() -> t!() {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn g(arg: t!()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id<T>(arg: T) -> T {
|
||||||
|
arg
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
id::<t!()>(15);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
macro_rules! t {
|
||||||
|
() => {
|
||||||
|
i32
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id<T>(arg: T) -> T {
|
||||||
|
arg
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> i32 {
|
||||||
|
id::<t!()>(15) - 15
|
||||||
|
}
|
Loading…
Reference in New Issue