From c3825c835197a97ff4f254802efde80335d3833b Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 7 Aug 2013 00:50:23 -0400 Subject: [PATCH] env! syntax extension changes env! aborts compilation of the specified environment variable is not defined and takes an optional second argument containing a custom error message. option_env! creates an Option<&'static str> containing the value of the environment variable. There are no run-pass tests that check the behavior when the environment variable is defined since the test framework doesn't support setting environment variables at compile time as opposed to runtime. However, both env! and option_env! are used inside of rustc itself, which should act as a sufficient test. Close #2248 --- src/librustc/back/rpath.rs | 9 +++++ src/librustc/driver/driver.rs | 16 ++++++++- src/librustc/metadata/filesearch.rs | 8 ++++- src/librustc/middle/resolve.rs | 6 ++-- src/librustc/rustc.rs | 11 ++++++ src/libsyntax/ext/asm.rs | 4 +-- src/libsyntax/ext/base.rs | 14 ++++---- src/libsyntax/ext/env.rs | 36 ++++++++++++++----- src/libsyntax/ext/fmt.rs | 4 +-- .../extenv-arg-2-not-string-literal.rs | 11 ++++++ src/test/compile-fail/extenv-no-args.rs | 6 ++-- .../compile-fail/extenv-not-defined-custom.rs | 11 ++++++ .../extenv-not-defined-default.rs | 11 ++++++ .../compile-fail/extenv-not-string-literal.rs | 6 ++-- src/test/compile-fail/extenv-too-many-args.rs | 4 +-- .../compile-fail/extoption_env-no-args.rs | 11 ++++++ .../extoption_env-not-string-literal.rs | 11 ++++++ .../extoption_env-too-many-args.rs | 11 ++++++ .../run-pass/extoption_env-not-defined.rs | 14 ++++++++ 19 files changed, 170 insertions(+), 34 deletions(-) create mode 100644 src/test/compile-fail/extenv-arg-2-not-string-literal.rs create mode 100644 src/test/compile-fail/extenv-not-defined-custom.rs create mode 100644 src/test/compile-fail/extenv-not-defined-default.rs create mode 100644 src/test/compile-fail/extoption_env-no-args.rs create mode 100644 src/test/compile-fail/extoption_env-not-string-literal.rs create mode 100644 src/test/compile-fail/extoption_env-too-many-args.rs create mode 100644 src/test/run-pass/extoption_env-not-defined.rs diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 571721ed40c..6aac627729c 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -168,6 +168,7 @@ pub fn get_absolute_rpath(lib: &Path) -> Path { os::make_absolute(lib).dir_path() } +#[cfg(stage0)] pub fn get_install_prefix_rpath(target_triple: &str) -> Path { let install_prefix = env!("CFG_PREFIX"); @@ -179,6 +180,14 @@ pub fn get_install_prefix_rpath(target_triple: &str) -> Path { os::make_absolute(&Path(install_prefix).push_rel(&tlib)) } +#[cfg(not(stage0))] +pub fn get_install_prefix_rpath(target_triple: &str) -> Path { + let install_prefix = env!("CFG_PREFIX"); + + let tlib = filesearch::relative_target_lib_path(target_triple); + os::make_absolute(&Path(install_prefix).push_rel(&tlib)) +} + pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { let mut set = HashSet::new(); let mut minimized = ~[]; diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 61ab826e9ee..1cf758b7e6c 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -578,6 +578,7 @@ pub fn build_target_config(sopts: @session::options, return target_cfg; } +#[cfg(stage0)] pub fn host_triple() -> ~str { // Get the host triple out of the build environment. This ensures that our // idea of the host triple is the same as for the set of libraries we've @@ -595,6 +596,19 @@ pub fn host_triple() -> ~str { }; } +#[cfg(not(stage0))] +pub fn host_triple() -> ~str { + // Get the host triple out of the build environment. This ensures that our + // idea of the host triple is the same as for the set of libraries we've + // actually built. We can't just take LLVM's host triple because they + // normalize all ix86 architectures to i386. + // + // Instead of grabbing the host triple (for the current host), we grab (at + // compile time) the target triple that this rustc is built with and + // calling that (at runtime) the host triple. + (env!("CFG_COMPILER_TRIPLE")).to_owned() +} + pub fn build_session_options(binary: @str, matches: &getopts::Matches, demitter: diagnostic::Emitter) diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 2422be3960b..e18879464e8 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -186,6 +186,7 @@ fn get_rustpkg_lib_path_nearest() -> Result { // The name of the directory rustc expects libraries to be located. // On Unix should be "lib", on windows "bin" +#[cfg(stage0)] pub fn libdir() -> ~str { let libdir = env!("CFG_LIBDIR"); if libdir.is_empty() { @@ -193,3 +194,8 @@ pub fn libdir() -> ~str { } libdir.to_owned() } + +#[cfg(not(stage0))] +pub fn libdir() -> ~str { + (env!("CFG_LIBDIR")).to_owned() +} diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index da0ba1558c9..d17646a95b5 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -4991,7 +4991,9 @@ impl Resolver { if self.structs.contains(&class_id) => { self.record_def(expr.id, definition); } - _ => { + result => { + debug!("(resolving expression) didn't find struct \ + def: %?", result); self.session.span_err( path.span, fmt!("`%s` does not name a structure", diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 1dfca0ba0e8..5b4565590b9 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -117,6 +117,7 @@ mod std { } */ +#[cfg(stage0)] pub fn version(argv0: &str) { let mut vers = ~"unknown version"; let env_vers = env!("CFG_VERSION"); @@ -125,6 +126,16 @@ pub fn version(argv0: &str) { printfln!("host: %s", host_triple()); } +#[cfg(not(stage0))] +pub fn version(argv0: &str) { + let vers = match option_env!("CFG_VERSION") { + Some(vers) => vers, + None => "unknown version" + }; + printfln!("%s %s", argv0, vers); + printfln!("host: %s", host_triple()); +} + pub fn usage(argv0: &str) { let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0); printfln!("%s\ diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index ee0ec664e1b..b5d97427baf 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -59,7 +59,7 @@ pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) match state { Asm => { asm = expr_to_str(cx, p.parse_expr(), - ~"inline assembly must be a string literal."); + "inline assembly must be a string literal."); } Outputs => { while *p.token != token::EOF && diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index efaf6b8e001..1ba32442d5e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -146,7 +146,9 @@ pub fn syntax_expander_table() -> SyntaxEnv { intern(&"auto_decode"), @SE(ItemDecorator(ext::auto_encode::expand_auto_decode))); syntax_expanders.insert(intern(&"env"), - builtin_normal_tt(ext::env::expand_syntax_ext)); + builtin_normal_tt(ext::env::expand_env)); + syntax_expanders.insert(intern(&"option_env"), + builtin_normal_tt(ext::env::expand_option_env)); syntax_expanders.insert(intern("bytes"), builtin_normal_tt(ext::bytes::expand_syntax_ext)); syntax_expanders.insert(intern("concat_idents"), @@ -311,7 +313,7 @@ impl ExtCtxt { } } -pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: ~str) -> @str { +pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> @str { match expr.node { ast::expr_lit(l) => match l.node { ast::lit_str(s) => s, @@ -536,8 +538,8 @@ mod test { a.insert (@"abc",@15); let m = MapChain::new(~a); m.insert (@"def",@16); - // FIXME: #4492 (ICE) assert_eq!(m.find(&@"abc"),Some(@15)); - // .... assert_eq!(m.find(&@"def"),Some(@16)); + assert_eq!(m.find(&@"abc"),Some(@15)); + assert_eq!(m.find(&@"def"),Some(@16)); assert_eq!(*(m.find(&@"abc").unwrap()),15); assert_eq!(*(m.find(&@"def").unwrap()),16); let n = m.push_frame(); @@ -549,8 +551,8 @@ mod test { assert_eq!(*(n.find(&@"abc").unwrap()),15); assert_eq!(*(n.find(&@"def").unwrap()),17); // ... but m still has the old ones - // FIXME: #4492: assert_eq!(m.find(&@"abc"),Some(@15)); - // FIXME: #4492: assert_eq!(m.find(&@"def"),Some(@16)); + assert_eq!(m.find(&@"abc"),Some(@15)); + assert_eq!(m.find(&@"def"),Some(@16)); assert_eq!(*(m.find(&@"abc").unwrap()),15); assert_eq!(*(m.find(&@"def").unwrap()),16); } diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index a6cb6155878..c9e01b0f0d5 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -22,17 +22,35 @@ use ext::build::AstBuilder; use std::os; -pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) +pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult { - - let var = get_single_str_from_tts(cx, sp, tts, "env!"); - - // FIXME (#2248): if this was more thorough it would manufacture an - // Option rather than just an maybe-empty string. + let var = get_single_str_from_tts(ext_cx, sp, tts, "option_env!"); let e = match os::getenv(var) { - None => cx.expr_str(sp, @""), - Some(s) => cx.expr_str(sp, s.to_managed()) + None => quote_expr!(::std::option::None), + Some(s) => quote_expr!(::std::option::Some($s)) + }; + MRExpr(e) +} + +pub fn expand_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) + -> base::MacResult { + let exprs = get_exprs_from_tts(ext_cx, sp, tts); + + if exprs.len() == 0 { + ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments"); + } + + let var = expr_to_str(ext_cx, exprs[0], "expected string literal"); + let msg = match exprs.len() { + 1 => fmt!("Environment variable %s not defined", var).to_managed(), + 2 => expr_to_str(ext_cx, exprs[1], "expected string literal"), + _ => ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments") + }; + + let e = match os::getenv(var) { + None => ext_cx.span_fatal(sp, msg), + Some(s) => ext_cx.expr_str(sp, s.to_managed()) }; MRExpr(e) } diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 2dbf6887a21..008545c9729 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -32,7 +32,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) } let fmt = expr_to_str(cx, args[0], - ~"first argument to fmt! must be a string literal."); + "first argument to fmt! must be a string literal."); let fmtspan = args[0].span; debug!("Format string: %s", fmt); fn parse_fmt_err_(cx: @ExtCtxt, sp: span, msg: &str) -> ! { diff --git a/src/test/compile-fail/extenv-arg-2-not-string-literal.rs b/src/test/compile-fail/extenv-arg-2-not-string-literal.rs new file mode 100644 index 00000000000..c2362689721 --- /dev/null +++ b/src/test/compile-fail/extenv-arg-2-not-string-literal.rs @@ -0,0 +1,11 @@ +// 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. + +fn main() { env!("one", 10); } //~ ERROR: expected string literal diff --git a/src/test/compile-fail/extenv-no-args.rs b/src/test/compile-fail/extenv-no-args.rs index 7ff1357dcf3..afa47dbe744 100644 --- a/src/test/compile-fail/extenv-no-args.rs +++ b/src/test/compile-fail/extenv-no-args.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: env! takes 1 argument - -fn main() { env!(); } +fn main() { env!(); } //~ ERROR: env! takes 1 or 2 arguments diff --git a/src/test/compile-fail/extenv-not-defined-custom.rs b/src/test/compile-fail/extenv-not-defined-custom.rs new file mode 100644 index 00000000000..485b6c09f0a --- /dev/null +++ b/src/test/compile-fail/extenv-not-defined-custom.rs @@ -0,0 +1,11 @@ +// 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. + +fn main() { env!("__HOPEFULLY_NOT_DEFINED__", "my error message"); } //~ ERROR: my error message diff --git a/src/test/compile-fail/extenv-not-defined-default.rs b/src/test/compile-fail/extenv-not-defined-default.rs new file mode 100644 index 00000000000..d7a543c045a --- /dev/null +++ b/src/test/compile-fail/extenv-not-defined-default.rs @@ -0,0 +1,11 @@ +// Copyright 2012 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. + +fn main() { env!("__HOPEFULLY_NOT_DEFINED__"); } //~ ERROR: Environment variable __HOPEFULLY_NOT_DEFINED__ not defined diff --git a/src/test/compile-fail/extenv-not-string-literal.rs b/src/test/compile-fail/extenv-not-string-literal.rs index 3f09f81b85b..07ce47a14d8 100644 --- a/src/test/compile-fail/extenv-not-string-literal.rs +++ b/src/test/compile-fail/extenv-not-string-literal.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:requires a string - -fn main() { env!(10); } +fn main() { env!(10, "two"); } //~ ERROR: expected string literal diff --git a/src/test/compile-fail/extenv-too-many-args.rs b/src/test/compile-fail/extenv-too-many-args.rs index b1b2001abc3..c6c4f0ec6b8 100644 --- a/src/test/compile-fail/extenv-too-many-args.rs +++ b/src/test/compile-fail/extenv-too-many-args.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: env! takes 1 argument - -fn main() { env!("one", "two"); } +fn main() { env!("one", "two", "three"); } //~ ERROR: env! takes 1 or 2 arguments diff --git a/src/test/compile-fail/extoption_env-no-args.rs b/src/test/compile-fail/extoption_env-no-args.rs new file mode 100644 index 00000000000..fd56756584a --- /dev/null +++ b/src/test/compile-fail/extoption_env-no-args.rs @@ -0,0 +1,11 @@ +// Copyright 2012 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. + +fn main() { option_env!(); } //~ ERROR: option_env! takes 1 argument diff --git a/src/test/compile-fail/extoption_env-not-string-literal.rs b/src/test/compile-fail/extoption_env-not-string-literal.rs new file mode 100644 index 00000000000..10f6c34980e --- /dev/null +++ b/src/test/compile-fail/extoption_env-not-string-literal.rs @@ -0,0 +1,11 @@ +// Copyright 2012-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. + +fn main() { option_env!(10); } //~ ERROR: requires a string diff --git a/src/test/compile-fail/extoption_env-too-many-args.rs b/src/test/compile-fail/extoption_env-too-many-args.rs new file mode 100644 index 00000000000..b31e857c14e --- /dev/null +++ b/src/test/compile-fail/extoption_env-too-many-args.rs @@ -0,0 +1,11 @@ +// Copyright 2012-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. + +fn main() { option_env!("one", "two"); } //~ ERROR: option_env! takes 1 argument diff --git a/src/test/run-pass/extoption_env-not-defined.rs b/src/test/run-pass/extoption_env-not-defined.rs new file mode 100644 index 00000000000..412efcc25a8 --- /dev/null +++ b/src/test/run-pass/extoption_env-not-defined.rs @@ -0,0 +1,14 @@ +// 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. + +fn main() { + let opt: Option<&'static str> = option_env!("__HOPEFULLY_DOESNT_EXIST__"); + assert!(opt.is_none()); +}