Skip to content

Commit

Permalink
Merge pull request #2805 from epage/validate_default
Browse files Browse the repository at this point in the history
fix(derive): Type check `default_value_t`
  • Loading branch information
epage authored Oct 6, 2021
2 parents 6fd3e0b + d0b22b5 commit 6f95650
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
25 changes: 13 additions & 12 deletions clap_derive/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,27 +340,28 @@ impl Attrs {
VerbatimDocComment(ident) => self.verbatim_doc_comment = Some(ident),

DefaultValueT(ident, expr) => {
let ty = if let Some(ty) = self.ty.as_ref() {
ty
} else {
abort!(
ident,
"#[clap(default_value_t)] (without an argument) can be used \
only on field level";

note = "see \
https://docs.rs/structopt/0.3.5/structopt/#magical-methods")
};

let val = if let Some(expr) = expr {
quote!(#expr)
} else {
let ty = if let Some(ty) = self.ty.as_ref() {
ty
} else {
abort!(
ident,
"#[clap(default_value_t)] (without an argument) can be used \
only on field level";

note = "see \
https://docs.rs/structopt/0.3.5/structopt/#magical-methods")
};
quote!(<#ty as ::std::default::Default>::default())
};

let val = quote_spanned!(ident.span()=> {
clap::lazy_static::lazy_static! {
static ref DEFAULT_VALUE: &'static str = {
let val = #val;
let val: #ty = #val;
let s = ::std::string::ToString::to_string(&val);
::std::boxed::Box::leak(s.into_boxed_str())
};
Expand Down
21 changes: 21 additions & 0 deletions clap_derive/tests/ui/default_value_t_invalid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
//
// 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.

use clap::Clap;

#[derive(Clap, Debug)]
#[clap(name = "basic")]
struct Opt {
#[clap(default_value_t = -10)]
value: u32,
}

fn main() {
let opt = Opt::parse();
println!("{:?}", opt);
}
7 changes: 7 additions & 0 deletions clap_derive/tests/ui/default_value_t_invalid.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0600]: cannot apply unary operator `-` to type `u32`
--> $DIR/default_value_t_invalid.rs:14:30
|
14 | #[clap(default_value_t = -10)]
| ^^^ cannot apply unary operator `-`
|
= note: unsigned values cannot be negated

0 comments on commit 6f95650

Please sign in to comment.