]> git.lizzy.rs Git - rust.git/commitdiff
rustc_resolve: don't deny outer type parameters in embedded constants.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 21 Apr 2017 14:10:22 +0000 (17:10 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Sat, 13 May 2017 14:45:54 +0000 (17:45 +0300)
13 files changed:
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/test/compile-fail/E0435.rs
src/test/compile-fail/associated-const-type-parameter-arrays-2.rs
src/test/compile-fail/associated-const-type-parameter-arrays.rs
src/test/compile-fail/inner-static-type-parameter.rs
src/test/compile-fail/issue-27433.rs
src/test/compile-fail/issue-3521-2.rs
src/test/compile-fail/issue-3668-2.rs
src/test/compile-fail/issue-3668.rs
src/test/compile-fail/issue-39559-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-39559.rs
src/test/run-pass/associated-const-type-parameters.rs

index 2c2babf0a66535724b080ec1d8913c210f98eacd..368fb7a88685b00d461a33a87ba51485920c9e81 100644 (file)
@@ -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
index c4512cb38c4e24270b85ef4a5d8755801295bfbb..774e84de36638d84ba4abd4a7773081b1360734a 100644 (file)
@@ -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;
-                        }
                     }
                 }
             }
index f687633d34d86c4cb59af93ee989fae152616a6f..b15bf44fbd063dcdbd0c5af28929d175a731cb6e 100644 (file)
@@ -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
 }
index 7fd9605ef2cdc6323b7177cd822272e9e1e748a0..e284a61eb2daa3bf9d74c9d079629681749a4efa 100644 (file)
@@ -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() {
index 71c7a3965ec3c8c5af96d6211de60b14cf3ca692..848ea65a9cfd15d9a6d1a2f8e9213ef7cac55a27 100644 (file)
@@ -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() {
index a6a331984583675c99a942ea23f96347bc95f091..6fb497092d2173cc45902dd2f2c7aa83e48c1029 100644 (file)
@@ -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() {
index 78d96398b958710938f672921dc48ea45c8c3008..782b20574387136b062516765251a55c18b2c9dc 100644 (file)
@@ -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
 }
index 6cd2c02c417ea8ed5f8aacfd19367259ed7b72b5..1742cb4fb7214b5b243121c176d20757f419c927 100644 (file)
@@ -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);
 }
index 16fb2f68133f291f9519dcb591330338e28684d8..fe46877e8d34073f868cbdc647095245b9f6839b 100644 (file)
@@ -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() {}
index 9c31dc1e38ef8ff312193b105a73e9346e9d0153..00f64414a9e72eaca70a8fca55f22d510e446b88 100644 (file)
@@ -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!();
    }
 }
diff --git a/src/test/compile-fail/issue-39559-2.rs b/src/test/compile-fail/issue-39559-2.rs
new file mode 100644 (file)
index 0000000..aa07502
--- /dev/null
@@ -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 <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
+}
index b7f767f109c0c7437ce421135f1c358bb7c16cfa..871ecf269ceec4b926448bbeb08764e460ad0ba7 100644 (file)
@@ -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() {}
index b276589f0c47b1ed0b4136853d07799664f34238..df2083530646e3404c7825a4e638adf8a4a6c9b6 100644 (file)
@@ -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);