librustc: Forbid inherent implementations that aren't adjacent to the

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]
This commit is contained in:
Patrick Walton 2014-09-10 22:26:41 -07:00
parent a9cf19889a
commit 467bea04fa
20 changed files with 89 additions and 36 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 {
@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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");
@ -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<()> {
@ -868,13 +870,14 @@ 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.
@ -882,31 +885,39 @@ impl path::Path {
/// 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

View File

@ -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() {

View File

@ -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");

View File

@ -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};

View File

@ -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;

View File

@ -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;

View File

@ -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> {
@ -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::<()>;

View File

@ -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() {}

View File

@ -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 {

View File

@ -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() {

View File

@ -20,6 +20,7 @@
extern crate debug;
use std::io::fs::PathExtensions;
use std::io::{fs, TempDir};
use std::io;
use std::os;