Remove ExtCtxt::ident_of
.
It's equivalent to `Ident::from_str_and_span`. The commit also introduces some more static symbols so that `Ident::new` can be used in various places instead of `Ident::from_str_and_span`. The commit also changes `Path::path` from a `&str` to a `Symbol`, which then allows the lifetime annotation to be removed from `Ty`. Also, the use of `Symbol` in `Bounds` removes the need for its lifetime annotation.
This commit is contained in:
parent
bccff14a20
commit
9f0080801d
19 changed files with 209 additions and 134 deletions
|
@ -29,7 +29,7 @@ pub fn expand_deriving_ord(
|
||||||
name: sym::cmp,
|
name: sym::cmp,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(borrowed_self(), "other")],
|
args: vec![(borrowed_self(), sym::other)],
|
||||||
ret_ty: Literal(path_std!(cmp::Ordering)),
|
ret_ty: Literal(path_std!(cmp::Ordering)),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub fn expand_deriving_partial_eq(
|
||||||
name: $name,
|
name: $name,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(borrowed_self(), "other")],
|
args: vec![(borrowed_self(), sym::other)],
|
||||||
ret_ty: Literal(path_local!(bool)),
|
ret_ty: Literal(path_local!(bool)),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn expand_deriving_partial_ord(
|
||||||
name: $name,
|
name: $name,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(borrowed_self(), "other")],
|
args: vec![(borrowed_self(), sym::other)],
|
||||||
ret_ty: Literal(path_local!(bool)),
|
ret_ty: Literal(path_local!(bool)),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
@ -52,7 +52,7 @@ pub fn expand_deriving_partial_ord(
|
||||||
name: sym::partial_cmp,
|
name: sym::partial_cmp,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(borrowed_self(), "other")],
|
args: vec![(borrowed_self(), sym::other)],
|
||||||
ret_ty,
|
ret_ty,
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn expand_deriving_debug(
|
||||||
name: sym::fmt,
|
name: sym::fmt,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(fmtr, "f")],
|
args: vec![(fmtr, sym::f)],
|
||||||
ret_ty: Literal(path_std!(fmt::Result)),
|
ret_ty: Literal(path_std!(fmt::Result)),
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||||
// We want to make sure we have the ctxt set so that we can use unstable methods
|
// We want to make sure we have the ctxt set so that we can use unstable methods
|
||||||
let span = cx.with_def_site_ctxt(span);
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
|
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
|
||||||
let builder = cx.ident_of("debug_trait_builder", span);
|
let builder = Ident::new(sym::debug_trait_builder, span);
|
||||||
let builder_expr = cx.expr_ident(span, builder);
|
let builder_expr = cx.expr_ident(span, builder);
|
||||||
|
|
||||||
let fmt = substr.nonself_args[0].clone();
|
let fmt = substr.nonself_args[0].clone();
|
||||||
|
@ -71,7 +71,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||||
match vdata {
|
match vdata {
|
||||||
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
|
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
|
||||||
// tuple struct/"normal" variant
|
// tuple struct/"normal" variant
|
||||||
let expr = cx.expr_method_call(span, fmt, cx.ident_of("debug_tuple", span), vec![name]);
|
let expr =
|
||||||
|
cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]);
|
||||||
stmts.push(cx.stmt_let(span, true, builder, expr));
|
stmts.push(cx.stmt_let(span, true, builder, expr));
|
||||||
|
|
||||||
for field in fields {
|
for field in fields {
|
||||||
|
@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||||
ast::VariantData::Struct(..) => {
|
ast::VariantData::Struct(..) => {
|
||||||
// normal struct/struct variant
|
// normal struct/struct variant
|
||||||
let expr =
|
let expr =
|
||||||
cx.expr_method_call(span, fmt, cx.ident_of("debug_struct", span), vec![name]);
|
cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]);
|
||||||
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
|
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
|
||||||
|
|
||||||
for field in fields {
|
for field in fields {
|
||||||
|
@ -117,7 +118,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr = cx.expr_method_call(span, builder_expr, cx.ident_of("finish", span), vec![]);
|
let expr = cx.expr_method_call(span, builder_expr, Ident::new(sym::finish, span), vec![]);
|
||||||
|
|
||||||
stmts.push(cx.stmt_expr(expr));
|
stmts.push(cx.stmt_expr(expr));
|
||||||
let block = cx.block(span, stmts);
|
let block = cx.block(span, stmts);
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_ast::ast;
|
||||||
use rustc_ast::ast::{Expr, MetaItem, Mutability};
|
use rustc_ast::ast::{Expr, MetaItem, Mutability};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
pub fn expand_deriving_rustc_decodable(
|
pub fn expand_deriving_rustc_decodable(
|
||||||
|
@ -18,13 +18,13 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
let krate = "rustc_serialize";
|
let krate = sym::rustc_serialize;
|
||||||
let typaram = "__D";
|
let typaram = sym::__D;
|
||||||
|
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
path: Path::new_(vec![krate, "Decodable"], None, vec![], PathKind::Global),
|
path: Path::new_(vec![krate, sym::Decodable], None, vec![], PathKind::Global),
|
||||||
additional_bounds: Vec::new(),
|
additional_bounds: Vec::new(),
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
@ -34,13 +34,13 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
generics: Bounds {
|
generics: Bounds {
|
||||||
bounds: vec![(
|
bounds: vec![(
|
||||||
typaram,
|
typaram,
|
||||||
vec![Path::new_(vec![krate, "Decoder"], None, vec![], PathKind::Global)],
|
vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)],
|
||||||
)],
|
)],
|
||||||
},
|
},
|
||||||
explicit_self: None,
|
explicit_self: None,
|
||||||
args: vec![(
|
args: vec![(
|
||||||
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
||||||
"d",
|
sym::d,
|
||||||
)],
|
)],
|
||||||
ret_ty: Literal(Path::new_(
|
ret_ty: Literal(Path::new_(
|
||||||
pathvec_std!(result::Result),
|
pathvec_std!(result::Result),
|
||||||
|
@ -48,7 +48,7 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
vec![
|
vec![
|
||||||
Box::new(Self_),
|
Box::new(Self_),
|
||||||
Box::new(Literal(Path::new_(
|
Box::new(Literal(Path::new_(
|
||||||
vec![typaram, "Error"],
|
vec![typaram, sym::Error],
|
||||||
None,
|
None,
|
||||||
vec![],
|
vec![],
|
||||||
PathKind::Local,
|
PathKind::Local,
|
||||||
|
@ -73,17 +73,17 @@ fn decodable_substructure(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substr: &Substructure<'_>,
|
substr: &Substructure<'_>,
|
||||||
krate: &str,
|
krate: Symbol,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
let decoder = substr.nonself_args[0].clone();
|
let decoder = substr.nonself_args[0].clone();
|
||||||
let recurse = vec![
|
let recurse = vec![
|
||||||
cx.ident_of(krate, trait_span),
|
Ident::new(krate, trait_span),
|
||||||
cx.ident_of("Decodable", trait_span),
|
Ident::new(sym::Decodable, trait_span),
|
||||||
cx.ident_of("decode", trait_span),
|
Ident::new(sym::decode, trait_span),
|
||||||
];
|
];
|
||||||
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
|
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
|
||||||
// throw an underscore in front to suppress unused variable warnings
|
// throw an underscore in front to suppress unused variable warnings
|
||||||
let blkarg = cx.ident_of("_d", trait_span);
|
let blkarg = Ident::new(sym::_d, trait_span);
|
||||||
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
||||||
|
|
||||||
match *substr.fields {
|
match *substr.fields {
|
||||||
|
@ -92,7 +92,7 @@ fn decodable_substructure(
|
||||||
Unnamed(ref fields, _) => fields.len(),
|
Unnamed(ref fields, _) => fields.len(),
|
||||||
Named(ref fields) => fields.len(),
|
Named(ref fields) => fields.len(),
|
||||||
};
|
};
|
||||||
let read_struct_field = cx.ident_of("read_struct_field", trait_span);
|
let read_struct_field = Ident::new(sym::read_struct_field, trait_span);
|
||||||
|
|
||||||
let path = cx.path_ident(trait_span, substr.type_ident);
|
let path = cx.path_ident(trait_span, substr.type_ident);
|
||||||
let result =
|
let result =
|
||||||
|
@ -115,7 +115,7 @@ fn decodable_substructure(
|
||||||
cx.expr_method_call(
|
cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
decoder,
|
decoder,
|
||||||
cx.ident_of("read_struct", trait_span),
|
Ident::new(sym::read_struct, trait_span),
|
||||||
vec![
|
vec![
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
cx.expr_str(trait_span, substr.type_ident.name),
|
||||||
cx.expr_usize(trait_span, nfields),
|
cx.expr_usize(trait_span, nfields),
|
||||||
|
@ -124,11 +124,11 @@ fn decodable_substructure(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
StaticEnum(_, ref fields) => {
|
StaticEnum(_, ref fields) => {
|
||||||
let variant = cx.ident_of("i", trait_span);
|
let variant = Ident::new(sym::i, trait_span);
|
||||||
|
|
||||||
let mut arms = Vec::with_capacity(fields.len() + 1);
|
let mut arms = Vec::with_capacity(fields.len() + 1);
|
||||||
let mut variants = Vec::with_capacity(fields.len());
|
let mut variants = Vec::with_capacity(fields.len());
|
||||||
let rvariant_arg = cx.ident_of("read_enum_variant_arg", trait_span);
|
let rvariant_arg = Ident::new(sym::read_enum_variant_arg, trait_span);
|
||||||
|
|
||||||
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
|
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
|
||||||
variants.push(cx.expr_str(v_span, ident.name));
|
variants.push(cx.expr_str(v_span, ident.name));
|
||||||
|
@ -163,13 +163,13 @@ fn decodable_substructure(
|
||||||
let result = cx.expr_method_call(
|
let result = cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
blkdecoder,
|
blkdecoder,
|
||||||
cx.ident_of("read_enum_variant", trait_span),
|
Ident::new(sym::read_enum_variant, trait_span),
|
||||||
vec![variant_vec, lambda],
|
vec![variant_vec, lambda],
|
||||||
);
|
);
|
||||||
cx.expr_method_call(
|
cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
decoder,
|
decoder,
|
||||||
cx.ident_of("read_enum", trait_span),
|
Ident::new(sym::read_enum, trait_span),
|
||||||
vec![
|
vec![
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
cx.expr_str(trait_span, substr.type_ident.name),
|
||||||
cx.lambda1(trait_span, result, blkarg),
|
cx.lambda1(trait_span, result, blkarg),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::deriving::generic::ty::*;
|
use crate::deriving::generic::ty::*;
|
||||||
use crate::deriving::generic::*;
|
use crate::deriving::generic::*;
|
||||||
use crate::deriving::path_std;
|
|
||||||
|
|
||||||
use rustc_ast::ast::{Expr, MetaItem};
|
use rustc_ast::ast::{Expr, MetaItem};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
@ -21,7 +20,7 @@ pub fn expand_deriving_default(
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
path: path_std!(default::Default),
|
path: Path::new(vec![kw::Default, sym::Default]),
|
||||||
additional_bounds: Vec::new(),
|
additional_bounds: Vec::new(),
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
|
|
@ -92,7 +92,7 @@ use crate::deriving::pathvec_std;
|
||||||
use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability};
|
use rustc_ast::ast::{Expr, ExprKind, MetaItem, Mutability};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
pub fn expand_deriving_rustc_encodable(
|
pub fn expand_deriving_rustc_encodable(
|
||||||
|
@ -102,13 +102,13 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
let krate = "rustc_serialize";
|
let krate = sym::rustc_serialize;
|
||||||
let typaram = "__S";
|
let typaram = sym::__S;
|
||||||
|
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global),
|
path: Path::new_(vec![krate, sym::Encodable], None, vec![], PathKind::Global),
|
||||||
additional_bounds: Vec::new(),
|
additional_bounds: Vec::new(),
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
@ -118,13 +118,18 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
generics: Bounds {
|
generics: Bounds {
|
||||||
bounds: vec![(
|
bounds: vec![(
|
||||||
typaram,
|
typaram,
|
||||||
vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)],
|
vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)],
|
||||||
)],
|
)],
|
||||||
},
|
},
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(
|
args: vec![(
|
||||||
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
||||||
"s",
|
// FIXME: we could use `sym::s` here, but making `s` a static
|
||||||
|
// symbol changes the symbol index ordering in a way that makes
|
||||||
|
// ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
|
||||||
|
// fail. The linting code should be fixed so that its output
|
||||||
|
// does not depend on the symbol index ordering.
|
||||||
|
Symbol::intern("s"),
|
||||||
)],
|
)],
|
||||||
ret_ty: Literal(Path::new_(
|
ret_ty: Literal(Path::new_(
|
||||||
pathvec_std!(result::Result),
|
pathvec_std!(result::Result),
|
||||||
|
@ -132,7 +137,7 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
vec![
|
vec![
|
||||||
Box::new(Tuple(Vec::new())),
|
Box::new(Tuple(Vec::new())),
|
||||||
Box::new(Literal(Path::new_(
|
Box::new(Literal(Path::new_(
|
||||||
vec![typaram, "Error"],
|
vec![typaram, sym::Error],
|
||||||
None,
|
None,
|
||||||
vec![],
|
vec![],
|
||||||
PathKind::Local,
|
PathKind::Local,
|
||||||
|
@ -157,24 +162,24 @@ fn encodable_substructure(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substr: &Substructure<'_>,
|
substr: &Substructure<'_>,
|
||||||
krate: &'static str,
|
krate: Symbol,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
let encoder = substr.nonself_args[0].clone();
|
let encoder = substr.nonself_args[0].clone();
|
||||||
// throw an underscore in front to suppress unused variable warnings
|
// throw an underscore in front to suppress unused variable warnings
|
||||||
let blkarg = cx.ident_of("_e", trait_span);
|
let blkarg = Ident::new(sym::_e, trait_span);
|
||||||
let blkencoder = cx.expr_ident(trait_span, blkarg);
|
let blkencoder = cx.expr_ident(trait_span, blkarg);
|
||||||
let fn_path = cx.expr_path(cx.path_global(
|
let fn_path = cx.expr_path(cx.path_global(
|
||||||
trait_span,
|
trait_span,
|
||||||
vec![
|
vec![
|
||||||
cx.ident_of(krate, trait_span),
|
Ident::new(krate, trait_span),
|
||||||
cx.ident_of("Encodable", trait_span),
|
Ident::new(sym::Encodable, trait_span),
|
||||||
cx.ident_of("encode", trait_span),
|
Ident::new(sym::encode, trait_span),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
match *substr.fields {
|
match *substr.fields {
|
||||||
Struct(_, ref fields) => {
|
Struct(_, ref fields) => {
|
||||||
let emit_struct_field = cx.ident_of("emit_struct_field", trait_span);
|
let emit_struct_field = Ident::new(sym::emit_struct_field, trait_span);
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
|
for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
|
||||||
let name = match name {
|
let name = match name {
|
||||||
|
@ -214,7 +219,7 @@ fn encodable_substructure(
|
||||||
cx.expr_method_call(
|
cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
encoder,
|
encoder,
|
||||||
cx.ident_of("emit_struct", trait_span),
|
Ident::new(sym::emit_struct, trait_span),
|
||||||
vec![
|
vec![
|
||||||
cx.expr_str(trait_span, substr.type_ident.name),
|
cx.expr_str(trait_span, substr.type_ident.name),
|
||||||
cx.expr_usize(trait_span, fields.len()),
|
cx.expr_usize(trait_span, fields.len()),
|
||||||
|
@ -230,7 +235,7 @@ fn encodable_substructure(
|
||||||
// actually exist.
|
// actually exist.
|
||||||
let me = cx.stmt_let(trait_span, false, blkarg, encoder);
|
let me = cx.stmt_let(trait_span, false, blkarg, encoder);
|
||||||
let encoder = cx.expr_ident(trait_span, blkarg);
|
let encoder = cx.expr_ident(trait_span, blkarg);
|
||||||
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg", trait_span);
|
let emit_variant_arg = Ident::new(sym::emit_enum_variant_arg, trait_span);
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
if !fields.is_empty() {
|
if !fields.is_empty() {
|
||||||
let last = fields.len() - 1;
|
let last = fields.len() - 1;
|
||||||
|
@ -263,7 +268,7 @@ fn encodable_substructure(
|
||||||
let call = cx.expr_method_call(
|
let call = cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
blkencoder,
|
blkencoder,
|
||||||
cx.ident_of("emit_enum_variant", trait_span),
|
Ident::new(sym::emit_enum_variant, trait_span),
|
||||||
vec![
|
vec![
|
||||||
name,
|
name,
|
||||||
cx.expr_usize(trait_span, idx),
|
cx.expr_usize(trait_span, idx),
|
||||||
|
@ -275,7 +280,7 @@ fn encodable_substructure(
|
||||||
let ret = cx.expr_method_call(
|
let ret = cx.expr_method_call(
|
||||||
trait_span,
|
trait_span,
|
||||||
encoder,
|
encoder,
|
||||||
cx.ident_of("emit_enum", trait_span),
|
Ident::new(sym::emit_enum, trait_span),
|
||||||
vec![cx.expr_str(trait_span, substr.type_ident.name), blk],
|
vec![cx.expr_str(trait_span, substr.type_ident.name), blk],
|
||||||
);
|
);
|
||||||
cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
|
cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
|
||||||
|
|
|
@ -204,14 +204,14 @@ pub struct TraitDef<'a> {
|
||||||
pub attributes: Vec<ast::Attribute>,
|
pub attributes: Vec<ast::Attribute>,
|
||||||
|
|
||||||
/// Path of the trait, including any type parameters
|
/// Path of the trait, including any type parameters
|
||||||
pub path: Path<'a>,
|
pub path: Path,
|
||||||
|
|
||||||
/// Additional bounds required of any type parameters of the type,
|
/// Additional bounds required of any type parameters of the type,
|
||||||
/// other than the current trait
|
/// other than the current trait
|
||||||
pub additional_bounds: Vec<Ty<'a>>,
|
pub additional_bounds: Vec<Ty>,
|
||||||
|
|
||||||
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
|
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
|
||||||
pub generics: Bounds<'a>,
|
pub generics: Bounds,
|
||||||
|
|
||||||
/// Is it an `unsafe` trait?
|
/// Is it an `unsafe` trait?
|
||||||
pub is_unsafe: bool,
|
pub is_unsafe: bool,
|
||||||
|
@ -221,14 +221,14 @@ pub struct TraitDef<'a> {
|
||||||
|
|
||||||
pub methods: Vec<MethodDef<'a>>,
|
pub methods: Vec<MethodDef<'a>>,
|
||||||
|
|
||||||
pub associated_types: Vec<(Ident, Ty<'a>)>,
|
pub associated_types: Vec<(Ident, Ty)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MethodDef<'a> {
|
pub struct MethodDef<'a> {
|
||||||
/// name of the method
|
/// name of the method
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
/// List of generics, e.g., `R: rand::Rng`
|
/// List of generics, e.g., `R: rand::Rng`
|
||||||
pub generics: Bounds<'a>,
|
pub generics: Bounds,
|
||||||
|
|
||||||
/// Whether there is a self argument (outer Option) i.e., whether
|
/// Whether there is a self argument (outer Option) i.e., whether
|
||||||
/// this is a static function, and whether it is a pointer (inner
|
/// this is a static function, and whether it is a pointer (inner
|
||||||
|
@ -236,10 +236,10 @@ pub struct MethodDef<'a> {
|
||||||
pub explicit_self: Option<Option<PtrTy>>,
|
pub explicit_self: Option<Option<PtrTy>>,
|
||||||
|
|
||||||
/// Arguments other than the self argument
|
/// Arguments other than the self argument
|
||||||
pub args: Vec<(Ty<'a>, &'a str)>,
|
pub args: Vec<(Ty, Symbol)>,
|
||||||
|
|
||||||
/// Returns type
|
/// Returns type
|
||||||
pub ret_ty: Ty<'a>,
|
pub ret_ty: Ty,
|
||||||
|
|
||||||
pub attributes: Vec<ast::Attribute>,
|
pub attributes: Vec<ast::Attribute>,
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ impl<'a> MethodDef<'a> {
|
||||||
|
|
||||||
for (ty, name) in self.args.iter() {
|
for (ty, name) in self.args.iter() {
|
||||||
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
|
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
|
||||||
let ident = cx.ident_of(name, trait_.span);
|
let ident = Ident::new(*name, trait_.span);
|
||||||
arg_tys.push((ident, ast_ty));
|
arg_tys.push((ident, ast_ty));
|
||||||
|
|
||||||
let arg_expr = cx.expr_ident(trait_.span, ident);
|
let arg_expr = cx.expr_ident(trait_.span, ident);
|
||||||
|
@ -1170,8 +1170,10 @@ impl<'a> MethodDef<'a> {
|
||||||
)
|
)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let self_arg_idents =
|
let self_arg_idents = self_arg_names
|
||||||
self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::<Vec<Ident>>();
|
.iter()
|
||||||
|
.map(|name| Ident::from_str_and_span(name, sp))
|
||||||
|
.collect::<Vec<Ident>>();
|
||||||
|
|
||||||
// The `vi_idents` will be bound, solely in the catch-all, to
|
// The `vi_idents` will be bound, solely in the catch-all, to
|
||||||
// a series of let statements mapping each self_arg to an int
|
// a series of let statements mapping each self_arg to an int
|
||||||
|
@ -1180,7 +1182,7 @@ impl<'a> MethodDef<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
let vi_suffix = format!("{}_vi", &name[..]);
|
let vi_suffix = format!("{}_vi", &name[..]);
|
||||||
cx.ident_of(&vi_suffix[..], trait_.span)
|
Ident::from_str_and_span(&vi_suffix, trait_.span)
|
||||||
})
|
})
|
||||||
.collect::<Vec<Ident>>();
|
.collect::<Vec<Ident>>();
|
||||||
|
|
||||||
|
@ -1568,7 +1570,7 @@ impl<'a> TraitDef<'a> {
|
||||||
let mut ident_exprs = Vec::new();
|
let mut ident_exprs = Vec::new();
|
||||||
for (i, struct_field) in struct_def.fields().iter().enumerate() {
|
for (i, struct_field) in struct_def.fields().iter().enumerate() {
|
||||||
let sp = struct_field.span.with_ctxt(self.span.ctxt());
|
let sp = struct_field.span.with_ctxt(self.span.ctxt());
|
||||||
let ident = cx.ident_of(&format!("{}_{}", prefix, i), self.span);
|
let ident = Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
|
||||||
paths.push(ident.with_span_pos(sp));
|
paths.push(ident.with_span_pos(sp));
|
||||||
let val = cx.expr_path(cx.path_ident(sp, ident));
|
let val = cx.expr_path(cx.path_ident(sp, ident));
|
||||||
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
|
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_ast::ast::{self, Expr, GenericArg, GenericParamKind, Generics, SelfKin
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_expand::base::ExtCtxt;
|
use rustc_expand::base::ExtCtxt;
|
||||||
use rustc_span::source_map::{respan, DUMMY_SP};
|
use rustc_span::source_map::{respan, DUMMY_SP};
|
||||||
use rustc_span::symbol::{kw, Ident};
|
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
/// The types of pointers
|
/// The types of pointers
|
||||||
|
@ -24,10 +24,10 @@ pub enum PtrTy {
|
||||||
/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
|
/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
|
||||||
/// for type parameters and a lifetime.
|
/// for type parameters and a lifetime.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Path<'a> {
|
pub struct Path {
|
||||||
path: Vec<&'a str>,
|
path: Vec<Symbol>,
|
||||||
lifetime: Option<Ident>,
|
lifetime: Option<Ident>,
|
||||||
params: Vec<Box<Ty<'a>>>,
|
params: Vec<Box<Ty>>,
|
||||||
kind: PathKind,
|
kind: PathKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,19 +38,19 @@ pub enum PathKind {
|
||||||
Std,
|
Std,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Path<'a> {
|
impl Path {
|
||||||
pub fn new(path: Vec<&str>) -> Path<'_> {
|
pub fn new(path: Vec<Symbol>) -> Path {
|
||||||
Path::new_(path, None, Vec::new(), PathKind::Std)
|
Path::new_(path, None, Vec::new(), PathKind::Std)
|
||||||
}
|
}
|
||||||
pub fn new_local(path: &str) -> Path<'_> {
|
pub fn new_local(path: Symbol) -> Path {
|
||||||
Path::new_(vec![path], None, Vec::new(), PathKind::Local)
|
Path::new_(vec![path], None, Vec::new(), PathKind::Local)
|
||||||
}
|
}
|
||||||
pub fn new_<'r>(
|
pub fn new_(
|
||||||
path: Vec<&'r str>,
|
path: Vec<Symbol>,
|
||||||
lifetime: Option<Ident>,
|
lifetime: Option<Ident>,
|
||||||
params: Vec<Box<Ty<'r>>>,
|
params: Vec<Box<Ty>>,
|
||||||
kind: PathKind,
|
kind: PathKind,
|
||||||
) -> Path<'r> {
|
) -> Path {
|
||||||
Path { path, lifetime, params, kind }
|
Path { path, lifetime, params, kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ impl<'a> Path<'a> {
|
||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
self_generics: &Generics,
|
self_generics: &Generics,
|
||||||
) -> ast::Path {
|
) -> ast::Path {
|
||||||
let mut idents = self.path.iter().map(|s| cx.ident_of(*s, span)).collect();
|
let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
|
||||||
let lt = mk_lifetimes(cx, span, &self.lifetime);
|
let lt = mk_lifetimes(cx, span, &self.lifetime);
|
||||||
let tys: Vec<P<ast::Ty>> =
|
let tys: Vec<P<ast::Ty>> =
|
||||||
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
|
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
|
||||||
|
@ -94,21 +94,21 @@ impl<'a> Path<'a> {
|
||||||
|
|
||||||
/// A type. Supports pointers, Self, and literals.
|
/// A type. Supports pointers, Self, and literals.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Ty<'a> {
|
pub enum Ty {
|
||||||
Self_,
|
Self_,
|
||||||
/// &/Box/ Ty
|
/// &/Box/ Ty
|
||||||
Ptr(Box<Ty<'a>>, PtrTy),
|
Ptr(Box<Ty>, PtrTy),
|
||||||
/// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
|
/// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
|
||||||
/// parameter, and things like `i32`
|
/// parameter, and things like `i32`
|
||||||
Literal(Path<'a>),
|
Literal(Path),
|
||||||
/// includes unit
|
/// includes unit
|
||||||
Tuple(Vec<Ty<'a>>),
|
Tuple(Vec<Ty>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borrowed_ptrty() -> PtrTy {
|
pub fn borrowed_ptrty() -> PtrTy {
|
||||||
Borrowed(None, ast::Mutability::Not)
|
Borrowed(None, ast::Mutability::Not)
|
||||||
}
|
}
|
||||||
pub fn borrowed(ty: Box<Ty<'_>>) -> Ty<'_> {
|
pub fn borrowed(ty: Box<Ty>) -> Ty {
|
||||||
Ptr(ty, borrowed_ptrty())
|
Ptr(ty, borrowed_ptrty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,11 +116,11 @@ pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
|
||||||
Some(Some(borrowed_ptrty()))
|
Some(Some(borrowed_ptrty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borrowed_self<'r>() -> Ty<'r> {
|
pub fn borrowed_self() -> Ty {
|
||||||
borrowed(Box::new(Self_))
|
borrowed(Box::new(Self_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nil_ty<'r>() -> Ty<'r> {
|
pub fn nil_ty() -> Ty {
|
||||||
Tuple(Vec::new())
|
Tuple(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Li
|
||||||
mk_lifetime(cx, span, lt).into_iter().collect()
|
mk_lifetime(cx, span, lt).into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Ty<'a> {
|
impl Ty {
|
||||||
pub fn to_ty(
|
pub fn to_ty(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
|
@ -199,9 +199,9 @@ impl<'a> Ty<'a> {
|
||||||
fn mk_ty_param(
|
fn mk_ty_param(
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
name: &str,
|
name: Symbol,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
bounds: &[Path<'_>],
|
bounds: &[Path],
|
||||||
self_ident: Ident,
|
self_ident: Ident,
|
||||||
self_generics: &Generics,
|
self_generics: &Generics,
|
||||||
) -> ast::GenericParam {
|
) -> ast::GenericParam {
|
||||||
|
@ -212,7 +212,7 @@ fn mk_ty_param(
|
||||||
cx.trait_bound(path)
|
cx.trait_bound(path)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
cx.typaram(span, cx.ident_of(name, span), attrs.to_owned(), bounds, None)
|
cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
|
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
|
||||||
|
@ -225,12 +225,12 @@ fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
|
||||||
|
|
||||||
/// Bounds on type parameters.
|
/// Bounds on type parameters.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Bounds<'a> {
|
pub struct Bounds {
|
||||||
pub bounds: Vec<(&'a str, Vec<Path<'a>>)>,
|
pub bounds: Vec<(Symbol, Vec<Path>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Bounds<'a> {
|
impl Bounds {
|
||||||
pub fn empty() -> Bounds<'a> {
|
pub fn empty() -> Bounds {
|
||||||
Bounds { bounds: Vec::new() }
|
Bounds { bounds: Vec::new() }
|
||||||
}
|
}
|
||||||
pub fn to_generics(
|
pub fn to_generics(
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn expand_deriving_hash(
|
||||||
) {
|
) {
|
||||||
let path = Path::new_(pathvec_std!(hash::Hash), None, vec![], PathKind::Std);
|
let path = Path::new_(pathvec_std!(hash::Hash), None, vec![], PathKind::Std);
|
||||||
|
|
||||||
let typaram = "__H";
|
let typaram = sym::__H;
|
||||||
|
|
||||||
let arg = Path::new_local(typaram);
|
let arg = Path::new_local(typaram);
|
||||||
let hash_trait_def = TraitDef {
|
let hash_trait_def = TraitDef {
|
||||||
|
@ -32,7 +32,7 @@ pub fn expand_deriving_hash(
|
||||||
name: sym::hash,
|
name: sym::hash,
|
||||||
generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
|
generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: borrowed_explicit_self(),
|
||||||
args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), "state")],
|
args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), sym::state)],
|
||||||
ret_ty: nil_ty(),
|
ret_ty: nil_ty(),
|
||||||
attributes: vec![],
|
attributes: vec![],
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
|
|
|
@ -7,11 +7,11 @@ use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
macro path_local($x:ident) {
|
macro path_local($x:ident) {
|
||||||
generic::ty::Path::new_local(stringify!($x))
|
generic::ty::Path::new_local(sym::$x)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro pathvec_std($($rest:ident)::+) {{
|
macro pathvec_std($($rest:ident)::+) {{
|
||||||
vec![ $( stringify!($rest) ),+ ]
|
vec![ $( sym::$rest ),+ ]
|
||||||
}}
|
}}
|
||||||
|
|
||||||
macro path_std($($x:tt)*) {
|
macro path_std($($x:tt)*) {
|
||||||
|
@ -84,7 +84,7 @@ fn inject_impl_of_structural_trait(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
structural_path: generic::ty::Path<'_>,
|
structural_path: generic::ty::Path,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
let item = match *item {
|
let item = match *item {
|
||||||
|
|
|
@ -578,31 +578,31 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
self.count_args_index_offset = sofar;
|
self.count_args_index_offset = sofar;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<Ident> {
|
fn rtpath(ecx: &ExtCtxt<'_>, s: Symbol) -> Vec<Ident> {
|
||||||
ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)])
|
ecx.std_path(&[sym::fmt, sym::rt, sym::v1, s])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_count(&self, c: parse::Count) -> P<ast::Expr> {
|
fn build_count(&self, c: parse::Count) -> P<ast::Expr> {
|
||||||
let sp = self.macsp;
|
let sp = self.macsp;
|
||||||
let count = |c, arg| {
|
let count = |c, arg| {
|
||||||
let mut path = Context::rtpath(self.ecx, "Count");
|
let mut path = Context::rtpath(self.ecx, sym::Count);
|
||||||
path.push(self.ecx.ident_of(c, sp));
|
path.push(Ident::new(c, sp));
|
||||||
match arg {
|
match arg {
|
||||||
Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]),
|
Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]),
|
||||||
None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
|
None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match c {
|
match c {
|
||||||
parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))),
|
parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
|
||||||
parse::CountIsParam(i) => {
|
parse::CountIsParam(i) => {
|
||||||
// This needs mapping too, as `i` is referring to a macro
|
// This needs mapping too, as `i` is referring to a macro
|
||||||
// argument. If `i` is not found in `count_positions` then
|
// argument. If `i` is not found in `count_positions` then
|
||||||
// the error had already been emitted elsewhere.
|
// the error had already been emitted elsewhere.
|
||||||
let i = self.count_positions.get(&i).cloned().unwrap_or(0)
|
let i = self.count_positions.get(&i).cloned().unwrap_or(0)
|
||||||
+ self.count_args_index_offset;
|
+ self.count_args_index_offset;
|
||||||
count("Param", Some(self.ecx.expr_usize(sp, i)))
|
count(sym::Param, Some(self.ecx.expr_usize(sp, i)))
|
||||||
}
|
}
|
||||||
parse::CountImplied => count("Implied", None),
|
parse::CountImplied => count(sym::Implied, None),
|
||||||
// should never be the case, names are already resolved
|
// should never be the case, names are already resolved
|
||||||
parse::CountIsName(_) => panic!("should never happen"),
|
parse::CountIsName(_) => panic!("should never happen"),
|
||||||
}
|
}
|
||||||
|
@ -690,40 +690,40 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
// Build the format
|
// Build the format
|
||||||
let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
|
let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
|
||||||
let align = |name| {
|
let align = |name| {
|
||||||
let mut p = Context::rtpath(self.ecx, "Alignment");
|
let mut p = Context::rtpath(self.ecx, sym::Alignment);
|
||||||
p.push(self.ecx.ident_of(name, sp));
|
p.push(Ident::new(name, sp));
|
||||||
self.ecx.path_global(sp, p)
|
self.ecx.path_global(sp, p)
|
||||||
};
|
};
|
||||||
let align = match arg.format.align {
|
let align = match arg.format.align {
|
||||||
parse::AlignLeft => align("Left"),
|
parse::AlignLeft => align(sym::Left),
|
||||||
parse::AlignRight => align("Right"),
|
parse::AlignRight => align(sym::Right),
|
||||||
parse::AlignCenter => align("Center"),
|
parse::AlignCenter => align(sym::Center),
|
||||||
parse::AlignUnknown => align("Unknown"),
|
parse::AlignUnknown => align(sym::Unknown),
|
||||||
};
|
};
|
||||||
let align = self.ecx.expr_path(align);
|
let align = self.ecx.expr_path(align);
|
||||||
let flags = self.ecx.expr_u32(sp, arg.format.flags);
|
let flags = self.ecx.expr_u32(sp, arg.format.flags);
|
||||||
let prec = self.build_count(arg.format.precision);
|
let prec = self.build_count(arg.format.precision);
|
||||||
let width = self.build_count(arg.format.width);
|
let width = self.build_count(arg.format.width);
|
||||||
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
|
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::FormatSpec));
|
||||||
let fmt = self.ecx.expr_struct(
|
let fmt = self.ecx.expr_struct(
|
||||||
sp,
|
sp,
|
||||||
path,
|
path,
|
||||||
vec![
|
vec![
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("fill", sp), fill),
|
self.ecx.field_imm(sp, Ident::new(sym::fill, sp), fill),
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("align", sp), align),
|
self.ecx.field_imm(sp, Ident::new(sym::align, sp), align),
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("flags", sp), flags),
|
self.ecx.field_imm(sp, Ident::new(sym::flags, sp), flags),
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("precision", sp), prec),
|
self.ecx.field_imm(sp, Ident::new(sym::precision, sp), prec),
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("width", sp), width),
|
self.ecx.field_imm(sp, Ident::new(sym::width, sp), width),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument"));
|
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, sym::Argument));
|
||||||
Some(self.ecx.expr_struct(
|
Some(self.ecx.expr_struct(
|
||||||
sp,
|
sp,
|
||||||
path,
|
path,
|
||||||
vec![
|
vec![
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("position", sp), pos),
|
self.ecx.field_imm(sp, Ident::new(sym::position, sp), pos),
|
||||||
self.ecx.field_imm(sp, self.ecx.ident_of("format", sp), fmt),
|
self.ecx.field_imm(sp, Ident::new(sym::format, sp), fmt),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
let mut heads = Vec::with_capacity(self.args.len());
|
let mut heads = Vec::with_capacity(self.args.len());
|
||||||
|
|
||||||
let names_pos: Vec<_> = (0..self.args.len())
|
let names_pos: Vec<_> = (0..self.args.len())
|
||||||
.map(|i| self.ecx.ident_of(&format!("arg{}", i), self.macsp))
|
.map(|i| Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// First, build up the static array which will become our precompiled
|
// First, build up the static array which will become our precompiled
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl AllocFnFactory<'_, '_> {
|
||||||
let mut abi_args = Vec::new();
|
let mut abi_args = Vec::new();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut mk = || {
|
let mut mk = || {
|
||||||
let name = self.cx.ident_of(&format!("arg{}", i), self.span);
|
let name = Ident::from_str_and_span(&format!("arg{}", i), self.span);
|
||||||
i += 1;
|
i += 1;
|
||||||
name
|
name
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,7 @@ impl AllocFnFactory<'_, '_> {
|
||||||
let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
|
let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
|
||||||
let item = self.cx.item(
|
let item = self.cx.item(
|
||||||
self.span,
|
self.span,
|
||||||
self.cx.ident_of(&self.kind.fn_name(method.name), self.span),
|
Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),
|
||||||
self.attrs(),
|
self.attrs(),
|
||||||
kind,
|
kind,
|
||||||
);
|
);
|
||||||
|
|
|
@ -384,12 +384,12 @@ fn mk_decls(
|
||||||
let proc_macro = Ident::new(sym::proc_macro, span);
|
let proc_macro = Ident::new(sym::proc_macro, span);
|
||||||
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
|
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
|
||||||
|
|
||||||
let bridge = cx.ident_of("bridge", span);
|
let bridge = Ident::new(sym::bridge, span);
|
||||||
let client = cx.ident_of("client", span);
|
let client = Ident::new(sym::client, span);
|
||||||
let proc_macro_ty = cx.ident_of("ProcMacro", span);
|
let proc_macro_ty = Ident::new(sym::ProcMacro, span);
|
||||||
let custom_derive = cx.ident_of("custom_derive", span);
|
let custom_derive = Ident::new(sym::custom_derive, span);
|
||||||
let attr = cx.ident_of("attr", span);
|
let attr = Ident::new(sym::attr, span);
|
||||||
let bang = cx.ident_of("bang", span);
|
let bang = Ident::new(sym::bang, span);
|
||||||
|
|
||||||
let krate_ref = RefCell::new(ast_krate);
|
let krate_ref = RefCell::new(ast_krate);
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ fn mk_decls(
|
||||||
let decls_static = cx
|
let decls_static = cx
|
||||||
.item_static(
|
.item_static(
|
||||||
span,
|
span,
|
||||||
cx.ident_of("_DECLS", span),
|
Ident::new(sym::_DECLS, span),
|
||||||
cx.ty_rptr(
|
cx.ty_rptr(
|
||||||
span,
|
span,
|
||||||
cx.ty(
|
cx.ty(
|
||||||
|
|
|
@ -108,22 +108,38 @@ pub fn expand_test_or_bench(
|
||||||
let test_id = Ident::new(sym::test, attr_sp);
|
let test_id = Ident::new(sym::test, attr_sp);
|
||||||
|
|
||||||
// creates test::$name
|
// creates test::$name
|
||||||
let test_path = |name| cx.path(sp, vec![test_id, cx.ident_of(name, sp)]);
|
let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
|
||||||
|
|
||||||
// creates test::ShouldPanic::$name
|
// creates test::ShouldPanic::$name
|
||||||
let should_panic_path =
|
let should_panic_path = |name| {
|
||||||
|name| cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic", sp), cx.ident_of(name, sp)]);
|
cx.path(
|
||||||
|
sp,
|
||||||
|
vec![
|
||||||
|
test_id,
|
||||||
|
Ident::from_str_and_span("ShouldPanic", sp),
|
||||||
|
Ident::from_str_and_span(name, sp),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// creates test::TestType::$name
|
// creates test::TestType::$name
|
||||||
let test_type_path =
|
let test_type_path = |name| {
|
||||||
|name| cx.path(sp, vec![test_id, cx.ident_of("TestType", sp), cx.ident_of(name, sp)]);
|
cx.path(
|
||||||
|
sp,
|
||||||
|
vec![
|
||||||
|
test_id,
|
||||||
|
Ident::from_str_and_span("TestType", sp),
|
||||||
|
Ident::from_str_and_span(name, sp),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// creates $name: $expr
|
// creates $name: $expr
|
||||||
let field = |name, expr| cx.field_imm(sp, cx.ident_of(name, sp), expr);
|
let field = |name, expr| cx.field_imm(sp, Ident::from_str_and_span(name, sp), expr);
|
||||||
|
|
||||||
let test_fn = if is_bench {
|
let test_fn = if is_bench {
|
||||||
// A simple ident for a lambda
|
// A simple ident for a lambda
|
||||||
let b = cx.ident_of("b", attr_sp);
|
let b = Ident::from_str_and_span("b", attr_sp);
|
||||||
|
|
||||||
cx.expr_call(
|
cx.expr_call(
|
||||||
sp,
|
sp,
|
||||||
|
|
|
@ -270,7 +270,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
||||||
let mut test_runner = cx
|
let mut test_runner = cx
|
||||||
.test_runner
|
.test_runner
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or(ecx.path(sp, vec![test_id, ecx.ident_of(runner_name, sp)]));
|
.unwrap_or(ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
|
||||||
|
|
||||||
test_runner.span = sp;
|
test_runner.span = sp;
|
||||||
|
|
||||||
|
|
|
@ -1061,9 +1061,6 @@ impl<'a> ExtCtxt<'a> {
|
||||||
pub fn set_trace_macros(&mut self, x: bool) {
|
pub fn set_trace_macros(&mut self, x: bool) {
|
||||||
self.ecfg.trace_mac = x
|
self.ecfg.trace_mac = x
|
||||||
}
|
}
|
||||||
pub fn ident_of(&self, st: &str, sp: Span) -> Ident {
|
|
||||||
Ident::from_str_and_span(st, sp)
|
|
||||||
}
|
|
||||||
pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
|
pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
|
||||||
let def_site = self.with_def_site_ctxt(DUMMY_SP);
|
let def_site = self.with_def_site_ctxt(DUMMY_SP);
|
||||||
iter::once(Ident::new(kw::DollarCrate, def_site))
|
iter::once(Ident::new(kw::DollarCrate, def_site))
|
||||||
|
|
|
@ -368,7 +368,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
|
let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
|
||||||
let err_path = self.path_global(sp, err);
|
let err_path = self.path_global(sp, err);
|
||||||
|
|
||||||
let binding_variable = self.ident_of("__try_var", sp);
|
let binding_variable = Ident::new(sym::__try_var, sp);
|
||||||
let binding_pat = self.pat_ident(sp, binding_variable);
|
let binding_pat = self.pat_ident(sp, binding_variable);
|
||||||
let binding_expr = self.expr_ident(sp, binding_variable);
|
let binding_expr = self.expr_ident(sp, binding_variable);
|
||||||
|
|
||||||
|
|
|
@ -122,19 +122,28 @@ symbols! {
|
||||||
// There is currently no checking that all symbols are used; that would be
|
// There is currently no checking that all symbols are used; that would be
|
||||||
// nice to have.
|
// nice to have.
|
||||||
Symbols {
|
Symbols {
|
||||||
|
Alignment,
|
||||||
Arc,
|
Arc,
|
||||||
|
Argument,
|
||||||
ArgumentV1,
|
ArgumentV1,
|
||||||
Arguments,
|
Arguments,
|
||||||
C,
|
C,
|
||||||
|
Center,
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
|
Count,
|
||||||
Debug,
|
Debug,
|
||||||
Decodable,
|
Decodable,
|
||||||
|
Decoder,
|
||||||
Default,
|
Default,
|
||||||
Encodable,
|
Encodable,
|
||||||
|
Encoder,
|
||||||
Eq,
|
Eq,
|
||||||
Equal,
|
Equal,
|
||||||
Err,
|
Err,
|
||||||
|
Error,
|
||||||
|
FormatSpec,
|
||||||
|
Formatter,
|
||||||
From,
|
From,
|
||||||
Future,
|
Future,
|
||||||
FxHashMap,
|
FxHashMap,
|
||||||
|
@ -143,11 +152,15 @@ symbols! {
|
||||||
Hash,
|
Hash,
|
||||||
HashMap,
|
HashMap,
|
||||||
HashSet,
|
HashSet,
|
||||||
|
Hasher,
|
||||||
|
Implied,
|
||||||
Input,
|
Input,
|
||||||
IntoIterator,
|
IntoIterator,
|
||||||
|
Is,
|
||||||
ItemContext,
|
ItemContext,
|
||||||
Iterator,
|
Iterator,
|
||||||
Layout,
|
Layout,
|
||||||
|
Left,
|
||||||
LintPass,
|
LintPass,
|
||||||
None,
|
None,
|
||||||
Ok,
|
Ok,
|
||||||
|
@ -155,11 +168,13 @@ symbols! {
|
||||||
Ord,
|
Ord,
|
||||||
Ordering,
|
Ordering,
|
||||||
Output,
|
Output,
|
||||||
|
Param,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
PartialOrd,
|
PartialOrd,
|
||||||
Pending,
|
Pending,
|
||||||
Pin,
|
Pin,
|
||||||
Poll,
|
Poll,
|
||||||
|
ProcMacro,
|
||||||
ProcMacroHack,
|
ProcMacroHack,
|
||||||
ProceduralMasqueradeDummyType,
|
ProceduralMasqueradeDummyType,
|
||||||
Range,
|
Range,
|
||||||
|
@ -172,20 +187,31 @@ symbols! {
|
||||||
Ready,
|
Ready,
|
||||||
Result,
|
Result,
|
||||||
Return,
|
Return,
|
||||||
|
Right,
|
||||||
RustcDecodable,
|
RustcDecodable,
|
||||||
RustcEncodable,
|
RustcEncodable,
|
||||||
Send,
|
Send,
|
||||||
Some,
|
Some,
|
||||||
|
StructuralEq,
|
||||||
|
StructuralPartialEq,
|
||||||
Sync,
|
Sync,
|
||||||
Target,
|
Target,
|
||||||
Try,
|
Try,
|
||||||
Ty,
|
Ty,
|
||||||
TyCtxt,
|
TyCtxt,
|
||||||
TyKind,
|
TyKind,
|
||||||
|
Unknown,
|
||||||
Vec,
|
Vec,
|
||||||
Yield,
|
Yield,
|
||||||
|
_DECLS,
|
||||||
_Self,
|
_Self,
|
||||||
|
__D,
|
||||||
|
__H,
|
||||||
|
__S,
|
||||||
__next,
|
__next,
|
||||||
|
__try_var,
|
||||||
|
_d,
|
||||||
|
_e,
|
||||||
_task_context,
|
_task_context,
|
||||||
aarch64_target_feature,
|
aarch64_target_feature,
|
||||||
abi,
|
abi,
|
||||||
|
@ -256,6 +282,7 @@ symbols! {
|
||||||
automatically_derived,
|
automatically_derived,
|
||||||
avx512_target_feature,
|
avx512_target_feature,
|
||||||
await_macro,
|
await_macro,
|
||||||
|
bang,
|
||||||
begin_panic,
|
begin_panic,
|
||||||
bench,
|
bench,
|
||||||
bin,
|
bin,
|
||||||
|
@ -278,6 +305,7 @@ symbols! {
|
||||||
box_syntax,
|
box_syntax,
|
||||||
braced_empty_structs,
|
braced_empty_structs,
|
||||||
breakpoint,
|
breakpoint,
|
||||||
|
bridge,
|
||||||
bswap,
|
bswap,
|
||||||
c_variadic,
|
c_variadic,
|
||||||
call,
|
call,
|
||||||
|
@ -299,6 +327,7 @@ symbols! {
|
||||||
cfg_target_vendor,
|
cfg_target_vendor,
|
||||||
cfg_version,
|
cfg_version,
|
||||||
char,
|
char,
|
||||||
|
client,
|
||||||
clippy,
|
clippy,
|
||||||
clone,
|
clone,
|
||||||
clone_closures,
|
clone_closures,
|
||||||
|
@ -370,11 +399,15 @@ symbols! {
|
||||||
custom_derive,
|
custom_derive,
|
||||||
custom_inner_attributes,
|
custom_inner_attributes,
|
||||||
custom_test_frameworks,
|
custom_test_frameworks,
|
||||||
|
d,
|
||||||
dead_code,
|
dead_code,
|
||||||
dealloc,
|
dealloc,
|
||||||
debug,
|
debug,
|
||||||
debug_assertions,
|
debug_assertions,
|
||||||
|
debug_struct,
|
||||||
debug_trait,
|
debug_trait,
|
||||||
|
debug_trait_builder,
|
||||||
|
debug_tuple,
|
||||||
decl_macro,
|
decl_macro,
|
||||||
declare_lint_pass,
|
declare_lint_pass,
|
||||||
decode,
|
decode,
|
||||||
|
@ -420,6 +453,11 @@ symbols! {
|
||||||
dyn_trait,
|
dyn_trait,
|
||||||
eh_catch_typeinfo,
|
eh_catch_typeinfo,
|
||||||
eh_personality,
|
eh_personality,
|
||||||
|
emit_enum,
|
||||||
|
emit_enum_variant,
|
||||||
|
emit_enum_variant_arg,
|
||||||
|
emit_struct,
|
||||||
|
emit_struct_field,
|
||||||
enable,
|
enable,
|
||||||
enclosing_scope,
|
enclosing_scope,
|
||||||
encode,
|
encode,
|
||||||
|
@ -447,6 +485,7 @@ symbols! {
|
||||||
extern_prelude,
|
extern_prelude,
|
||||||
extern_types,
|
extern_types,
|
||||||
external_doc,
|
external_doc,
|
||||||
|
f,
|
||||||
f16c_target_feature,
|
f16c_target_feature,
|
||||||
f32,
|
f32,
|
||||||
f32_runtime,
|
f32_runtime,
|
||||||
|
@ -463,6 +502,9 @@ symbols! {
|
||||||
field,
|
field,
|
||||||
field_init_shorthand,
|
field_init_shorthand,
|
||||||
file,
|
file,
|
||||||
|
fill,
|
||||||
|
finish,
|
||||||
|
flags,
|
||||||
float_to_int_unchecked,
|
float_to_int_unchecked,
|
||||||
floorf32,
|
floorf32,
|
||||||
floorf64,
|
floorf64,
|
||||||
|
@ -477,6 +519,7 @@ symbols! {
|
||||||
fn_once_output,
|
fn_once_output,
|
||||||
forbid,
|
forbid,
|
||||||
forget,
|
forget,
|
||||||
|
format,
|
||||||
format_args,
|
format_args,
|
||||||
format_args_capture,
|
format_args_capture,
|
||||||
format_args_nl,
|
format_args_nl,
|
||||||
|
@ -518,6 +561,7 @@ symbols! {
|
||||||
html_no_source,
|
html_no_source,
|
||||||
html_playground_url,
|
html_playground_url,
|
||||||
html_root_url,
|
html_root_url,
|
||||||
|
i,
|
||||||
i128,
|
i128,
|
||||||
i128_type,
|
i128_type,
|
||||||
i16,
|
i16,
|
||||||
|
@ -707,6 +751,7 @@ symbols! {
|
||||||
options,
|
options,
|
||||||
or,
|
or,
|
||||||
or_patterns,
|
or_patterns,
|
||||||
|
other,
|
||||||
out,
|
out,
|
||||||
overlapping_marker_traits,
|
overlapping_marker_traits,
|
||||||
owned_box,
|
owned_box,
|
||||||
|
@ -738,6 +783,7 @@ symbols! {
|
||||||
plugins,
|
plugins,
|
||||||
pointer,
|
pointer,
|
||||||
poll,
|
poll,
|
||||||
|
position,
|
||||||
post_dash_lto: "post-lto",
|
post_dash_lto: "post-lto",
|
||||||
powerpc_target_feature,
|
powerpc_target_feature,
|
||||||
powf32,
|
powf32,
|
||||||
|
@ -746,6 +792,7 @@ symbols! {
|
||||||
powif64,
|
powif64,
|
||||||
pre_dash_lto: "pre-lto",
|
pre_dash_lto: "pre-lto",
|
||||||
precise_pointer_size_matching,
|
precise_pointer_size_matching,
|
||||||
|
precision,
|
||||||
pref_align_of,
|
pref_align_of,
|
||||||
prefetch_read_data,
|
prefetch_read_data,
|
||||||
prefetch_read_instruction,
|
prefetch_read_instruction,
|
||||||
|
@ -782,6 +829,11 @@ symbols! {
|
||||||
raw_identifiers,
|
raw_identifiers,
|
||||||
raw_ref_op,
|
raw_ref_op,
|
||||||
re_rebalance_coherence,
|
re_rebalance_coherence,
|
||||||
|
read_enum,
|
||||||
|
read_enum_variant,
|
||||||
|
read_enum_variant_arg,
|
||||||
|
read_struct,
|
||||||
|
read_struct_field,
|
||||||
readonly,
|
readonly,
|
||||||
realloc,
|
realloc,
|
||||||
reason,
|
reason,
|
||||||
|
@ -871,6 +923,7 @@ symbols! {
|
||||||
rustc_promotable,
|
rustc_promotable,
|
||||||
rustc_regions,
|
rustc_regions,
|
||||||
rustc_reservation_impl,
|
rustc_reservation_impl,
|
||||||
|
rustc_serialize,
|
||||||
rustc_specialization_trait,
|
rustc_specialization_trait,
|
||||||
rustc_stable,
|
rustc_stable,
|
||||||
rustc_std_internal_symbol,
|
rustc_std_internal_symbol,
|
||||||
|
@ -974,6 +1027,7 @@ symbols! {
|
||||||
stable,
|
stable,
|
||||||
staged_api,
|
staged_api,
|
||||||
start,
|
start,
|
||||||
|
state,
|
||||||
static_in_const,
|
static_in_const,
|
||||||
static_nobundle,
|
static_nobundle,
|
||||||
static_recursion,
|
static_recursion,
|
||||||
|
@ -1121,6 +1175,7 @@ symbols! {
|
||||||
wasm_import_module,
|
wasm_import_module,
|
||||||
wasm_target_feature,
|
wasm_target_feature,
|
||||||
while_let,
|
while_let,
|
||||||
|
width,
|
||||||
windows,
|
windows,
|
||||||
windows_subsystem,
|
windows_subsystem,
|
||||||
wrapping_add,
|
wrapping_add,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue