Repository navigation
Closed
Labels
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Description
trait Deserialize<'de> {}
trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
// Based on this impl, `&'static str` only implements Deserialize<'static>.
// It does not implement for<'de> Deserialize<'de>.
impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
fn main() {
// Then why does it implement DeserializeOwned? This compiles.
fn assert_deserialize_owned<T: DeserializeOwned>() {}
assert_deserialize_owned::<&'static str>();
// It correctly does not implement for<'de> Deserialize<'de>.
//fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
//assert_hrtb::<&'static str>();
}This is a regression between rustc 1.20.0 and 1.21.0.
1.20 correctly rejects this code with the following error.
error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
--> src/main.rs:13:5
|
13 | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `for<'de> Deserialize<'de>` for `&'static str`
= note: required because of the requirements on the impl of `DeserializeOwned` for `&'static str`
= note: required by `main::assert_deserialize_owned`Metadata
Metadata
Assignees
Labels
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Activity
dtolnay commentedon Sep 17, 2018
Tagging P-high because this very much affects Serde. @rust-lang/compiler
dtolnay commentedon Sep 17, 2018
Same issue using Serde traits:
(One possible) output:
¢ÚU�estebank commentedon Sep 17, 2018
Even better, enabling NLL causes an ICE:
nikomatsakis commentedon Sep 19, 2018
Perhaps we can bisect this regression? (e.g., with https://github.com/rust-lang-nursery/cargo-bisect-rustc)
dtolnay commentedon Sep 19, 2018
Bisected to correct behavior in nightly-2017-07-07 -- rustc 1.20.0-nightly (696412d 2017-07-06), incorrect behavior in nightly-2017-07-08 -- rustc 1.20.0-nightly (9b85e1c 2017-07-07).
That range is 696412d...9b85e1c.
Looks like #42840.
pnkfelix commentedon Sep 20, 2018
visited for triage. Assigning to @nikomatsakis
nikomatsakis commentedon Sep 20, 2018
@dtolnay thanks, very helpful!
nikomatsakis commentedon Sep 20, 2018
I think the bug is here:
rust/src/librustc/traits/fulfill.rs
Lines 296 to 304 in f7f4c50
In particular, I think the
has_late_bound_regionscondition is not strong enough.predicate_must_holddoesn't consider region annotations, so we probably need to not use this logic if there are any regions.But I'm wondering if the whole concept is flawed. I'm a bit fearful of
'staticregions being introduced through associated type normalization.nikomatsakis commentedon Sep 20, 2018
I have a fix.
arielb1 commentedon Sep 21, 2018
Of course, any approach that relies on any lifetimes in the affected trait-ref is fatally flawed - here's an example where the trait ref is the region-free
<u32 as RefFoo>.nikomatsakis commentedon Sep 25, 2018
@arielb1 I'm not really sure what your example is meant to illustrate. That said, running that on my branch gives an error:
This seems like the error I would expect, more or less. We try to use the impl to prove that
for<'a> &'a T: Foobut we fail to do so (because of the side condition that it adds).Auto merge of #54401 - nikomatsakis:issue-54302-hrtb-fail, r=<try>
arielb1 commentedon Sep 25, 2018
BTW, the
has_late_bounds_regioncheck looks like it happened because I usedis_globalthere, and @matthewjasper added an explicit check when he changedis_globalin #48557 to note be made true by late-bound regions.pnkfelix commentedon Sep 27, 2018
visited for triage. bug seems to be being dealt with, assuming that PR #54401 is eventually deemed as passing muster...
nikomatsakis commentedon Sep 27, 2018
@arielb1
Yes, I think that the "no late-bound regions" check was basically a workaround for this same problem; I removed it in the PR since I think it has a "more correct" fix.
Rollup merge of rust-lang#54624 - arielb1:evaluate-outlives, r=nikoma…
Auto merge of #54624 - arielb1:evaluate-outlives, r=nikomatsakis