Skip to content

Commit

Permalink
Merge pull request #922 from sdroege/assertion-configuration
Browse files Browse the repository at this point in the history
Allow overriding safety assertions for functions
  • Loading branch information
EPashkin committed May 31, 2020
2 parents 1f84b54 + 5307b27 commit 57dbee3
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 11 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ generate_builder = true
no_future = true
# to rename the generated function
rename = "something_else"
# to override the default safety assertions: "none", "skip",
# "in-main-thread"
assertions = "in-main-thread"
# override for parameter
[[object.function.parameter]]
# filter by name
Expand Down
7 changes: 6 additions & 1 deletion src/analysis/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@ fn analyze_function(
let doc_hidden = configured_functions.iter().any(|f| f.doc_hidden);
let disable_length_detect = configured_functions.iter().any(|f| f.disable_length_detect);
let no_future = configured_functions.iter().any(|f| f.no_future);
let assertion = configured_functions
.iter()
.filter_map(|f| f.assertion)
.next();

imports.set_defaults(version, &cfg_condition);

Expand Down Expand Up @@ -765,7 +769,8 @@ fn analyze_function(
Visibility::Public
};
let is_method = func.kind == library::FunctionKind::Method;
let assertion = SafetyAssertionMode::of(env, is_method, &parameters);
let assertion =
assertion.unwrap_or_else(|| SafetyAssertionMode::of(env, is_method, &parameters));

imports.reset_defaults();

Expand Down
14 changes: 14 additions & 0 deletions src/analysis/safety_assertion_mode.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{analysis::function_parameters::Parameters, env::Env, library};
use std::str::FromStr;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SafetyAssertionMode {
Expand All @@ -7,6 +8,19 @@ pub enum SafetyAssertionMode {
InMainThread,
}

impl FromStr for SafetyAssertionMode {
type Err = String;
fn from_str(name: &str) -> Result<SafetyAssertionMode, String> {
use self::SafetyAssertionMode::*;
match name {
"none" => Ok(None),
"skip" => Ok(Skip),
"in-main-thread" => Ok(InMainThread),
_ => Err(format!("Unknown safety assertion mode '{}'", name)),
}
}
}

impl Default for SafetyAssertionMode {
fn default() -> SafetyAssertionMode {
SafetyAssertionMode::None
Expand Down
6 changes: 3 additions & 3 deletions src/analysis/special_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ pub enum Type {
}

impl FromStr for Type {
type Err = ();
type Err = String;

fn from_str(s: &str) -> Result<Type, ()> {
fn from_str(s: &str) -> Result<Type, String> {
use self::Type::*;
match s {
"compare" => Ok(Compare),
Expand All @@ -31,7 +31,7 @@ impl FromStr for Type {
"to_string" => Ok(ToString),
"unref" => Ok(Unref),
"hash" => Ok(Hash),
_ => Err(()),
_ => Err(format!("Unknown type '{}'", s)),
}
}
}
Expand Down
17 changes: 16 additions & 1 deletion src/config/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use super::{
parsable::{Parsable, Parse},
string_type::StringType,
};
use crate::{library::Nullable, version::Version};
use crate::{
analysis::safety_assertion_mode::SafetyAssertionMode, library::Nullable, version::Version,
};
use log::error;
use std::str::FromStr;
use toml::Value;
Expand Down Expand Up @@ -202,6 +204,7 @@ pub struct Function {
pub doc_trait_name: Option<String>,
pub no_future: bool,
pub rename: Option<String>,
pub assertion: Option<SafetyAssertionMode>,
}

impl Parse for Function {
Expand Down Expand Up @@ -231,6 +234,7 @@ impl Parse for Function {
"doc_trait_name",
"no_future",
"rename",
"assertion",
],
&format!("function {}", object_name),
);
Expand Down Expand Up @@ -277,6 +281,16 @@ impl Parse for Function {
return None;
}

let assertion = toml
.lookup("assertion")
.and_then(Value::as_str)
.map(|s| s.parse::<SafetyAssertionMode>())
.transpose();
if let Err(ref err) = assertion {
error!("{}", err);
}
let assertion = assertion.ok().flatten();

Some(Function {
ident,
ignore,
Expand All @@ -290,6 +304,7 @@ impl Parse for Function {
doc_trait_name,
no_future,
rename,
assertion,
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/config/string_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl FromStr for StringType {
"utf8" => Ok(StringType::Utf8),
"filename" => Ok(StringType::Filename),
"os_string" => Ok(StringType::OsString),
_ => Err("Wrong string type".into()),
_ => Err(format!("Wrong string type '{}'", s)),
}
}
}
2 changes: 1 addition & 1 deletion src/config/work_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl FromStr for WorkMode {
"sys" => Ok(WorkMode::Sys),
"doc" => Ok(WorkMode::Doc),
"not_bound" => Ok(WorkMode::DisplayNotBound),
_ => Err("Wrong work mode".into()),
_ => Err(format!("Wrong work mode '{}'", s)),
}
}
}
8 changes: 4 additions & 4 deletions src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl FromStr for Transfer {
"none" => Ok(None),
"container" => Ok(Container),
"full" => Ok(Full),
_ => Err("Unknown ownership transfer mode".into()),
_ => Err(format!("Unknown ownership transfer mode '{}'", name)),
}
}
}
Expand All @@ -53,7 +53,7 @@ impl FromStr for ParameterDirection {
"in" => Ok(In),
"out" => Ok(Out),
"inout" => Ok(InOut),
_ => Err("Unknown parameter direction".into()),
_ => Err(format!("Unknown parameter direction '{}'", name)),
}
}
}
Expand Down Expand Up @@ -153,7 +153,7 @@ impl FromStr for FunctionKind {
"method" => Ok(Method),
"callback" => Ok(Function),
"global" => Ok(Global),
_ => Err("Unknown function kind".into()),
_ => Err(format!("Unknown function kind '{}'", name)),
}
}
}
Expand All @@ -175,7 +175,7 @@ impl FromStr for Concurrency {
"send-unique" => Ok(SendUnique),
"send" => Ok(Send),
"send+sync" => Ok(SendSync),
_ => Err("Unknown concurrency kind".into()),
_ => Err(format!("Unknown concurrency kind '{}'", name)),
}
}
}
Expand Down

0 comments on commit 57dbee3

Please sign in to comment.