Code change:
The compiler allows this code when it shouldn't The following code is buggy: Invalid string contains, as the name suggests, an invalid string; sometimes I get a string filled with , sometimes just garbage, and usually it will eventually assert that the string contains invalid characters. It appears that the first gets dropped when the second one is assigned? Either the first is supposed to be dropped as happens now, and the borrow checker should forbid this code (since the old no longer exists, cannot have a lifetime), or it should let the first live until the end of the current scope, and make the above work.
What platform are you running this on? This code compiles and prints for me on OSX
I hadn't actually tried in my own rustc, I created the minimized version on rusti: Inspired by an actual bug that I got after trying to read some stuff from a file. It seems what I posted originally does actually compile and work properly on my system as well, I guess I should have tested that... I'll try and find and find a minimized example tomorrow.
is getting old at this point, and I suspect that this was fixed by
This one asserts (sometimes, it's random) for real on my system, most recent build of master (debian 64-bit, rustc 0.10-pre 2014-02-12 14:51:48 -0800) Assuming the executable is named bug: run with Removing the line that says gives me the output: Otherwise it appears random, usually asserting:
Quite plausibly due to , though I haven't dug in in detail.
It seems the bug persists even without the shadowing so perhaps this is related to , except for the 'match' part?
It appears that we allow this code to compile: Nominating, that's bad.
Any suggestions for a better name for this issue? The current name is misleading. Perhaps something along the lines of "Stale pointers can be created in safe code"?
Updated title and description
cc me
cc
Interestingly enough, the compiler rejects this code: It appears that the type ascription is throwing off the compiler?
Another example taken from
0, P-backcompat-lang
The compiler correctly rejects:
cc me
has taken a major detour to fix other two more fundamental bugs first. On top of that fix, the root cause of this bug is also becoming clearer. Case 1: Case 2: Case 3: The difference here is that the RHS is directly assignable to LHS in case 1 but not in case 2 + 3 so takes different code paths. And in latter two cases, there's bug in which upstream and downstream code inside disagree with the order of two parameters so two regions are merged incorrectly. The fix is rather simple. But the variance inference adds another twist to case 3. The result of variance inference can be used to do type parameter substitution, which is not enabled yet. The net effect is two negatives become positive; the current rejects that too.It did compile on top of , which in itself is incorrect. So I guess the fix for this bug must wait for the PR to land.

Related discussion:
text: WriteAndRead, // x += y } <ins> enum OverloadedCallType { FnOverloadedCall, FnMutOverloadedCall, FnOnceOverloadedCall, } impl OverloadedCallType { fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId) -> OverloadedCallType { for &(maybe_function_trait, overloaded_call_type) in [ (tcx.lang_items.fn_once_trait(), FnOnceOverloadedCall), (tcx.lang_items.fn_mut_trait(), FnMutOverloadedCall), (tcx.lang_items.fn_trait(), FnOverloadedCall) ].iter() { match maybe_function_trait { Some(function_trait) if function_trait == trait_id => { return overloaded_call_type } _ => continue, } } tcx.sess.bug("overloaded call didn't map to known function trait") } fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId) -> OverloadedCallType { let method_descriptor = match tcx.methods.borrow_mut().find(&method_id) { None => { tcx.sess.bug("overloaded call method wasn't in method  map") } Some(ref method_descriptor) => (*method_descriptor).clone(), }; let impl_id = match method_descriptor.container { ty::TraitContainer(_) => { tcx.sess.bug("statically resolved overloaded call method  belonged to a trait?!") } ty::ImplContainer(impl_id) => impl_id, }; let trait_ref = match ty::impl_trait_ref(tcx, impl_id) { None => { tcx.sess.bug("statically resolved overloaded call impl  didn't implement a trait?!") } Some(ref trait_ref) => (*trait_ref).clone(), }; OverloadedCallType::from_trait_id(tcx, trait_ref.def_id) } fn from_method_origin(tcx: &ty::ctxt, origin: &MethodOrigin) -> OverloadedCallType { match *origin { MethodStatic(def_id) => { OverloadedCallType::from_method_id(tcx, def_id) } MethodParam(ref method_param) => { OverloadedCallType::from_trait_id(tcx, method_param.trait_id) } MethodObject(ref method_object) => { OverloadedCallType::from_trait_id(tcx, method_object.trait_id) } } } } </ins> /////////////////////////////////////////////////////////////////////////// // The ExprUseVisitor type //