Skip to content

Commit

Permalink
Rollup merge of rust-lang#63462 - matthewjasper:hygienic-builtin-deri…
Browse files Browse the repository at this point in the history
…ves, r=petrochenkov

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 rust-lang#60869
r? @petrochenkov
  • Loading branch information
Centril committed Aug 15, 2019
2 parents 7cef357 + 01587b1 commit 3296a0c
Show file tree
Hide file tree
Showing 48 changed files with 361 additions and 272 deletions.
1 change: 0 additions & 1 deletion src/libcore/clone.rs
Expand Up @@ -135,7 +135,6 @@ pub trait Clone : Sized {

/// Derive macro generating an impl of the trait `Clone`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
4 changes: 0 additions & 4 deletions src/libcore/cmp.rs
Expand Up @@ -202,7 +202,6 @@ pub trait PartialEq<Rhs: ?Sized = Self> {

/// Derive macro generating an impl of the trait `PartialEq`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down Expand Up @@ -265,7 +264,6 @@ pub trait Eq: PartialEq<Self> {

/// Derive macro generating an impl of the trait `Eq`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down Expand Up @@ -616,7 +614,6 @@ pub trait Ord: Eq + PartialOrd<Self> {

/// Derive macro generating an impl of the trait `Ord`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down Expand Up @@ -865,7 +862,6 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {

/// Derive macro generating an impl of the trait `PartialOrd`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
1 change: 0 additions & 1 deletion src/libcore/default.rs
Expand Up @@ -117,7 +117,6 @@ pub trait Default: Sized {

/// Derive macro generating an impl of the trait `Default`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
13 changes: 8 additions & 5 deletions src/libcore/fmt/builders.rs
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion src/libcore/fmt/mod.rs
Expand Up @@ -549,7 +549,6 @@ pub trait Debug {
pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Debug`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
1 change: 0 additions & 1 deletion src/libcore/hash/mod.rs
Expand Up @@ -202,7 +202,6 @@ pub trait Hash {
pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Hash`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/macros.rs
Expand Up @@ -1270,14 +1270,12 @@ pub(crate) mod builtin {

/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
#[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"]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
Expand Down
1 change: 0 additions & 1 deletion src/libcore/marker.rs
Expand Up @@ -290,7 +290,6 @@ pub trait Copy : Clone {

/// Derive macro generating an impl of the trait `Copy`.
#[rustc_builtin_macro]
#[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 */ }
Expand Down
1 change: 0 additions & 1 deletion src/librustc/hir/lowering/expr.rs
Expand Up @@ -984,7 +984,6 @@ impl LoweringContext<'_> {
volatile: asm.volatile,
alignstack: asm.alignstack,
dialect: asm.dialect,
ctxt: asm.ctxt,
};

let outputs = asm.outputs
Expand Down
5 changes: 1 addition & 4 deletions src/librustc/hir/lowering/item.rs
Expand Up @@ -750,10 +750,7 @@ impl LoweringContext<'_> {
}

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 {
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/hir/mod.rs
Expand Up @@ -23,7 +23,6 @@ use rustc_target::spec::abi::Abi;
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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)]
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_codegen_llvm/asm.rs
Expand Up @@ -6,9 +6,9 @@ use crate::value::Value;

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};
Expand All @@ -19,7 +19,8 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
&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![];
Expand Down Expand Up @@ -102,7 +103,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
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));
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_codegen_ssa/mir/statement.rs
Expand Up @@ -89,7 +89,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
});

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");
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_codegen_ssa/traits/asm.rs
@@ -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
Expand All @@ -9,6 +10,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
ia: &InlineAsm,
outputs: Vec<PlaceRef<'tcx, Self::Value>>,
inputs: Vec<Self::Value>,
span: Span,
) -> bool;
}

Expand Down
8 changes: 8 additions & 0 deletions src/librustc_metadata/decoder.rs
Expand Up @@ -348,6 +348,14 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
}
}

impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
// FIXME(jseyfried): intercrate hygiene

Ok(Ident::with_empty_ctxt(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)
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_metadata/encoder.rs
Expand Up @@ -31,7 +31,7 @@ use std::u32;
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};

Expand Down Expand Up @@ -173,6 +173,13 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
}
}

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> {
Expand Down
14 changes: 8 additions & 6 deletions src/librustc_resolve/diagnostics.rs
Expand Up @@ -166,12 +166,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
Expand Down
16 changes: 13 additions & 3 deletions src/librustc_resolve/error_codes.rs
Expand Up @@ -526,15 +526,25 @@ Some type parameters have the same name.
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);
}
```
"##,

Expand Down
31 changes: 31 additions & 0 deletions src/librustc_resolve/late.rs
Expand Up @@ -104,6 +104,24 @@ crate enum RibKind<'a> {
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
Expand Down Expand Up @@ -792,6 +810,19 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
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 { .. } => {}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/lib.rs
Expand Up @@ -1448,7 +1448,7 @@ impl<'a> Resolver<'a> {
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
Expand Down

0 comments on commit 3296a0c

Please sign in to comment.