Skip to content

Commit ef6a97d

Browse files
committed
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.
2 parents ba9fa89 + 11e9c48 commit ef6a97d

File tree

8 files changed

+29
-9
lines changed

8 files changed

+29
-9
lines changed

src/librustc/middle/effect.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ impl Visitor<()> for EffectCheckVisitor {
102102
fn visit_block(&mut self, block:&Block, _:()) {
103103

104104
let old_unsafe_context = self.context.unsafe_context;
105-
if block.rules == ast::UnsafeBlock &&
106-
self.context.unsafe_context == SafeContext {
105+
let is_unsafe = match block.rules {
106+
ast::UnsafeBlock(*) => true, ast::DefaultBlock => false
107+
};
108+
if is_unsafe && self.context.unsafe_context == SafeContext {
107109
self.context.unsafe_context = UnsafeBlock(block.id)
108110
}
109111

src/librustc/middle/lint.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1131,8 +1131,11 @@ impl Visitor<@mut Context> for UnusedUnsafeLintVisitor {
11311131
fn visit_expr(&mut self, e:@ast::Expr, cx:@mut Context) {
11321132

11331133
match e.node {
1134-
ast::ExprBlock(ref blk) if blk.rules == ast::UnsafeBlock => {
1135-
if !cx.tcx.used_unsafe.contains(&blk.id) {
1134+
// Don't warn about generated blocks, that'll just pollute the
1135+
// output.
1136+
ast::ExprBlock(ref blk) => {
1137+
if blk.rules == ast::UnsafeBlock(ast::UserProvided) &&
1138+
!cx.tcx.used_unsafe.contains(&blk.id) {
11361139
cx.span_lint(unused_unsafe, blk.span,
11371140
"unnecessary `unsafe` block");
11381141
}

src/librustc/middle/typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl PurityState {
200200

201201
purity => {
202202
let (purity, def) = match blk.rules {
203-
ast::UnsafeBlock => (ast::unsafe_fn, blk.id),
203+
ast::UnsafeBlock(*) => (ast::unsafe_fn, blk.id),
204204
ast::DefaultBlock => (purity, self.def),
205205
};
206206
PurityState{ def: def,

src/libsyntax/ast.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,13 @@ pub struct Field {
479479
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
480480
pub enum BlockCheckMode {
481481
DefaultBlock,
482-
UnsafeBlock,
482+
UnsafeBlock(UnsafeSource),
483+
}
484+
485+
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
486+
pub enum UnsafeSource {
487+
CompilerGenerated,
488+
UserProvided,
483489
}
484490

485491
#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]

src/libsyntax/ext/ifmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ impl Context {
632632
stmts: ~[],
633633
expr: Some(result),
634634
id: ast::DUMMY_NODE_ID,
635-
rules: ast::UnsafeBlock,
635+
rules: ast::UnsafeBlock(ast::CompilerGenerated),
636636
span: self.fmtsp,
637637
});
638638

src/libsyntax/parse/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ impl Parser {
17921792
} else if self.eat_keyword(keywords::Match) {
17931793
return self.parse_match_expr();
17941794
} else if self.eat_keyword(keywords::Unsafe) {
1795-
return self.parse_block_expr(lo, UnsafeBlock);
1795+
return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
17961796
} else if *self.token == token::LBRACKET {
17971797
self.bump();
17981798
let mutbl = self.parse_mutability();

src/libsyntax/print/pprust.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
951951
attrs: &[ast::Attribute],
952952
close_box: bool) {
953953
match blk.rules {
954-
ast::UnsafeBlock => word_space(s, "unsafe"),
954+
ast::UnsafeBlock(*) => word_space(s, "unsafe"),
955955
ast::DefaultBlock => ()
956956
}
957957
maybe_print_comment(s, blk.span.lo);

src/test/run-pass/ifmt.rs

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// xfail-fast: check-fast screws up repr paths
1212

13+
#[deny(warnings)];
14+
1315
use std::fmt;
1416

1517
struct A;
@@ -226,6 +228,13 @@ pub fn main() {
226228
let a = ~3;
227229
format!("{:?}", a);
228230
format!("{:?}", a);
231+
232+
// make sure that format! doesn't cause spurious unused-unsafe warnings when
233+
// it's inside of an outer unsafe block
234+
unsafe {
235+
let a: int = ::std::cast::transmute(3u);
236+
format!("{}", a);
237+
}
229238
}
230239

231240
// Basic test to make sure that we can invoke the `write!` macro with an

0 commit comments

Comments
 (0)