You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
unsoundness caused by hidden borrow in nightly match ergonomics #49631
#[derive(Copy,Clone,Debug,Eq,PartialEq)]pubenumFoo{ReallyReallyReallyLongName,Foo2,Foo3,}structIter{done:bool}implIteratorforIter{typeItem = Result<Foo,String>;fnnext(&mutself) -> Option<Self::Item>{ifself.done{returnNone;}self.done = true;Some(Ok(Foo::ReallyReallyReallyLongName))}}fnmain(){let iter = Iter{done:false};letmut 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 &FoowhileletSome(Ok(foo)) = iter.peek(){
iter.next();// destroys what foo is pointing toprintln!("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.
OK, so I found the bug. Not sure yet what is best fix. Let me write out what is going on:
ExprUseVisitor winds up aborting because it invokes the mem-categorization code on a pattern gets back an Err result. It assumes (incorrectly) that this indicates a compilation error was reported in typeck.
mem-categorization is correctly looking at the desugared pattern Some(&Ok(ref foo))
however, it is incorrectly tracking the type of the value being matched
that type starts out correct, as Option<&Result<..>>
but when we pass through the Some pattern to the subpatterns:
we incorrectly adjust the type to Result, not &Result
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.
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.
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 !...)
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:
Errresult. It assumes (incorrectly) that this indicates a compilation error was reported in typeck.Some(&Ok(ref foo))Option<&Result<..>>Somepattern to the subpatterns:Result, not&Resultpat_ty:rust/src/librustc/middle/mem_categorization.rs
Line 1265 in 56714ac
So we need to stop doing that. Ah, I guess the
pat_adjustmentsarray 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.
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
!...)Auto merge of #49714 - nikomatsakis:issue-49631, r=eddyb
make mem-categorization use adjusted type for patterns