diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index f9d2ac5afd884..925d9430ede8c 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -59,6 +59,10 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("quad_precision_float", Active), + // A temporary feature gate used to enable parser extensions needed + // to bootstrap fix for #5723. + ("issue_5723_bootstrap", Active), + // These are used to test this portion of the compiler, they don't actually // mean anything ("test_accepted_feature", Accepted), @@ -80,14 +84,16 @@ enum Status { /// A set of features to be used by later passes. pub struct Features { pub default_type_params: Cell, - pub quad_precision_float: Cell + pub quad_precision_float: Cell, + pub issue_5723_bootstrap: Cell, } impl Features { pub fn new() -> Features { Features { default_type_params: Cell::new(false), - quad_precision_float: Cell::new(false) + quad_precision_float: Cell::new(false), + issue_5723_bootstrap: Cell::new(false), } } } @@ -367,4 +373,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { sess.features.default_type_params.set(cx.has_feature("default_type_params")); sess.features.quad_precision_float.set(cx.has_feature("quad_precision_float")); + sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap")); } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index cd6cd48508d73..38aa64b92daca 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3828,7 +3828,8 @@ impl<'a> Resolver<'a> { TraitTyParamBound(ref tref) => { self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter) } - RegionTyParamBound => {} + StaticRegionTyParamBound => {} + OtherRegionTyParamBound(_) => {} } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 77f339ec10e24..cc8aab3a87ceb 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -818,9 +818,17 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option { + ast::StaticRegionTyParamBound => { builtin_bounds.add(ty::BoundStatic); } + ast::OtherRegionTyParamBound(span) => { + if !tcx.sess.features.issue_5723_bootstrap.get() { + tcx.sess.span_err( + span, + format!("only the 'static lifetime is \ + accepted here.")); + } + } } } builtin_bounds diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 9c49512d4dc0d..bb829a1145228 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -50,7 +50,8 @@ use std::rc::Rc; use collections::{HashMap, HashSet}; use syntax::abi; -use syntax::ast::{RegionTyParamBound, TraitTyParamBound}; +use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, + TraitTyParamBound}; use syntax::ast; use syntax::ast_map; use syntax::ast_util::{local_def, split_trait_methods}; @@ -1109,9 +1110,18 @@ fn ty_generics(ccx: &CrateCtxt, } } - RegionTyParamBound => { + StaticRegionTyParamBound => { param_bounds.builtin_bounds.add(ty::BoundStatic); } + + OtherRegionTyParamBound(span) => { + if !ccx.tcx.sess.features.issue_5723_bootstrap.get() { + ccx.tcx.sess.span_err( + span, + format!("only the 'static lifetime is \ + accepted here.")); + } + } } } diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index df102b8aadf3f..b87b6988a3a60 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -893,7 +893,8 @@ impl<'a> Rebuilder<'a> { -> OwnedSlice { ty_param_bounds.map(|tpb| { match tpb { - &ast::RegionTyParamBound => ast::RegionTyParamBound, + &ast::StaticRegionTyParamBound => ast::StaticRegionTyParamBound, + &ast::OtherRegionTyParamBound(s) => ast::OtherRegionTyParamBound(s), &ast::TraitTyParamBound(ref tr) => { let last_seg = tr.path.segments.last().unwrap(); let mut insert = Vec::new(); diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index cabfe695df714..d904a0ce6a207 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -350,7 +350,8 @@ pub enum TyParamBound { impl Clean for ast::TyParamBound { fn clean(&self) -> TyParamBound { match *self { - ast::RegionTyParamBound => RegionBound, + ast::StaticRegionTyParamBound => RegionBound, + ast::OtherRegionTyParamBound(_) => RegionBound, ast::TraitTyParamBound(ref t) => TraitBound(t.clean()), } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 45f753d0e9832..b65215e71a6d4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -173,7 +173,8 @@ pub static DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - RegionTyParamBound + StaticRegionTyParamBound, + OtherRegionTyParamBound(Span) // FIXME -- just here until work for #5723 lands } #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 47ef23b82d2e2..685e08dd91819 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -437,7 +437,8 @@ fn fold_ty_param_bound(tpb: &TyParamBound, fld: &mut T) -> TyParamBound { match *tpb { TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), - RegionTyParamBound => RegionTyParamBound + StaticRegionTyParamBound => StaticRegionTyParamBound, + OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s) } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5d8443b64d5ef..1917ea2dafb01 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -12,7 +12,7 @@ use abi; use ast::{BareFnTy, ClosureTy}; -use ast::{RegionTyParamBound, TraitTyParamBound}; +use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound}; use ast::{Provided, Public, FnStyle}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, Block}; @@ -3351,7 +3351,7 @@ impl<'a> Parser<'a> { token::LIFETIME(lifetime) => { let lifetime_interned_string = token::get_ident(lifetime); if lifetime_interned_string.equiv(&("static")) { - result.push(RegionTyParamBound); + result.push(StaticRegionTyParamBound); if allow_any_lifetime && ret_lifetime.is_none() { ret_lifetime = Some(ast::Lifetime { id: ast::DUMMY_NODE_ID, @@ -3366,8 +3366,7 @@ impl<'a> Parser<'a> { name: lifetime.name }); } else { - self.span_err(self.span, - "`'static` is the only permissible region bound here"); + result.push(OtherRegionTyParamBound(self.span)); } self.bump(); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7ea4dcbf28a2e..09e0684ba293b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -9,7 +9,8 @@ // except according to those terms. use abi; -use ast::{P, RegionTyParamBound, TraitTyParamBound, Required, Provided}; +use ast::{P, StaticRegionTyParamBound, OtherRegionTyParamBound, + TraitTyParamBound, Required, Provided}; use ast; use ast_util; use owned_slice::OwnedSlice; @@ -1882,7 +1883,8 @@ impl<'a> State<'a> { try!(match *bound { TraitTyParamBound(ref tref) => self.print_trait_ref(tref), - RegionTyParamBound => word(&mut self.s, "'static"), + StaticRegionTyParamBound => word(&mut self.s, "'static"), + OtherRegionTyParamBound(_) => Ok(()) }) } Ok(()) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 260ba2470921e..f715b3a68aee9 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -472,7 +472,8 @@ pub fn walk_ty_param_bounds>(visitor: &mut V, TraitTyParamBound(ref typ) => { walk_trait_ref_helper(visitor, typ, env.clone()) } - RegionTyParamBound => {} + StaticRegionTyParamBound => {} + OtherRegionTyParamBound(..) => {} } } } diff --git a/src/test/compile-fail/regions-bound-lists-feature-gate.rs b/src/test/compile-fail/regions-bound-lists-feature-gate.rs new file mode 100644 index 0000000000000..05050b72e5e8d --- /dev/null +++ b/src/test/compile-fail/regions-bound-lists-feature-gate.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 Foo { } + +fn foo<'a>(x: ~Foo:'a) { //~ ERROR only the 'static lifetime is accepted here +} + +fn bar<'a, T:'a>() { //~ ERROR only the 'static lifetime is accepted here +} + +fn main() { } diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs new file mode 100644 index 0000000000000..e2ac9e4c79e0c --- /dev/null +++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs @@ -0,0 +1,22 @@ +// Copyright 2014 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. + + +#![feature(issue_5723_bootstrap)] + +trait Foo { } + +fn foo<'a>(x: ~Foo:'a) { +} + +fn bar<'a, T:'a>() { +} + +pub fn main() { }