]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #63462 - matthewjasper:hygienic-builtin-derives, r=petrochenkov
authorbors <bors@rust-lang.org>
Sat, 17 Aug 2019 12:53:53 +0000 (12:53 +0000)
committerbors <bors@rust-lang.org>
Sat, 17 Aug 2019 12:53:53 +0000 (12:53 +0000)
Opaque builtin derive macros

* Buiilt-in derives are now opaque macros
    * This required limiting the visibility of some previously unexposed functions in `core`.
    * This also required the change to `Ident` serialization.
* All gensyms are replaced with hygienic identifiers
* Use hygiene to avoid most other name-resolution issues with buiilt-in derives.
    *  As far as I know the only remaining case that breaks is an ADT that has the same name as one of its parameters. Fixing this completely seemed to be more effort than it's worth.
* Remove gensym in `Ident::decode`, which lead to linker errors due to `inline` being gensymmed.
    * `Ident`now panics if incremental compilation tries to serialize it (it currently doesn't).
    * `Ident` no longer uses `gensym` to emulate cross-crate hygiene. It only applied to reexports.
    * `SyntaxContext` is no longer serializable.
    * The long-term fix for this is to properly implement cross-crate hygiene, but this seemed to be acceptable for now.
* Move type/const parameter shadowing checks to `resolve`
    * This was previously split between resolve and type checking. The type checking pass compared `InternedString`s, not Identifiers.
* Removed the `SyntaxContext` from `{ast, hir}::{InlineAsm, GlobalAsm}`

cc #60869
r? @petrochenkov

49 files changed:
src/bootstrap/bin/rustc.rs
src/libcore/clone.rs
src/libcore/cmp.rs
src/libcore/default.rs
src/libcore/fmt/builders.rs
src/libcore/fmt/mod.rs
src/libcore/hash/mod.rs
src/libcore/macros.rs
src/libcore/marker.rs
src/librustc/hir/lowering/expr.rs
src/librustc/hir/lowering/item.rs
src/librustc/hir/mod.rs
src/librustc_codegen_llvm/asm.rs
src/librustc_codegen_ssa/mir/statement.rs
src/librustc_codegen_ssa/traits/asm.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/error_codes.rs
src/librustc_resolve/late.rs
src/librustc_resolve/lib.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/error_codes.rs
src/libsyntax/ast.rs
src/libsyntax/mut_visit.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/deriving/cmp/ord.rs
src/libsyntax_ext/deriving/cmp/partial_ord.rs
src/libsyntax_ext/deriving/debug.rs
src/libsyntax_ext/deriving/decodable.rs
src/libsyntax_ext/deriving/encodable.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/deriving/hash.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/global_asm.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/symbol.rs
src/test/ui/derives/derive-hygiene.rs [new file with mode: 0644]
src/test/ui/duplicate/duplicate-type-parameter.stderr
src/test/ui/error-codes/E0194.rs
src/test/ui/error-codes/E0194.stderr
src/test/ui/error-codes/E0403.stderr
src/test/ui/hygiene/auxiliary/codegen-attrs.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-codegen-attrs.rs [new file with mode: 0644]
src/test/ui/rfc1598-generic-associated-types/shadowing.rs
src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
src/test/ui/shadowed/shadowed-type-parameter.rs
src/test/ui/shadowed/shadowed-type-parameter.stderr

index da372781738d66e7a2ecf94c10ce618b214d8ecb..ce92ce026967117016ab27620dafaad86770e207 100644 (file)
@@ -37,7 +37,7 @@ fn main() {
             let mut new = None;
             if let Some(current_as_str) = args[i].to_str() {
                 if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) ||
-                   current_as_str.starts_with("-Cmetadata") {
+                    current_as_str.starts_with("-Cmetadata") {
                     new = Some(format!("{}-{}", current_as_str, s));
                 }
             }
@@ -89,7 +89,7 @@ fn main() {
     if let Some(crate_name) = crate_name {
         if let Some(target) = env::var_os("RUSTC_TIME") {
             if target == "all" ||
-               target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
+                target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
             {
                 cmd.arg("-Ztime");
             }
index ec22a7ccfe4c34c9ecc470a798cb3f6f12056cd0..ec70d396e966d586fcdb1ff2893de24943f85353 100644 (file)
@@ -135,7 +135,7 @@ fn clone_from(&mut self, source: &Self) {
 
 /// Derive macro generating an impl of the trait `Clone`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
 pub macro Clone($item:item) { /* compiler built-in */ }
index b802216036b9336c5ee803ece9b8c1b7ec0e8b8d..cb9feb074dd70d58d51c1b95da226ce662ea16eb 100644 (file)
@@ -202,7 +202,7 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 
 /// Derive macro generating an impl of the trait `PartialEq`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro PartialEq($item:item) { /* compiler built-in */ }
@@ -265,7 +265,7 @@ fn assert_receiver_is_total_eq(&self) {}
 
 /// Derive macro generating an impl of the trait `Eq`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_eq)]
 pub macro Eq($item:item) { /* compiler built-in */ }
@@ -616,7 +616,7 @@ fn clamp(self, min: Self, max: Self) -> Self
 
 /// Derive macro generating an impl of the trait `Ord`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro Ord($item:item) { /* compiler built-in */ }
@@ -865,7 +865,7 @@ fn ge(&self, other: &Rhs) -> bool {
 
 /// Derive macro generating an impl of the trait `PartialOrd`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro PartialOrd($item:item) { /* compiler built-in */ }
index 9b1616ccce448885720571e065d51a7da149d769..66acc5165fc5b9ad9b2fa3714225a664da3c71cd 100644 (file)
@@ -117,7 +117,7 @@ pub trait Default: Sized {
 
 /// Derive macro generating an impl of the trait `Default`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro Default($item:item) { /* compiler built-in */ }
index cb4e32622ff1f6a169725e06651d918fb02f8cf2..15ce2277fa00d9188aad74dc7043f72faa149a3e 100644 (file)
@@ -98,7 +98,7 @@ pub struct DebugStruct<'a, 'b: 'a> {
     has_fields: bool,
 }
 
-pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
+pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
                                 name: &str)
                                 -> DebugStruct<'a, 'b> {
     let result = fmt.write_str(name);
@@ -251,7 +251,10 @@ pub struct DebugTuple<'a, 'b: 'a> {
     empty_name: bool,
 }
 
-pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
+pub(super) fn debug_tuple_new<'a, 'b>(
+    fmt: &'a mut fmt::Formatter<'b>,
+    name: &str,
+) -> DebugTuple<'a, 'b> {
     let result = fmt.write_str(name);
     DebugTuple {
         fmt,
@@ -418,7 +421,7 @@ pub struct DebugSet<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
+pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
     let result = fmt.write_str("{");
     DebugSet {
         inner: DebugInner {
@@ -555,7 +558,7 @@ pub struct DebugList<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
+pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
     let result = fmt.write_str("[");
     DebugList {
         inner: DebugInner {
@@ -697,7 +700,7 @@ pub struct DebugMap<'a, 'b: 'a> {
     state: PadAdapterState,
 }
 
-pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
+pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
     let result = fmt.write_str("{");
     DebugMap {
         fmt,
index d5fae9e74013663ca079cf203ca857b81f57c481..bd31d25dd034b2063c33b665e9e3d63e50e159cd 100644 (file)
@@ -549,7 +549,7 @@ pub trait Debug {
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Debug`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro Debug($item:item) { /* compiler built-in */ }
index b3971191123901307a98c12bfca26b595b1f1437..bf3daa32840d85cb598ee4e0d1ec6ad34be98e1a 100644 (file)
@@ -202,7 +202,7 @@ fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Hash`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro Hash($item:item) { /* compiler built-in */ }
index e114f3af0c5155bb5d75dbc024d02b177a3fb86c..6c88a766a2f10eb39eb7c5096b81bd2e78e1f936 100644 (file)
@@ -1263,14 +1263,14 @@ macro_rules! trace_macros {
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
     pub macro RustcDecodable($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro RustcEncodable($item:item) { /* compiler built-in */ }
index 3befd421b0125e54995c2d882b2f03e3116e483b..89af2528c052a2dea2b2e8834ccca0c9bc191714 100644 (file)
@@ -290,7 +290,7 @@ pub trait Copy : Clone {
 
 /// Derive macro generating an impl of the trait `Copy`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
 pub macro Copy($item:item) { /* compiler built-in */ }
index 4ba61e9d4fdc8ad8deb8c6b9557c565fe17e5781..ff0c44a23874bfa96bd824625fc1e162583416de 100644 (file)
@@ -984,7 +984,6 @@ fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind {
             volatile: asm.volatile,
             alignstack: asm.alignstack,
             dialect: asm.dialect,
-            ctxt: asm.ctxt,
         };
 
         let outputs = asm.outputs
index 51a0c4184f9ef86ffd455ff507d5ea0516404fc4..4f9a9ed5673c7acc83d363e43d27943ecae58291 100644 (file)
@@ -750,10 +750,7 @@ fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
     }
 
     fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
-        P(hir::GlobalAsm {
-            asm: ga.asm,
-            ctxt: ga.ctxt,
-        })
+        P(hir::GlobalAsm { asm: ga.asm })
     }
 
     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
index 57fd0be77ecff108c5dd4c56598a77170fe5c786..e5ada1fb9aec4b5df22ee3f76bdb654026242c8f 100644 (file)
@@ -23,7 +23,6 @@
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
 use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::{InlineAttr, OptimizeAttr};
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::symbol::{Symbol, kw};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
@@ -2004,8 +2003,6 @@ pub struct InlineAsm {
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
-    #[stable_hasher(ignore)] // This is used for error reporting
-    pub ctxt: SyntaxContext,
 }
 
 /// Represents an argument in a function header.
@@ -2184,8 +2181,6 @@ pub struct ForeignMod {
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GlobalAsm {
     pub asm: Symbol,
-    #[stable_hasher(ignore)] // This is used for error reporting
-    pub ctxt: SyntaxContext,
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
index 9763d523a2ac405ecf1d75261c378893e557d91d..b68ee2cb44d4bcb9cf02a5bab742f596bff1cdcf 100644 (file)
@@ -6,9 +6,9 @@
 
 use rustc::hir;
 use rustc_codegen_ssa::traits::*;
-
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::mir::operand::OperandValue;
+use syntax_pos::Span;
 
 use std::ffi::{CStr, CString};
 use libc::{c_uint, c_char};
@@ -19,7 +19,8 @@ fn codegen_inline_asm(
         &mut self,
         ia: &hir::InlineAsm,
         outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
-        mut inputs: Vec<&'ll Value>
+        mut inputs: Vec<&'ll Value>,
+        span: Span,
     ) -> bool {
         let mut ext_constraints = vec![];
         let mut output_types = vec![];
@@ -102,7 +103,7 @@ fn codegen_inline_asm(
             let kind = llvm::LLVMGetMDKindIDInContext(self.llcx,
                 key.as_ptr() as *const c_char, key.len() as c_uint);
 
-            let val: &'ll Value = self.const_i32(ia.ctxt.outer_expn().as_u32() as i32);
+            let val: &'ll Value = self.const_i32(span.ctxt().outer_expn().as_u32() as i32);
 
             llvm::LLVMSetMetadata(r, kind,
                 llvm::LLVMMDNodeInContext(self.llcx, &val, 1));
index 3717be4b4175338fb1200a4f36c999ae50bd90c3..3617f3afaae4148a37224672b6b9374f35e7ec00 100644 (file)
@@ -89,7 +89,12 @@ pub fn codegen_statement(
                 });
 
                 if input_vals.len() == asm.inputs.len() {
-                    let res = bx.codegen_inline_asm(&asm.asm, outputs, input_vals);
+                    let res = bx.codegen_inline_asm(
+                        &asm.asm,
+                        outputs,
+                        input_vals,
+                        statement.source_info.span,
+                    );
                     if !res {
                         span_err!(bx.sess(), statement.source_info.span, E0668,
                                   "malformed inline assembly");
index fd3c868bbc50727251cf12ab6f1569ef1d8f7614..c9e1ed86e97e0ff37159fc8c746be8bc3e837950 100644 (file)
@@ -1,6 +1,7 @@
 use super::BackendTypes;
 use crate::mir::place::PlaceRef;
 use rustc::hir::{GlobalAsm, InlineAsm};
+use syntax_pos::Span;
 
 pub trait AsmBuilderMethods<'tcx>: BackendTypes {
     /// Take an inline assembly expression and splat it out via LLVM
@@ -9,6 +10,7 @@ fn codegen_inline_asm(
         ia: &InlineAsm,
         outputs: Vec<PlaceRef<'tcx, Self::Value>>,
         inputs: Vec<Self::Value>,
+        span: Span,
     ) -> bool;
 }
 
index 0bec31d70765f7c786db98fd8c83795672fc0c11..772b2d3ec4d85264d3dea721a7b56b1ba70f1c4e 100644 (file)
@@ -348,6 +348,14 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
     }
 }
 
+impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
+    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
+        // FIXME(jseyfried): intercrate hygiene
+
+        Ok(Ident::with_dummy_span(Symbol::decode(self)?))
+    }
+}
+
 impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
         Fingerprint::decode_opaque(&mut self.opaque)
index fb675d7d841e1bbb6938f09bc6199a0293527dbc..e2de0552cd651d6a2e26482d0724adf8d1aea553 100644 (file)
@@ -31,7 +31,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
 use syntax_pos::{self, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -173,6 +173,13 @@ fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
     }
 }
 
+impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
+    fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
+        // FIXME(jseyfried): intercrate hygiene
+        ident.name.encode(self)
+    }
+}
+
 impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
     #[inline]
     fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
index afdcec19d8ef6014f8a190bb8a742cf3c9df5ae8..b79e0c2bd3b2672257f12aacd1cbc652b7a86fad 100644 (file)
@@ -169,12 +169,14 @@ impl<'a> Resolver<'a> {
                 err
             }
             ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
-                let mut err = struct_span_err!(self.session,
-                                                span,
-                                                E0403,
-                                                "the name `{}` is already used for a generic \
-                                                parameter in this list of generic parameters",
-                                                name);
+                let mut err = struct_span_err!(
+                    self.session,
+                    span,
+                    E0403,
+                    "the name `{}` is already used for a generic \
+                     parameter in this item's generic parameters",
+                    name,
+                );
                 err.span_label(span, "already used");
                 err.span_label(first_use_span, format!("first use of `{}`", name));
                 err
index e01f53786edab2cd3a239c928fda288f0c4e10cd..1faaf97e981c14fed761bb802019e1098eb264b4 100644 (file)
@@ -526,15 +526,25 @@ fn bar(&self, y: T) {
 Erroneous code example:
 
 ```compile_fail,E0403
-fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
-                            //        parameter in this type parameter list
+fn f<T, T>(s: T, u: T) {} // error: the name `T` is already used for a generic
+                          //        parameter in this item's generic parameters
 ```
 
 Please verify that none of the type parameters are misspelled, and rename any
 clashing parameters. Example:
 
 ```
-fn foo<T, Y>(s: T, u: Y) {} // ok!
+fn f<T, Y>(s: T, u: Y) {} // ok!
+```
+
+Type parameters in an associated item also cannot shadow parameters from the
+containing item:
+
+```compile_fail,E0403
+trait Foo<T> {
+    fn do_something(&self) -> T;
+    fn do_something_else<T: Clone>(&self, bar: T);
+}
 ```
 "##,
 
index d8bd86699b7af966982543c6143c77599f8d110d..e15d02a9f7ec7abcd69bc082aaf9a6ecd9b64a0b 100644 (file)
@@ -111,6 +111,24 @@ fn descr(self) -> &'static str {
     TyParamAsConstParamTy,
 }
 
+impl RibKind<'_> {
+    // Whether this rib kind contains generic parameters, as opposed to local
+    // variables.
+    crate fn contains_params(&self) -> bool {
+        match self {
+            NormalRibKind
+            | FnItemRibKind
+            | ConstantItemRibKind
+            | ModuleRibKind(_)
+            | MacroDefinition(_) => false,
+            AssocItemRibKind
+            | ItemRibKind
+            | ForwardTyParamBanRibKind
+            | TyParamAsConstParamTy => true,
+        }
+    }
+}
+
 /// A single local scope.
 ///
 /// A rib represents a scope names can live in. Note that these appear in many places, not just
@@ -798,6 +816,19 @@ fn with_generic_param_rib<'c, F>(&'c mut self, generic_params: GenericParameters
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut function_value_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap::default();
+                // We also can't shadow bindings from the parent item
+                if let AssocItemRibKind = rib_kind {
+                    let mut add_bindings_for_ns = |ns| {
+                        let parent_rib = self.ribs[ns].iter()
+                            .rfind(|rib| if let ItemRibKind = rib.kind { true } else { false })
+                            .expect("associated item outside of an item");
+                        seen_bindings.extend(
+                            parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span)),
+                        );
+                    };
+                    add_bindings_for_ns(ValueNS);
+                    add_bindings_for_ns(TypeNS);
+                }
                 for param in &generics.params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {}
index 12c4f5bfe8e617f8fb538d147c4297ae4d55a279..984473d781e62c0355611f1685d9932a8f6ab173 100644 (file)
@@ -1499,7 +1499,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
             debug!("walk rib\n{:?}", ribs[i].bindings);
             // Use the rib kind to determine whether we are resolving parameters
             // (modern hygiene) or local variables (legacy hygiene).
-            let rib_ident = if let AssocItemRibKind | ItemRibKind = ribs[i].kind {
+            let rib_ident = if ribs[i].kind.contains_params() {
                 modern_ident
             } else {
                 ident
index b2c0e34d6fad7638dc19ad0c01629db0e7520cb8..28a1ccda4d84187f334fb4c3facbddbba8c8ea86 100644 (file)
@@ -203,7 +203,6 @@ fn check_associated_item(
                 fcx.register_wf_obligation(ty, span, code.clone());
             }
             ty::AssocKind::Method => {
-                reject_shadowing_parameters(fcx.tcx, item.def_id);
                 let sig = fcx.tcx.fn_sig(item.def_id);
                 let sig = fcx.normalize_associated_types_in(span, &sig);
                 check_fn_or_method(tcx, fcx, span, sig,
@@ -998,34 +997,6 @@ fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) {
     err.emit();
 }
 
-fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) {
-    let generics = tcx.generics_of(def_id);
-    let parent = tcx.generics_of(generics.parent.unwrap());
-    let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
-        GenericParamDefKind::Lifetime => None,
-        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
-            Some((param.name, param.def_id))
-        }
-    }).collect();
-
-    for method_param in &generics.params {
-        // Shadowing is checked in `resolve_lifetime`.
-        if let GenericParamDefKind::Lifetime = method_param.kind {
-            continue
-        }
-        if impl_params.contains_key(&method_param.name) {
-            // Tighten up the span to focus on only the shadowing type.
-            let type_span = tcx.def_span(method_param.def_id);
-
-            // The expectation here is that the original trait declaration is
-            // local so it should be okay to just unwrap everything.
-            let trait_def_id = impl_params[&method_param.name];
-            let trait_decl_span = tcx.def_span(trait_def_id);
-            error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
-        }
-    }
-}
-
 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
 /// aren't true.
 fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
@@ -1152,12 +1123,3 @@ fn error_392(
     err.span_label(span, "unused parameter");
     err
 }
-
-fn error_194(tcx: TyCtxt<'_>, span: Span, trait_decl_span: Span, name: &str) {
-    struct_span_err!(tcx.sess, span, E0194,
-                     "type parameter `{}` shadows another type parameter of the same name",
-                     name)
-        .span_label(span, "shadows another type parameter")
-        .span_label(trait_decl_span, format!("first `{}` declared here", name))
-        .emit();
-}
index 90118a9f191d9d2cc1e5bb897591fefbcb4761f3..ca9ce3d22b5cb0dcb2c3858412dcc0386147dab2 100644 (file)
@@ -1718,22 +1718,6 @@ fn bar(&self) { }
 reason to also specify it in a `where` clause.
 "##,
 
-E0194: r##"
-A type parameter was declared which shadows an existing one. An example of this
-error:
-
-```compile_fail,E0194
-trait Foo<T> {
-    fn do_something(&self) -> T;
-    fn do_something_else<T: Clone>(&self, bar: T);
-}
-```
-
-In this example, the trait `Foo` and the trait method `do_something_else` both
-define a type parameter `T`. This is not allowed: if the method wishes to
-define a type parameter, it must use a different name for it.
-"##,
-
 E0195: r##"
 Your method's lifetime parameters do not match the trait declaration.
 Erroneous code example:
@@ -4837,6 +4821,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
 //  E0188, // can not cast an immutable reference to a mutable pointer
 //  E0189, // deprecated: can only cast a boxed pointer to a boxed object
 //  E0190, // deprecated: can only cast a &-pointer to an &-object
+//  E0194, // merged into E0403
 //  E0196, // cannot determine a type for this closure
     E0203, // type parameter has more than one relaxed default bound,
            // and only one is supported
index 3ae37f734b77ee41cdf1007772460a9505d854ba..9091607629e0fabae7c1938ff9c8c1b8e2a4f926 100644 (file)
@@ -5,7 +5,7 @@
 pub use crate::symbol::{Ident, Symbol as Name};
 pub use crate::util::parser::ExprPrecedence;
 
-use crate::ext::hygiene::{ExpnId, SyntaxContext};
+use crate::ext::hygiene::ExpnId;
 use crate::parse::token::{self, DelimToken};
 use crate::print::pprust;
 use crate::ptr::P;
@@ -1782,7 +1782,6 @@ pub struct InlineAsm {
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
-    pub ctxt: SyntaxContext,
 }
 
 /// An argument in a function header.
@@ -2030,7 +2029,6 @@ pub struct ForeignMod {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub struct GlobalAsm {
     pub asm: Symbol,
-    pub ctxt: SyntaxContext,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
index acafe327640d028a6784bf70534b965c3e2781d9..18d4a6463558d6114041ba2b3802a8f88c6ada90 100644 (file)
@@ -1182,7 +1182,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         }
         ExprKind::InlineAsm(asm) => {
             let InlineAsm { asm: _, asm_str_style: _, outputs, inputs, clobbers: _, volatile: _,
-                            alignstack: _, dialect: _, ctxt: _ } = asm.deref_mut();
+                            alignstack: _, dialect: _ } = asm.deref_mut();
             for out in outputs {
                 let InlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
                 vis.visit_expr(expr);
index 950166f9260e2358f58a6956d2266c28de3ae30f..644a44f1989dbd5d6e75b2628cf80dfd20116f3f 100644 (file)
@@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(inline_asm)),
-        span: sp,
+        span: sp.with_ctxt(cx.backtrace()),
         attrs: ThinVec::new(),
     }))
 }
@@ -277,6 +277,5 @@ fn parse_inline_asm<'a>(
         volatile,
         alignstack,
         dialect,
-        ctxt: cx.backtrace(),
     }))
 }
index 885cfee35658a8bc0e4f9e9035403e7d8626b7fc..55687c3175b9dbfe83f82a5fd4945eb1341522b4 100644 (file)
@@ -43,17 +43,18 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
 }
 
 
-pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
-                          span: Span,
-                          self_arg_tags: &[ast::Ident])
-                          -> P<ast::Expr> {
+pub fn ordering_collapsed(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
-    cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
+    cx.expr_method_call(span, lft, ast::Ident::new(sym::cmp, span), vec![rgt])
 }
 
 pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = cx.ident_of("cmp").gensym();
+    let test_id = ast::Ident::new(sym::cmp, span);
     let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
 
     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<
             // as the outermost one, and the last as the innermost.
             false,
             |cx, span, old, self_f, other_fs| {
-        // match new {
-        //     ::std::cmp::Ordering::Equal => old,
-        //     cmp => cmp
-        // }
+                // match new {
+                //     ::std::cmp::Ordering::Equal => old,
+                //     cmp => cmp
+                // }
 
-        let new = {
-            let other_f = match other_fs {
-                [o_f] => o_f,
-                _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
-            };
+                let new = {
+                    let other_f = match other_fs {
+                        [o_f] => o_f,
+                        _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
+                    };
 
-            let args = vec![
-                    cx.expr_addr_of(span, self_f),
-                    cx.expr_addr_of(span, other_f.clone()),
-                ];
+                    let args = vec![
+                            cx.expr_addr_of(span, self_f),
+                            cx.expr_addr_of(span, other_f.clone()),
+                        ];
 
-            cx.expr_call_global(span, cmp_path.clone(), args)
-        };
+                    cx.expr_call_global(span, cmp_path.clone(), args)
+                };
 
-        let eq_arm = cx.arm(span,
-                            vec![cx.pat_path(span, equals_path.clone())],
-                            old);
-        let neq_arm = cx.arm(span,
-                             vec![cx.pat_ident(span, test_id)],
-                             cx.expr_ident(span, test_id));
+                let eq_arm = cx.arm(span,
+                                    vec![cx.pat_path(span, equals_path.clone())],
+                                    old);
+                let neq_arm = cx.arm(span,
+                                     vec![cx.pat_ident(span, test_id)],
+                                     cx.expr_ident(span, test_id));
 
-        cx.expr_match(span, new, vec![eq_arm, neq_arm])
-    },
+                cx.expr_match(span, new, vec![eq_arm, neq_arm])
+            },
             cx.expr_path(equals_path.clone()),
             Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
         if self_args.len() != 2 {
index 0ec30f5924fbe273ef24129976d51d1222325003..740b92a9b7978bbf9ac21a122bcbf0524450de17 100644 (file)
@@ -94,11 +94,12 @@ pub enum OrderingOp {
     GeOp,
 }
 
-pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
-                               span: Span,
-                               op: OrderingOp,
-                               self_arg_tags: &[ast::Ident])
-                               -> P<ast::Expr> {
+pub fn some_ordering_collapsed(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    op: OrderingOp,
+    self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
     let op_str = match op {
@@ -108,11 +109,11 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
         GtOp => "gt",
         GeOp => "ge",
     };
-    cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
+    cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = cx.ident_of("cmp").gensym();
+    let test_id = ast::Ident::new(sym::cmp, span);
     let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
index 1d5234a9b7b4f90f033208fdb9bb42143a44f358..441535410480b678593f9025868dd0e1c2d84924 100644 (file)
@@ -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
     let span = span.with_ctxt(cx.backtrace());
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
-    let builder = Ident::from_str("debug_trait_builder").gensym();
+    let builder = Ident::from_str_and_span("debug_trait_builder", span);
     let builder_expr = cx.expr_ident(span, builder.clone());
 
     let fmt = substr.nonself_args[0].clone();
@@ -73,7 +73,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
             // tuple struct/"normal" variant
             let expr =
                 cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
-            stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
+            stmts.push(cx.stmt_let(span, true, builder, expr));
 
             for field in fields {
                 // 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<'_>
 
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_dummy_span(sym::field),
+                                                Ident::new(sym::field, span),
                                                 vec![field]);
 
                 // Use `let _ = expr;` to avoid triggering the
@@ -106,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
                 let field = cx.expr_addr_of(field.span, field);
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_dummy_span(sym::field),
+                                                Ident::new(sym::field, span),
                                                 vec![name, field]);
                 stmts.push(stmt_let_undescore(cx, span, expr));
             }
index 293c5a1e7e71b867bed4c2dccdba687f8c93fca9..9b6f8518de046dc16e2049aa593150d06ed5909f 100644 (file)
@@ -1,6 +1,6 @@
-//! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
+//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
 
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
 use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
@@ -17,7 +17,7 @@ pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt<'_>,
                                        item: &Annotatable,
                                        push: &mut dyn FnMut(Annotatable)) {
     let krate = "rustc_serialize";
-    let typaram = &*deriving::hygienic_type_parameter(item, "__D");
+    let typaram = "__D";
 
     let trait_def = TraitDef {
         span,
index 52e74a7c57e8ca26bed7c06ef98c420a9b595e70..8b18fb25e90c121e7bea4120927c5f5111d3f483 100644 (file)
@@ -1,11 +1,12 @@
-//! The compiler code necessary to implement the `#[derive(Encodable)]`
-//! (and `Decodable`, in `decodable.rs`) extension. The idea here is that
-//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
+//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
+//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
+//! type-defining items may be tagged with
+//! `#[derive(RustcEncodable, RustcDecodable)]`.
 //!
 //! For example, a type like:
 //!
 //! ```
-//! #[derive(Encodable, Decodable)]
+//! #[derive(RustcEncodable, RustcDecodable)]
 //! struct Node { id: usize }
 //! ```
 //!
 //! references other non-built-in types. A type definition like:
 //!
 //! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
-//! #[derive(Encodable, Decodable)]
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
+//! #[derive(RustcEncodable, RustcDecodable)]
 //! struct Spanned<T> { node: T, span: Span }
 //! ```
 //!
 //! would yield functions like:
 //!
 //! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
 //! # struct Spanned<T> { node: T, span: Span }
 //! impl<
 //!     S: Encoder<E>,
@@ -82,7 +85,7 @@
 //! }
 //! ```
 
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
 use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
@@ -98,7 +101,7 @@ pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt<'_>,
                                        item: &Annotatable,
                                        push: &mut dyn FnMut(Annotatable)) {
     let krate = "rustc_serialize";
-    let typaram = &*deriving::hygienic_type_parameter(item, "__S");
+    let typaram = "__S";
 
     let trait_def = TraitDef {
         span,
index 55fb7677038ba6223b38d05e71dc1d0f38384a5c..1475bac0688460444c50fe5f7688048251c813b8 100644 (file)
@@ -890,7 +890,7 @@ fn split_self_nonself_args
 
         for (ty, name) in self.args.iter() {
             let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
-            let ident = cx.ident_of(name).gensym();
+            let ident = ast::Ident::from_str_and_span(name, trait_.span);
             arg_tys.push((ident, ast_ty));
 
             let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -1210,7 +1210,7 @@ fn build_enum_match_tuple<'b>(&self,
         let vi_idents = self_arg_names.iter()
             .map(|name| {
                 let vi_suffix = format!("{}_vi", &name[..]);
-                cx.ident_of(&vi_suffix[..]).gensym()
+                ast::Ident::from_str_and_span(&vi_suffix[..], trait_.span)
             })
             .collect::<Vec<ast::Ident>>();
 
@@ -1387,7 +1387,10 @@ fn build_enum_match_tuple<'b>(&self,
                 let variant_value =
                     deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
 
-                let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
+                let target_ty = cx.ty_ident(
+                    sp,
+                    ast::Ident::from_str_and_span(target_type_name, sp),
+                );
                 let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
                 let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
                 index_let_stmts.push(let_stmt);
@@ -1588,7 +1591,7 @@ fn create_struct_pattern
         let mut ident_exprs = Vec::new();
         for (i, struct_field) in struct_def.fields().iter().enumerate() {
             let sp = struct_field.span.with_ctxt(self.span.ctxt());
-            let ident = cx.ident_of(&format!("{}_{}", prefix, i)).gensym();
+            let ident = ast::Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
             paths.push(ident.with_span_pos(sp));
             let val = cx.expr_path(cx.path_ident(sp, ident));
             let val = if use_temporaries {
index 399829eaefd14be930e2e48b78e03a30b341a7e0..7fcf036fc817690de2c57b082cd317dc8ae68918 100644 (file)
@@ -72,7 +72,7 @@ pub fn to_path(&self,
                    self_ty: Ident,
                    self_generics: &Generics)
                    -> ast::Path {
-        let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
+        let mut idents = self.path.iter().map(|s| Ident::from_str_and_span(*s, span)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
         let tys: Vec<P<ast::Ty>> =
             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<'_>,
             cx.trait_bound(path)
         })
         .collect();
-    cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
+    cx.typaram(span, ast::Ident::from_str_and_span(name, span), attrs.to_owned(), bounds, None)
 }
 
 fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
index 9787722e81dd065827da3c6f41a80c14b480219d..2fc594abd705e38290571dbc5a4a3b1fb6e27b21 100644 (file)
@@ -16,7 +16,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>,
 
     let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
 
-    let typaram = &*deriving::hygienic_type_parameter(item, "__H");
+    let typaram = "__H";
 
     let arg = Path::new_local(typaram);
     let hash_trait_def = TraitDef {
index 8cd2853e5383ddb81fccccd982ce99d44f54758f..da68eea0c50e72606f7f845eb8c036749b5163ed 100644 (file)
@@ -54,33 +54,6 @@ fn expand(&self,
     }
 }
 
-/// Construct a name for the inner type parameter that can't collide with any type parameters of
-/// the item. This is achieved by starting with a base and then concatenating the names of all
-/// other type parameters.
-// FIXME(aburka): use real hygiene when that becomes possible
-fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
-    let mut typaram = String::from(base);
-    if let Annotatable::Item(ref item) = *item {
-        match item.node {
-            ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
-            ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
-                for param in params {
-                    match param.kind {
-                        ast::GenericParamKind::Type { .. } => {
-                            typaram.push_str(&param.ident.as_str());
-                        }
-                        _ => {}
-                    }
-                }
-            }
-
-            _ => {}
-        }
-    }
-
-    typaram
-}
-
 /// Constructs an expression that calls an intrinsic
 fn call_intrinsic(cx: &ExtCtxt<'_>,
                   span: Span,
index 112192fac5d26dd79531eaf808eb0e6a479561d7..73ebeaec454975c9e17b237c8c6185c63c41fe6d 100644 (file)
@@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 id: ast::DUMMY_NODE_ID,
                 node: ast::ItemKind::GlobalAsm(P(global_asm)),
                 vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                span: sp,
+                span: sp.with_ctxt(cx.backtrace()),
                 tokens: None,
             })])
         }
@@ -61,8 +61,5 @@ fn parse_global_asm<'a>(
         None => return Ok(None),
     };
 
-    Ok(Some(ast::GlobalAsm {
-        asm,
-        ctxt: cx.backtrace(),
-    }))
+    Ok(Some(ast::GlobalAsm { asm }))
 }
index 87d930f897afc45d817c03c478887b308ddf0980..ebfb0764fa2b2c684f8b8c7db216b686d44f85e1 100644 (file)
@@ -750,15 +750,3 @@ fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
         Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene
     }
 }
-
-impl Encodable for SyntaxContext {
-    fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
-        Ok(()) // FIXME(jseyfried) intercrate hygiene
-    }
-}
-
-impl Decodable for SyntaxContext {
-    fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
-        Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
-    }
-}
index 27fc66d3b09e6b4a6cb2d388e0117f109efa78e0..bed898f10b432ee64e301b8c09231d2cb99298da 100644 (file)
@@ -8,6 +8,7 @@
 use rustc_data_structures::newtype_index;
 use rustc_macros::symbols;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
 
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
 use std::fmt;
@@ -847,28 +848,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl Encodable for Ident {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        if !self.span.modern().from_expansion() {
-            s.emit_str(&self.as_str())
-        } else { // FIXME(jseyfried): intercrate hygiene
-            let mut string = "#".to_owned();
-            string.push_str(&self.as_str());
-            s.emit_str(&string)
-        }
-    }
-}
+impl UseSpecializedEncodable for Ident {}
 
-impl Decodable for Ident {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        let string = d.read_str()?;
-        Ok(if !string.starts_with('#') {
-            Ident::from_str(&string)
-        } else { // FIXME(jseyfried): intercrate hygiene
-            Ident::from_str(&string[1..]).gensym()
-        })
-    }
-}
+impl UseSpecializedDecodable for Ident {}
 
 /// A symbol is an interned or gensymed string. A gensym is a symbol that is
 /// never equal to any other symbol.
diff --git a/src/test/ui/derives/derive-hygiene.rs b/src/test/ui/derives/derive-hygiene.rs
new file mode 100644 (file)
index 0000000..4fa83c4
--- /dev/null
@@ -0,0 +1,121 @@
+// Make sure that built-in derives don't rely on the user not declaring certain
+// names to work properly.
+
+// check-pass
+
+#![allow(nonstandard_style)]
+#![feature(decl_macro)]
+
+use std::prelude::v1::test as inline;
+
+static f: () = ();
+static cmp: () = ();
+static other: () = ();
+static state: () = ();
+static __self_0_0: () = ();
+static __self_1_0: () = ();
+static __self_vi: () = ();
+static __arg_1_0: () = ();
+static debug_trait_builder: () = ();
+
+struct isize;
+trait i16 {}
+
+trait MethodsInDerives: Sized {
+    fn debug_tuple(self) {}
+    fn debug_struct(self) {}
+    fn field(self) {}
+    fn finish(self) {}
+    fn clone(self) {}
+    fn cmp(self) {}
+    fn partial_cmp(self) {}
+    fn eq(self) {}
+    fn ne(self) {}
+    fn le(self) {}
+    fn lt(self) {}
+    fn ge(self) {}
+    fn gt(self) {}
+    fn hash(self) {}
+}
+
+trait GenericAny<T, U> {}
+impl<S, T, U> GenericAny<T, U> for S {}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum __H { V(i32), }
+
+#[repr(i16)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum W { A, B }
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct X<A: GenericAny<A, self::X<i32>>> {
+    A: A,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct Y<B>(B)
+where
+    B: From<B>;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum Z<C> {
+    C(C),
+    B { C: C },
+}
+
+// Make sure that we aren't using `self::` in paths, since it doesn't work in
+// non-module scopes.
+const NON_MODULE: () = {
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum __H { V(i32), }
+
+    #[repr(i16)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum W { A, B }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct X<A: Fn(A) -> self::X<i32>> {
+        A: A,
+    }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct Y<B>(B)
+    where
+        B: From<B>;
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum Z<C> {
+        C(C),
+        B { C: C },
+    }
+};
+
+macro m() {
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum __H { V(i32), }
+
+    #[repr(i16)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum W { A, B }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct X<A: GenericAny<A, self::X<i32>>> {
+        A: A,
+    }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct Y<B>(B)
+    where
+        B: From<B>;
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum Z<C> {
+        C(C),
+        B { C: C },
+    }
+}
+
+m!();
+
+fn main() {}
index 8606479ff6863b9ba905cdca26503916773f4756..6754574f0b953673bbe7034498d4d5445f5e6b67 100644 (file)
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:1:12
    |
 LL | type Foo<T,T> = Option<T>;
@@ -6,7 +6,7 @@ LL | type Foo<T,T> = Option<T>;
    |          |
    |          first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:4:14
    |
 LL | struct Bar<T,T>(T);
@@ -14,7 +14,7 @@ LL | struct Bar<T,T>(T);
    |            |
    |            first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:7:14
    |
 LL | struct Baz<T,T> {
@@ -22,7 +22,7 @@ LL | struct Baz<T,T> {
    |            |
    |            first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:12:12
    |
 LL | enum Boo<T,T> {
@@ -30,7 +30,7 @@ LL | enum Boo<T,T> {
    |          |
    |          first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:18:11
    |
 LL | fn quux<T,T>(x: T) {}
@@ -38,7 +38,7 @@ LL | fn quux<T,T>(x: T) {}
    |         |
    |         first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:21:13
    |
 LL | trait Qux<T,T> {}
@@ -46,7 +46,7 @@ LL | trait Qux<T,T> {}
    |           |
    |           first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:24:8
    |
 LL | impl<T,T> Qux<T,T> for Option<T> {}
index 71eff0e7465a5aefa8a411c0ace14e3c487547a2..8a43f38fcfd5ff159999c51a32c72d4c4fd73b6b 100644 (file)
@@ -1,7 +1,7 @@
 trait Foo<T> {
     fn do_something(&self) -> T;
     fn do_something_else<T: Clone>(&self, bar: T);
-    //~^ ERROR E0194
+    //~^ ERROR E0403
 }
 
 fn main() {
index ab4918a4e27d50d7de8e5c90fafdc0f736f62d3f..f2c908eea0bb094bb4484a11f9cf0056b8913542 100644 (file)
@@ -1,12 +1,12 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/E0194.rs:3:26
    |
 LL | trait Foo<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 LL |     fn do_something(&self) -> T;
 LL |     fn do_something_else<T: Clone>(&self, bar: T);
-   |                          ^ shadows another type parameter
+   |                          ^ already used
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.
index 2bd7de6c24614db39299f9985675f62986882eb1..d76a58a7c80de33bcb13b5b1d00b4f95a9f33fb2 100644 (file)
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/E0403.rs:1:11
    |
 LL | fn foo<T, T>(s: T, u: T) {}
diff --git a/src/test/ui/hygiene/auxiliary/codegen-attrs.rs b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
new file mode 100644 (file)
index 0000000..74afedb
--- /dev/null
@@ -0,0 +1,10 @@
+#![feature(decl_macro)]
+
+macro m($f:ident) {
+    #[export_name = "export_function_name"]
+    pub fn $f() -> i32 {
+        2
+    }
+}
+
+m!(rust_function_name);
diff --git a/src/test/ui/hygiene/cross-crate-codegen-attrs.rs b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs
new file mode 100644 (file)
index 0000000..af6b133
--- /dev/null
@@ -0,0 +1,12 @@
+// Make sure that macro expanded codegen attributes work across crates.
+// We used to gensym the identifiers in attributes, which stopped dependent
+// crates from seeing them, resulting in linker errors in cases like this one.
+
+// run-pass
+// aux-build:codegen-attrs.rs
+
+extern crate codegen_attrs;
+
+fn main() {
+    assert_eq!(codegen_attrs::rust_function_name(), 2);
+}
index 03492631cb7c83335478b990465480917406d931..f5197fd01bfd6cd8a724007ba53e21d13060653d 100644 (file)
@@ -1,12 +1,9 @@
+#![allow(incomplete_features)]
 #![feature(generic_associated_types)]
 
-//FIXME(#44265): The lifetime shadowing and type parameter shadowing
-// should cause an error. Now it compiles (erroneously) and this will be addressed
-// by a future PR. Then remove the following:
-// build-pass (FIXME(62277): could be check-pass?)
-
 trait Shadow<'a> {
-    type Bar<'a>; // Error: shadowed lifetime
+    //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+    type Bar<'a>;
 }
 
 trait NoShadow<'a> {
@@ -14,11 +11,12 @@ trait NoShadow<'a> {
 }
 
 impl<'a> NoShadow<'a> for &'a u32 {
-    type Bar<'a> = i32; // Error: shadowed lifetime
+    //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+    type Bar<'a> = i32;
 }
 
 trait ShadowT<T> {
-    type Bar<T>; // Error: shadowed type parameter
+    type Bar<T>; //~ ERROR the name `T` is already used
 }
 
 trait NoShadowT<T> {
@@ -26,7 +24,7 @@ trait NoShadowT<T> {
 }
 
 impl<T> NoShadowT<T> for Option<T> {
-    type Bar<T> = i32; // Error: shadowed type parameter
+    type Bar<T> = i32; //~ ERROR the name `T` is already used
 }
 
 fn main() {}
index 9526df258c497128ba0ea6adf237e011b8f2d6f1..a06c635084525200067ecf23e0567a74138c379b 100644 (file)
@@ -1,8 +1,19 @@
-warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
-  --> $DIR/shadowing.rs:1:12
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowing.rs:19:14
    |
-LL | #![feature(generic_associated_types)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | trait ShadowT<T> {
+   |               - first use of `T`
+LL |     type Bar<T>;
+   |              ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowing.rs:27:14
    |
-   = note: `#[warn(incomplete_features)]` on by default
+LL | impl<T> NoShadowT<T> for Option<T> {
+   |      - first use of `T`
+LL |     type Bar<T> = i32;
+   |              ^ already used
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0403`.
index ba9f3abcf7adeaef483e7d8f5dec13eb9a25351c..e74620f8900c08922d1bb81abc0ff2788e913d69 100644 (file)
@@ -6,7 +6,7 @@
 
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn not_shadow_in_item<U>(&self) {
         struct Bar<T, U>(T,U); // not a shadow, separate item
@@ -18,10 +18,10 @@ trait Bar<T> {
     fn dummy(&self) -> T;
 
     fn shadow_in_required<T>(&self);
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn shadow_in_provided<T>(&self) {}
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn not_shadow_in_required<U>(&self);
     fn not_shadow_in_provided<U>(&self) {}
index 6b4d1fae3de1801490537cb5f399f49523a16192..0ea82f983f1a70806880925f1b1879e0bff182af 100644 (file)
@@ -1,29 +1,29 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed-type-parameter.rs:8:25
+   |
+LL | impl<T> Foo<T> {
+   |      - first use of `T`
+LL |     fn shadow_in_method<T>(&self) {}
+   |                         ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/shadowed-type-parameter.rs:20:27
    |
 LL | trait Bar<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 ...
 LL |     fn shadow_in_required<T>(&self);
-   |                           ^ shadows another type parameter
+   |                           ^ already used
 
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/shadowed-type-parameter.rs:23:27
    |
 LL | trait Bar<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 ...
 LL |     fn shadow_in_provided<T>(&self) {}
-   |                           ^ shadows another type parameter
-
-error[E0194]: type parameter `T` shadows another type parameter of the same name
-  --> $DIR/shadowed-type-parameter.rs:8:25
-   |
-LL | impl<T> Foo<T> {
-   |      - first `T` declared here
-LL |     fn shadow_in_method<T>(&self) {}
-   |                         ^ shadows another type parameter
+   |                           ^ already used
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.