Skip to content

Commit

Permalink
librustc: Forbid inherent implementations that aren't adjacent to the
Browse files Browse the repository at this point in the history
type they provide an implementation for.

This breaks code like:

    mod foo {
        struct Foo { ... }
    }

    impl foo::Foo {
        ...
    }

Change this code to:

    mod foo {
        struct Foo { ... }

        impl Foo {
            ...
        }
    }

Additionally, if you used the I/O path extension methods `stat`,
`lstat`, `exists`, `is_file`, or `is_dir`, note that these methods have
been moved to the the `std::io::fs::PathExtensions` trait. This breaks
code like:

    fn is_it_there() -> bool {
        Path::new("/foo/bar/baz").exists()
    }

Change this code to:

    use std::io::fs::PathExtensions;

    fn is_it_there() -> bool {
        Path::new("/foo/bar/baz").exists()
    }

Closes #17059.

RFC #155.

[breaking-change]
  • Loading branch information
pcwalton committed Sep 13, 2014
1 parent a9cf198 commit 467bea0
Show file tree
Hide file tree
Showing 20 changed files with 89 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use util::logv;
use util;

use std::io::File;
use std::io::fs::PathExtensions;
use std::io::fs;
use std::io::net::tcp;
use std::io::process::ProcessExit;
Expand Down
1 change: 1 addition & 0 deletions src/libglob/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

use std::cell::Cell;
use std::{cmp, os, path};
use std::io::fs::PathExtensions;
use std::io::fs;
use std::path::is_sep;
use std::string::String;
Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use std::rt::rtio;
use super::file;
use super::util;

#[cfg(windows)] use std::io::fs::PathExtensions;
#[cfg(windows)] use std::string::String;
#[cfg(unix)] use super::c;
#[cfg(unix)] use super::retry;
Expand Down
1 change: 1 addition & 0 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use util::ppaux;
use util::sha2::{Digest, Sha256};

use std::char;
use std::io::fs::PathExtensions;
use std::io::{fs, TempDir, Command};
use std::io;
use std::mem;
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/metadata/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
#![allow(non_camel_case_types)]

use std::cell::RefCell;
use std::os;
use std::io::fs;
use std::collections::HashSet;
use std::io::fs::PathExtensions;
use std::io::fs;
use std::os;

use util::fs as myfs;

Expand Down
1 change: 1 addition & 0 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ use util::fs;

use std::c_str::ToCStr;
use std::cmp;
use std::io::fs::PathExtensions;
use std::io;
use std::mem;
use std::ptr;
Expand Down
12 changes: 7 additions & 5 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,10 +1313,6 @@ impl<'a> Resolver<'a> {
// If this implements an anonymous trait, then add all the
// methods within to a new module, if the type was defined
// within this module.
//
// FIXME (#3785): This is quite unsatisfactory. Perhaps we
// should modify anonymous traits to only be implementable in
// the same module that declared the type.

// Create the module and add all methods.
match ty.node {
Expand Down Expand Up @@ -1400,7 +1396,13 @@ impl<'a> Resolver<'a> {
}
}
}
_ => {}
_ => {
self.resolve_error(ty.span,
"inherent implementations may \
only be implemented in the same \
module as the type they are \
implemented for")
}
}

parent
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

//! A helper class for dealing with static archives

use std::io::fs::PathExtensions;
use std::io::process::{Command, ProcessOutput};
use std::io::{fs, TempDir};
use std::io;
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

use std::collections::{HashMap, HashSet};
use std::fmt;
use std::io::fs::PathExtensions;
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
use std::io;
use std::str;
Expand Down
39 changes: 25 additions & 14 deletions src/libstd/io/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ particular bits of it, etc.
```rust
# #![allow(unused_must_use)]
use std::io::fs::PathExtensions;
use std::io::{File, fs};
let path = Path::new("foo.txt");
Expand Down Expand Up @@ -622,8 +623,9 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
/// # Example
///
/// ```rust
/// use std::io;
/// use std::io::fs::PathExtensions;
/// use std::io::fs;
/// use std::io;
///
/// // one possible implementation of fs::walk_dir only visiting files
/// fn visit_dirs(dir: &Path, cb: |&Path|) -> io::IoResult<()> {
Expand Down Expand Up @@ -868,45 +870,54 @@ impl Seek for File {
}
}

impl path::Path {
/// Utility methods for paths.
pub trait PathExtensions {
/// Get information on the file, directory, etc at this path.
///
/// Consult the `fs::stat` documentation for more info.
///
/// This call preserves identical runtime/error semantics with `file::stat`.
pub fn stat(&self) -> IoResult<FileStat> { stat(self) }
fn stat(&self) -> IoResult<FileStat>;

/// Get information on the file, directory, etc at this path, not following
/// symlinks.
///
/// Consult the `fs::lstat` documentation for more info.
///
/// This call preserves identical runtime/error semantics with `file::lstat`.
pub fn lstat(&self) -> IoResult<FileStat> { lstat(self) }
fn lstat(&self) -> IoResult<FileStat>;

/// Boolean value indicator whether the underlying file exists on the local
/// filesystem. Returns false in exactly the cases where `fs::stat` fails.
pub fn exists(&self) -> bool {
self.stat().is_ok()
}
fn exists(&self) -> bool;

/// Whether the underlying implementation (be it a file path, or something
/// else) points at a "regular file" on the FS. Will return false for paths
/// to non-existent locations or directories or other non-regular files
/// (named pipes, etc). Follows links when making this determination.
pub fn is_file(&self) -> bool {
match self.stat() {
Ok(s) => s.kind == io::TypeFile,
Err(..) => false
}
}
fn is_file(&self) -> bool;

/// Whether the underlying implementation (be it a file path, or something
/// else) is pointing at a directory in the underlying FS. Will return
/// false for paths to non-existent locations or if the item is not a
/// directory (eg files, named pipes, etc). Follows links when making this
/// determination.
pub fn is_dir(&self) -> bool {
fn is_dir(&self) -> bool;
}

impl PathExtensions for path::Path {
fn stat(&self) -> IoResult<FileStat> { stat(self) }
fn lstat(&self) -> IoResult<FileStat> { lstat(self) }
fn exists(&self) -> bool {
self.stat().is_ok()
}
fn is_file(&self) -> bool {
match self.stat() {
Ok(s) => s.kind == io::TypeFile,
Err(..) => false
}
}
fn is_dir(&self) -> bool {
match self.stat() {
Ok(s) => s.kind == io::TypeDirectory,
Err(..) => false
Expand Down
1 change: 1 addition & 0 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,7 @@ pub enum FileType {
/// # Example
///
/// ```
/// # use std::io::fs::PathExtensions;
/// # fn main() {}
/// # fn foo() {
/// let info = match Path::new("foo.txt").stat() {
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ actually operates on the path; it is only intended for display.
## Example
```rust
use std::io::fs::PathExtensions;
let mut path = Path::new("/tmp/path");
println!("path: {}", path.display());
path.set_filename("foo");
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ use parse::{new_sub_parser_from_file, ParseSess};
use owned_slice::OwnedSlice;

use std::collections::HashSet;
use std::io::fs::PathExtensions;
use std::mem::replace;
use std::rc::Rc;
use std::gc::{Gc, GC};
Expand Down
1 change: 1 addition & 0 deletions src/libterm/terminfo/searcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! Does not support hashed database, only filesystem!

use std::io::File;
use std::io::fs::PathExtensions;
use std::os::getenv;
use std::os;

Expand Down
1 change: 1 addition & 0 deletions src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use std::f64;
use std::fmt;
use std::fmt::Show;
use std::from_str::FromStr;
use std::io::fs::PathExtensions;
use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter};
use std::io;
Expand Down
24 changes: 12 additions & 12 deletions src/test/auxiliary/inner_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ pub struct B<T>;

pub mod test {
pub struct A<T>;

impl<T> A<T> {
pub fn foo(&self) -> int {
static a: int = 5;
return a
}

pub fn bar(&self) -> int {
static a: int = 6;
return a;
}
}
}

impl<T> A<T> {
Expand All @@ -39,18 +51,6 @@ impl<T> B<T> {
}
}

impl<T> test::A<T> {
pub fn foo(&self) -> int {
static a: int = 5;
return a
}

pub fn bar(&self) -> int {
static a: int = 6;
return a;
}
}

pub fn foo() -> int {
let a = A::<()>;
let b = B::<()>;
Expand Down
24 changes: 24 additions & 0 deletions src/test/compile-fail/impl-not-adjacent-to-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod foo {
pub struct Foo {
x: int,
y: int,
}
}

impl foo::Foo {
//~^ ERROR implementations may only be implemented in the same module
fn bar() {}
}

fn main() {}

5 changes: 3 additions & 2 deletions src/test/run-pass/rename-directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
extern crate libc;

use std::io::TempDir;
use std::os;
use std::io;
use std::io::fs::PathExtensions;
use std::io::fs;
use std::io;
use std::os;

fn rename_directory() {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.


use std::io::fs::PathExtensions;
use std::io::{File, TempDir};

pub fn main() {
Expand Down
1 change: 1 addition & 0 deletions src/test/run-pass/tempfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

extern crate debug;

use std::io::fs::PathExtensions;
use std::io::{fs, TempDir};
use std::io;
use std::os;
Expand Down

17 comments on commit 467bea0

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at pcwalton@467bea0

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/impls-next-to-struct = 467bea0 into auto

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/impls-next-to-struct = 467bea0 merged ok, testing candidate = b6e79799

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at pcwalton@467bea0

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/impls-next-to-struct = 467bea0 into auto

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/impls-next-to-struct = 467bea0 merged ok, testing candidate = b7753e79

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at pcwalton@467bea0

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/impls-next-to-struct = 467bea0 into auto

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/impls-next-to-struct = 467bea0 merged ok, testing candidate = 10b27dd2

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at pcwalton@467bea0

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/impls-next-to-struct = 467bea0 into auto

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/impls-next-to-struct = 467bea0 merged ok, testing candidate = 13037a3

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 467bea0 Sep 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 13037a3

Please sign in to comment.