Auto merge of #63462 - matthewjasper:hygienic-builtin-derives, 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 #60869
r? @petrochenkov
This commit is contained in:
bors 2019-08-17 12:53:53 +00:00
commit d65e272a9f
49 changed files with 384 additions and 280 deletions

View 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");
}

View File

@ -135,7 +135,7 @@ pub trait Clone : Sized {
/// 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 */ }

View File

@ -202,7 +202,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
/// 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 @@ pub trait Eq: PartialEq<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 @@ pub trait Ord: Eq + PartialOrd<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 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
/// 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 */ }

View 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 */ }

View 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,

View 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 */ }

View File

@ -202,7 +202,7 @@ pub trait Hash {
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 */ }

View File

@ -1263,14 +1263,14 @@ pub(crate) mod builtin {
/// 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 */ }

View 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 */ }

View File

@ -984,7 +984,6 @@ impl LoweringContext<'_> {
volatile: asm.volatile,
alignstack: asm.alignstack,
dialect: asm.dialect,
ctxt: asm.ctxt,
};
let outputs = asm.outputs

View File

@ -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 {

View File

@ -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;
@ -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)]

View File

@ -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};
@ -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![];
@ -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));

View File

@ -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");

View 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 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
ia: &InlineAsm,
outputs: Vec<PlaceRef<'tcx, Self::Value>>,
inputs: Vec<Self::Value>,
span: Span,
) -> bool;
}

View File

@ -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_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)

View File

@ -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};
@ -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> {

View 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

View File

@ -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);
}
```
"##,

View File

@ -111,6 +111,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
@ -798,6 +816,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 { .. } => {}

View File

@ -1499,7 +1499,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

View 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();
}

View File

@ -1718,22 +1718,6 @@ Since we know for certain that `Wrapper<u32>` implements `Clone`, there's no
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 @@ register_diagnostics! {
// 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

View File

@ -5,7 +5,7 @@ pub use UnsafeSource::*;
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)]

View 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);

View 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(),
}))
}

View 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 {

View 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);

View 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));
}

View 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,

View 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 }
//! ```
//!
@ -40,15 +41,17 @@
//! 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,

View File

@ -890,7 +890,7 @@ impl<'a> MethodDef<'a> {
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 @@ impl<'a> MethodDef<'a> {
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 @@ impl<'a> MethodDef<'a> {
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 @@ impl<'a> TraitDef<'a> {
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 {

View File

@ -72,7 +72,7 @@ impl<'a> Path<'a> {
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 {

View 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 {

View File

@ -54,33 +54,6 @@ impl MultiItemModifier for BuiltinDerive {
}
}
/// 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,

View 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 }))
}

View File

@ -750,15 +750,3 @@ impl Decodable for ExpnId {
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
}
}

View File

@ -8,6 +8,7 @@ use rustc_data_structures::indexed_vec::Idx;
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 @@ impl fmt::Display for Ident {
}
}
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.

View File

@ -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() {}

View 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> {}

View 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() {

View 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`.

View 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) {}

View File

@ -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);

View File

@ -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);
}

View 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() {}

View 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
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
|
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`.

View File

@ -6,7 +6,7 @@ struct Foo<T>(T);
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) {}

View File

@ -1,29 +1,29 @@
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> $DIR/shadowed-type-parameter.rs:20:27
|
LL | trait Bar<T> {
| - first `T` declared here
...
LL | fn shadow_in_required<T>(&self);
| ^ shadows another type parameter
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> $DIR/shadowed-type-parameter.rs:23:27
|
LL | trait Bar<T> {
| - first `T` declared here
...
LL | fn shadow_in_provided<T>(&self) {}
| ^ shadows another type parameter
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 `T` declared here
| - first use of `T`
LL | fn shadow_in_method<T>(&self) {}
| ^ shadows another type parameter
| ^ 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 use of `T`
...
LL | fn shadow_in_required<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:23:27
|
LL | trait Bar<T> {
| - first use of `T`
...
LL | fn shadow_in_provided<T>(&self) {}
| ^ 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`.