Proper way to use PathBuf


Hello, I’ve just started to learn Rust. So, probably my problems arise from misunderstanding of some concepts.
Currently I’m experiencing problems using PathBuf. I want to construct some path to directory and then set it as CWD.
The simplified code below arises several questions:

let pb = PathBuf::new("/home/marvin/imonitor");

And the first question here is Deref trait. From its implementation for PathBuf I could see that dereference returns reference to Path:

impl ops::Deref for PathBuf {
    type Target = Path;
    fn deref(&self) -> &Path {
        unsafe { mem::transmute(&self.inner[..]) }

But type Target is Path, so my code won’t compile, I have to change it to something like that:

let pb = PathBuf::new("/home/marvin/imonitor");
env::set_current_dir(&*pb); // &* looks wrong to me, but OK.

Still, this code doesn’t compile:

expected `&std::old_path::posix::Path`,
found `&std::path::Path`

Why? I decided to check env::set_current_dir implementation. It expects reference to some Path as it’s argument:

pub fn set_current_dir(p: &Path) -> IoResult<()> {

What kind of Path it expects? Let’s check imports section:

use prelude::v1::*;

In prelude:

pub use old_path::{Path, GenericPath};

In of old_path:

pub use self::posix::Path as Path;

Now we have two Path structs to deal with. One, constructed from PathBuf:

pub struct Path {
    inner: OsStr

Another, expected by set_current_dir:

pub struct Path {
    repr: Vec,
    sepidx: Option

Basically, OsStr is just container for [u8]. So I could cast first Path to second:

trait AsOldPosixPath {
    fn as_old_path(&self) -> Option;

impl AsOldPosixPath for std::path::Path {
    fn as_old_path(&self) -> Option {
        match self.to_str() {
            Some(str_ref) => Some(std::old_path::posix::Path::new(str_ref)),
            None => None

fn main() {
    let pb = PathBuf::new("/home/marvin/imonitor");
    match pb.as_old_path() {
        Some(old_path) => {env::set_current_dir(&old_path);},
        None => panic!("Couldn't convert path!")

This works but seems incredibly wrong to me.
As I stated earlier, it’s possible that I just don’t understand some concepts. Please, help me with it.
Sorry for overly-detailed explanation. I just wanted to make sure, that I move in right direction.


I think the main problem here is that std::env is currently using old paths, which was done to ease transition. However, there is now a PR to update it which should be landing soon.

Once this is done, you should be able to call set_current_dir(&some_path_buf).