提交 dc7ffbec 编写于 作者: E Eduard-Mihai Burtescu

rustc_resolve: don't deny outer type parameters in embedded constants.

上级 ef3ec5ec
......@@ -1222,27 +1222,26 @@ fn bar() -> u32 {
"##,
E0435: r##"
A non-constant value was used to initialise a constant.
A non-constant value was used in a constant expression.
Erroneous code example:
```compile_fail,E0435
let foo = 42u32;
const FOO : u32 = foo; // error: attempt to use a non-constant value in a
// constant
let foo = 42;
let a: [u8; foo]; // error: attempt to use a non-constant value in a constant
```
To fix this error, please replace the value with a constant. Example:
```
const FOO : u32 = 42u32; // ok!
let a: [u8; 42]; // ok!
```
Or:
```
const OTHER_FOO : u32 = 42u32;
const FOO : u32 = OTHER_FOO; // ok!
const FOO: usize = 42;
let a: [u8; FOO]; // ok!
```
"##,
......@@ -1560,7 +1559,7 @@ fn print_on_failure(state: &State) {
// E0157, unused error code
// E0257,
// E0258,
E0402, // cannot use an outer type parameter in this context
// E0402, // cannot use an outer type parameter in this context
// E0406, merged into 420
// E0410, merged into 408
// E0413, merged into 530
......
......@@ -127,8 +127,6 @@ fn cmp(&self, other: &BindingError) -> cmp::Ordering {
enum ResolutionError<'a> {
/// error E0401: can't use type parameters from outer function
TypeParametersFromOuterFunction,
/// error E0402: cannot use an outer type parameter in this context
OuterTypeParameterContext,
/// error E0403: the name is already used for a type parameter in this type parameter list
NameAlreadyUsedInTypeParameterList(Name, &'a Span),
/// error E0407: method is not a member of trait
......@@ -187,12 +185,6 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
err.span_label(span, "use of type variable from outer function");
err
}
ResolutionError::OuterTypeParameterContext => {
struct_span_err!(resolver.session,
span,
E0402,
"cannot use an outer type parameter in this context")
}
ResolutionError::NameAlreadyUsedInTypeParameterList(name, first_use_span) => {
let mut err = struct_span_err!(resolver.session,
span,
......@@ -1671,16 +1663,16 @@ fn resolve_item(&mut self, item: &Item) {
this.check_proc_macro_attrs(&trait_item.attrs);
match trait_item.node {
TraitItemKind::Const(_, ref default) => {
TraitItemKind::Const(ref ty, ref default) => {
this.visit_ty(ty);
// Only impose the restrictions of
// ConstRibKind if there's an actual constant
// ConstRibKind for an actual constant
// expression in a provided default.
if default.is_some() {
if let Some(ref expr) = *default{
this.with_constant_rib(|this| {
visit::walk_trait_item(this, trait_item)
this.visit_expr(expr);
});
} else {
visit::walk_trait_item(this, trait_item)
}
}
TraitItemKind::Method(ref sig, _) => {
......@@ -1709,9 +1701,13 @@ fn resolve_item(&mut self, item: &Item) {
});
}
ItemKind::Const(..) | ItemKind::Static(..) => {
self.with_constant_rib(|this| {
visit::walk_item(this, item);
ItemKind::Static(ref ty, _, ref expr) |
ItemKind::Const(ref ty, ref expr) => {
self.with_item_rib(|this| {
this.visit_ty(ty);
this.with_constant_rib(|this| {
this.visit_expr(expr);
});
});
}
......@@ -1782,13 +1778,21 @@ fn with_label_rib<F>(&mut self, f: F)
self.label_ribs.pop();
}
fn with_item_rib<F>(&mut self, f: F)
where F: FnOnce(&mut Resolver)
{
self.ribs[ValueNS].push(Rib::new(ItemRibKind));
self.ribs[TypeNS].push(Rib::new(ItemRibKind));
f(self);
self.ribs[TypeNS].pop();
self.ribs[ValueNS].pop();
}
fn with_constant_rib<F>(&mut self, f: F)
where F: FnOnce(&mut Resolver)
{
self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
self.ribs[TypeNS].push(Rib::new(ConstantItemRibKind));
f(self);
self.ribs[TypeNS].pop();
self.ribs[ValueNS].pop();
}
......@@ -2755,7 +2759,8 @@ fn adjust_local_def(&mut self,
for rib in ribs {
match rib.kind {
NormalRibKind | MethodRibKind(_) | ClosureRibKind(..) |
ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind => {
ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
ConstantItemRibKind => {
// Nothing to do. Continue.
}
ItemRibKind => {
......@@ -2767,14 +2772,6 @@ fn adjust_local_def(&mut self,
}
return Def::Err;
}
ConstantItemRibKind => {
// see #9186
if record_used {
resolve_error(self, span,
ResolutionError::OuterTypeParameterContext);
}
return Def::Err;
}
}
}
}
......
......@@ -10,6 +10,6 @@
fn main () {
let foo = 42u32;
const FOO : u32 = foo; //~ ERROR E0435
let _: [u8; foo]; //~ ERROR E0435
//~| NOTE non-constant used with constant
}
......@@ -26,7 +26,7 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>() {
let _array = [4; <A as Foo>::Y];
//~^ ERROR cannot use an outer type parameter in this context [E0402]
//~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
}
fn main() {
......
......@@ -26,7 +26,7 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>() {
let _array: [u32; <A as Foo>::Y];
//~^ ERROR cannot use an outer type parameter in this context [E0402]
//~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
}
fn main() {
......
......@@ -14,7 +14,7 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used
fn foo<T>() {
static a: Bar<T> = Bar::What;
//~^ ERROR cannot use an outer type parameter in this context
//~^ ERROR can't use type parameters from outer function; try using a local type parameter instead
}
fn main() {
......
......@@ -11,5 +11,5 @@
fn main() {
let foo = 42u32;
const FOO : u32 = foo;
//~^ ERROR attempt to use a non-constant value in a constant
//~^ ERROR can't capture dynamic environment
}
......@@ -12,7 +12,7 @@ fn main() {
let foo = 100;
static y: isize = foo + 1;
//~^ ERROR attempt to use a non-constant value in a constant
//~^ ERROR can't capture dynamic environment
println!("{}", y);
}
......@@ -10,7 +10,7 @@
fn f(x:isize) {
static child: isize = x + 1;
//~^ ERROR attempt to use a non-constant value in a constant
//~^ ERROR can't capture dynamic environment
}
fn main() {}
......@@ -16,7 +16,7 @@ trait PTrait {
impl PTrait for P {
fn getChildOption(&self) -> Option<Box<P>> {
static childVal: Box<P> = self.child.get();
//~^ ERROR attempt to use a non-constant value in a constant
//~^ ERROR can't capture dynamic environment
panic!();
}
}
......
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
trait Dim {
fn dim() -> usize;
}
enum Dim3 {}
impl Dim for Dim3 {
fn dim() -> usize {
3
}
}
fn main() {
let array: [usize; Dim3::dim()]
//~^ ERROR calls in constants are limited to constant functions
= [0; Dim3::dim()];
//~^ ERROR calls in constants are limited to constant functions
}
......@@ -22,12 +22,7 @@ fn dim() -> usize {
pub struct Vector<T, D: Dim> {
entries: [T; D::dim()]
//~^ ERROR cannot use an outer type parameter in this context
//~^ ERROR no associated item named `dim` found for type `D` in the current scope
}
fn main() {
let array: [usize; Dim3::dim()]
//~^ ERROR calls in constants are limited to constant functions
= [0; Dim3::dim()];
//~^ ERROR calls in constants are limited to constant functions
}
fn main() {}
......@@ -37,6 +37,10 @@ fn sub<A: Foo, B: Foo>() -> i32 {
A::X - B::X
}
trait Bar: Foo {
const Y: i32 = Self::X;
}
fn main() {
assert_eq!(11, Abc::X);
assert_eq!(97, Def::X);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册