Skip to content

Commit 8d5e64f

Browse files
committed
auto merge of #16981 : kmcallister/rust/ctypes-warning, r=alexcrichton
2 parents 6d8b5c9 + f422de1 commit 8d5e64f

File tree

4 files changed

+77
-41
lines changed

4 files changed

+77
-41
lines changed

src/liblibc/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4542,7 +4542,7 @@ pub mod funcs {
45424542
pub fn glob(pattern: *const c_char,
45434543
flags: c_int,
45444544
errfunc: ::Nullable<extern "C" fn(epath: *const c_char,
4545-
errno: c_int) -> int>,
4545+
errno: c_int) -> c_int>,
45464546
pglob: *mut glob_t);
45474547
pub fn globfree(pglob: *mut glob_t);
45484548
}

src/librustc/lint/builtin.rs

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use syntax::attr;
4545
use syntax::codemap::Span;
4646
use syntax::parse::token;
4747
use syntax::{ast, ast_util, visit};
48+
use syntax::visit::Visitor;
4849

4950
declare_lint!(WHILE_TRUE, Warn,
5051
"suggest using `loop { }` instead of `while true { }`")
@@ -339,6 +340,51 @@ impl LintPass for TypeLimits {
339340
declare_lint!(CTYPES, Warn,
340341
"proper use of libc types in foreign modules")
341342

343+
struct CTypesVisitor<'a> {
344+
cx: &'a Context<'a>
345+
}
346+
347+
impl<'a> CTypesVisitor<'a> {
348+
fn check_def(&mut self, sp: Span, ty_id: ast::NodeId, path_id: ast::NodeId) {
349+
match self.cx.tcx.def_map.borrow().get_copy(&path_id) {
350+
def::DefPrimTy(ast::TyInt(ast::TyI)) => {
351+
self.cx.span_lint(CTYPES, sp,
352+
"found rust type `int` in foreign module, while \
353+
libc::c_int or libc::c_long should be used");
354+
}
355+
def::DefPrimTy(ast::TyUint(ast::TyU)) => {
356+
self.cx.span_lint(CTYPES, sp,
357+
"found rust type `uint` in foreign module, while \
358+
libc::c_uint or libc::c_ulong should be used");
359+
}
360+
def::DefTy(..) => {
361+
let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().find(&ty_id) {
362+
Some(&ty::atttce_resolved(t)) => t,
363+
_ => fail!("ast_ty_to_ty_cache was incomplete after typeck!")
364+
};
365+
366+
if !ty::is_ffi_safe(self.cx.tcx, tty) {
367+
self.cx.span_lint(CTYPES, sp,
368+
"found type without foreign-function-safe
369+
representation annotation in foreign module, consider \
370+
adding a #[repr(...)] attribute to the type");
371+
}
372+
}
373+
_ => ()
374+
}
375+
}
376+
}
377+
378+
impl<'a> Visitor<()> for CTypesVisitor<'a> {
379+
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
380+
match ty.node {
381+
ast::TyPath(_, _, id) => self.check_def(ty.span, ty.id, id),
382+
_ => (),
383+
}
384+
visit::walk_ty(self, ty, ());
385+
}
386+
}
387+
342388
pub struct CTypes;
343389

344390
impl LintPass for CTypes {
@@ -348,38 +394,8 @@ impl LintPass for CTypes {
348394

349395
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
350396
fn check_ty(cx: &Context, ty: &ast::Ty) {
351-
match ty.node {
352-
ast::TyPath(_, _, id) => {
353-
match cx.tcx.def_map.borrow().get_copy(&id) {
354-
def::DefPrimTy(ast::TyInt(ast::TyI)) => {
355-
cx.span_lint(CTYPES, ty.span,
356-
"found rust type `int` in foreign module, while \
357-
libc::c_int or libc::c_long should be used");
358-
}
359-
def::DefPrimTy(ast::TyUint(ast::TyU)) => {
360-
cx.span_lint(CTYPES, ty.span,
361-
"found rust type `uint` in foreign module, while \
362-
libc::c_uint or libc::c_ulong should be used");
363-
}
364-
def::DefTy(..) => {
365-
let tty = match cx.tcx.ast_ty_to_ty_cache.borrow().find(&ty.id) {
366-
Some(&ty::atttce_resolved(t)) => t,
367-
_ => fail!("ast_ty_to_ty_cache was incomplete after typeck!")
368-
};
369-
370-
if !ty::is_ffi_safe(cx.tcx, tty) {
371-
cx.span_lint(CTYPES, ty.span,
372-
"found type without foreign-function-safe
373-
representation annotation in foreign module, consider \
374-
adding a #[repr(...)] attribute to the type");
375-
}
376-
}
377-
_ => ()
378-
}
379-
}
380-
ast::TyPtr(ref mt) => { check_ty(cx, &*mt.ty) }
381-
_ => {}
382-
}
397+
let mut vis = CTypesVisitor { cx: cx };
398+
vis.visit_ty(ty, ());
383399
}
384400

385401
fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
@@ -390,15 +406,15 @@ impl LintPass for CTypes {
390406
}
391407

392408
match it.node {
393-
ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
394-
for ni in nmod.items.iter() {
395-
match ni.node {
396-
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, &*decl),
397-
ast::ForeignItemStatic(t, _) => check_ty(cx, &*t)
409+
ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
410+
for ni in nmod.items.iter() {
411+
match ni.node {
412+
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, &*decl),
413+
ast::ForeignItemStatic(t, _) => check_ty(cx, &*t)
414+
}
398415
}
399416
}
400-
}
401-
_ => {/* nothing to do */ }
417+
_ => (),
402418
}
403419
}
404420
}
@@ -493,7 +509,7 @@ struct RawPtrDerivingVisitor<'a> {
493509
cx: &'a Context<'a>
494510
}
495511

496-
impl<'a> visit::Visitor<()> for RawPtrDerivingVisitor<'a> {
512+
impl<'a> Visitor<()> for RawPtrDerivingVisitor<'a> {
497513
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
498514
static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
499515
match ty.node {

src/libtime/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ pub fn tzset() {
232232

233233
/// Holds a calendar date and time broken down into its components (year, month, day, and so on),
234234
/// also called a broken-down time value.
235+
// FIXME: use c_int instead of i32?
236+
#[repr(C)]
235237
#[deriving(Clone, PartialEq, Eq, Show)]
236238
pub struct Tm {
237239
/// Seconds after the minute - [0, 60]

src/test/compile-fail/issue-16250.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(warnings)]
12+
13+
extern {
14+
pub fn foo(x: (int)); //~ ERROR found rust type `int` in foreign module
15+
}
16+
17+
fn main() {
18+
}

0 commit comments

Comments
 (0)