rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.82k stars 12.66k forks source link

compiletest SRC_DIR rewriting mishandles symlinks to other disks #83184

Open pnkfelix opened 3 years ago

pnkfelix commented 3 years ago

I tried this code:

% mount | grep /dev/[ns]
/dev/nvme0n1p6 on / type ext4 (rw,noatime,errors=remount-ro)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
/dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/sda on /media/pnkfelix/Rust type ext4 (rw,nosuid,nodev,relatime,uhelper=udisks2)
% pwd
/home/pnkfelix/Dev/Rust/rust.git/objdir-opt
% ls -ld /home/pnkfelix/Dev/Rust
lrwxrwxrwx 1 pnkfelix pnkfelix 20 Mar  5 10:45 /home/pnkfelix/Dev/Rust -> /media/pnkfelix/Rust
% ls
build  config.toml  config.toml~  Makefile  tmp
% diff ../config.toml.example ./config.toml
% time python ../x.py build --stage 1 library/std && time python ../x.py test --stage 1
[...]

In particular, note that I've put my Rust stuff into a separate disk that is mounted beneath my personal home directory.

Then, from the context of a path that, from the viewpoint of pwd, is under my home directory (but is physically on that separate disk), I ran our test suite.

I expected to see this happen: A successful run, since my checkout is pristine.

Instead, this happened: 125 of the ui tests failed. 11344 passed.

Click here for the Failure list ``` failures: [ui] ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs [ui] ui/associated-type-bounds/bounds-on-assoc-in-trait.rs [ui] ui/associated-types/defaults-wf.rs [ui] ui/associated-types/trait-with-supertraits-needing-sized-self.rs [ui] ui/async-await/generator-desc.rs [ui] ui/async-await/issue-72442.rs [ui] ui/async-await/issues/issue-65159.rs [ui] ui/bad/bad-sized.rs [ui] ui/binop/binop-consume-args.rs [ui] ui/binop/binop-move-semantics.rs [ui] ui/binop/issue-77910-1.rs [ui] ui/bound-suggestions.rs [ui] ui/closures/closure-move-sync.rs [ui] ui/codemap_tests/tab_3.rs [ui] ui/const-generics/const-argument-if-length.rs#full [ui] ui/const-generics/invalid-const-arg-for-type-param.rs [ui] ui/const-generics/invalid-constant-in-args.rs [ui] ui/const-ptr/out_of_bounds_read.rs [ui] ui/consts/assume-type-intrinsics.rs [ui] ui/consts/const-eval/unwind-abort.rs [ui] ui/consts/const-unwrap.rs [ui] ui/consts/const_unsafe_unreachable_ub.rs [ui] ui/consts/miri_unleashed/drop.rs [ui] ui/consts/offset_from_ub.rs [ui] ui/consts/offset_ub.rs [ui] ui/consts/ptr_comparisons.rs [ui] ui/copy-a-resource.rs [ui] ui/derives/derive-assoc-type-not-impl.rs [ui] ui/derives/derives-span-Eq-enum-struct-variant.rs [ui] ui/derives/derives-span-Eq-enum.rs [ui] ui/derives/derives-span-Eq-struct.rs [ui] ui/derives/derives-span-Eq-tuple-struct.rs [ui] ui/derives/derives-span-Hash-enum-struct-variant.rs [ui] ui/derives/derives-span-Hash-enum.rs [ui] ui/derives/derives-span-Hash-struct.rs [ui] ui/derives/derives-span-Hash-tuple-struct.rs [ui] ui/derives/deriving-meta-unknown-trait.rs [ui] ui/error-codes/E0004-2.rs [ui] ui/error-codes/E0005.rs [ui] ui/error-codes/E0297.rs [ui] ui/feature-gates/feature-gate-associated_type_bounds.rs [ui] ui/feature-gates/feature-gate-exhaustive-patterns.rs [ui] ui/generator/sized-yield.rs [ui] ui/generics/wrong-number-of-args.rs [ui] ui/hygiene/panic-location.rs [ui] ui/impl-trait/impl-generic-mismatch.rs [ui] ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs [ui] ui/in-band-lifetimes/mismatched_trait_impl-2.rs [ui] ui/interior-mutability/interior-mutability.rs [ui] ui/issues/issue-14092.rs [ui] ui/issues/issue-16939.rs [ui] ui/issues/issue-17546.rs [ui] ui/issues/issue-18423.rs [ui] ui/issues/issue-20433.rs [ui] ui/issues/issue-21160.rs [ui] ui/issues/issue-23024.rs [ui] ui/issues/issue-27033.rs [ui] ui/issues/issue-2823.rs [ui] ui/issues/issue-3044.rs [ui] ui/issues/issue-31173.rs [ui] ui/issues/issue-38857.rs [ui] ui/issues/issue-59488.rs [ui] ui/issues/issue-60283.rs [ui] ui/issues/issue-61108.rs [ui] ui/issues/issue-64559.rs [ui] ui/issues/issue-69725.rs [ui] ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs [ui] ui/issues/issue-7607-1.rs [ui] ui/issues/issue-78720.rs [ui] ui/limits/issue-55878.rs [ui] ui/lint/lint-const-item-mutation.rs [ui] ui/loops/issue-82916.rs [ui] ui/macros/macro-name-typo.rs [ui] ui/macros/macro-path-prelude-fail-3.rs [ui] ui/macros/unknown-builtin.rs [ui] ui/malformed/malformed-derive-entry.rs [ui] ui/mir/issue-80742.rs [ui] ui/mismatched_types/issue-36053-2.rs [ui] ui/mismatched_types/issue-74918-missing-lifetime.rs [ui] ui/mismatched_types/overloaded-calls-bad.rs [ui] ui/moves/move-fn-self-receiver.rs [ui] ui/moves/moves-based-on-type-access-to-field.rs [ui] ui/moves/moves-based-on-type-exprs.rs [ui] ui/no-capture-arc.rs [ui] ui/no-reuse-move-arc.rs [ui] ui/no-send-res-ports.rs [ui] ui/non-copyable-void.rs [ui] ui/noncopyable-class.rs [ui] ui/parser/issue-62894.rs [ui] ui/pattern/usefulness/match-arm-statics-2.rs [ui] ui/pattern/usefulness/match-privately-empty.rs [ui] ui/pattern/usefulness/non-exhaustive-match.rs [ui] ui/proc-macro/parent-source-spans.rs [ui] ui/proc-macro/resolve-error.rs [ui] ui/range/range-1.rs [ui] ui/recursion/issue-38591-non-regular-dropck-recursion.rs [ui] ui/recursion/recursive-types-are-not-uninhabited.rs [ui] ui/resolve/levenshtein.rs [ui] ui/resolve/resolve-primitive-fallback.rs [ui] ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs [ui] ui/stability-in-private-module.rs [ui] ui/suggestions/attribute-typos.rs [ui] ui/suggestions/borrow-for-loop-head.rs [ui] ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.rs [ui] ui/suggestions/expected-boxed-future-isnt-pinned.rs [ui] ui/suggestions/imm-ref-trait-object.rs [ui] ui/suggestions/mut-borrow-needed-by-trait.rs [ui] ui/suggestions/suggest-change-mut.rs [ui] ui/traits/alias/object-fail.rs [ui] ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs [ui] ui/traits/mutual-recursion-issue-75860.rs [ui] ui/traits/negative-impls/explicitly-unimplemented-error-message.rs [ui] ui/traits/suggest-deferences/issue-39029.rs [ui] ui/traits/suggest-where-clause.rs [ui] ui/type/ascription/issue-34255-1.rs [ui] ui/type/type-ascription-instead-of-initializer.rs [ui] ui/type_length_limit.rs [ui] ui/typeck/typeck-builtin-bound-type-parameters.rs [ui] ui/uninhabited/uninhabited-matches-feature-gated.rs [ui] ui/union/union-derive-clone.rs [ui] ui/union/union-derive-eq.rs [ui] ui/unique-object-noncopyable.rs [ui] ui/unique-pinned-nocopy.rs [ui] ui/unop-move-semantics.rs [ui] ui/wf/wf-impl-self-type.rs ```

The errors all original with problems when compiletest diffs the actual vs expected stder, with compiletest complaining about paths that should have been normalized to SRC_DIR but were not.

Example here ``` ---- [ui] ui/associated-type-bounds/bounds-on-assoc-in-trait.rs stdout ---- diff of stderr: 4 LL | type A: Iterator; 5 | ^^^^^ `<::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` 6 | - ::: $SRC_DIR/core/src/fmt/mod.rs:LL:COL + ::: /media/pnkfelix/Rust/rust.git/library/core/src/fmt/mod.rs:550:1 8 | 9 LL | pub trait Debug { 10 | --------------- required by this bound in `Debug` 21 LL | pub trait Foo { type Out: Baz; } 22 | ^^^^^^^ the trait `Default` is not implemented for `<::Out as Baz>::Assoc` 23 | - ::: $SRC_DIR/core/src/default.rs:LL:COL + ::: /media/pnkfelix/Rust/rust.git/library/core/src/default.rs:85:1 25 | 26 LL | pub trait Default: Sized { 27 | ------------------------ required by this bound in `Default` The actual stderr differed from the expected stderr. Actual stderr saved to /media/pnkfelix/Rust/rust.git/objdir-opt/build/x86_64-unknown-linux-gnu/test/ui/associated-type-bounds/bounds-on-assoc-in-trait/bounds-on-assoc-in-trait.stderr ```

(This may well be a case of "Q: Doctor, it hurts when I do that. A: Well, don't do that." But it wasn't easy for me to see what was going on when I encountered it, and so I thought it warranted a bug.)

I think the real heart of the problem might be more evident when one sees the concrete output itself for a test:

Click here for concrete output ``` error[E0277]: `<::A as Iterator>::Item` doesn't implement `Debug` --> /home/pnkfelix/Dev/Rust/rust.git/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs:18:28 | LL | type A: Iterator; | ^^^^^ `<::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ::: /media/pnkfelix/Rust/rust.git/library/core/src/fmt/mod.rs:550:1 | LL | pub trait Debug { | --------------- required by this bound in `Debug` | = help: the trait `Debug` is not implemented for `<::A as Iterator>::Item` help: consider further restricting the associated type | LL | trait Case1 where <::A as Iterator>::Item: Debug { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `<::Out as Baz>::Assoc: Default` is not satisfied --> /home/pnkfelix/Dev/Rust/rust.git/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs:35:38 | LL | pub trait Foo { type Out: Baz; } | ^^^^^^^ the trait `Default` is not implemented for `<::Out as Baz>::Assoc` | ::: /media/pnkfelix/Rust/rust.git/library/core/src/default.rs:85:1 | LL | pub trait Default: Sized { | ------------------------ required by this bound in `Default` | help: consider further restricting the associated type | LL | pub trait Foo where <::Out as Baz>::Assoc: Default { type Out: Baz; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors ```

Notably, the stderr output has a path with a prefix /home/pnkfelix/Dev/Rust/ in some parts, but other diagnostics have /media/pnkfelix/Rust/ for the prefix. That seems like an inconsistency we should try to resolve.

pnkfelix commented 3 years ago

The details of the context where the inconsistency arises is not obvious to me. replicating this bug is not as simple as introducing an arbitrary symlink; or at least, my simple-minded attempts to make an MCVE were flummoxed when I tried doing "just make a symlink."

For example, it is not yet clear if a second disk is actually relevant or not. Maybe a symlink in the parent hierarchy is all that is needed.

Hopefully I'll have a chance in the near term to try making another replication attempt that mirrors the scenario except by using /tmp instead of a second disk, or something.

the8472 commented 3 years ago

If you need a workaround, I have a similar setup but I have put a bind mount in my fstab instead of using a symlink. That works without issues.