Stabilize static_recursion

This commit is contained in:
Taylor Cramer 2017-02-21 23:41:04 -08:00
parent fc6f092c21
commit 802a826a57
8 changed files with 8 additions and 94 deletions

View file

@ -18,7 +18,6 @@ use rustc::hir::def::{Def, CtorKind};
use rustc::util::nodemap::{NodeMap, NodeSet};
use syntax::ast;
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax_pos::Span;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir;
@ -43,7 +42,7 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
match it.node {
hir::ItemStatic(..) |
hir::ItemConst(..) => {
let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &it.span);
let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
recursion_visitor.visit_item(it);
}
hir::ItemEnum(ref enum_def, ref generics) => {
@ -52,8 +51,7 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
// less redundant output.
for variant in &enum_def.variants {
if let Some(_) = variant.node.disr_expr {
let mut recursion_visitor = CheckItemRecursionVisitor::new(self,
&variant.span);
let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
recursion_visitor.populate_enum_discriminants(enum_def);
recursion_visitor.visit_variant(variant, generics, it.id);
}
@ -68,7 +66,7 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
match ti.node {
hir::TraitItemKind::Const(_, ref default) => {
if let Some(_) = *default {
let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ti.span);
let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
recursion_visitor.visit_trait_item(ti);
}
}
@ -80,7 +78,7 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) {
match ii.node {
hir::ImplItemKind::Const(..) => {
let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ii.span);
let mut recursion_visitor = CheckItemRecursionVisitor::new(self);
recursion_visitor.visit_impl_item(ii);
}
_ => {}
@ -105,7 +103,6 @@ pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) -> Compil
}
struct CheckItemRecursionVisitor<'a, 'b: 'a, 'hir: 'b> {
root_span: &'b Span,
sess: &'b Session,
hir_map: &'b hir_map::Map<'hir>,
discriminant_map: &'a mut NodeMap<Option<hir::BodyId>>,
@ -114,9 +111,8 @@ struct CheckItemRecursionVisitor<'a, 'b: 'a, 'hir: 'b> {
}
impl<'a, 'b: 'a, 'hir: 'b> CheckItemRecursionVisitor<'a, 'b, 'hir> {
fn new(v: &'a mut CheckCrateVisitor<'b, 'hir>, span: &'b Span) -> Self {
fn new(v: &'a mut CheckCrateVisitor<'b, 'hir>) -> Self {
CheckItemRecursionVisitor {
root_span: span,
sess: v.sess,
hir_map: v.hir_map,
discriminant_map: &mut v.discriminant_map,
@ -143,15 +139,7 @@ impl<'a, 'b: 'a, 'hir: 'b> CheckItemRecursionVisitor<'a, 'b, 'hir> {
false
}
});
if any_static {
if !self.sess.features.borrow().static_recursion {
emit_feature_err(&self.sess.parse_sess,
"static_recursion",
*self.root_span,
GateIssue::Language,
"recursive static");
}
} else {
if !any_static {
struct_span_err!(self.sess, span, E0265, "recursive constant")
.span_label(span, &format!("recursion not allowed in constant"))
.emit();

View file

@ -197,9 +197,6 @@ declare_features! (
// rustc internal
(active, prelude_import, "1.2.0", None),
// Allows the definition recursive static items.
(active, static_recursion, "1.3.0", Some(29719)),
// Allows default type parameters to influence type inference.
(active, default_type_parameter_fallback, "1.3.0", Some(27336)),
@ -384,6 +381,8 @@ declare_features! (
(accepted, static_in_const, "1.17.0", Some(35897)),
// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
(accepted, field_init_shorthand, "1.17.0", Some(37340)),
// Allows the definition recursive static items.
(accepted, static_recursion, "1.17.0", Some(29719)),
);
// (changing above list without updating src/doc/reference.md makes @cmr sad)

View file

@ -1,49 +0,0 @@
// Copyright 2015 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.
static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
//~^ ERROR recursive static (see issue #29719)
struct StaticDoubleLinked {
prev: &'static StaticDoubleLinked,
next: &'static StaticDoubleLinked,
data: i32,
head: bool,
}
static L1: StaticDoubleLinked = StaticDoubleLinked{prev: &L3, next: &L2, data: 1, head: true};
//~^ ERROR recursive static (see issue #29719)
//~^^ ERROR recursive static (see issue #29719)
//~^^^ ERROR recursive static (see issue #29719)
static L2: StaticDoubleLinked = StaticDoubleLinked{prev: &L1, next: &L3, data: 2, head: false};
static L3: StaticDoubleLinked = StaticDoubleLinked{prev: &L2, next: &L1, data: 3, head: false};
pub fn main() {
unsafe { assert_eq!(S, *(S as *const *const u8)); }
let mut test_vec = Vec::new();
let mut cur = &L1;
loop {
test_vec.push(cur.data);
cur = cur.next;
if cur.head { break }
}
assert_eq!(&test_vec, &[1,2,3]);
let mut test_vec = Vec::new();
let mut cur = &L1;
loop {
cur = cur.prev;
test_vec.push(cur.data);
if cur.head { break }
}
assert_eq!(&test_vec, &[3,2,1]);
}

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(static_recursion)]
enum foo { foo_(bar) }
struct bar { x: bar }
//~^ ERROR E0072

View file

@ -1,16 +0,0 @@
// Copyright 2015 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.
static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
//~^ ERROR recursive static
pub fn main() {
unsafe { assert_eq!(S, *(S as *const *const u8)); }
}

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(static_recursion)]
// test that autoderef of a type like this does not
// cause compiler to loop. Note that no instances
// of such a type could ever be constructed.

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(static_recursion)]
// test that autoderef of a type like this does not
// cause compiler to loop. Note that no instances
// of such a type could ever be constructed.

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(static_recursion)]
static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
struct StaticDoubleLinked {