Skip to content

Commit 4e0e188

Browse files
committed
Make name resolution handle consts in GenericParamsFromOuterFunction properly
1 parent 451f128 commit 4e0e188

26 files changed

+120
-93
lines changed

src/librustc_resolve/lib.rs

+37-12
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ impl Ord for BindingError {
142142
}
143143

144144
enum ResolutionError<'a> {
145-
/// error E0401: can't use type parameters from outer function
146-
TypeParametersFromOuterFunction(Def),
145+
/// error E0401: can't use type or const parameters from outer function
146+
GenericParamsFromOuterFunction(Def),
147147
/// error E0403: the name is already used for a type/const parameter in this list of
148148
/// generic parameters
149149
NameAlreadyUsedInParameterList(Name, &'a Span),
@@ -196,13 +196,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
196196
resolution_error: ResolutionError<'a>)
197197
-> DiagnosticBuilder<'sess> {
198198
match resolution_error {
199-
ResolutionError::TypeParametersFromOuterFunction(outer_def) => {
199+
ResolutionError::GenericParamsFromOuterFunction(outer_def) => {
200200
let mut err = struct_span_err!(resolver.session,
201201
span,
202202
E0401,
203-
"can't use type parameters from outer function",
203+
"can't use generic parameters from outer function",
204204
);
205-
err.span_label(span, format!("use of type variable from outer function"));
205+
err.span_label(span, format!("use of generic parameter from outer function"));
206206

207207
let cm = resolver.session.source_map();
208208
match outer_def {
@@ -231,15 +231,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
231231
err.span_label(span, "type variable from outer function");
232232
}
233233
}
234+
Def::ConstParam(def_id) => {
235+
if let Some(span) = resolver.definitions.opt_span(def_id) {
236+
err.span_label(span, "const variable from outer function");
237+
}
238+
}
234239
_ => {
235-
bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy, \
240+
bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
236241
Def::TyParam");
237242
}
238243
}
239244

240245
// Try to retrieve the span of the function signature and generate a new message with
241246
// a local type or const parameter.
242-
let sugg_msg = &format!("try using a local type parameter instead");
247+
let sugg_msg = &format!("try using a local generic parameter instead");
243248
if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) {
244249
// Suggest the modification to the user
245250
err.span_suggestion(
@@ -250,9 +255,9 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
250255
);
251256
} else if let Some(sp) = cm.generate_fn_name_span(span) {
252257
err.span_label(sp,
253-
format!("try adding a local type parameter in this method instead"));
258+
format!("try adding a local generic parameter in this method instead"));
254259
} else {
255-
err.help(&format!("try using a local type parameter instead"));
260+
err.help(&format!("try using a local generic parameter instead"));
256261
}
257262

258263
err
@@ -549,8 +554,7 @@ impl<'a> PathSource<'a> {
549554
Def::Struct(..) | Def::Union(..) | Def::Enum(..) |
550555
Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) |
551556
Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) |
552-
Def::SelfTy(..) | Def::Existential(..) | Def::ConstParam(..) |
553-
Def::ForeignTy(..) => true,
557+
Def::SelfTy(..) | Def::Existential(..) | Def::ForeignTy(..) => true,
554558
_ => false,
555559
},
556560
PathSource::Trait(AliasPossibility::No) => match def {
@@ -803,6 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
803807
_: Span,
804808
node_id: NodeId)
805809
{
810+
debug!("(resolving function) entering function");
806811
let (rib_kind, asyncness) = match function_kind {
807812
FnKind::ItemFn(_, ref header, ..) =>
808813
(ItemRibKind, header.asyncness),
@@ -2053,6 +2058,7 @@ impl<'a> Resolver<'a> {
20532058
let record_used = record_used_id.is_some();
20542059
let mut module = self.graph_root;
20552060
for i in (0 .. self.ribs[ns].len()).rev() {
2061+
debug!("walk rib\n{:?}", self.ribs[ns][i].bindings);
20562062
if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
20572063
// The ident resolves to a type parameter or local variable.
20582064
return Some(LexicalScopeBinding::Def(
@@ -4223,14 +4229,33 @@ impl<'a> Resolver<'a> {
42234229
resolve_error(
42244230
self,
42254231
span,
4226-
ResolutionError::TypeParametersFromOuterFunction(def),
4232+
ResolutionError::GenericParamsFromOuterFunction(def),
42274233
);
42284234
}
42294235
return Def::Err;
42304236
}
42314237
}
42324238
}
42334239
}
4240+
Def::ConstParam(..) => {
4241+
// A const param is always declared in a signature, which is always followed by
4242+
// some kind of function rib kind (specifically, ItemRibKind in the case of a
4243+
// normal function), so we can skip the first rib as it will be guaranteed to
4244+
// (spuriously) conflict with the const param.
4245+
for rib in &ribs[1..] {
4246+
if let ItemRibKind = rib.kind {
4247+
// This was an attempt to use a const parameter outside its scope.
4248+
if record_used {
4249+
resolve_error(
4250+
self,
4251+
span,
4252+
ResolutionError::GenericParamsFromOuterFunction(def),
4253+
);
4254+
}
4255+
return Def::Err;
4256+
}
4257+
}
4258+
}
42344259
_ => {}
42354260
}
42364261
def

src/librustc_typeck/diagnostics.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,14 @@ fn main() {
348348
"##,
349349

350350
E0044: r##"
351-
You can't use type parameters on foreign items. Example of erroneous code:
351+
You can't use type or const parameters on foreign items.
352+
Example of erroneous code:
352353
353354
```compile_fail,E0044
354355
extern { fn some_func<T>(x: T); }
355356
```
356357
357-
To fix this, replace the type parameter with the specializations that you
358+
To fix this, replace the generic parameter with the specializations that you
358359
need:
359360
360361
```

src/libsyntax/parse/token.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ impl Token {
284284
match self {
285285
OpenDelim(Brace) => true,
286286
Interpolated(ref nt) => match nt.0 {
287+
NtExpr(..) => true,
287288
NtBlock(..) => true,
288289
NtLiteral(..) => true,
289290
_ => false,
@@ -306,7 +307,7 @@ impl Token {
306307
}
307308
}
308309

309-
/// Returns `true` if the token is any literal, a minus (which can follow a literal,
310+
/// Returns `true` if the token is any literal, a minus (which can prefix a literal,
310311
/// for example a '-42', or one of the boolean idents).
311312
crate fn can_begin_literal_or_bool(&self) -> bool {
312313
match *self {
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fn foo<T>() {
2-
fn bar(b: T) { } //~ ERROR can't use type parameters from outer
2+
fn bar(b: T) { } //~ ERROR can't use generic parameters from outer
33
}
44
fn main() { }

src/test/ui/bad/bad-type-env-capture.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/bad-type-env-capture.rs:2:15
33
|
44
LL | fn foo<T>() {
55
| - type variable from outer function
6-
LL | fn bar(b: T) { } //~ ERROR can't use type parameters from outer
7-
| --- ^ use of type variable from outer function
6+
LL | fn bar(b: T) { } //~ ERROR can't use generic parameters from outer
7+
| --- ^ use of generic parameter from outer function
88
| |
9-
| help: try using a local type parameter instead: `bar<T>`
9+
| help: try using a local generic parameter instead: `bar<T>`
1010

1111
error: aborting due to previous error
1212

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/E0401.rs:4:39
33
|
44
LL | fn foo<T>(x: T) {
55
| - type variable from outer function
66
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { //~ ERROR E0401
7-
| --------------------------- ^ use of type variable from outer function
7+
| --------------------------- ^ use of generic parameter from outer function
88
| |
9-
| help: try using a local type parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
9+
| help: try using a local generic parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
1010

11-
error[E0401]: can't use type parameters from outer function
11+
error[E0401]: can't use generic parameters from outer function
1212
--> $DIR/E0401.rs:9:16
1313
|
1414
LL | fn foo<T>(x: T) {
1515
| - type variable from outer function
1616
...
1717
LL | fn baz<U,
18-
| --- try adding a local type parameter in this method instead
18+
| --- try adding a local generic parameter in this method instead
1919
...
2020
LL | (y: T) { //~ ERROR E0401
21-
| ^ use of type variable from outer function
21+
| ^ use of generic parameter from outer function
2222

23-
error[E0401]: can't use type parameters from outer function
23+
error[E0401]: can't use generic parameters from outer function
2424
--> $DIR/E0401.rs:22:25
2525
|
2626
LL | impl<T> Iterator for A<T> {
@@ -29,7 +29,7 @@ LL | impl<T> Iterator for A<T> {
2929
LL | fn helper(sel: &Self) -> u8 { //~ ERROR E0401
3030
| ^^^^
3131
| |
32-
| use of type variable from outer function
32+
| use of generic parameter from outer function
3333
| use a type here instead
3434

3535
error: aborting due to 3 previous errors

src/test/ui/inner-static-type-parameter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used
44

55
fn foo<T>() {
66
static a: Bar<T> = Bar::What;
7-
//~^ ERROR can't use type parameters from outer function
7+
//~^ ERROR can't use generic parameters from outer function
88
}
99

1010
fn main() {

src/test/ui/inner-static-type-parameter.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/inner-static-type-parameter.rs:6:19
33
|
44
LL | fn foo<T>() {
55
| --- - type variable from outer function
66
| |
7-
| try adding a local type parameter in this method instead
7+
| try adding a local generic parameter in this method instead
88
LL | static a: Bar<T> = Bar::What;
9-
| ^ use of type variable from outer function
9+
| ^ use of generic parameter from outer function
1010

1111
error[E0392]: parameter `T` is never used
1212
--> $DIR/inner-static-type-parameter.rs:3:10

src/test/ui/issues/issue-12796.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
trait Trait {
22
fn outer(&self) {
33
fn inner(_: &Self) {
4-
//~^ ERROR can't use type parameters from outer function
4+
//~^ ERROR can't use generic parameters from outer function
55
}
66
}
77
}

src/test/ui/issues/issue-12796.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/issue-12796.rs:3:22
33
|
44
LL | fn inner(_: &Self) {
55
| ^^^^
66
| |
7-
| use of type variable from outer function
7+
| use of generic parameter from outer function
88
| can't use `Self` here
99

1010
error: aborting due to previous error

src/test/ui/issues/issue-3021-c.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
fn siphash<T>() {
22

33
trait U {
4-
fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
5-
//~^ ERROR can't use type parameters from outer function
4+
fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
5+
//~^ ERROR can't use generic parameters from outer function
66
}
77
}
88

src/test/ui/issues/issue-3021-c.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/issue-3021-c.rs:4:24
33
|
44
LL | fn siphash<T>() {
55
| - type variable from outer function
66
...
7-
LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
8-
| - ^ use of type variable from outer function
7+
LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
8+
| - ^ use of generic parameter from outer function
99
| |
10-
| help: try using a local type parameter instead: `g<T>`
10+
| help: try using a local generic parameter instead: `g<T>`
1111

12-
error[E0401]: can't use type parameters from outer function
12+
error[E0401]: can't use generic parameters from outer function
1313
--> $DIR/issue-3021-c.rs:4:30
1414
|
1515
LL | fn siphash<T>() {
1616
| - type variable from outer function
1717
...
18-
LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
19-
| - ^ use of type variable from outer function
18+
LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
19+
| - ^ use of generic parameter from outer function
2020
| |
21-
| help: try using a local type parameter instead: `g<T>`
21+
| help: try using a local generic parameter instead: `g<T>`
2222

2323
error: aborting due to 2 previous errors
2424

src/test/ui/issues/issue-3214.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn foo<T>() {
22
struct Foo {
3-
x: T, //~ ERROR can't use type parameters from outer function
3+
x: T, //~ ERROR can't use generic parameters from outer function
44
}
55

66
impl<T> Drop for Foo<T> {

src/test/ui/issues/issue-3214.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/issue-3214.rs:3:12
33
|
44
LL | fn foo<T>() {
55
| --- - type variable from outer function
66
| |
7-
| try adding a local type parameter in this method instead
7+
| try adding a local generic parameter in this method instead
88
LL | struct Foo {
9-
LL | x: T, //~ ERROR can't use type parameters from outer function
10-
| ^ use of type variable from outer function
9+
LL | x: T, //~ ERROR can't use generic parameters from outer function
10+
| ^ use of generic parameter from outer function
1111

1212
error[E0107]: wrong number of type arguments: expected 0, found 1
1313
--> $DIR/issue-3214.rs:6:26

src/test/ui/issues/issue-5997-enum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn f<Z>() -> bool {
22
enum E { V(Z) }
3-
//~^ ERROR can't use type parameters from outer function
3+
//~^ ERROR can't use generic parameters from outer function
44
true
55
}
66

src/test/ui/issues/issue-5997-enum.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/issue-5997-enum.rs:2:16
33
|
44
LL | fn f<Z>() -> bool {
55
| - - type variable from outer function
66
| |
7-
| try adding a local type parameter in this method instead
7+
| try adding a local generic parameter in this method instead
88
LL | enum E { V(Z) }
9-
| ^ use of type variable from outer function
9+
| ^ use of generic parameter from outer function
1010

1111
error: aborting due to previous error
1212

src/test/ui/issues/issue-5997-struct.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn f<T>() -> bool {
2-
struct S(T); //~ ERROR can't use type parameters from outer function
2+
struct S(T); //~ ERROR can't use generic parameters from outer function
33

44
true
55
}

src/test/ui/issues/issue-5997-struct.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0401]: can't use type parameters from outer function
1+
error[E0401]: can't use generic parameters from outer function
22
--> $DIR/issue-5997-struct.rs:2:14
33
|
44
LL | fn f<T>() -> bool {
55
| - - type variable from outer function
66
| |
7-
| try adding a local type parameter in this method instead
8-
LL | struct S(T); //~ ERROR can't use type parameters from outer function
9-
| ^ use of type variable from outer function
7+
| try adding a local generic parameter in this method instead
8+
LL | struct S(T); //~ ERROR can't use generic parameters from outer function
9+
| ^ use of generic parameter from outer function
1010

1111
error: aborting due to previous error
1212

src/test/ui/nested-ty-params.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// error-pattern:can't use type parameters from outer function
1+
// error-pattern:can't use generic parameters from outer function
22
fn hd<U>(v: Vec<U> ) -> U {
33
fn hd1(w: [U]) -> U { return w[0]; }
44

0 commit comments

Comments
 (0)