Closed
Description
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Foo {
ReallyReallyReallyLongName,
Foo2,
Foo3,
}
struct Iter {
done: bool
}
impl Iterator for Iter {
type Item = Result<Foo, String>;
fn next(&mut self) -> Option<Self::Item> {
if self.done { return None; }
self.done = true;
Some(Ok(Foo::ReallyReallyReallyLongName))
}
}
fn main() {
let iter = Iter{done: false};
let mut iter = iter.peekable();
// peek() returns type Option<&Result<Foo, String>>
// pattern Some(Ok(foo)) is used instead of Some(&Ok(foo))
// This causes foo to be a hidden borrow of type &Foo
while let Some(Ok(foo)) = iter.peek() {
iter.next(); // destroys what foo is pointing to
println!("foo={:?}", *foo);
}
}
Output:
Illegal instruction (core dumped)
The above code should fail the borrow checker. They key line seems to be the pattern match. It creates a borrow that seems to be invisible to the borrow checker. This appears to only be possible in nightly due to the match_default_bindings
feature.
Metadata
Metadata
Assignees
Labels
Type
Projects
Relationships
Development
No branches or pull requests
Activity
varkor commentedon Apr 4, 2018
Note that this is not a problem when using NLL: playground link.
nikomatsakis commentedon Apr 5, 2018
Sigh. It works with an explicit ref, as well, which suggests that the problem is the ExprUseVisitor.
nikomatsakis commentedon Apr 5, 2018
OK, so I found the bug. Not sure yet what is best fix. Let me write out what is going on:
Err
result. It assumes (incorrectly) that this indicates a compilation error was reported in typeck.Some(&Ok(ref foo))
Option<&Result<..>>
Some
pattern to the subpatterns:Result
, not&Result
pat_ty
:rust/src/librustc/middle/mem_categorization.rs
Line 1265 in 56714ac
So we need to stop doing that. Ah, I guess the
pat_adjustments
array stores the information we need:rust/src/librustc/ty/context.rs
Lines 368 to 381 in 56714ac
leoyvens commentedon Apr 5, 2018
I think we should not stabilize language features right before beta is branched. I don't know if this issue in particular is big deal to backport or not, but stabilizing things at the begging/middle of the cycle avoids rushing to stabilize and then rushing to fix and backport regressions.
make mem-categorization use adjusted type for patterns
nikomatsakis commentedon Apr 5, 2018
( Fix in #49714 )
nikomatsakis commentedon Apr 5, 2018
@leodasvacas
In this case, the fix is trivial -- you can see #49714.
In general, we thought about trying to time landings into the middle of the cycle back in the early days, but we wound up concluding that there is no "right time" to land something. Any change can break stuff, of course, and wherever we draw the line, we've got a shot at getting something breaking.
So I don't know. Maybe it's worth putting rules against stabilizing, but I kinda don't think so. At worst we can "unstabilize" (which I fear we will have to do for
!
...)4 remaining items