diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 7ef9ba76b99..db5b12f021e 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -145,7 +145,7 @@ impl TreeMap { pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { TreeMapIterator { stack: ~[], - node: &self.root, + node: deref(&self.root), remaining_min: self.length, remaining_max: self.length } @@ -162,7 +162,7 @@ impl TreeMap { fn iter_for_traversal<'a>(&'a self) -> TreeMapIterator<'a, K, V> { TreeMapIterator { stack: ~[], - node: &self.root, + node: deref(&self.root), remaining_min: 0, remaining_max: self.length } @@ -173,8 +173,8 @@ impl TreeMap { pub fn lower_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal(); loop { - match *iter.node { - Some(ref r) => { + match iter.node { + Some(r) => { match k.cmp(&r.key) { Less => iter_traverse_left(&mut iter), Greater => iter_traverse_right(&mut iter), @@ -197,8 +197,8 @@ impl TreeMap { pub fn upper_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal(); loop { - match *iter.node { - Some(ref r) => { + match iter.node { + Some(r) => { match k.cmp(&r.key) { Less => iter_traverse_left(&mut iter), Greater => iter_traverse_right(&mut iter), @@ -229,24 +229,34 @@ impl TreeMap { /// Lazy forward iterator over a map pub struct TreeMapIterator<'self, K, V> { - priv stack: ~[&'self ~TreeNode], - priv node: &'self Option<~TreeNode>, + priv stack: ~[&'self TreeNode], + priv node: Option<&'self TreeNode>, priv remaining_min: uint, priv remaining_max: uint } +fn deref<'a, K, V>(node: &'a Option<~TreeNode>) -> Option<&'a TreeNode> { + match *node { + Some(ref n) => { + let n: &TreeNode = *n; + Some(n) + } + None => None + } +} + impl<'self, K, V> TreeMapIterator<'self, K, V> { #[inline(always)] fn next_(&mut self, forward: bool) -> Option<(&'self K, &'self V)> { while !self.stack.is_empty() || self.node.is_some() { - match *self.node { - Some(ref x) => { + match self.node { + Some(x) => { self.stack.push(x); - self.node = if forward { &x.left } else { &x.right }; + self.node = deref(if forward { &x.left } else { &x.right }); } None => { let res = self.stack.pop(); - self.node = if forward { &res.right } else { &res.left }; + self.node = deref(if forward { &res.right } else { &res.left }); self.remaining_max -= 1; if self.remaining_min > 0 { self.remaining_min -= 1; @@ -302,14 +312,14 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapRevIterator<'self, K /// - complete initialization with `iter_traverse_complete` #[inline] fn iter_traverse_left<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - let node = it.node.get_ref(); + let node = it.node.unwrap(); it.stack.push(node); - it.node = &node.left; + it.node = deref(&node.left); } #[inline] fn iter_traverse_right<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - it.node = &(it.node.get_ref().right); + it.node = deref(&it.node.get_ref().right); } /// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to @@ -321,11 +331,10 @@ fn iter_traverse_right<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { /// traversed left. #[inline] fn iter_traverse_complete<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - static none: Option<~TreeNode> = None; - match *it.node { - Some(ref n) => { + match it.node { + Some(n) => { it.stack.push(n); - it.node = &none; + it.node = None; } None => () } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8c5deeb94d5..9f848b4c227 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3488,10 +3488,17 @@ impl Resolver { return None; } ConstantItemRibKind => { - // Still doesn't deal with upvars - self.resolve_error(span, - "attempt to use a non-constant \ - value in a constant"); + if is_ty_param { + // see #9186 + self.resolve_error(span, + "cannot use an outer type \ + parameter in this context"); + } else { + // Still doesn't deal with upvars + self.resolve_error(span, + "attempt to use a non-constant \ + value in a constant"); + } } } @@ -3764,7 +3771,9 @@ impl Resolver { fn with_constant_rib(&mut self, f: &fn(&mut Resolver)) { self.value_ribs.push(@Rib::new(ConstantItemRibKind)); + self.type_ribs.push(@Rib::new(ConstantItemRibKind)); f(self); + self.type_ribs.pop(); self.value_ribs.pop(); } diff --git a/src/test/compile-fail/inner-static-type-parameter.rs b/src/test/compile-fail/inner-static-type-parameter.rs new file mode 100644 index 00000000000..0ec4b62f8d2 --- /dev/null +++ b/src/test/compile-fail/inner-static-type-parameter.rs @@ -0,0 +1,21 @@ +// Copyright 2013 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. + +// see #9186 + +enum Bar { What } + +fn foo() { + static a: Bar = What; + //~^ ERROR: cannot use an outer type parameter in this context +} + +fn main() { +}