Skip to content

Commit f70c90c

Browse files
committed
Move type parameter shadowing errors to resolve
For some reason type checking did this. Further it didn't consider hygiene.
1 parent 3296d0e commit f70c90c

File tree

14 files changed

+108
-109
lines changed

14 files changed

+108
-109
lines changed

src/librustc_resolve/diagnostics.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,14 @@ impl<'a> Resolver<'a> {
169169
err
170170
}
171171
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
172-
let mut err = struct_span_err!(self.session,
173-
span,
174-
E0403,
175-
"the name `{}` is already used for a generic \
176-
parameter in this list of generic parameters",
177-
name);
172+
let mut err = struct_span_err!(
173+
self.session,
174+
span,
175+
E0403,
176+
"the name `{}` is already used for a generic \
177+
parameter in this item's generic parameters",
178+
name,
179+
);
178180
err.span_label(span, "already used");
179181
err.span_label(first_use_span, format!("first use of `{}`", name));
180182
err

src/librustc_resolve/error_codes.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,25 @@ Some type parameters have the same name.
526526
Erroneous code example:
527527
528528
```compile_fail,E0403
529-
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
530-
// parameter in this type parameter list
529+
fn f<T, T>(s: T, u: T) {} // error: the name `T` is already used for a generic
530+
// parameter in this item's generic parameters
531531
```
532532
533533
Please verify that none of the type parameters are misspelled, and rename any
534534
clashing parameters. Example:
535535
536536
```
537-
fn foo<T, Y>(s: T, u: Y) {} // ok!
537+
fn f<T, Y>(s: T, u: Y) {} // ok!
538+
```
539+
540+
Type parameters in an associated item also cannot shadow parameters from the
541+
containing item:
542+
543+
```compile_fail,E0403
544+
trait Foo<T> {
545+
fn do_something(&self) -> T;
546+
fn do_something_else<T: Clone>(&self, bar: T);
547+
}
538548
```
539549
"##,
540550

src/librustc_resolve/late.rs

+31
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ crate enum RibKind<'a> {
111111
TyParamAsConstParamTy,
112112
}
113113

114+
impl RibKind<'_> {
115+
// Whether this rib kind contains generic parameters, as opposed to local
116+
// variables.
117+
crate fn contains_params(&self) -> bool {
118+
match self {
119+
NormalRibKind
120+
| FnItemRibKind
121+
| ConstantItemRibKind
122+
| ModuleRibKind(_)
123+
| MacroDefinition(_) => false,
124+
AssocItemRibKind
125+
| ItemRibKind
126+
| ForwardTyParamBanRibKind
127+
| TyParamAsConstParamTy => true,
128+
}
129+
}
130+
}
131+
114132
/// A single local scope.
115133
///
116134
/// 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, '_> {
798816
let mut function_type_rib = Rib::new(rib_kind);
799817
let mut function_value_rib = Rib::new(rib_kind);
800818
let mut seen_bindings = FxHashMap::default();
819+
// We also can't shadow bindings from the parent item
820+
if let AssocItemRibKind = rib_kind {
821+
let mut add_bindings_for_ns = |ns| {
822+
let parent_rib = self.ribs[ns].iter()
823+
.rfind(|rib| if let ItemRibKind = rib.kind { true } else { false })
824+
.expect("associated item outside of an item");
825+
seen_bindings.extend(
826+
parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span)),
827+
);
828+
};
829+
add_bindings_for_ns(ValueNS);
830+
add_bindings_for_ns(TypeNS);
831+
}
801832
for param in &generics.params {
802833
match param.kind {
803834
GenericParamKind::Lifetime { .. } => {}

src/librustc_resolve/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ impl<'a> Resolver<'a> {
14991499
debug!("walk rib\n{:?}", ribs[i].bindings);
15001500
// Use the rib kind to determine whether we are resolving parameters
15011501
// (modern hygiene) or local variables (legacy hygiene).
1502-
let rib_ident = if let AssocItemRibKind | ItemRibKind = ribs[i].kind {
1502+
let rib_ident = if ribs[i].kind.contains_params() {
15031503
modern_ident
15041504
} else {
15051505
ident

src/librustc_typeck/check/wfcheck.rs

-38
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ fn check_associated_item(
203203
fcx.register_wf_obligation(ty, span, code.clone());
204204
}
205205
ty::AssocKind::Method => {
206-
reject_shadowing_parameters(fcx.tcx, item.def_id);
207206
let sig = fcx.tcx.fn_sig(item.def_id);
208207
let sig = fcx.normalize_associated_types_in(span, &sig);
209208
check_fn_or_method(tcx, fcx, span, sig,
@@ -998,34 +997,6 @@ fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) {
998997
err.emit();
999998
}
1000999

1001-
fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) {
1002-
let generics = tcx.generics_of(def_id);
1003-
let parent = tcx.generics_of(generics.parent.unwrap());
1004-
let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
1005-
GenericParamDefKind::Lifetime => None,
1006-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
1007-
Some((param.name, param.def_id))
1008-
}
1009-
}).collect();
1010-
1011-
for method_param in &generics.params {
1012-
// Shadowing is checked in `resolve_lifetime`.
1013-
if let GenericParamDefKind::Lifetime = method_param.kind {
1014-
continue
1015-
}
1016-
if impl_params.contains_key(&method_param.name) {
1017-
// Tighten up the span to focus on only the shadowing type.
1018-
let type_span = tcx.def_span(method_param.def_id);
1019-
1020-
// The expectation here is that the original trait declaration is
1021-
// local so it should be okay to just unwrap everything.
1022-
let trait_def_id = impl_params[&method_param.name];
1023-
let trait_decl_span = tcx.def_span(trait_def_id);
1024-
error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
1025-
}
1026-
}
1027-
}
1028-
10291000
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
10301001
/// aren't true.
10311002
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
@@ -1152,12 +1123,3 @@ fn error_392(
11521123
err.span_label(span, "unused parameter");
11531124
err
11541125
}
1155-
1156-
fn error_194(tcx: TyCtxt<'_>, span: Span, trait_decl_span: Span, name: &str) {
1157-
struct_span_err!(tcx.sess, span, E0194,
1158-
"type parameter `{}` shadows another type parameter of the same name",
1159-
name)
1160-
.span_label(span, "shadows another type parameter")
1161-
.span_label(trait_decl_span, format!("first `{}` declared here", name))
1162-
.emit();
1163-
}

src/librustc_typeck/error_codes.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -1718,22 +1718,6 @@ Since we know for certain that `Wrapper<u32>` implements `Clone`, there's no
17181718
reason to also specify it in a `where` clause.
17191719
"##,
17201720

1721-
E0194: r##"
1722-
A type parameter was declared which shadows an existing one. An example of this
1723-
error:
1724-
1725-
```compile_fail,E0194
1726-
trait Foo<T> {
1727-
fn do_something(&self) -> T;
1728-
fn do_something_else<T: Clone>(&self, bar: T);
1729-
}
1730-
```
1731-
1732-
In this example, the trait `Foo` and the trait method `do_something_else` both
1733-
define a type parameter `T`. This is not allowed: if the method wishes to
1734-
define a type parameter, it must use a different name for it.
1735-
"##,
1736-
17371721
E0195: r##"
17381722
Your method's lifetime parameters do not match the trait declaration.
17391723
Erroneous code example:
@@ -4837,6 +4821,7 @@ register_diagnostics! {
48374821
// E0188, // can not cast an immutable reference to a mutable pointer
48384822
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
48394823
// E0190, // deprecated: can only cast a &-pointer to an &-object
4824+
// E0194, // merged into E0403
48404825
// E0196, // cannot determine a type for this closure
48414826
E0203, // type parameter has more than one relaxed default bound,
48424827
// and only one is supported

src/test/ui/duplicate/duplicate-type-parameter.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
1+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
22
--> $DIR/duplicate-type-parameter.rs:1:12
33
|
44
LL | type Foo<T,T> = Option<T>;
55
| - ^ already used
66
| |
77
| first use of `T`
88

9-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
9+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
1010
--> $DIR/duplicate-type-parameter.rs:4:14
1111
|
1212
LL | struct Bar<T,T>(T);
1313
| - ^ already used
1414
| |
1515
| first use of `T`
1616

17-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
17+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
1818
--> $DIR/duplicate-type-parameter.rs:7:14
1919
|
2020
LL | struct Baz<T,T> {
2121
| - ^ already used
2222
| |
2323
| first use of `T`
2424

25-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
25+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
2626
--> $DIR/duplicate-type-parameter.rs:12:12
2727
|
2828
LL | enum Boo<T,T> {
2929
| - ^ already used
3030
| |
3131
| first use of `T`
3232

33-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
33+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
3434
--> $DIR/duplicate-type-parameter.rs:18:11
3535
|
3636
LL | fn quux<T,T>(x: T) {}
3737
| - ^ already used
3838
| |
3939
| first use of `T`
4040

41-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
41+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
4242
--> $DIR/duplicate-type-parameter.rs:21:13
4343
|
4444
LL | trait Qux<T,T> {}
4545
| - ^ already used
4646
| |
4747
| first use of `T`
4848

49-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
49+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
5050
--> $DIR/duplicate-type-parameter.rs:24:8
5151
|
5252
LL | impl<T,T> Qux<T,T> for Option<T> {}

src/test/ui/error-codes/E0194.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
trait Foo<T> {
22
fn do_something(&self) -> T;
33
fn do_something_else<T: Clone>(&self, bar: T);
4-
//~^ ERROR E0194
4+
//~^ ERROR E0403
55
}
66

77
fn main() {

src/test/ui/error-codes/E0194.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0194]: type parameter `T` shadows another type parameter of the same name
1+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
22
--> $DIR/E0194.rs:3:26
33
|
44
LL | trait Foo<T> {
5-
| - first `T` declared here
5+
| - first use of `T`
66
LL | fn do_something(&self) -> T;
77
LL | fn do_something_else<T: Clone>(&self, bar: T);
8-
| ^ shadows another type parameter
8+
| ^ already used
99

1010
error: aborting due to previous error
1111

12-
For more information about this error, try `rustc --explain E0194`.
12+
For more information about this error, try `rustc --explain E0403`.

src/test/ui/error-codes/E0403.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
1+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
22
--> $DIR/E0403.rs:1:11
33
|
44
LL | fn foo<T, T>(s: T, u: T) {}
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1+
#![allow(incomplete_features)]
12
#![feature(generic_associated_types)]
23

3-
//FIXME(#44265): The lifetime shadowing and type parameter shadowing
4-
// should cause an error. Now it compiles (erroneously) and this will be addressed
5-
// by a future PR. Then remove the following:
6-
// build-pass (FIXME(62277): could be check-pass?)
7-
84
trait Shadow<'a> {
9-
type Bar<'a>; // Error: shadowed lifetime
5+
//FIXME(#44265): The lifetime parameter shadowing should cause an error.
6+
type Bar<'a>;
107
}
118

129
trait NoShadow<'a> {
1310
type Bar<'b>; // OK
1411
}
1512

1613
impl<'a> NoShadow<'a> for &'a u32 {
17-
type Bar<'a> = i32; // Error: shadowed lifetime
14+
//FIXME(#44265): The lifetime parameter shadowing should cause an error.
15+
type Bar<'a> = i32;
1816
}
1917

2018
trait ShadowT<T> {
21-
type Bar<T>; // Error: shadowed type parameter
19+
type Bar<T>; //~ ERROR the name `T` is already used
2220
}
2321

2422
trait NoShadowT<T> {
2523
type Bar<U>; // OK
2624
}
2725

2826
impl<T> NoShadowT<T> for Option<T> {
29-
type Bar<T> = i32; // Error: shadowed type parameter
27+
type Bar<T> = i32; //~ ERROR the name `T` is already used
3028
}
3129

3230
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
2-
--> $DIR/shadowing.rs:1:12
1+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
2+
--> $DIR/shadowing.rs:19:14
33
|
4-
LL | #![feature(generic_associated_types)]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | trait ShadowT<T> {
5+
| - first use of `T`
6+
LL | type Bar<T>;
7+
| ^ already used
8+
9+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
10+
--> $DIR/shadowing.rs:27:14
611
|
7-
= note: `#[warn(incomplete_features)]` on by default
12+
LL | impl<T> NoShadowT<T> for Option<T> {
13+
| - first use of `T`
14+
LL | type Bar<T> = i32;
15+
| ^ already used
16+
17+
error: aborting due to 2 previous errors
818

19+
For more information about this error, try `rustc --explain E0403`.

src/test/ui/shadowed/shadowed-type-parameter.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct Foo<T>(T);
66

77
impl<T> Foo<T> {
88
fn shadow_in_method<T>(&self) {}
9-
//~^ ERROR type parameter `T` shadows another type parameter
9+
//~^ ERROR the name `T` is already used
1010

1111
fn not_shadow_in_item<U>(&self) {
1212
struct Bar<T, U>(T,U); // not a shadow, separate item
@@ -18,10 +18,10 @@ trait Bar<T> {
1818
fn dummy(&self) -> T;
1919

2020
fn shadow_in_required<T>(&self);
21-
//~^ ERROR type parameter `T` shadows another type parameter
21+
//~^ ERROR the name `T` is already used
2222

2323
fn shadow_in_provided<T>(&self) {}
24-
//~^ ERROR type parameter `T` shadows another type parameter
24+
//~^ ERROR the name `T` is already used
2525

2626
fn not_shadow_in_required<U>(&self);
2727
fn not_shadow_in_provided<U>(&self) {}

0 commit comments

Comments
 (0)