From 2fd2210b880498829bf1556aee47f3753887ecfa Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 12 Apr 2016 15:41:46 +0200 Subject: [PATCH] prevent other `encode` methods from breaking `derive(RustcEncodable)` --- src/librustc_incremental/persist/data.rs | 4 +-- src/librustc_incremental/persist/directory.rs | 3 +- src/libsyntax_ext/deriving/encodable.rs | 17 ++++++---- .../rustc_encodable_hygiene.rs | 32 +++++++++++++++++++ 4 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs index 8be8bd60b2367..60d644ba7681a 100644 --- a/src/librustc_incremental/persist/data.rs +++ b/src/librustc_incremental/persist/data.rs @@ -11,8 +11,7 @@ //! The data that we will serialize and deserialize. use rustc::dep_graph::DepNode; -use rustc_serialize::{Decoder as RustcDecoder, - Encodable as RustcEncodable, Encoder as RustcEncoder}; +use rustc_serialize::{Decoder as RustcDecoder, Encoder as RustcEncoder}; use super::directory::DefPathIndex; @@ -32,4 +31,3 @@ pub struct SerializedHash { /// the hash itself, computed by `calculate_item_hash` pub hash: u64, } - diff --git a/src/librustc_incremental/persist/directory.rs b/src/librustc_incremental/persist/directory.rs index 0d0054cadc692..7f4c7d919c0cb 100644 --- a/src/librustc_incremental/persist/directory.rs +++ b/src/librustc_incremental/persist/directory.rs @@ -18,8 +18,7 @@ use rustc::hir::map::DefPath; use rustc::hir::def_id::DefId; use rustc::ty; use rustc::util::nodemap::DefIdMap; -use rustc_serialize::{Decoder as RustcDecoder, - Encodable as RustcEncodable, Encoder as RustcEncoder}; +use rustc_serialize::{Decoder as RustcDecoder, Encoder as RustcEncoder}; use std::fmt::{self, Debug}; /// Index into the DefIdDirectory diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index a05bd7869b2a9..6e47f2dd08f6b 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -162,7 +162,7 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt, attributes: Vec::new(), is_unsafe: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { - encodable_substructure(a, b, c) + encodable_substructure(a, b, c, krate) })), } ), @@ -173,12 +173,14 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt, } fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, - substr: &Substructure) -> P { + substr: &Substructure, krate: &'static str) -> P { let encoder = substr.nonself_args[0].clone(); // throw an underscore in front to suppress unused variable warnings let blkarg = cx.ident_of("_e"); let blkencoder = cx.expr_ident(trait_span, blkarg); - let encode = cx.ident_of("encode"); + let fn_path = cx.expr_path(cx.path_global(trait_span, vec![cx.ident_of(krate), + cx.ident_of("Encodable"), + cx.ident_of("encode")])); return match *substr.fields { Struct(_, ref fields) => { @@ -196,8 +198,8 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, token::intern_and_get_ident(&format!("_field{}", i)) } }; - let enc = cx.expr_method_call(span, self_.clone(), - encode, vec!(blkencoder.clone())); + let self_ref = cx.expr_addr_of(span, self_.clone()); + let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]); let lambda = cx.lambda_expr_1(span, enc, blkarg); let call = cx.expr_method_call(span, blkencoder.clone(), emit_struct_field, @@ -245,8 +247,9 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, if !fields.is_empty() { let last = fields.len() - 1; for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() { - let enc = cx.expr_method_call(span, self_.clone(), - encode, vec!(blkencoder.clone())); + let self_ref = cx.expr_addr_of(span, self_.clone()); + let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, + blkencoder.clone()]); let lambda = cx.lambda_expr_1(span, enc, blkarg); let call = cx.expr_method_call(span, blkencoder.clone(), emit_variant_arg, diff --git a/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs b/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs new file mode 100644 index 0000000000000..655b08225ab39 --- /dev/null +++ b/src/test/run-pass-fulldeps/rustc_encodable_hygiene.rs @@ -0,0 +1,32 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_private)] + +#[allow(dead_code)] + +extern crate serialize as rustc_serialize; + +#[derive(RustcDecodable, RustcEncodable,Debug)] +struct A { + a: String, +} + +trait Trait { + fn encode(&self); +} + +impl Trait for T { + fn encode(&self) { + unimplemented!() + } +} + +fn main() {}