From bde225e2fafc7f593cfa5a9e1e6c750264682b71 Mon Sep 17 00:00:00 2001 From: Jakub Bukaj Date: Tue, 18 Nov 2014 17:39:16 +0100 Subject: [PATCH] Feature gate non-ASCII lifetime identifiers Fixes #19069. --- src/librustc/lint/builtin.rs | 2 +- src/librustc/lint/context.rs | 4 ++-- src/librustc/lint/mod.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc_back/svh.rs | 6 +++--- src/libsyntax/ast_map/mod.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/feature_gate.rs | 4 ++-- src/libsyntax/visit.rs | 26 ++++++++++++++++++------- src/test/compile-fail/utf8_idents.rs | 24 +++++++++++++++++++++++ 10 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/utf8_idents.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index df014eb1206..9ab45ff0f7a 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -992,7 +992,7 @@ impl LintPass for NonSnakeCase { self.check_snake_case(cx, "trait method", t.ident, t.span); } - fn check_lifetime_decl(&mut self, cx: &Context, t: &ast::LifetimeDef) { + fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) { self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span); } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e9b235a2fe3..52d1c72de68 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -725,8 +725,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { run_lints!(self, check_lifetime_ref, lt); } - fn visit_lifetime_decl(&mut self, lt: &ast::LifetimeDef) { - run_lints!(self, check_lifetime_decl, lt); + fn visit_lifetime_def(&mut self, lt: &ast::LifetimeDef) { + run_lints!(self, check_lifetime_def, lt); } fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 315462235be..d6b83752cc5 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -155,7 +155,7 @@ pub trait LintPass { fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) { } fn check_opt_lifetime_ref(&mut self, _: &Context, _: Span, _: &Option) { } fn check_lifetime_ref(&mut self, _: &Context, _: &ast::Lifetime) { } - fn check_lifetime_decl(&mut self, _: &Context, _: &ast::LifetimeDef) { } + fn check_lifetime_def(&mut self, _: &Context, _: &ast::LifetimeDef) { } fn check_explicit_self(&mut self, _: &Context, _: &ast::ExplicitSelf) { } fn check_mac(&mut self, _: &Context, _: &ast::Mac) { } fn check_path(&mut self, _: &Context, _: &ast::Path, _: ast::NodeId) { } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a1257caf47f..3fc92a84194 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -226,7 +226,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |this| { this.check_lifetime_defs(&trait_ref.bound_lifetimes); for lifetime in trait_ref.bound_lifetimes.iter() { - this.visit_lifetime_decl(lifetime); + this.visit_lifetime_def(lifetime); } this.visit_trait_ref(&trait_ref.trait_ref) }) diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index c7a7888c1cd..2cca63bd65d 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -181,7 +181,7 @@ mod svh_visitor { SawStructDef(token::InternedString), SawLifetimeRef(token::InternedString), - SawLifetimeDecl(token::InternedString), + SawLifetimeDef(token::InternedString), SawMod, SawViewItem, @@ -414,8 +414,8 @@ mod svh_visitor { SawLifetimeRef(content(l.name)).hash(self.st); } - fn visit_lifetime_decl(&mut self, l: &LifetimeDef) { - SawLifetimeDecl(content(l.lifetime.name)).hash(self.st); + fn visit_lifetime_def(&mut self, l: &LifetimeDef) { + SawLifetimeDef(content(l.lifetime.name)).hash(self.st); } // We do recursively walk the bodies of functions/methods diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index b116c84552e..472331bc9e1 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -866,7 +866,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert(lifetime.id, NodeLifetime(lifetime)); } - fn visit_lifetime_decl(&mut self, def: &'ast LifetimeDef) { + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { self.visit_lifetime_ref(&def.lifetime); } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 30cdecbc851..043e79bffd9 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -535,7 +535,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { self.operation.visit_id(lifetime.id); } - fn visit_lifetime_decl(&mut self, def: &'v LifetimeDef) { + fn visit_lifetime_def(&mut self, def: &'v LifetimeDef) { self.visit_lifetime_ref(&def.lifetime); } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ebdcf278934..460a94a8d5a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -141,8 +141,8 @@ impl<'a> Context<'a> { } impl<'a, 'v> Visitor<'v> for Context<'a> { - fn visit_ident(&mut self, sp: Span, id: ast::Ident) { - if !token::get_ident(id).get().is_ascii() { + fn visit_name(&mut self, sp: Span, name: ast::Name) { + if !token::get_name(name).get().is_ascii() { self.gate_feature("non_ascii_idents", sp, "non-ascii idents are not fully supported."); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index efe1e18eda9..e98cc3b9c71 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -55,8 +55,11 @@ pub enum FnKind<'a> { /// new default implementation gets introduced.) pub trait Visitor<'v> { - fn visit_ident(&mut self, _sp: Span, _ident: Ident) { - /*! Visit the idents */ + fn visit_name(&mut self, _span: Span, _name: Name) { + // Nothing to do. + } + fn visit_ident(&mut self, span: Span, ident: Ident) { + self.visit_name(span, ident.name); } fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) } fn visit_view_item(&mut self, i: &'v ViewItem) { walk_view_item(self, i) } @@ -102,11 +105,11 @@ pub trait Visitor<'v> { None => () } } - fn visit_lifetime_ref(&mut self, _lifetime: &'v Lifetime) { - /*! Visits a reference to a lifetime */ + fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) { + self.visit_name(lifetime.span, lifetime.name) } - fn visit_lifetime_decl(&mut self, _lifetime: &'v LifetimeDef) { - /*! Visits a declaration of a lifetime */ + fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) { + walk_lifetime_def(self, lifetime) } fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { walk_explicit_self(self, es) @@ -207,6 +210,14 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { walk_expr_opt(visitor, &local.init); } +pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, + lifetime_def: &'v LifetimeDef) { + visitor.visit_lifetime_ref(&lifetime_def.lifetime); + for bound in lifetime_def.bounds.iter() { + visitor.visit_lifetime_ref(bound); + } +} + pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, explicit_self: &'v ExplicitSelf) { match explicit_self.node { @@ -424,7 +435,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { pub fn walk_lifetime_decls_helper<'v, V: Visitor<'v>>(visitor: &mut V, lifetimes: &'v Vec) { for l in lifetimes.iter() { - visitor.visit_lifetime_decl(l); + visitor.visit_lifetime_def(l); } } @@ -555,6 +566,7 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { for type_parameter in generics.ty_params.iter() { + visitor.visit_ident(type_parameter.span, type_parameter.ident); walk_ty_param_bounds_helper(visitor, &type_parameter.bounds); match type_parameter.default { Some(ref ty) => visitor.visit_ty(&**ty), diff --git a/src/test/compile-fail/utf8_idents.rs b/src/test/compile-fail/utf8_idents.rs new file mode 100644 index 00000000000..0c3c11ccd07 --- /dev/null +++ b/src/test/compile-fail/utf8_idents.rs @@ -0,0 +1,24 @@ +// 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. +// +// ignore-lexer-test FIXME #15679 + +fn foo< + 'β, //~ ERROR non-ascii idents are not fully supported. + γ //~ ERROR non-ascii idents are not fully supported. +>() {} + +struct X { + δ: uint //~ ERROR non-ascii idents are not fully supported. +} + +pub fn main() { + let α = 0.00001f64; //~ ERROR non-ascii idents are not fully supported. +}