-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
analyze: refactor struct and static rewrites (#1005)
This branch refactors rewrite generation for structs and statics to make it easier for `main.rs` to control exactly which items get rewritten. This is in preparation for adding a filtering option that can disable rewriting for any `DefId`. In particular, rewriting of structs and fields has been separated from rewriting of function signatures, and static rewriting has been broken up, so that all `rewrite::gen_*_rewrites` functions work on a single item per call rather than internally iterating over all relevant items.
- Loading branch information
Showing
4 changed files
with
314 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,51 @@ | ||
use crate::context::PermissionSet; | ||
use crate::pointer_id::PointerId; | ||
use crate::rewrite::Rewrite; | ||
use crate::{GlobalAnalysisCtxt, GlobalAssignment}; | ||
use crate::GlobalAssignment; | ||
use rustc_hir::def_id::DefId; | ||
use rustc_hir::{ItemKind, Mutability, Node}; | ||
use rustc_middle::ty::TyCtxt; | ||
use rustc_span::Span; | ||
|
||
/// For every static, if its write permission does not match its declared mutability, emit a rewrite | ||
/// changing the declaration to match observed/analyzed usage. | ||
pub fn gen_static_rewrites<'tcx>( | ||
gacx: &GlobalAnalysisCtxt<'tcx>, | ||
tcx: TyCtxt<'tcx>, | ||
gasn: &GlobalAssignment, | ||
) -> Vec<(Span, Rewrite)> { | ||
let mut hir_rewrites = Vec::new(); | ||
for (did, &ptr) in gacx.addr_of_static.iter() { | ||
// The map of statics and their ty + permissions tracks statics by did; map this to an Item | ||
// node to look at the static's spans and declared mutability. | ||
let item = if let Some(Node::Item(item)) = gacx.tcx.hir().get_if_local(*did) { | ||
item | ||
} else { | ||
panic!("def id {:?} not found", did); | ||
}; | ||
if let ItemKind::Static(_ty, mutbl, _body_id) = item.kind { | ||
let perms = gasn.perms[ptr]; | ||
let written_to = perms.contains(PermissionSet::WRITE); | ||
let is_mutable = mutbl == Mutability::Mut; | ||
if written_to != is_mutable { | ||
let ident = gacx | ||
.tcx | ||
.opt_item_ident(*did) | ||
.expect("did not find ident when trying to generate rewrite for static item"); | ||
// Generate a span from beginning of ident to end of body. | ||
let span = ident.span.with_hi(item.span.hi()); | ||
hir_rewrites.push(( | ||
item.span, | ||
Rewrite::StaticMut( | ||
if written_to { | ||
Mutability::Mut | ||
} else { | ||
Mutability::Not | ||
}, | ||
span, | ||
), | ||
)) | ||
} | ||
} else { | ||
panic!("expected item {:?} to be a `static`", item); | ||
} | ||
def_id: DefId, | ||
ptr: PointerId, | ||
) -> Option<(Span, Rewrite)> { | ||
// The map of statics and their ty + permissions tracks statics by DefId; map this to an Item | ||
// node to look at the static's spans and declared mutability. | ||
let item = if let Some(Node::Item(item)) = tcx.hir().get_if_local(def_id) { | ||
item | ||
} else { | ||
panic!("def id {:?} not found", def_id); | ||
}; | ||
let is_mutable = match item.kind { | ||
ItemKind::Static(_ty, mutbl, _body_id) => mutbl == Mutability::Mut, | ||
_ => panic!("expected item {:?} to be a `static`", item), | ||
}; | ||
let perms = gasn.perms[ptr]; | ||
let written_to = perms.contains(PermissionSet::WRITE); | ||
if written_to != is_mutable { | ||
let ident = tcx | ||
.opt_item_ident(def_id) | ||
.expect("def_id has no ident when trying to generate rewrite for static item"); | ||
// Generate a span from beginning of ident to end of body. | ||
let span = ident.span.with_hi(item.span.hi()); | ||
Some(( | ||
item.span, | ||
Rewrite::StaticMut( | ||
if written_to { | ||
Mutability::Mut | ||
} else { | ||
Mutability::Not | ||
}, | ||
span, | ||
), | ||
)) | ||
} else { | ||
None | ||
} | ||
|
||
hir_rewrites | ||
} |
Oops, something went wrong.