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
[NLL] check other sorts of rvalues beyond aggregates #45959
This is a meta-issue to cover the various cases. As PRs come in, I can check things off. Here is a list. In practice, all of the issues boil down to needing to verify various trait requirements, so the main step here will be building a subroutine for checking that a given trait reference is satisfied at a particular location (somewhat similar to normalize -- instructions to come shortly).
Rvalue::Use(Operand) -- let y = x
Nothing to do here, I think. added by @arielb1 verify that the operand is Sized? Do that for every operand?
Rvalue::Repeat(Operand, ConstUsize) -- let y = [x; N]
We must check that the operand is Copy.
Rvalue::Ref(Region, BorrowKind, Lvalue) -- let y = &x
The only special rules here are region-specific -- e.g., reborrowing constraints -- so we'll let the NLL region inference handle them.
Rvalue::Len(X)
No special rules.
Rvalue::Cast(CastKind, Operand, Ty), let's break this down by CastKind:
Misc -- some form of bitcast I think, no action needed
ReifyFnPointer - added by @arielb1 the signatures must match
ClosureFnPointer - added by @arielb1 the signatures must match
UnsafeFnPointer - added by @arielb1 the signatures must match
Unsize - I think we should verify a trait obligation here, something like T: Unsize<U> where T is the operand's type and U` is the target type. Have to double check this.
Rvalue::BinaryOp(..) -- built-in binary operators. Probably we should check that e.g. the LHS and RHS are of the same type, but I'm not sure if that must be true and it doesn't really affect NLL anyhow. Leave it for now.
As noted above, the main thing we need is some kind of function to check that a given trait reference is satisfied at a particular location. Let's call it prove. I imagine it would have a signature like this:
Inernally, like normalize, it should use fully_perform_op and look a little something like this:
self.fully_perform_op(location.at_self(), |this| {letmut selcx = traits::SelectionContext::new(this.infcx);let cause = traits::ObligationCause::misc(this.last_span, ast::CRATE_NODE_ID);let obligation = traits::Obligation::new(cause, this.param_env, trait_ref.to_poly_trait_ref());ifletSome(vtable) = selcx.select(&obligation)? {Ok(InferOk{value:(),obligations: vtable.nested_obligations()})}else{mir_span_bug!(...)// typeck should have ensured that this will succeed}}).unwrap()
This basically invokes the trait checker (selcx.select) and gets back a (hopefully) successful resolution (vtable) which may carry with it some more work to do, which we then propagate upwards via vtable.nested_obligations().
ReifyFnPointer. This coercion casts from the TyFnDef type (a zero-sized type given to each function) to a TyFnPtr type (the "reified" form, a function pointer whose origin we do not statically know). We basically want to check that the "target type" of the cast is equal to a TyFnPtr with the signature that we can derive from the source type ty (which is a TyFnDef).
To compute the signature, we do ty.fn_sig(tcx) -- this gives a PolyFnSig. This can be then converted into a TyFnPtr via tcx.mk_fn_ptr(ty.fn_sig(tcx)). We can then equate that with the target type of the cast.
Activity
[-][NLL] check other sorts of rvalues beyond [/-][+][NLL] check other sorts of rvalues beyond aggregates[/+]nikomatsakis commentedon Nov 13, 2017
Mentoring instructions
As noted above, the main thing we need is some kind of function to check that a given trait reference is satisfied at a particular location. Let's call it
prove. I imagine it would have a signature like this:Inernally, like
normalize, it should usefully_perform_opand look a little something like this:This basically invokes the trait checker (
selcx.select) and gets back a (hopefully) successful resolution (vtable) which may carry with it some more work to do, which we then propagate upwards viavtable.nested_obligations().spastorino commentedon Nov 13, 2017
I'm taking this one, I've already talk with @nikomatsakis about it :).
Auto merge of #46054 - nikomatsakis:nll-master-to-rust-master-1, r=ar…
nikomatsakis commentedon Nov 27, 2017
OK, so, some notes.
ReifyFnPointer. This coercion casts from the
TyFnDeftype (a zero-sized type given to each function) to aTyFnPtrtype (the "reified" form, a function pointer whose origin we do not statically know). We basically want to check that the "target type" of the cast is equal to aTyFnPtrwith the signature that we can derive from the source typety(which is aTyFnDef).To compute the signature, we do
ty.fn_sig(tcx)-- this gives aPolyFnSig. This can be then converted into aTyFnPtrviatcx.mk_fn_ptr(ty.fn_sig(tcx)). We can then equate that with the target type of the cast.nikomatsakis commentedon Dec 5, 2017
Done (in nll-master)