auto merge of #9013 : alexcrichton/rust/generated-unsafe-blocks, r=sanxiyn
This way syntax extensions can generate unsafe blocks without worrying about them generating unnecessary unsafe warnings. Perhaps a special keyword could be added to be used in macros, but I don't think that's the best solution. Currently if you use `format!` and friends in an `unsafe` block you're guaranteed to get some unused-unsafe warnings which is unfortunate. We normally do want these warnings, but I'm ok ignoring them in the case of compiler-generated unsafe blocks. I tried to do this in the least intrusive way possible, but others may have better ideas about how to do this.
This commit is contained in:
commit
ef6a97ddbe
8 changed files with 29 additions and 9 deletions
|
|
@ -102,8 +102,10 @@ impl Visitor<()> for EffectCheckVisitor {
|
|||
fn visit_block(&mut self, block:&Block, _:()) {
|
||||
|
||||
let old_unsafe_context = self.context.unsafe_context;
|
||||
if block.rules == ast::UnsafeBlock &&
|
||||
self.context.unsafe_context == SafeContext {
|
||||
let is_unsafe = match block.rules {
|
||||
ast::UnsafeBlock(*) => true, ast::DefaultBlock => false
|
||||
};
|
||||
if is_unsafe && self.context.unsafe_context == SafeContext {
|
||||
self.context.unsafe_context = UnsafeBlock(block.id)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1131,8 +1131,11 @@ impl Visitor<@mut Context> for UnusedUnsafeLintVisitor {
|
|||
fn visit_expr(&mut self, e:@ast::Expr, cx:@mut Context) {
|
||||
|
||||
match e.node {
|
||||
ast::ExprBlock(ref blk) if blk.rules == ast::UnsafeBlock => {
|
||||
if !cx.tcx.used_unsafe.contains(&blk.id) {
|
||||
// Don't warn about generated blocks, that'll just pollute the
|
||||
// output.
|
||||
ast::ExprBlock(ref blk) => {
|
||||
if blk.rules == ast::UnsafeBlock(ast::UserProvided) &&
|
||||
!cx.tcx.used_unsafe.contains(&blk.id) {
|
||||
cx.span_lint(unused_unsafe, blk.span,
|
||||
"unnecessary `unsafe` block");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ impl PurityState {
|
|||
|
||||
purity => {
|
||||
let (purity, def) = match blk.rules {
|
||||
ast::UnsafeBlock => (ast::unsafe_fn, blk.id),
|
||||
ast::UnsafeBlock(*) => (ast::unsafe_fn, blk.id),
|
||||
ast::DefaultBlock => (purity, self.def),
|
||||
};
|
||||
PurityState{ def: def,
|
||||
|
|
|
|||
|
|
@ -479,7 +479,13 @@ pub struct Field {
|
|||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||
pub enum BlockCheckMode {
|
||||
DefaultBlock,
|
||||
UnsafeBlock,
|
||||
UnsafeBlock(UnsafeSource),
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||
pub enum UnsafeSource {
|
||||
CompilerGenerated,
|
||||
UserProvided,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ impl Context {
|
|||
stmts: ~[],
|
||||
expr: Some(result),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
rules: ast::UnsafeBlock,
|
||||
rules: ast::UnsafeBlock(ast::CompilerGenerated),
|
||||
span: self.fmtsp,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1792,7 +1792,7 @@ impl Parser {
|
|||
} else if self.eat_keyword(keywords::Match) {
|
||||
return self.parse_match_expr();
|
||||
} else if self.eat_keyword(keywords::Unsafe) {
|
||||
return self.parse_block_expr(lo, UnsafeBlock);
|
||||
return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
|
||||
} else if *self.token == token::LBRACKET {
|
||||
self.bump();
|
||||
let mutbl = self.parse_mutability();
|
||||
|
|
|
|||
|
|
@ -951,7 +951,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
|
|||
attrs: &[ast::Attribute],
|
||||
close_box: bool) {
|
||||
match blk.rules {
|
||||
ast::UnsafeBlock => word_space(s, "unsafe"),
|
||||
ast::UnsafeBlock(*) => word_space(s, "unsafe"),
|
||||
ast::DefaultBlock => ()
|
||||
}
|
||||
maybe_print_comment(s, blk.span.lo);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
// xfail-fast: check-fast screws up repr paths
|
||||
|
||||
#[deny(warnings)];
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct A;
|
||||
|
|
@ -226,6 +228,13 @@ pub fn main() {
|
|||
let a = ~3;
|
||||
format!("{:?}", a);
|
||||
format!("{:?}", a);
|
||||
|
||||
// make sure that format! doesn't cause spurious unused-unsafe warnings when
|
||||
// it's inside of an outer unsafe block
|
||||
unsafe {
|
||||
let a: int = ::std::cast::transmute(3u);
|
||||
format!("{}", a);
|
||||
}
|
||||
}
|
||||
|
||||
// Basic test to make sure that we can invoke the `write!` macro with an
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue