Skip to content

Commit 9b989ea

Browse files
authored
Rollup merge of #65133 - davidtwco:issue-65035-static-with-generic-in-foreign-mod, r=petrochenkov
typeck: prohibit foreign statics w/ generics Fixes #65035 and fixes #65025. This PR modifies resolve to disallow foreign statics that have generics. `improper_ctypes` is not written to support type parameters, as these are normally disallowed before the lint is run. Thus, type parameters in foreign statics must be prohibited before the lint. The only other case where this *could* have occured is in functions, but typeck prohibits this with a "foreign items may not have type parameters" error - a similar error did not exist for statics, because statics cannot have type parameters, but they can use any type parameters that are in scope (which isn't the case for functions).
2 parents 3f2ae44 + ccbf2b7 commit 9b989ea

8 files changed

+266
-181
lines changed

src/librustc_resolve/diagnostics.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use syntax_pos::{BytePos, Span, MultiSpan};
2020

2121
use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
2222
use crate::{path_names_to_string, KNOWN_TOOLS};
23-
use crate::{BindingError, CrateLint, LegacyScope, Module, ModuleOrUniformRoot};
23+
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
2424
use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};
2525

2626
type Res = def::Res<ast::NodeId>;
@@ -102,7 +102,7 @@ impl<'a> Resolver<'a> {
102102
&self, span: Span, resolution_error: ResolutionError<'_>
103103
) -> DiagnosticBuilder<'_> {
104104
match resolution_error {
105-
ResolutionError::GenericParamsFromOuterFunction(outer_res) => {
105+
ResolutionError::GenericParamsFromOuterFunction(outer_res, has_generic_params) => {
106106
let mut err = struct_span_err!(self.session,
107107
span,
108108
E0401,
@@ -148,22 +148,24 @@ impl<'a> Resolver<'a> {
148148
}
149149
}
150150

151-
// Try to retrieve the span of the function signature and generate a new message
152-
// with a local type or const parameter.
153-
let sugg_msg = &format!("try using a local generic parameter instead");
154-
if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) {
155-
// Suggest the modification to the user
156-
err.span_suggestion(
157-
sugg_span,
158-
sugg_msg,
159-
new_snippet,
160-
Applicability::MachineApplicable,
161-
);
162-
} else if let Some(sp) = cm.generate_fn_name_span(span) {
163-
err.span_label(sp,
164-
format!("try adding a local generic parameter in this method instead"));
165-
} else {
166-
err.help(&format!("try using a local generic parameter instead"));
151+
if has_generic_params == HasGenericParams::Yes {
152+
// Try to retrieve the span of the function signature and generate a new
153+
// message with a local type or const parameter.
154+
let sugg_msg = &format!("try using a local generic parameter instead");
155+
if let Some((sugg_span, snippet)) = cm.generate_local_type_param_snippet(span) {
156+
// Suggest the modification to the user
157+
err.span_suggestion(
158+
sugg_span,
159+
sugg_msg,
160+
snippet,
161+
Applicability::MachineApplicable,
162+
);
163+
} else if let Some(sp) = cm.generate_fn_name_span(span) {
164+
err.span_label(sp,
165+
format!("try adding a local generic parameter in this method instead"));
166+
} else {
167+
err.help(&format!("try using a local generic parameter instead"));
168+
}
167169
}
168170

169171
err

src/librustc_resolve/late.rs

+116-139
Large diffs are not rendered by default.

src/librustc_resolve/lib.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ use rustc_data_structures::fx::FxIndexMap;
6161

6262
use diagnostics::{Suggestion, ImportSuggestion};
6363
use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
64-
use late::{PathSource, Rib, RibKind::*};
64+
use late::{HasGenericParams, PathSource, Rib, RibKind::*};
6565
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
6666
use macros::{LegacyBinding, LegacyScope};
6767

@@ -178,7 +178,7 @@ impl Ord for BindingError {
178178

179179
enum ResolutionError<'a> {
180180
/// Error E0401: can't use type or const parameters from outer function.
181-
GenericParamsFromOuterFunction(Res),
181+
GenericParamsFromOuterFunction(Res, HasGenericParams),
182182
/// Error E0403: the name is already used for a type or const parameter in this generic
183183
/// parameter list.
184184
NameAlreadyUsedInParameterList(Name, Span),
@@ -2156,7 +2156,7 @@ impl<'a> Resolver<'a> {
21562156
ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
21572157
// Nothing to do. Continue.
21582158
}
2159-
ItemRibKind | FnItemRibKind | AssocItemRibKind => {
2159+
ItemRibKind(_) | FnItemRibKind | AssocItemRibKind => {
21602160
// This was an attempt to access an upvar inside a
21612161
// named function item. This is not allowed, so we
21622162
// report an error.
@@ -2184,22 +2184,23 @@ impl<'a> Resolver<'a> {
21842184
}
21852185
Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => {
21862186
for rib in ribs {
2187-
match rib.kind {
2187+
let has_generic_params = match rib.kind {
21882188
NormalRibKind | AssocItemRibKind |
21892189
ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
21902190
ConstantItemRibKind | TyParamAsConstParamTy => {
21912191
// Nothing to do. Continue.
2192+
continue;
21922193
}
2193-
ItemRibKind | FnItemRibKind => {
2194-
// This was an attempt to use a type parameter outside its scope.
2195-
if record_used {
2196-
self.report_error(
2197-
span, ResolutionError::GenericParamsFromOuterFunction(res)
2198-
);
2199-
}
2200-
return Res::Err;
2201-
}
2194+
// This was an attempt to use a type parameter outside its scope.
2195+
ItemRibKind(has_generic_params) => has_generic_params,
2196+
FnItemRibKind => HasGenericParams::Yes,
2197+
};
2198+
2199+
if record_used {
2200+
self.report_error(span, ResolutionError::GenericParamsFromOuterFunction(
2201+
res, has_generic_params));
22022202
}
2203+
return Res::Err;
22032204
}
22042205
}
22052206
Res::Def(DefKind::ConstParam, _) => {
@@ -2211,15 +2212,18 @@ impl<'a> Resolver<'a> {
22112212
ribs.next();
22122213
}
22132214
for rib in ribs {
2214-
if let ItemRibKind | FnItemRibKind = rib.kind {
2215-
// This was an attempt to use a const parameter outside its scope.
2216-
if record_used {
2217-
self.report_error(
2218-
span, ResolutionError::GenericParamsFromOuterFunction(res)
2219-
);
2220-
}
2221-
return Res::Err;
2215+
let has_generic_params = match rib.kind {
2216+
ItemRibKind(has_generic_params) => has_generic_params,
2217+
FnItemRibKind => HasGenericParams::Yes,
2218+
_ => continue,
2219+
};
2220+
2221+
// This was an attempt to use a const parameter outside its scope.
2222+
if record_used {
2223+
self.report_error(span, ResolutionError::GenericParamsFromOuterFunction(
2224+
res, has_generic_params));
22222225
}
2226+
return Res::Err;
22232227
}
22242228
}
22252229
_ => {}

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ 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>() {
5-
| --- - type parameter from outer function
6-
| |
7-
| try adding a local generic parameter in this method instead
5+
| - type parameter from outer function
86
LL | static a: Bar<T> = Bar::What;
97
| ^ use of generic parameter from outer function
108

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
unsafe fn foo<A>() {
2+
extern "C" {
3+
static baz: *const A;
4+
//~^ ERROR can't use generic parameters from outer function
5+
}
6+
7+
let bar: *const u64 = core::mem::transmute(&baz);
8+
}
9+
10+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0401]: can't use generic parameters from outer function
2+
--> $DIR/issue-65025-extern-static-parent-generics.rs:3:28
3+
|
4+
LL | unsafe fn foo<A>() {
5+
| - type parameter from outer function
6+
LL | extern "C" {
7+
LL | static baz: *const A;
8+
| ^ use of generic parameter from outer function
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0401`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
fn f<T>() {
5+
extern "C" {
6+
static a: *const T;
7+
//~^ ERROR can't use generic parameters from outer function
8+
}
9+
}
10+
11+
fn g<T: Default>() {
12+
static a: *const T = Default::default();
13+
//~^ ERROR can't use generic parameters from outer function
14+
}
15+
16+
fn h<const N: usize>() {
17+
extern "C" {
18+
static a: [u8; N];
19+
//~^ ERROR can't use generic parameters from outer function
20+
}
21+
}
22+
23+
fn i<const N: usize>() {
24+
static a: [u8; N] = [0; N];
25+
//~^ ERROR can't use generic parameters from outer function
26+
//~^^ ERROR can't use generic parameters from outer function
27+
}
28+
29+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0401]: can't use generic parameters from outer function
2+
--> $DIR/issue-65035-static-with-parent-generics.rs:6:26
3+
|
4+
LL | fn f<T>() {
5+
| - type parameter from outer function
6+
LL | extern "C" {
7+
LL | static a: *const T;
8+
| ^ use of generic parameter from outer function
9+
10+
error[E0401]: can't use generic parameters from outer function
11+
--> $DIR/issue-65035-static-with-parent-generics.rs:12:22
12+
|
13+
LL | fn g<T: Default>() {
14+
| - type parameter from outer function
15+
LL | static a: *const T = Default::default();
16+
| ^ use of generic parameter from outer function
17+
18+
error[E0401]: can't use generic parameters from outer function
19+
--> $DIR/issue-65035-static-with-parent-generics.rs:18:24
20+
|
21+
LL | fn h<const N: usize>() {
22+
| - const parameter from outer function
23+
LL | extern "C" {
24+
LL | static a: [u8; N];
25+
| ^ use of generic parameter from outer function
26+
27+
error[E0401]: can't use generic parameters from outer function
28+
--> $DIR/issue-65035-static-with-parent-generics.rs:24:20
29+
|
30+
LL | fn i<const N: usize>() {
31+
| - const parameter from outer function
32+
LL | static a: [u8; N] = [0; N];
33+
| ^ use of generic parameter from outer function
34+
35+
error[E0401]: can't use generic parameters from outer function
36+
--> $DIR/issue-65035-static-with-parent-generics.rs:24:29
37+
|
38+
LL | fn i<const N: usize>() {
39+
| - const parameter from outer function
40+
LL | static a: [u8; N] = [0; N];
41+
| ^ use of generic parameter from outer function
42+
43+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
44+
--> $DIR/issue-65035-static-with-parent-generics.rs:1:12
45+
|
46+
LL | #![feature(const_generics)]
47+
| ^^^^^^^^^^^^^^
48+
|
49+
= note: `#[warn(incomplete_features)]` on by default
50+
51+
error: aborting due to 5 previous errors
52+
53+
For more information about this error, try `rustc --explain E0401`.

0 commit comments

Comments
 (0)