Change:
When visiting a page such as or the link src (for the source code) no longer works. Instead a 404 is returned. This seems to have been broken for several days now.
even before this, many but not all were broken. there may be multiple issues with this symptom.
The links link in the form but it seems like the actual source is being placed in a location in the form For example here's a link from the current docs which will 404: But the following will resolve:
Really annoyed by this. :<

Discussion:
/// Takes a path to a source file and cleans the path to it. This canonicalizes /// things like ".." to components which preserve the "top down" hierarchy of a <del> /// static HTML tree. </del> <ins> /// static HTML tree. Each component in the cleaned path will be passed as an /// argument to `f`. The very last component of the path (ie the file name) will /// be passed to `f` if `keep_filename` is true, and ignored otherwise. </ins> // FIXME (#9639): The closure should deal with &[u8] instead of &str // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths <del> fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where </del> <ins> fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) where </ins> F: FnMut(&str), { // make it relative, if possible let p = p.relative_from(src_root).unwrap_or(p); <del> for c in p.iter().map(|x| x.to_str().unwrap()) { </del> <ins> let mut iter = p.iter().map(|x| x.to_str().unwrap()).peekable(); while let Some(c) = iter.next() { if !keep_filename && iter.peek().is_none() { break; } </ins> if ".." == c { f("up"); } else {

// Create the intermediate directories let mut cur = self.dst.clone(); let mut root_path = String::from_str("../../"); <del> clean_srcpath(&self.cx.src_root, &p, |component| { </del> <ins> clean_srcpath(&self.cx.src_root, &p, false, |component| { </ins> cur.push(component); mkdir(&cur).unwrap(); root_path.push_str("../");

if ast_util::is_local(self.item.def_id) { let mut path = Vec::new(); clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename), <del> |component| { </del> <ins> true, |component| { </ins> path.push(component.to_string()); }); let href = if self.item.source.loline == self.item.source.hiline {

<ins> -include ../tools.mk all: $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs $(HTMLDOCCK) $(TMPDIR)/doc foo.rs $(HTMLDOCCK) $(TMPDIR)/doc qux/mod.rs </ins>

<ins> // Copyright 2015 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. #![crate_name = "foo"] //! Dox // @has src/foo/foo.rs.html // @has foo/index.html '//a/@href' '../src/foo/foo.rs.html' pub mod qux; // @has foo/bar/index.html '//a/@href' '../../src/foo/foo.rs.html' pub mod bar { /// Dox // @has foo/bar/baz/index.html '//a/@href' '../../../src/foo/foo.rs.html' pub mod baz { /// Dox // @has foo/bar/baz/fn.baz.html '//a/@href' '../../../src/foo/foo.rs.html' pub fn baz() { } } /// Dox // @has foo/bar/trait.Foobar.html '//a/@href' '../../src/foo/foo.rs.html' pub trait Foobar { fn dummy(&self) { } } // @has foo/bar/struct.Foo.html '//a/@href' '../../src/foo/foo.rs.html' pub struct Foo { x: i32, y: u32 } // @has foo/bar/fn.prawns.html '//a/@href' '../../src/foo/foo.rs.html' pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { } } /// Dox // @has foo/fn.modfn.html '//a/@href' '../src/foo/foo.rs.html' pub fn modfn() { } </ins>

<ins> // Copyright 2015 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. //! Dox // @has src/foo/qux/mod.rs.html // @has foo/qux/index.html '//a/@href' '../../src/foo/qux/mod.rs.html' // @has foo/qux/bar/index.html '//a/@href' '../../../src/foo/qux/mod.rs.html' pub mod bar { /// Dox // @has foo/qux/bar/baz/index.html '//a/@href' '../../../../src/foo/qux/mod.rs.html' pub mod baz { /// Dox // @has foo/qux/bar/baz/fn.baz.html '//a/@href' '../../../../src/foo/qux/mod.rs.html' pub fn baz() { } } /// Dox // @has foo/qux/bar/trait.Foobar.html '//a/@href' '../../../src/foo/qux/mod.rs.html' pub trait Foobar { fn dummy(&self) { } } // @has foo/qux/bar/struct.Foo.html '//a/@href' '../../../src/foo/qux/mod.rs.html' pub struct Foo { x: i32, y: u32 } // @has foo/qux/bar/fn.prawns.html '//a/@href' '../../../src/foo/qux/mod.rs.html' pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { } } /// Dox // @has foo/qux/fn.modfn.html '//a/@href' '../../src/foo/qux/mod.rs.html' pub fn modfn() { } </ins>