From: Eduard-Mihai Burtescu Date: Fri, 21 Apr 2017 14:10:22 +0000 (+0300) Subject: rustc_resolve: don't deny outer type parameters in embedded constants. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=dc7ffbeca452e870c18354d59300562bf6536dd3;p=rust.git rustc_resolve: don't deny outer type parameters in embedded constants. --- diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 2c2babf0a66..368fb7a8868 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -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 diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c4512cb38c4..774e84de366 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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(&mut self, f: F) self.label_ribs.pop(); } + fn with_item_rib(&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(&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; - } } } } diff --git a/src/test/compile-fail/E0435.rs b/src/test/compile-fail/E0435.rs index f687633d34d..b15bf44fbd0 100644 --- a/src/test/compile-fail/E0435.rs +++ b/src/test/compile-fail/E0435.rs @@ -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 } diff --git a/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs b/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs index 7fd9605ef2c..e284a61eb2d 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs @@ -26,7 +26,7 @@ impl Foo for Def { pub fn test() { let _array = [4; ::Y]; - //~^ ERROR cannot use an outer type parameter in this context [E0402] + //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277] } fn main() { diff --git a/src/test/compile-fail/associated-const-type-parameter-arrays.rs b/src/test/compile-fail/associated-const-type-parameter-arrays.rs index 71c7a3965ec..848ea65a9cf 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arrays.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arrays.rs @@ -26,7 +26,7 @@ impl Foo for Def { pub fn test() { let _array: [u32; ::Y]; - //~^ ERROR cannot use an outer type parameter in this context [E0402] + //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277] } fn main() { diff --git a/src/test/compile-fail/inner-static-type-parameter.rs b/src/test/compile-fail/inner-static-type-parameter.rs index a6a33198458..6fb497092d2 100644 --- a/src/test/compile-fail/inner-static-type-parameter.rs +++ b/src/test/compile-fail/inner-static-type-parameter.rs @@ -14,7 +14,7 @@ enum Bar { What } //~ ERROR parameter `T` is never used fn foo() { static a: Bar = 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() { diff --git a/src/test/compile-fail/issue-27433.rs b/src/test/compile-fail/issue-27433.rs index 78d96398b95..782b2057438 100644 --- a/src/test/compile-fail/issue-27433.rs +++ b/src/test/compile-fail/issue-27433.rs @@ -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 } diff --git a/src/test/compile-fail/issue-3521-2.rs b/src/test/compile-fail/issue-3521-2.rs index 6cd2c02c417..1742cb4fb72 100644 --- a/src/test/compile-fail/issue-3521-2.rs +++ b/src/test/compile-fail/issue-3521-2.rs @@ -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); } diff --git a/src/test/compile-fail/issue-3668-2.rs b/src/test/compile-fail/issue-3668-2.rs index 16fb2f68133..fe46877e8d3 100644 --- a/src/test/compile-fail/issue-3668-2.rs +++ b/src/test/compile-fail/issue-3668-2.rs @@ -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() {} diff --git a/src/test/compile-fail/issue-3668.rs b/src/test/compile-fail/issue-3668.rs index 9c31dc1e38e..00f64414a9e 100644 --- a/src/test/compile-fail/issue-3668.rs +++ b/src/test/compile-fail/issue-3668.rs @@ -16,7 +16,7 @@ trait PTrait { impl PTrait for P { fn getChildOption(&self) -> Option> { static childVal: Box

= self.child.get(); - //~^ ERROR attempt to use a non-constant value in a constant + //~^ ERROR can't capture dynamic environment panic!(); } } diff --git a/src/test/compile-fail/issue-39559-2.rs b/src/test/compile-fail/issue-39559-2.rs new file mode 100644 index 00000000000..aa075023064 --- /dev/null +++ b/src/test/compile-fail/issue-39559-2.rs @@ -0,0 +1,28 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/compile-fail/issue-39559.rs b/src/test/compile-fail/issue-39559.rs index b7f767f109c..871ecf269ce 100644 --- a/src/test/compile-fail/issue-39559.rs +++ b/src/test/compile-fail/issue-39559.rs @@ -22,12 +22,7 @@ fn dim() -> usize { pub struct Vector { 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() {} diff --git a/src/test/run-pass/associated-const-type-parameters.rs b/src/test/run-pass/associated-const-type-parameters.rs index b276589f0c4..df208353064 100644 --- a/src/test/run-pass/associated-const-type-parameters.rs +++ b/src/test/run-pass/associated-const-type-parameters.rs @@ -37,6 +37,10 @@ fn sub() -> 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);