about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-04-21 17:10:22 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-05-13 17:45:54 +0300
commitdc7ffbeca452e870c18354d59300562bf6536dd3 (patch)
tree66abc8a61d0f48223013e744e9f17a4d33cc9019 /src/librustc_resolve
parentef3ec5ece5bdf8950810225a9a3bc3cd1926e3d5 (diff)
downloadrust-dc7ffbeca452e870c18354d59300562bf6536dd3.tar.gz
rust-dc7ffbeca452e870c18354d59300562bf6536dd3.zip
rustc_resolve: don't deny outer type parameters in embedded constants.
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/diagnostics.rs15
-rw-r--r--src/librustc_resolve/lib.rs53
2 files changed, 32 insertions, 36 deletions
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 foo() {
 "##,
 
 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 @@ register_diagnostics! {
 //  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 @@ impl Ord for BindingError {
 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 @@ impl<'a> Resolver<'a> {
                             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 @@ impl<'a> Resolver<'a> {
                 });
             }
 
-            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 @@ impl<'a> Resolver<'a> {
         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 @@ impl<'a> Resolver<'a> {
                 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 @@ impl<'a> Resolver<'a> {
                             }
                             return Def::Err;
                         }
-                        ConstantItemRibKind => {
-                            // see #9186
-                            if record_used {
-                                resolve_error(self, span,
-                                              ResolutionError::OuterTypeParameterContext);
-                            }
-                            return Def::Err;
-                        }
                     }
                 }
             }