Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backwards-incompatible lifetime change (regression) #85574

Closed
staktrace opened this issue May 22, 2021 · 16 comments
Closed

Backwards-incompatible lifetime change (regression) #85574

staktrace opened this issue May 22, 2021 · 16 comments
Labels
C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. relnotes Marks issues that should be documented in the release notes of the next release. T-release Relevant to the release subteam, which will review and decide on the PR/issue.
Milestone

Comments

@staktrace
Copy link
Contributor

staktrace commented May 22, 2021

I tried this:

rustup update nightly
git clone https://github.com/rust-lang/git2-rs && cd git2-rs
cargo +nightly build

I expected to see this happen: build completes

Instead, this happened: build failed with this output:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/attr.rs:74:15
   |
74 |         match (self, other) {
   |               ^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 73:26...
  --> src/attr.rs:73:26
   |
73 |     fn eq(&self, other: &AttrValue<'_>) -> bool {
   |                          ^^^^^^^^^^^^^
note: ...so that the types are compatible
  --> src/attr.rs:74:15
   |
74 |         match (self, other) {
   |               ^^^^^^^^^^^^^
   = note: expected `(&AttrValue<'_>, &AttrValue<'_>)`
              found `(&AttrValue<'_>, &AttrValue<'_>)`
note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 72:30...
  --> src/attr.rs:72:30
   |
72 | impl PartialEq for AttrValue<'_> {
   |                              ^^
note: ...so that the types are compatible
  --> src/attr.rs:79:16
   |
79 |             | (Self::Bytes(bytes), AttrValue::String(string)) => string.as_bytes() == *bytes,
   |                ^^^^^^^^^^^^^^^^^^
   = note: expected `AttrValue<'_>`
              found `AttrValue<'_>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: could not compile `git2`

To learn more, run the command again with --verbose.

Meta

rustc +nightly --version --verbose:

rustc 1.54.0-nightly (5dc8789e3 2021-05-21)
binary: rustc
commit-hash: 5dc8789e300930751a78996da0fa906be5a344a2
commit-date: 2021-05-21
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.1

This was working with the rustc nightly from rustc 1.54.0-nightly (f94942d84 2021-05-19) so this is a very recent regression.

@staktrace staktrace added the C-bug Category: This is a bug. label May 22, 2021
@Mark-Simulacrum Mark-Simulacrum added the regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. label May 22, 2021
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label May 22, 2021
@Mark-Simulacrum Mark-Simulacrum added the E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc label May 22, 2021
@Mark-Simulacrum
Copy link
Member

Might be #85511, but would be good to bisect.

@ehuss
Copy link
Contributor

ehuss commented May 22, 2021

Bisect confirmed it is #85511. This is blocking cargo's CI. Let me know if there's any way I can help.

@ehuss
Copy link
Contributor

ehuss commented May 22, 2021

Here's a reproduction:

pub enum Foo<'string> {
    String(&'string str),
}

impl Foo<'_> {
    fn f(&self, other: &Foo<'_>) {
        match (self, other) {
            // Important: a and b swap between the two patterns, and one pattern uses `Self`
            (Foo::String(a), Foo::String(b))
            | (Self::String(b), Foo::String(a)) => {}
        }
    }
}

I couldn't get it smaller than that.

I don't know if this is helpful, but the following will ICE on stable/beta, but returns E0495 on nightly:

enum Foo<'a> {
    Var(&'a str)
}

impl Foo<'_> {
    fn f(other: Foo<'_>) {
        match other {
            Self::Var(..) => {}
        }
    }
}

@matthiaskrgr
Copy link
Member

Note for those also affected by this:
git2 0.12 still builds so you might be able to temporarily downgrade your git2 dependency as a workaround until there is a solution.

MikailBag added a commit to jjs-dev/ci-config-gen that referenced this issue May 22, 2021
MikailBag added a commit to jjs-dev/ci-config-gen that referenced this issue May 22, 2021
@Mark-Simulacrum
Copy link
Member

Cc @nikomatsakis

I'd lean towards reverting for now (and potentially landing as future compat or something). I'm not sure if this is technically a soundness fix, Niko can likely give a better reading there. I think the problem is that Self::String as a constructor is now (I believe arguably correctly, but not sure if it has any soundness implications) requiring the argument to outlive the lifetime on Self - but of course this isn't necessarily true of the other branch.

This means that changing Self to the actual name of the type will fix this, so maybe patching git2 quickly is a good idea; it'll fix things before the next nightly at least for Cargo.

@Mark-Simulacrum Mark-Simulacrum added P-critical Critical priority and removed E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc labels May 22, 2021
@Mark-Simulacrum Mark-Simulacrum added this to the 1.54.0 milestone May 22, 2021
@staktrace
Copy link
Contributor Author

staktrace commented May 22, 2021

This means that changing Self to the actual name of the type will fix this, so maybe patching git2 quickly is a good idea; it'll fix things before the next nightly at least for Cargo.

Replacing the <'_> with <'a> in src/attr.rs in git2 seems to fix the error (with appropriate decorations on the impl)

@staktrace
Copy link
Contributor Author

Note for those also affected by this:
git2 0.12 still builds so you might be able to temporarily downgrade your git2 dependency as a workaround until there is a solution.

You can actually just downgrade to 0.13.17 and that will work too. The src/attr.rs code is new in 0.13.18.

@Mark-Simulacrum
Copy link
Member

I haven't been able to come up with an example that uses the lifetime mismatch to do anything bad yet, but judging by the fact that other similar code seems to demand equality, it seems likely that this is indeed a bug fix.

Filed #85584 to revert the PR on nightly for now.

staktrace added a commit to staktrace/git2-rs that referenced this issue May 22, 2021
@Stupremee Stupremee removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label May 22, 2021
alexcrichton pushed a commit to rust-lang/git2-rs that referenced this issue May 24, 2021
@nikomatsakis
Copy link
Contributor

nikomatsakis commented May 24, 2021

I believe the new behavior is correct, yes. In the minimized example, the variable b is being forced to have both types. I'm not sure if one can create an unsoundness from pattern matching specifically, but @Mark-Simulacrum we already found one soundness hole that was closed by the PR.

@nikomatsakis
Copy link
Contributor

Region errors like this are traditionally the sort of thing that is hard to manage with a warning period. We could potentially swing it but it'll take some effort.

@Mark-Simulacrum
Copy link
Member

Hm. Well, so far I think the only breakage we know of is in git2 and an easy fix -- and a patch release is already out there.

Let's not land the revert for now then since we do recognize it as a soundness bug "in theory" if not necessarily in practice, and we can see what beta crater (in the next cycle, this is in nightly for now) reveals.

bors added a commit to rust-lang/crates.io that referenced this issue Jun 8, 2021
Upgrade git2 to fix compliation on nightly

The compilation error is a known regression related to a soundness fix.
The latest git2 avoids the error. See also
rust-lang/rust#85574 (comment)

r? `@Turbo87`
connec pushed a commit to maidsafe/sn_routing that referenced this issue Jun 14, 2021
This works around a compilation issue caused by
rust-lang/rust#85574. A more permanent fix may
come in future.
dirvine pushed a commit to maidsafe/sn_routing that referenced this issue Jun 14, 2021
This works around a compilation issue caused by
rust-lang/rust#85574. A more permanent fix may
come in future.
@pietroalbini pietroalbini added regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. labels Jun 25, 2021
@cuviper cuviper added the relnotes Marks issues that should be documented in the release notes of the next release. label Jun 25, 2021
@Mark-Simulacrum Mark-Simulacrum changed the title Backwards-incompatible lifetime change (regression) introduced in 2021-05-21 Backwards-incompatible lifetime change (regression) Jul 2, 2021
@arturoc
Copy link
Contributor

arturoc commented Aug 11, 2021

I'm getting a similar problem on some rust code after updating stable from 1.53 to 1.54. Will try to find a small example to post but it seems related to use for<'a> ... to specify bounds on a trait implementation

wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this issue Aug 12, 2021
Pkgsrc changes:
 * Bump bootstrap requirements to 1.53.0.
 * Adjust patches, adapt to upstream changes, adjust cargo checksums
 * If using an external llvm, require >= 10.0

Upsteream changes:

Version 1.54.0 (2021-07-29)
============================

Language
-----------------------

- [You can now use macros for values in built-in attribute macros.][83366]
  While a seemingly minor addition on its own, this enables a lot of
  powerful functionality when combined correctly. Most notably you can
  now include external documentation in your crate by writing the following.
  ```rust
  #![doc = include_str!("README.md")]
  ```
  You can also use this to include auto-generated modules:
  ```rust
  #[path = concat!(env!("OUT_DIR"), "/generated.rs")]
  mod generated;
  ```

- [You can now cast between unsized slice types (and types which contain
  unsized slices) in `const fn`.][85078]
- [You can now use multiple generic lifetimes with `impl Trait` where the
   lifetimes don't explicitly outlive another.][84701] In code this means
   that you can now have `impl Trait<'a, 'b>` where as before you could
   only have `impl Trait<'a, 'b> where 'b: 'a`.

Compiler
-----------------------

- [Rustc will now search for custom JSON targets in
  `/lib/rustlib/<target-triple>/target.json` where `/` is the "sysroot"
  directory.][83800] You can find your sysroot directory by running
  `rustc --print sysroot`.
- [Added `wasm` as a `target_family` for WebAssembly platforms.][84072]
- [You can now use `#[target_feature]` on safe functions when targeting
  WebAssembly platforms.][84988]
- [Improved debugger output for enums on Windows MSVC platforms.][85292]
- [Added tier 3\* support for `bpfel-unknown-none`
   and `bpfeb-unknown-none`.][79608]

\* Refer to Rust's [platform support page][platform-support-doc] for more
   information on Rust's tiered platform support.

Libraries
-----------------------

- [`panic::panic_any` will now `#[track_caller]`.][85745]
- [Added `OutOfMemory` as a variant of `io::ErrorKind`.][84744]
- [ `proc_macro::Literal` now implements `FromStr`.][84717]
- [The implementations of vendor intrinsics in core::arch have been
   significantly refactored.][83278] The main user-visible changes are
   a 50% reduction in the size of libcore.rlib and stricter validation
   of constant operands passed to intrinsics. The latter is technically
   a breaking change, but allows Rust to more closely match the C vendor
   intrinsics API.

Stabilized APIs
---------------

- [`BTreeMap::into_keys`]
- [`BTreeMap::into_values`]
- [`HashMap::into_keys`]
- [`HashMap::into_values`]
- [`arch::wasm32`]
- [`VecDeque::binary_search`]
- [`VecDeque::binary_search_by`]
- [`VecDeque::binary_search_by_key`]
- [`VecDeque::partition_point`]

Cargo
-----

- [Added the `--prune <spec>` option to `cargo-tree` to remove a package from
  the dependency graph.][cargo/9520]
- [Added the `--depth` option to `cargo-tree` to print only to a certain depth
  in the tree ][cargo/9499]
- [Added the `no-proc-macro` value to `cargo-tree --edges` to hide procedural
  macro dependencies.][cargo/9488]
- [A new environment variable named `CARGO_TARGET_TMPDIR` is
  available.][cargo/9375]
  This variable points to a directory that integration tests and
  benches can use as a "scratchpad" for testing filesystem operations.

Compatibility Notes
-------------------
- [Mixing Option and Result via `?` is no longer permitted in
  closures for inferred types.][86831]
- [Previously unsound code is no longer permitted where different
  constructors in branches could require different lifetimes.][85574]
- As previously mentioned the [`std::arch` instrinsics now uses
  stricter const checking][83278] than before and may reject some
  previously accepted code.
- [`i128` multiplication on Cortex M0+ platforms currently
  unconditionally causes overflow when compiled with `codegen-units
  = 1`.][86063]

[85574]: rust-lang/rust#85574
[86831]: rust-lang/rust#86831
[86063]: rust-lang/rust#86063
[86831]: rust-lang/rust#86831
[79608]: rust-lang/rust#79608
[84988]: rust-lang/rust#84988
[84701]: rust-lang/rust#84701
[84072]: rust-lang/rust#84072
[85745]: rust-lang/rust#85745
[84744]: rust-lang/rust#84744
[85078]: rust-lang/rust#85078
[84717]: rust-lang/rust#84717
[83800]: rust-lang/rust#83800
[83366]: rust-lang/rust#83366
[83278]: rust-lang/rust#83278
[85292]: rust-lang/rust#85292
[cargo/9520]: rust-lang/cargo#9520
[cargo/9499]: rust-lang/cargo#9499
[cargo/9488]: rust-lang/cargo#9488
[cargo/9375]: rust-lang/cargo#9375
[`BTreeMap::into_keys`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.into_keys
[`BTreeMap::into_values`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.into_values
[`HashMap::into_keys`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.into_keys
[`HashMap::into_values`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.into_values
[`arch::wasm32`]: https://doc.rust-lang.org/core/arch/wasm32/index.html
[`VecDeque::binary_search`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.binary_search
[`VecDeque::binary_search_by`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.binary_search_by
[`VecDeque::binary_search_by_key`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.binary_search_by_key
[`VecDeque::partition_point`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.partition_point
@nbdd0121
Copy link
Contributor

nbdd0121 commented Oct 4, 2021

A slightly modified version of @ehuss's mcve:

pub enum Foo<'string> {
    String(&'string str),
}

impl<'a> Foo<'a> {
    fn f<'b>(&self, other: &Foo<'b>) {
        match (self, other) {
            // Important: a and b swap between the two patterns, and one pattern uses `Self`
            (Foo::String(a), Foo::String(b))
            | (Foo::<'a>::String(b), Foo::String(a)) => {}
        }
    }
}

This wouldn't compile on 1.53. The only change is to spell Self out explicitly (with Foo::<'a>). So I would say this should indeed be considered as a bugfix. I guess the issue should be closed? (at least it shouldn't be P-critical)

Also the effected version is 1.54+, so retag:
@rustbot label -regression-from-stable-to-beta +regression-from-stable-to-stable

@rustbot
Copy link
Collaborator

rustbot commented Oct 4, 2021

Error: Parsing relabel command in comment failed: ...'-to-beta +' | error: empty label at >| ' regressio'...

Please let @rust-lang/release know if you're having trouble with this bot.

@rustbot rustbot added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-from-stable-to-beta Performance or correctness regression from stable to beta. labels Oct 4, 2021
karlmdavis added a commit to karlmdavis/fhir-benchmarks that referenced this issue Oct 5, 2021
Intended to workaround a backwards-incompatible change in `rustc`:
<rust-lang/rust#85574>. Frustrating, but it
was for a potential soundness fix, so oh well.
karlmdavis added a commit to karlmdavis/fhir-benchmarks that referenced this issue Oct 5, 2021
Intended to workaround a backwards-incompatible change in `rustc`:
<rust-lang/rust#85574>. Frustrating, but it
was for a potential soundness fix, so oh well.
@apiraino
Copy link
Contributor

apiraino commented Dec 2, 2021

Demoting to P-high after reading the latest comments

@rustbot label -P-critical +P-high

@rustbot rustbot added P-high High priority and removed P-critical Critical priority labels Dec 2, 2021
@apiraino
Copy link
Contributor

apiraino commented Feb 3, 2022

I think this issue can be closed since the release notes were amended to also include this compatibility note in commit 9fc2bfa

@rustbot label +T-release

@rustbot rustbot added the T-release Relevant to the release subteam, which will review and decide on the PR/issue. label Feb 3, 2022
@apiraino apiraino closed this as completed Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. relnotes Marks issues that should be documented in the release notes of the next release. T-release Relevant to the release subteam, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests