mirror of
https://github.com/rust-lang/cargo
synced 2024-10-05 23:39:47 +00:00
Emit error on [target.cfg(debug_assertions).dependencies]
This commit is contained in:
parent
61321125e3
commit
552ecc9438
|
@ -1,4 +1,4 @@
|
|||
use crate::error::{ParseError, ParseErrorKind::*};
|
||||
use crate::error::{ParseError, ParseErrorKind, ParseErrorKind::*};
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::str::{self, FromStr};
|
||||
|
@ -41,6 +41,28 @@ struct Parser<'a> {
|
|||
t: Tokenizer<'a>,
|
||||
}
|
||||
|
||||
impl Cfg {
|
||||
pub(crate) fn validate_as_target(&self) -> Result<(), ParseErrorKind> {
|
||||
match self {
|
||||
Cfg::Name(name) => match name.as_str() {
|
||||
"unix" | "windows" => Ok(()),
|
||||
_ => Err(InvalidCfgName(name.to_string())),
|
||||
},
|
||||
Cfg::KeyPair(name, _) => match name.as_str() {
|
||||
"target_arch"
|
||||
| "target_feature"
|
||||
| "target_os"
|
||||
| "target_family"
|
||||
| "target_env"
|
||||
| "target_endian"
|
||||
| "target_pointer_width"
|
||||
| "target_vendor" => Ok(()),
|
||||
_ => Err(InvalidCfgKey(name.to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Cfg {
|
||||
type Err = ParseError;
|
||||
|
||||
|
@ -89,6 +111,19 @@ impl CfgExpr {
|
|||
CfgExpr::Value(ref e) => cfg.contains(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate_as_target(&self) -> Result<(), ParseErrorKind> {
|
||||
match *self {
|
||||
CfgExpr::Not(ref e) => e.validate_as_target()?,
|
||||
CfgExpr::All(ref e) | CfgExpr::Any(ref e) => {
|
||||
for e in e {
|
||||
e.validate_as_target()?;
|
||||
}
|
||||
}
|
||||
CfgExpr::Value(ref e) => e.validate_as_target()?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CfgExpr {
|
||||
|
@ -317,3 +352,31 @@ impl<'a> Token<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfg_validate_as_target() {
|
||||
fn p(s: &str) -> CfgExpr {
|
||||
s.parse().unwrap()
|
||||
}
|
||||
|
||||
assert!(p("unix").validate_as_target().is_ok());
|
||||
assert!(p("windows").validate_as_target().is_ok());
|
||||
assert!(p("any(not(unix), windows)").validate_as_target().is_ok());
|
||||
|
||||
assert!(p("target_arch = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_feature = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_os = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_family = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_env = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_endian = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_pointer_width = \"abc\"").validate_as_target().is_ok());
|
||||
assert!(p("target_vendor = \"abc\"").validate_as_target().is_ok());
|
||||
|
||||
assert!(p("debug_assertions").validate_as_target().is_err());
|
||||
assert!(p("foo").validate_as_target().is_err());
|
||||
assert!(p("any(not(debug_assertions), windows)").validate_as_target().is_err());
|
||||
|
||||
assert!(p("feature = \"abc\"").validate_as_target().is_err());
|
||||
assert!(p("bar = \"def\"").validate_as_target().is_err());
|
||||
assert!(p("any(not(feature = \"def\"))").validate_as_target().is_err());
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ pub enum ParseErrorKind {
|
|||
IncompleteExpr(&'static str),
|
||||
UnterminatedExpression(String),
|
||||
InvalidTarget(String),
|
||||
InvalidCfgName(String),
|
||||
InvalidCfgKey(String),
|
||||
|
||||
#[doc(hidden)]
|
||||
__Nonexhaustive,
|
||||
|
@ -53,6 +55,8 @@ impl fmt::Display for ParseErrorKind {
|
|||
write!(f, "unexpected content `{}` found after cfg expression", s)
|
||||
}
|
||||
InvalidTarget(s) => write!(f, "invalid target specifier: {}", s),
|
||||
InvalidCfgName(name) => write!(f, "invalid name in target cfg: {}", name),
|
||||
InvalidCfgKey(name) => write!(f, "invalid key in target cfg: {}", name),
|
||||
__Nonexhaustive => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,10 @@ impl FromStr for Platform {
|
|||
fn from_str(s: &str) -> Result<Platform, ParseError> {
|
||||
if s.starts_with("cfg(") && s.ends_with(')') {
|
||||
let s = &s[4..s.len() - 1];
|
||||
s.parse().map(Platform::Cfg)
|
||||
let cfg: CfgExpr = s.parse()?;
|
||||
cfg.validate_as_target()
|
||||
.map_err(|kind| ParseError::new(s, kind))?;
|
||||
Ok(Platform::Cfg(cfg))
|
||||
} else {
|
||||
Platform::validate_named_platform(s)?;
|
||||
Ok(Platform::Name(s.to_string()))
|
||||
|
|
|
@ -155,6 +155,16 @@ fn bad_target_name() {
|
|||
"failed to parse `!foo` as a cfg expression: \
|
||||
invalid target specifier: unexpected character ! in target name",
|
||||
);
|
||||
bad::<Platform>(
|
||||
"cfg(debug_assertions)",
|
||||
"failed to parse `debug_assertions` as a cfg expression: \
|
||||
invalid name in target cfg: debug_assertions",
|
||||
);
|
||||
bad::<Platform>(
|
||||
"cfg(feature = \"abc\")",
|
||||
"failed to parse `feature = \"abc\"` as a cfg expression: \
|
||||
invalid key in target cfg: feature",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -476,6 +476,9 @@ dependencies based on optional crate features.
|
|||
Use [the `[features]` section](manifest.md#the-features-section)
|
||||
instead.
|
||||
|
||||
The same applies to `cfg(debug_assertions)`, `cfg(test)` and `cfg(prog_macro)`.
|
||||
There is currently no way to add dependencies based on these configuration values.
|
||||
|
||||
In addition to `#[cfg]` syntax, Cargo also supports listing out the full target
|
||||
the dependencies would apply to:
|
||||
|
||||
|
|
Loading…
Reference in a new issue