Skip to content

Commit 0c5740f

Browse files
committed
Auto merge of #49986 - zofrex:better-derived-argument-names, r=Manishearth
Provide better names for builtin deriving-generated attributes First attempt at fixing #49967 Not in love with any choices here, don't be shy if you aren't happy with anything :) I've tested that this produces nicer names in documentation, and that it no longer has issues conflicting with constants with the same name. (I guess we _could_ make a test for that... unsure if that would be valuable) In all cases I took the names from the methods as declared in the relevant trait. In some cases I had to prepend the names with _ otherwise there were errors about un-used variables. I'm uneasy with the inconsistency... do they all need to be like that? Is there a way to generate an alternate impl or use a different name (`_`?) in the cases where the arguments are not used? Lastly the gensym addition to Ident I implemented largely as suggested, but I want to point out it's a little circuitous (at least, as far as I understand it). `cx.ident_of(name)` is just `Ident::from_str`, so we create an Ident then another Ident from it. `Ident::with_empty_ctxt(Symbol::gensym(string))` may or may not be equivalent, I don't know if it's important to intern it _then_ gensym it. It seems like either we could use that, or if we do want a new method to make this convenient, it could be on Ident instead (`from_str_gensymed`?)
2 parents 190a6c4 + d6feab6 commit 0c5740f

File tree

14 files changed

+97
-40
lines changed

14 files changed

+97
-40
lines changed

src/librustc/middle/liveness.rs

+11
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
184184
b: hir::BodyId, s: Span, id: NodeId) {
185185
visit_fn(self, fk, fd, b, s, id);
186186
}
187+
187188
fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); }
188189
fn visit_expr(&mut self, ex: &'tcx Expr) { visit_expr(self, ex); }
189190
fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); }
@@ -361,6 +362,16 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
361362
// swap in a new set of IR maps for this function body:
362363
let mut fn_maps = IrMaps::new(ir.tcx);
363364

365+
// Don't run unused pass for #[derive()]
366+
if let FnKind::Method(..) = fk {
367+
let parent = ir.tcx.hir.get_parent(id);
368+
if let Some(hir::map::Node::NodeItem(i)) = ir.tcx.hir.find(parent) {
369+
if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
370+
return;
371+
}
372+
}
373+
}
374+
364375
debug!("creating fn_maps: {:?}", &fn_maps as *const IrMaps);
365376

366377
let body = ir.tcx.hir.body(body_id);

src/libsyntax_ext/deriving/cmp/ord.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
3838
name: "cmp",
3939
generics: LifetimeBounds::empty(),
4040
explicit_self: borrowed_explicit_self(),
41-
args: vec![borrowed_self()],
41+
args: vec![(borrowed_self(), "other")],
4242
ret_ty: Literal(path_std!(cx, cmp::Ordering)),
4343
attributes: attrs,
4444
is_unsafe: false,
@@ -64,7 +64,7 @@ pub fn ordering_collapsed(cx: &mut ExtCtxt,
6464
}
6565

6666
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
67-
let test_id = cx.ident_of("__cmp");
67+
let test_id = cx.ident_of("cmp").gensym();
6868
let equals_path = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
6969

7070
let cmp_path = cx.std_path(&["cmp", "Ord", "cmp"]);
@@ -77,9 +77,9 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
7777
// ::std::cmp::Ordering::Equal => {
7878
// ...
7979
// }
80-
// __cmp => __cmp
80+
// cmp => cmp
8181
// },
82-
// __cmp => __cmp
82+
// cmp => cmp
8383
// }
8484
//
8585
cs_fold(// foldr nests the if-elses correctly, leaving the first field
@@ -88,7 +88,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
8888
|cx, span, old, self_f, other_fs| {
8989
// match new {
9090
// ::std::cmp::Ordering::Equal => old,
91-
// __cmp => __cmp
91+
// cmp => cmp
9292
// }
9393

9494
let new = {

src/libsyntax_ext/deriving/cmp/partial_eq.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
7878
name: $name,
7979
generics: LifetimeBounds::empty(),
8080
explicit_self: borrowed_explicit_self(),
81-
args: vec![borrowed_self()],
81+
args: vec![(borrowed_self(), "other")],
8282
ret_ty: Literal(path_local!(bool)),
8383
attributes: attrs,
8484
is_unsafe: false,

src/libsyntax_ext/deriving/cmp/partial_ord.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
3434
name: $name,
3535
generics: LifetimeBounds::empty(),
3636
explicit_self: borrowed_explicit_self(),
37-
args: vec![borrowed_self()],
37+
args: vec![(borrowed_self(), "other")],
3838
ret_ty: Literal(path_local!(bool)),
3939
attributes: attrs,
4040
is_unsafe: false,
@@ -59,7 +59,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
5959
name: "partial_cmp",
6060
generics: LifetimeBounds::empty(),
6161
explicit_self: borrowed_explicit_self(),
62-
args: vec![borrowed_self()],
62+
args: vec![(borrowed_self(), "other")],
6363
ret_ty,
6464
attributes: attrs,
6565
is_unsafe: false,
@@ -123,7 +123,7 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
123123
}
124124

125125
pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
126-
let test_id = cx.ident_of("__cmp");
126+
let test_id = cx.ident_of("cmp").gensym();
127127
let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
128128
let ordering_expr = cx.expr_path(ordering.clone());
129129
let equals_expr = cx.expr_some(span, ordering_expr);
@@ -138,9 +138,9 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<
138138
// ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {
139139
// ...
140140
// }
141-
// __cmp => __cmp
141+
// cmp => cmp
142142
// },
143-
// __cmp => __cmp
143+
// cmp => cmp
144144
// }
145145
//
146146
cs_fold(// foldr nests the if-elses correctly, leaving the first field
@@ -149,7 +149,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<
149149
|cx, span, old, self_f, other_fs| {
150150
// match new {
151151
// Some(::std::cmp::Ordering::Equal) => old,
152-
// __cmp => __cmp
152+
// cmp => cmp
153153
// }
154154

155155
let new = {

src/libsyntax_ext/deriving/debug.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn expand_deriving_debug(cx: &mut ExtCtxt,
4040
name: "fmt",
4141
generics: LifetimeBounds::empty(),
4242
explicit_self: borrowed_explicit_self(),
43-
args: vec![fmtr],
43+
args: vec![(fmtr, "f")],
4444
ret_ty: Literal(path_std!(cx, fmt::Result)),
4545
attributes: Vec::new(),
4646
is_unsafe: false,
@@ -70,7 +70,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E
7070
// We want to make sure we have the ctxt set so that we can use unstable methods
7171
let span = span.with_ctxt(cx.backtrace());
7272
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
73-
let builder = Ident::from_str("__debug_trait_builder");
73+
let builder = Ident::from_str("debug_trait_builder").gensym();
7474
let builder_expr = cx.expr_ident(span, builder.clone());
7575

7676
let fmt = substr.nonself_args[0].clone();

src/libsyntax_ext/deriving/decodable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
6767
PathKind::Global)])],
6868
},
6969
explicit_self: None,
70-
args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
71-
Borrowed(None, Mutability::Mutable))],
70+
args: vec![(Ptr(Box::new(Literal(Path::new_local(typaram))),
71+
Borrowed(None, Mutability::Mutable)), "d")],
7272
ret_ty:
7373
Literal(Path::new_(pathvec_std!(cx, result::Result),
7474
None,

src/libsyntax_ext/deriving/encodable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
148148
],
149149
},
150150
explicit_self: borrowed_explicit_self(),
151-
args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
152-
Borrowed(None, Mutability::Mutable))],
151+
args: vec![(Ptr(Box::new(Literal(Path::new_local(typaram))),
152+
Borrowed(None, Mutability::Mutable)), "s")],
153153
ret_ty: Literal(Path::new_(
154154
pathvec_std!(cx, result::Result),
155155
None,

src/libsyntax_ext/deriving/generic/mod.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub struct MethodDef<'a> {
252252
pub explicit_self: Option<Option<PtrTy<'a>>>,
253253

254254
/// Arguments other than the self argument
255-
pub args: Vec<Ty<'a>>,
255+
pub args: Vec<(Ty<'a>, &'a str)>,
256256

257257
/// Return type
258258
pub ret_ty: Ty<'a>,
@@ -915,9 +915,9 @@ impl<'a> MethodDef<'a> {
915915
explicit_self
916916
});
917917

918-
for (i, ty) in self.args.iter().enumerate() {
918+
for (ty, name) in self.args.iter() {
919919
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
920-
let ident = cx.ident_of(&format!("__arg_{}", i));
920+
let ident = cx.ident_of(name).gensym();
921921
arg_tys.push((ident, ast_ty));
922922

923923
let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -1004,10 +1004,10 @@ impl<'a> MethodDef<'a> {
10041004
///
10051005
/// // equivalent to:
10061006
/// impl PartialEq for A {
1007-
/// fn eq(&self, __arg_1: &A) -> bool {
1007+
/// fn eq(&self, other: &A) -> bool {
10081008
/// match *self {
10091009
/// A {x: ref __self_0_0, y: ref __self_0_1} => {
1010-
/// match *__arg_1 {
1010+
/// match *other {
10111011
/// A {x: ref __self_1_0, y: ref __self_1_1} => {
10121012
/// __self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1)
10131013
/// }
@@ -1020,10 +1020,10 @@ impl<'a> MethodDef<'a> {
10201020
/// // or if A is repr(packed) - note fields are matched by-value
10211021
/// // instead of by-reference.
10221022
/// impl PartialEq for A {
1023-
/// fn eq(&self, __arg_1: &A) -> bool {
1023+
/// fn eq(&self, other: &A) -> bool {
10241024
/// match *self {
10251025
/// A {x: __self_0_0, y: __self_0_1} => {
1026-
/// match __arg_1 {
1026+
/// match other {
10271027
/// A {x: __self_1_0, y: __self_1_1} => {
10281028
/// __self_0_0.eq(&__self_1_0) && __self_0_1.eq(&__self_1_1)
10291029
/// }
@@ -1134,14 +1134,14 @@ impl<'a> MethodDef<'a> {
11341134
/// // is equivalent to
11351135
///
11361136
/// impl PartialEq for A {
1137-
/// fn eq(&self, __arg_1: &A) -> ::bool {
1138-
/// match (&*self, &*__arg_1) {
1137+
/// fn eq(&self, other: &A) -> ::bool {
1138+
/// match (&*self, &*other) {
11391139
/// (&A1, &A1) => true,
11401140
/// (&A2(ref self_0),
11411141
/// &A2(ref __arg_1_0)) => (*self_0).eq(&(*__arg_1_0)),
11421142
/// _ => {
11431143
/// let __self_vi = match *self { A1(..) => 0, A2(..) => 1 };
1144-
/// let __arg_1_vi = match *__arg_1 { A1(..) => 0, A2(..) => 1 };
1144+
/// let __arg_1_vi = match *other { A1(..) => 0, A2(..) => 1 };
11451145
/// false
11461146
/// }
11471147
/// }
@@ -1240,7 +1240,7 @@ impl<'a> MethodDef<'a> {
12401240
let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
12411241
.map(|name| {
12421242
let vi_suffix = format!("{}_vi", &name[..]);
1243-
cx.ident_of(&vi_suffix[..])
1243+
cx.ident_of(&vi_suffix[..]).gensym()
12441244
})
12451245
.collect::<Vec<ast::Ident>>();
12461246

@@ -1616,7 +1616,7 @@ impl<'a> TraitDef<'a> {
16161616
let mut ident_exprs = Vec::new();
16171617
for (i, struct_field) in struct_def.fields().iter().enumerate() {
16181618
let sp = struct_field.span.with_ctxt(self.span.ctxt());
1619-
let ident = cx.ident_of(&format!("{}_{}", prefix, i));
1619+
let ident = cx.ident_of(&format!("{}_{}", prefix, i)).gensym();
16201620
paths.push(ident.with_span_pos(sp));
16211621
let val = cx.expr_path(cx.path_ident(sp, ident));
16221622
let val = if use_temporaries {

src/libsyntax_ext/deriving/hash.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
4444
bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])],
4545
},
4646
explicit_self: borrowed_explicit_self(),
47-
args: vec![Ptr(Box::new(Literal(arg)),
48-
Borrowed(None, Mutability::Mutable))],
47+
args: vec![(Ptr(Box::new(Literal(arg)),
48+
Borrowed(None, Mutability::Mutable)), "state")],
4949
ret_ty: nil_ty(),
5050
attributes: vec![],
5151
is_unsafe: false,

src/libsyntax_ext/format.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,10 @@ impl<'a, 'b> Context<'a, 'b> {
543543
let mut pats = Vec::new();
544544
let mut heads = Vec::new();
545545

546+
let names_pos: Vec<_> = (0..self.args.len()).map(|i| {
547+
self.ecx.ident_of(&format!("arg{}", i)).gensym()
548+
}).collect();
549+
546550
// First, build up the static array which will become our precompiled
547551
// format "string"
548552
let pieces = self.ecx.expr_vec_slice(self.fmtsp, self.str_pieces);
@@ -560,7 +564,7 @@ impl<'a, 'b> Context<'a, 'b> {
560564
// of each variable because we don't want to move out of the arguments
561565
// passed to this function.
562566
for (i, e) in self.args.into_iter().enumerate() {
563-
let name = self.ecx.ident_of(&format!("__arg{}", i));
567+
let name = names_pos[i];
564568
let span =
565569
DUMMY_SP.with_ctxt(e.span.ctxt().apply_mark(self.ecx.current_expansion.mark));
566570
pats.push(self.ecx.pat_ident(span, name));
@@ -570,14 +574,12 @@ impl<'a, 'b> Context<'a, 'b> {
570574
heads.push(self.ecx.expr_addr_of(e.span, e));
571575
}
572576
for pos in self.count_args {
573-
let name = self.ecx.ident_of(&match pos {
574-
Exact(i) => format!("__arg{}", i),
575-
_ => panic!("should never happen"),
576-
});
577-
let span = match pos {
578-
Exact(i) => spans_pos[i],
577+
let index = match pos {
578+
Exact(i) => i,
579579
_ => panic!("should never happen"),
580580
};
581+
let name = names_pos[index];
582+
let span = spans_pos[index];
581583
counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count, name));
582584
}
583585

src/libsyntax_pos/symbol.rs

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ impl Ident {
5353
pub fn modern(self) -> Ident {
5454
Ident::new(self.name, self.span.modern())
5555
}
56+
57+
pub fn gensym(self) -> Ident {
58+
Ident::new(self.name.gensymed(), self.span)
59+
}
5660
}
5761

5862
impl PartialEq for Ident {

src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn expand_deriving_partial_eq(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, it
5858
name: "eq",
5959
generics: LifetimeBounds::empty(),
6060
explicit_self: borrowed_explicit_self(),
61-
args: vec![borrowed_self()],
61+
args: vec![(borrowed_self(), "other")],
6262
ret_ty: Literal(deriving::generic::ty::Path::new_local("bool")),
6363
attributes: attrs,
6464
is_unsafe: false,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_private)]
12+
extern crate serialize;
13+
14+
pub const other: u8 = 1;
15+
pub const f: u8 = 1;
16+
pub const d: u8 = 1;
17+
pub const s: u8 = 1;
18+
pub const state: u8 = 1;
19+
pub const cmp: u8 = 1;
20+
21+
#[derive(Ord,Eq,PartialOrd,PartialEq,Debug,Decodable,Encodable,Hash)]
22+
struct Foo {}
23+
24+
fn main() {
25+
}

src/test/run-pass/format-hygiene.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub const arg0: u8 = 1;
12+
13+
pub fn main() {
14+
format!("{}", 1);
15+
}

0 commit comments

Comments
 (0)