Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addressing instance methods in external annotations #165

Merged
merged 12 commits into from
Aug 29, 2024
54 changes: 26 additions & 28 deletions crates/paralegal-flow/src/ann/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ use super::{
ExceptionAnnotation, MarkerAnnotation, MarkerRefinement, MarkerRefinementKind, VerificationHash,
};
use crate::{
utils,
utils::{write_sep, Print, TinyBitSet},
utils::{resolve::def_path_res, TinyBitSet},
Symbol,
};
use paralegal_spdg::Identifier;

use rustc_ast::{self as ast, token, tokenstream};
use rustc_ast::{self as ast, token, tokenstream, ExprKind};
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use rustc_parse::parser as rustc_parser;
use token::*;
use tokenstream::*;

Expand Down Expand Up @@ -240,32 +240,30 @@ pub fn tiny_bitset(i: I) -> R<TinyBitSet> {
pub(crate) fn otype_ann_match(ann: &ast::AttrArgs, tcx: TyCtxt) -> Result<Vec<DefId>, String> {
match ann {
ast::AttrArgs::Delimited(dargs) => {
let mut p = nom::multi::separated_list0(
assert_token(TokenKind::Comma),
nom::multi::separated_list0(
assert_token(TokenKind::ModSep),
nom::combinator::map(identifier, |i| i.to_string()),
),
);
p(I::from_stream(&dargs.tokens))
.map_err(|err: nom::Err<_>| format!("parser failed with error {err:?}"))?
.1
.into_iter()
.map(|strs| {
let segment_vec = strs.iter().map(AsRef::as_ref).collect::<Vec<&str>>();
Ok(utils::resolve::def_path_res(tcx, &segment_vec)
.map_err(|err| {
format!(
"Could not resolve {}: {err:?}",
Print(|f| write_sep(f, "::", &segment_vec, |elem, f| f
.write_str(elem)))
)
})?
.def_id())
})
.collect()
let mut parser =
rustc_parser::Parser::new(&tcx.sess.parse_sess, dargs.tokens.clone(), None);
std::iter::from_fn(|| {
if parser.token.kind == TokenKind::Eof {
return None;
}
let ExprKind::Path(qself, path) = &parser.parse_expr().ok()?.kind else {
return Some(Result::Err(format!(
"Expected path expression, got {:?}",
dargs.tokens
)));
};
if parser.token.kind != TokenKind::Eof {
parser.expect(&TokenKind::Comma).ok()?;
}
Some(
def_path_res(tcx, qself.as_deref(), &path.segments)
.map_err(|err| format!("Failed resolution: {err:?}",))
.map(|d| d.def_id()),
)
})
.collect()
}
_ => Result::Err("Expected delimoted annotation".to_owned()),
_ => Result::Err("Expected delimited annotation".to_owned()),
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/paralegal-flow/src/discover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'tcx> CollectingVisitor<'tcx> {
.filter_map(|path| {
let def_id = expect_resolve_string_to_def_id(tcx, path, opts.relaxed())?;
if !def_id.is_local() {
tcx.sess.span_err(tcx.def_span(def_id), "found an external function as analysis target. Analysis targets are required to be local.");
tcx.sess.span_err(tcx.def_span(def_id), format!("found an external function {def_id:?} as analysis target. Analysis targets are required to be local."));
return None;
}
Some(FnToAnalyze {
Expand Down
1 change: 1 addition & 0 deletions crates/paralegal-flow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern crate rustc_interface;
extern crate rustc_macros;
extern crate rustc_middle;
extern crate rustc_mir_dataflow;
extern crate rustc_parse;
extern crate rustc_query_system;
extern crate rustc_serialize;
extern crate rustc_session;
Expand Down
22 changes: 14 additions & 8 deletions crates/paralegal-flow/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_interface::interface;
use crate::{
ann::dump_markers,
desc::{Identifier, ProgramDescription},
utils::Print,
HashSet, EXTRA_RUSTC_ARGS,
};
use std::hash::{Hash, Hasher};
Expand All @@ -22,6 +23,7 @@ use std::{

use paralegal_spdg::{
traverse::{generic_flows_to, EdgeSelection},
utils::write_sep,
DefInfo, EdgeInfo, Endpoint, Node, TypeId, SPDG,
};

Expand Down Expand Up @@ -202,7 +204,7 @@ impl InlineTestBuilder {
pub fn new(input: impl Into<String>) -> Self {
Self {
input: input.into(),
ctrl_name: "main".into(),
ctrl_name: "crate::main".into(),
}
}

Expand Down Expand Up @@ -240,12 +242,8 @@ impl InlineTestBuilder {
}

let args = crate::Args::try_from(
TopLevelArgs::parse_from([
"".into(),
"--analyze".into(),
format!("crate::{}", self.ctrl_name),
])
.args,
TopLevelArgs::parse_from(["".into(), "--analyze".into(), self.ctrl_name.to_string()])
.args,
)
.unwrap();

Expand Down Expand Up @@ -321,6 +319,7 @@ pub trait HasGraph<'g>: Sized + Copy {
}

fn ctrl_hashed(self, name: &str) -> Endpoint {
let name = name.strip_prefix("crate::").unwrap_or(name);
let candidates = self
.graph()
.desc
Expand All @@ -330,7 +329,14 @@ pub trait HasGraph<'g>: Sized + Copy {
.map(|(id, _)| *id)
.collect::<Vec<_>>();
match candidates.as_slice() {
[] => panic!("Could not find controller '{name}'"),
[] => panic!(
"Could not find controller '{name}'. Known controllers are {}",
Print(|fmt| {
write_sep(fmt, ", ", self.graph().desc.controllers.values(), |c, f| {
f.write_str(c.name.as_str())
})
})
),
[ctrl] => *ctrl,
more => panic!("Too many matching controllers, found candidates: {more:?}"),
}
Expand Down
Loading
Loading