about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/diagnostics.rs14
-rw-r--r--src/librustc_resolve/error_codes.rs16
-rw-r--r--src/librustc_resolve/late.rs31
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs38
-rw-r--r--src/librustc_typeck/error_codes.rs17
-rw-r--r--src/test/ui/duplicate/duplicate-type-parameter.stderr14
-rw-r--r--src/test/ui/error-codes/E0194.rs2
-rw-r--r--src/test/ui/error-codes/E0194.stderr8
-rw-r--r--src/test/ui/error-codes/E0403.stderr2
-rw-r--r--src/test/ui/rfc1598-generic-associated-types/shadowing.rs16
-rw-r--r--src/test/ui/rfc1598-generic-associated-types/shadowing.stderr21
-rw-r--r--src/test/ui/shadowed/shadowed-type-parameter.rs6
-rw-r--r--src/test/ui/shadowed/shadowed-type-parameter.stderr30
14 files changed, 108 insertions, 109 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index afdcec19d8e..b79e0c2bd3b 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -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
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index e01f53786ed..1faaf97e981 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -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);
+}
 ```
 "##,
 
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index d8bd86699b7..e15d02a9f7e 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -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 { .. } => {}
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 12c4f5bfe8e..984473d781e 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -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
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b2c0e34d6fa..28a1ccda4d8 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -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();
-}
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 90118a9f191..ca9ce3d22b5 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -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
diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr
index 8606479ff68..6754574f0b9 100644
--- a/src/test/ui/duplicate/duplicate-type-parameter.stderr
+++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr
@@ -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> {}
diff --git a/src/test/ui/error-codes/E0194.rs b/src/test/ui/error-codes/E0194.rs
index 71eff0e7465..8a43f38fcfd 100644
--- a/src/test/ui/error-codes/E0194.rs
+++ b/src/test/ui/error-codes/E0194.rs
@@ -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() {
diff --git a/src/test/ui/error-codes/E0194.stderr b/src/test/ui/error-codes/E0194.stderr
index ab4918a4e27..f2c908eea0b 100644
--- a/src/test/ui/error-codes/E0194.stderr
+++ b/src/test/ui/error-codes/E0194.stderr
@@ -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`.
diff --git a/src/test/ui/error-codes/E0403.stderr b/src/test/ui/error-codes/E0403.stderr
index 2bd7de6c246..d76a58a7c80 100644
--- a/src/test/ui/error-codes/E0403.stderr
+++ b/src/test/ui/error-codes/E0403.stderr
@@ -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/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
index 03492631cb7..f5197fd01bf 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
@@ -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() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
index 9526df258c4..a06c6350845 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
@@ -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`.
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.rs b/src/test/ui/shadowed/shadowed-type-parameter.rs
index ba9f3abcf7a..e74620f8900 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.rs
+++ b/src/test/ui/shadowed/shadowed-type-parameter.rs
@@ -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) {}
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.stderr b/src/test/ui/shadowed/shadowed-type-parameter.stderr
index 6b4d1fae3de..0ea82f983f1 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.stderr
+++ b/src/test/ui/shadowed/shadowed-type-parameter.stderr
@@ -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`.