diff options
| author | bors <bors@rust-lang.org> | 2013-09-11 00:36:07 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-09-11 00:36:07 -0700 |
| commit | ef6a97ddbed10ac3483c639fb27e7771fd155ebc (patch) | |
| tree | 0fe567f92d372b3d756a9e935ca35a82fee514bb | |
| parent | ba9fa89bfb4aae53db93e9ecac31807af96356fc (diff) | |
| parent | 11e9c48353a6fcbfd036e5ee58b1d4b5f572d7eb (diff) | |
| download | rust-ef6a97ddbed10ac3483c639fb27e7771fd155ebc.tar.gz rust-ef6a97ddbed10ac3483c639fb27e7771fd155ebc.zip | |
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.
| -rw-r--r-- | src/librustc/middle/effect.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/lint.rs | 7 | ||||
| -rw-r--r-- | src/librustc/middle/typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ast.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/ifmt.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/ifmt.rs | 9 |
8 files changed, 29 insertions, 9 deletions
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 160b03132e0..9c02f544fba 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -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) } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6f4d94e2a64..da181ff2eb6 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -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"); } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index b6e0fd93fa9..0c0326e9317 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8d557125d37..ef2e557b6ea 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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)] diff --git a/src/libsyntax/ext/ifmt.rs b/src/libsyntax/ext/ifmt.rs index b7722ffc297..486069db4f0 100644 --- a/src/libsyntax/ext/ifmt.rs +++ b/src/libsyntax/ext/ifmt.rs @@ -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, }); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4adc34d75a7..b5772a9eede 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 55f052d769d..9b9b157c9d8 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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); diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 3f0c7e07041..ab66bfc1011 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -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 |
