Skip to content

Commit ade2c8f

Browse files
committed
Remove gensyms from built-in derives
Also make them generally more hygienic with name resolution.
1 parent dd9a5b8 commit ade2c8f

File tree

10 files changed

+186
-86
lines changed

10 files changed

+186
-86
lines changed

src/libsyntax_ext/deriving/cmp/ord.rs

+30-29
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,18 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
4343
}
4444

4545

46-
pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
47-
span: Span,
48-
self_arg_tags: &[ast::Ident])
49-
-> P<ast::Expr> {
46+
pub fn ordering_collapsed(
47+
cx: &mut ExtCtxt<'_>,
48+
span: Span,
49+
self_arg_tags: &[ast::Ident],
50+
) -> P<ast::Expr> {
5051
let lft = cx.expr_ident(span, self_arg_tags[0]);
5152
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
52-
cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
53+
cx.expr_method_call(span, lft, ast::Ident::new(sym::cmp, span), vec![rgt])
5354
}
5455

5556
pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
56-
let test_id = cx.ident_of("cmp").gensym();
57+
let test_id = ast::Ident::new(sym::cmp, span);
5758
let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
5859

5960
let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
@@ -75,34 +76,34 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<
7576
// as the outermost one, and the last as the innermost.
7677
false,
7778
|cx, span, old, self_f, other_fs| {
78-
// match new {
79-
// ::std::cmp::Ordering::Equal => old,
80-
// cmp => cmp
81-
// }
79+
// match new {
80+
// ::std::cmp::Ordering::Equal => old,
81+
// cmp => cmp
82+
// }
8283

83-
let new = {
84-
let other_f = match other_fs {
85-
[o_f] => o_f,
86-
_ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
87-
};
84+
let new = {
85+
let other_f = match other_fs {
86+
[o_f] => o_f,
87+
_ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
88+
};
8889

89-
let args = vec![
90-
cx.expr_addr_of(span, self_f),
91-
cx.expr_addr_of(span, other_f.clone()),
92-
];
90+
let args = vec![
91+
cx.expr_addr_of(span, self_f),
92+
cx.expr_addr_of(span, other_f.clone()),
93+
];
9394

94-
cx.expr_call_global(span, cmp_path.clone(), args)
95-
};
95+
cx.expr_call_global(span, cmp_path.clone(), args)
96+
};
9697

97-
let eq_arm = cx.arm(span,
98-
vec![cx.pat_path(span, equals_path.clone())],
99-
old);
100-
let neq_arm = cx.arm(span,
101-
vec![cx.pat_ident(span, test_id)],
102-
cx.expr_ident(span, test_id));
98+
let eq_arm = cx.arm(span,
99+
vec![cx.pat_path(span, equals_path.clone())],
100+
old);
101+
let neq_arm = cx.arm(span,
102+
vec![cx.pat_ident(span, test_id)],
103+
cx.expr_ident(span, test_id));
103104

104-
cx.expr_match(span, new, vec![eq_arm, neq_arm])
105-
},
105+
cx.expr_match(span, new, vec![eq_arm, neq_arm])
106+
},
106107
cx.expr_path(equals_path.clone()),
107108
Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
108109
if self_args.len() != 2 {

src/libsyntax_ext/deriving/cmp/partial_ord.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,12 @@ pub enum OrderingOp {
9494
GeOp,
9595
}
9696

97-
pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
98-
span: Span,
99-
op: OrderingOp,
100-
self_arg_tags: &[ast::Ident])
101-
-> P<ast::Expr> {
97+
pub fn some_ordering_collapsed(
98+
cx: &mut ExtCtxt<'_>,
99+
span: Span,
100+
op: OrderingOp,
101+
self_arg_tags: &[ast::Ident],
102+
) -> P<ast::Expr> {
102103
let lft = cx.expr_ident(span, self_arg_tags[0]);
103104
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
104105
let op_str = match op {
@@ -108,11 +109,11 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
108109
GtOp => "gt",
109110
GeOp => "ge",
110111
};
111-
cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
112+
cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
112113
}
113114

114115
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
115-
let test_id = cx.ident_of("cmp").gensym();
116+
let test_id = ast::Ident::new(sym::cmp, span);
116117
let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
117118
let ordering_expr = cx.expr_path(ordering.clone());
118119
let equals_expr = cx.expr_some(span, ordering_expr);

src/libsyntax_ext/deriving/debug.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
6262
// We want to make sure we have the ctxt set so that we can use unstable methods
6363
let span = span.with_ctxt(cx.backtrace());
6464
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
65-
let builder = Ident::from_str("debug_trait_builder").gensym();
65+
let builder = Ident::from_str_and_span("debug_trait_builder", span);
6666
let builder_expr = cx.expr_ident(span, builder.clone());
6767

6868
let fmt = substr.nonself_args[0].clone();
@@ -73,7 +73,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
7373
// tuple struct/"normal" variant
7474
let expr =
7575
cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
76-
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
76+
stmts.push(cx.stmt_let(span, true, builder, expr));
7777

7878
for field in fields {
7979
// Use double indirection to make sure this works for unsized types
@@ -82,7 +82,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
8282

8383
let expr = cx.expr_method_call(span,
8484
builder_expr.clone(),
85-
Ident::with_empty_ctxt(sym::field),
85+
Ident::new(sym::field, span),
8686
vec![field]);
8787

8888
// Use `let _ = expr;` to avoid triggering the
@@ -106,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
106106
let field = cx.expr_addr_of(field.span, field);
107107
let expr = cx.expr_method_call(span,
108108
builder_expr.clone(),
109-
Ident::with_empty_ctxt(sym::field),
109+
Ident::new(sym::field, span),
110110
vec![name, field]);
111111
stmts.push(stmt_let_undescore(cx, span, expr));
112112
}

src/libsyntax_ext/deriving/decodable.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
1+
//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
22
3-
use crate::deriving::{self, pathvec_std};
3+
use crate::deriving::pathvec_std;
44
use crate::deriving::generic::*;
55
use crate::deriving::generic::ty::*;
66

@@ -17,7 +17,7 @@ pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt<'_>,
1717
item: &Annotatable,
1818
push: &mut dyn FnMut(Annotatable)) {
1919
let krate = "rustc_serialize";
20-
let typaram = &*deriving::hygienic_type_parameter(item, "__D");
20+
let typaram = "__D";
2121

2222
let trait_def = TraitDef {
2323
span,

src/libsyntax_ext/deriving/encodable.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
//! The compiler code necessary to implement the `#[derive(Encodable)]`
2-
//! (and `Decodable`, in `decodable.rs`) extension. The idea here is that
3-
//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
1+
//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
2+
//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
3+
//! type-defining items may be tagged with
4+
//! `#[derive(RustcEncodable, RustcDecodable)]`.
45
//!
56
//! For example, a type like:
67
//!
78
//! ```
8-
//! #[derive(Encodable, Decodable)]
9+
//! #[derive(RustcEncodable, RustcDecodable)]
910
//! struct Node { id: usize }
1011
//! ```
1112
//!
@@ -40,15 +41,17 @@
4041
//! references other non-built-in types. A type definition like:
4142
//!
4243
//! ```
43-
//! # #[derive(Encodable, Decodable)] struct Span;
44-
//! #[derive(Encodable, Decodable)]
44+
//! # #[derive(RustcEncodable, RustcDecodable)]
45+
//! # struct Span;
46+
//! #[derive(RustcEncodable, RustcDecodable)]
4547
//! struct Spanned<T> { node: T, span: Span }
4648
//! ```
4749
//!
4850
//! would yield functions like:
4951
//!
5052
//! ```
51-
//! # #[derive(Encodable, Decodable)] struct Span;
53+
//! # #[derive(RustcEncodable, RustcDecodable)]
54+
//! # struct Span;
5255
//! # struct Spanned<T> { node: T, span: Span }
5356
//! impl<
5457
//! S: Encoder<E>,
@@ -82,7 +85,7 @@
8285
//! }
8386
//! ```
8487
85-
use crate::deriving::{self, pathvec_std};
88+
use crate::deriving::pathvec_std;
8689
use crate::deriving::generic::*;
8790
use crate::deriving::generic::ty::*;
8891

@@ -98,7 +101,7 @@ pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt<'_>,
98101
item: &Annotatable,
99102
push: &mut dyn FnMut(Annotatable)) {
100103
let krate = "rustc_serialize";
101-
let typaram = &*deriving::hygienic_type_parameter(item, "__S");
104+
let typaram = "__S";
102105

103106
let trait_def = TraitDef {
104107
span,

src/libsyntax_ext/deriving/generic/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ impl<'a> MethodDef<'a> {
890890

891891
for (ty, name) in self.args.iter() {
892892
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
893-
let ident = cx.ident_of(name).gensym();
893+
let ident = ast::Ident::from_str_and_span(name, trait_.span);
894894
arg_tys.push((ident, ast_ty));
895895

896896
let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -1210,7 +1210,7 @@ impl<'a> MethodDef<'a> {
12101210
let vi_idents = self_arg_names.iter()
12111211
.map(|name| {
12121212
let vi_suffix = format!("{}_vi", &name[..]);
1213-
cx.ident_of(&vi_suffix[..]).gensym()
1213+
ast::Ident::from_str_and_span(&vi_suffix[..], trait_.span)
12141214
})
12151215
.collect::<Vec<ast::Ident>>();
12161216

@@ -1387,7 +1387,10 @@ impl<'a> MethodDef<'a> {
13871387
let variant_value =
13881388
deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
13891389

1390-
let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
1390+
let target_ty = cx.ty_ident(
1391+
sp,
1392+
ast::Ident::from_str_and_span(target_type_name, sp),
1393+
);
13911394
let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
13921395
let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
13931396
index_let_stmts.push(let_stmt);
@@ -1588,7 +1591,7 @@ impl<'a> TraitDef<'a> {
15881591
let mut ident_exprs = Vec::new();
15891592
for (i, struct_field) in struct_def.fields().iter().enumerate() {
15901593
let sp = struct_field.span.with_ctxt(self.span.ctxt());
1591-
let ident = cx.ident_of(&format!("{}_{}", prefix, i)).gensym();
1594+
let ident = ast::Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
15921595
paths.push(ident.with_span_pos(sp));
15931596
let val = cx.expr_path(cx.path_ident(sp, ident));
15941597
let val = if use_temporaries {

src/libsyntax_ext/deriving/generic/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<'a> Path<'a> {
7272
self_ty: Ident,
7373
self_generics: &Generics)
7474
-> ast::Path {
75-
let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
75+
let mut idents = self.path.iter().map(|s| Ident::from_str_and_span(*s, span)).collect();
7676
let lt = mk_lifetimes(cx, span, &self.lifetime);
7777
let tys: Vec<P<ast::Ty>> =
7878
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
@@ -209,7 +209,7 @@ fn mk_ty_param(cx: &ExtCtxt<'_>,
209209
cx.trait_bound(path)
210210
})
211211
.collect();
212-
cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
212+
cx.typaram(span, ast::Ident::from_str_and_span(name, span), attrs.to_owned(), bounds, None)
213213
}
214214

215215
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {

src/libsyntax_ext/deriving/hash.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>,
1616

1717
let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
1818

19-
let typaram = &*deriving::hygienic_type_parameter(item, "__H");
19+
let typaram = "__H";
2020

2121
let arg = Path::new_local(typaram);
2222
let hash_trait_def = TraitDef {

src/libsyntax_ext/deriving/mod.rs

-27
Original file line numberDiff line numberDiff line change
@@ -54,33 +54,6 @@ impl MultiItemModifier for BuiltinDerive {
5454
}
5555
}
5656

57-
/// Construct a name for the inner type parameter that can't collide with any type parameters of
58-
/// the item. This is achieved by starting with a base and then concatenating the names of all
59-
/// other type parameters.
60-
// FIXME(aburka): use real hygiene when that becomes possible
61-
fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
62-
let mut typaram = String::from(base);
63-
if let Annotatable::Item(ref item) = *item {
64-
match item.node {
65-
ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
66-
ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
67-
for param in params {
68-
match param.kind {
69-
ast::GenericParamKind::Type { .. } => {
70-
typaram.push_str(&param.ident.as_str());
71-
}
72-
_ => {}
73-
}
74-
}
75-
}
76-
77-
_ => {}
78-
}
79-
}
80-
81-
typaram
82-
}
83-
8457
/// Constructs an expression that calls an intrinsic
8558
fn call_intrinsic(cx: &ExtCtxt<'_>,
8659
span: Span,

0 commit comments

Comments
 (0)