mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Rust: Context typing for constructors
This commit is contained in:
@@ -260,11 +260,22 @@ private class NonMethodFunction extends Function {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private TypeMention getCallExprTypeArgument(CallExpr ce, TypeArgumentPosition apos) {
|
||||
exists(Path p, int i |
|
||||
private TypeMention getCallExprTypeMentionArgument(CallExpr ce, TypeArgumentPosition apos) {
|
||||
exists(Path p, int i | p = CallExprImpl::getFunctionPath(ce) |
|
||||
apos.asTypeParam() = resolvePath(p).getTypeParam(pragma[only_bind_into](i)) and
|
||||
result = getPathTypeArgument(p, pragma[only_bind_into](i))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Type getCallExprTypeArgument(CallExpr ce, TypeArgumentPosition apos, TypePath path) {
|
||||
result = getCallExprTypeMentionArgument(ce, apos).resolveTypeAt(path)
|
||||
or
|
||||
// Handle constructions that use `Self(...)` syntax
|
||||
exists(Path p, TypePath path0 |
|
||||
p = CallExprImpl::getFunctionPath(ce) and
|
||||
result = p.getSegment().getGenericArgList().getTypeArg(pragma[only_bind_into](i)) and
|
||||
apos.asTypeParam() = resolvePath(p).getTypeParam(pragma[only_bind_into](i))
|
||||
result = p.(TypeMention).resolveTypeAt(path0) and
|
||||
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -356,8 +367,7 @@ module CertainTypeInference {
|
||||
// For type parameters of the function we must resolve their
|
||||
// instantiation from the path. For instance, for `fn bar<A>(a: A) -> A`
|
||||
// and the path `bar<i64>`, we must resolve `A` to `i64`.
|
||||
result =
|
||||
getCallExprTypeArgument(ce, TTypeParamTypeArgumentPosition(tp)).resolveTypeAt(suffix)
|
||||
result = getCallExprTypeArgument(ce, TTypeParamTypeArgumentPosition(tp), suffix)
|
||||
)
|
||||
or
|
||||
not ty instanceof TypeParameter and
|
||||
@@ -748,6 +758,8 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
|
||||
/**
|
||||
* A matching configuration for resolving types of struct expressions
|
||||
* like `Foo { bar = baz }`.
|
||||
*
|
||||
* This also includes nullary struct expressions like `None`.
|
||||
*/
|
||||
private module StructExprMatchingInput implements MatchingInputSig {
|
||||
private newtype TPos =
|
||||
@@ -830,26 +842,86 @@ private module StructExprMatchingInput implements MatchingInputSig {
|
||||
|
||||
class AccessPosition = DeclarationPosition;
|
||||
|
||||
class Access extends StructExpr {
|
||||
abstract class Access extends AstNode {
|
||||
pragma[nomagic]
|
||||
abstract AstNode getNodeAt(AccessPosition apos);
|
||||
|
||||
pragma[nomagic]
|
||||
Type getInferredType(AccessPosition apos, TypePath path) {
|
||||
result = inferType(this.getNodeAt(apos), path)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
abstract Path getStructPath();
|
||||
|
||||
pragma[nomagic]
|
||||
Declaration getTarget() { result = resolvePath(this.getStructPath()) }
|
||||
|
||||
pragma[nomagic]
|
||||
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
|
||||
// Handle constructions that use `Self{...}` syntax
|
||||
exists(TypeMention tm, TypePath path0 |
|
||||
tm = this.getStructPath() and
|
||||
result = tm.resolveTypeAt(path0) and
|
||||
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the return type of this struct expression at `path` may have to
|
||||
* be inferred from the context.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate isContextTypedAt(DeclarationPosition pos, TypePath path) {
|
||||
exists(Declaration d, TypeParameter tp |
|
||||
d = this.getTarget() and
|
||||
pos.isStructPos() and
|
||||
tp = d.getDeclaredType(pos, path) and
|
||||
not exists(DeclarationPosition fieldPos |
|
||||
not fieldPos.isStructPos() and
|
||||
tp = d.getDeclaredType(fieldPos, _)
|
||||
) and
|
||||
// check that no explicit type arguments have been supplied for `tp`
|
||||
not exists(TypeArgumentPosition tapos |
|
||||
exists(this.getTypeArgument(tapos, _)) and
|
||||
TTypeParamTypeParameter(tapos.asTypeParam()) = tp
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class StructExprAccess extends Access, StructExpr {
|
||||
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
|
||||
result = super.getTypeArgument(apos, path)
|
||||
or
|
||||
exists(TypePath suffix |
|
||||
suffix.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path) and
|
||||
result = CertainTypeInference::inferCertainType(this, suffix)
|
||||
)
|
||||
}
|
||||
|
||||
AstNode getNodeAt(AccessPosition apos) {
|
||||
override AstNode getNodeAt(AccessPosition apos) {
|
||||
result = this.getFieldExpr(apos.asFieldPos()).getExpr()
|
||||
or
|
||||
result = this and
|
||||
apos.isStructPos()
|
||||
}
|
||||
|
||||
Type getInferredType(AccessPosition apos, TypePath path) {
|
||||
result = inferType(this.getNodeAt(apos), path)
|
||||
override Path getStructPath() { result = this.getPath() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A potential nullary struct/variant construction such as `None`.
|
||||
*/
|
||||
private class PathExprAccess extends Access, PathExpr {
|
||||
PathExprAccess() { not exists(CallExpr ce | this = ce.getFunction()) }
|
||||
|
||||
override AstNode getNodeAt(AccessPosition apos) {
|
||||
result = this and
|
||||
apos.isStructPos()
|
||||
}
|
||||
|
||||
Declaration getTarget() { result = resolvePath(this.getPath()) }
|
||||
override Path getStructPath() { result = this.getPath() }
|
||||
}
|
||||
|
||||
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) {
|
||||
@@ -859,17 +931,25 @@ private module StructExprMatchingInput implements MatchingInputSig {
|
||||
|
||||
private module StructExprMatching = Matching<StructExprMatchingInput>;
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferStructExprType0(AstNode n, boolean isReturn, TypePath path) {
|
||||
exists(StructExprMatchingInput::Access a, StructExprMatchingInput::AccessPosition apos |
|
||||
n = a.getNodeAt(apos) and
|
||||
if apos.isStructPos() then isReturn = true else isReturn = false
|
||||
|
|
||||
result = StructExprMatching::inferAccessType(a, apos, path)
|
||||
or
|
||||
a.isContextTypedAt(apos, path) and
|
||||
result = TContextType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of `n` at `path`, where `n` is either a struct expression or
|
||||
* a field expression of a struct expression.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Type inferStructExprType(AstNode n, TypePath path) {
|
||||
exists(StructExprMatchingInput::Access a, StructExprMatchingInput::AccessPosition apos |
|
||||
n = a.getNodeAt(apos) and
|
||||
result = StructExprMatching::inferAccessType(a, apos, path)
|
||||
)
|
||||
}
|
||||
private predicate inferStructExprType =
|
||||
ContextTyping::CheckContextTyping<inferStructExprType0/3>::check/2;
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferTupleRootType(AstNode n) {
|
||||
@@ -877,18 +957,6 @@ private Type inferTupleRootType(AstNode n) {
|
||||
result = TTuple([n.(TupleExpr).getNumberOfFields(), n.(TuplePat).getTupleArity()])
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferPathExprType(PathExpr pe, TypePath path) {
|
||||
// nullary struct/variant constructors
|
||||
not exists(CallExpr ce | pe = ce.getFunction()) and
|
||||
path.isEmpty() and
|
||||
exists(ItemNode i | i = resolvePath(pe.getPath()) |
|
||||
result = TEnum(i.(Variant).getEnum())
|
||||
or
|
||||
result = TStruct(i)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Path getCallExprPathQualifier(CallExpr ce) {
|
||||
result = CallExprImpl::getFunctionPath(ce).getQualifier()
|
||||
@@ -955,7 +1023,7 @@ private module ContextTyping {
|
||||
*/
|
||||
bindingset[this, i, target]
|
||||
predicate isContextTypedAt(
|
||||
ImplOrTraitItemNode i, Function target, TypePath path, FunctionPosition pos
|
||||
ImplOrTraitItemNode i, Function target, FunctionPosition pos, TypePath path
|
||||
) {
|
||||
exists(TypeParameter tp |
|
||||
assocFunctionReturnContextTypedAt(i, target, pos, path, tp) and
|
||||
@@ -982,7 +1050,7 @@ private module ContextTyping {
|
||||
pragma[nomagic]
|
||||
private predicate isContextTyped(AstNode n) { isContextTyped(n, _) }
|
||||
|
||||
signature Type inferCallTypeSig(AstNode n, FunctionPosition pos, TypePath path);
|
||||
signature Type inferCallTypeSig(AstNode n, boolean isReturn, TypePath path);
|
||||
|
||||
/**
|
||||
* Given a predicate `inferCallType` for inferring the type of a call at a given
|
||||
@@ -992,30 +1060,24 @@ private module ContextTyping {
|
||||
*/
|
||||
module CheckContextTyping<inferCallTypeSig/3 inferCallType> {
|
||||
pragma[nomagic]
|
||||
private Type inferCallTypeFromContextCand(
|
||||
AstNode n, FunctionPosition pos, TypePath path, TypePath prefix
|
||||
) {
|
||||
result = inferCallType(n, pos, path) and
|
||||
not pos.isReturn() and
|
||||
private Type inferCallTypeFromContextCand(AstNode n, TypePath path, TypePath prefix) {
|
||||
result = inferCallType(n, false, path) and
|
||||
isContextTyped(n) and
|
||||
prefix = path
|
||||
or
|
||||
exists(TypePath mid |
|
||||
result = inferCallTypeFromContextCand(n, pos, path, mid) and
|
||||
result = inferCallTypeFromContextCand(n, path, mid) and
|
||||
mid.isSnoc(prefix, _)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
Type check(AstNode n, TypePath path) {
|
||||
exists(FunctionPosition pos |
|
||||
result = inferCallType(n, pos, path) and
|
||||
pos.isReturn()
|
||||
or
|
||||
exists(TypePath prefix |
|
||||
result = inferCallTypeFromContextCand(n, pos, path, prefix) and
|
||||
isContextTyped(n, prefix)
|
||||
)
|
||||
result = inferCallType(n, true, path)
|
||||
or
|
||||
exists(TypePath prefix |
|
||||
result = inferCallTypeFromContextCand(n, path, prefix) and
|
||||
isContextTyped(n, prefix)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2037,12 +2099,14 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
|
||||
|
||||
pragma[nomagic]
|
||||
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
|
||||
exists(TypeMention arg | result = arg.resolveTypeAt(path) |
|
||||
arg =
|
||||
this.(MethodCallExpr).getGenericArgList().getTypeArg(apos.asMethodTypeArgumentPosition())
|
||||
or
|
||||
arg = getCallExprTypeArgument(this, apos)
|
||||
)
|
||||
result =
|
||||
this.(MethodCallExpr)
|
||||
.getGenericArgList()
|
||||
.getTypeArg(apos.asMethodTypeArgumentPosition())
|
||||
.(TypeMention)
|
||||
.resolveTypeAt(path)
|
||||
or
|
||||
result = getCallExprTypeArgument(this, apos, path)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2090,6 +2154,17 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
|
||||
}
|
||||
|
||||
Declaration getTarget(string derefChainBorrow) { result = this.getTarget(_, derefChainBorrow) }
|
||||
|
||||
/**
|
||||
* Holds if the return type of this call at `path` may have to be inferred
|
||||
* from the context.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate isContextTypedAt(string derefChainBorrow, FunctionPosition pos, TypePath path) {
|
||||
exists(ImplOrTraitItemNode i |
|
||||
this.isContextTypedAt(i, this.getTarget(i, derefChainBorrow), pos, path)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2105,10 +2180,8 @@ private Type inferMethodCallType0(
|
||||
(
|
||||
result = MethodCallMatching::inferAccessType(a, derefChainBorrow, apos, path0)
|
||||
or
|
||||
exists(ImplOrTraitItemNode i |
|
||||
a.isContextTypedAt(i, a.getTarget(i, derefChainBorrow), path0, apos) and
|
||||
result = TContextType()
|
||||
)
|
||||
a.isContextTypedAt(derefChainBorrow, apos, path0) and
|
||||
result = TContextType()
|
||||
)
|
||||
|
|
||||
if
|
||||
@@ -2122,11 +2195,13 @@ private Type inferMethodCallType0(
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferMethodCallType1(
|
||||
AstNode n, MethodCallMatchingInput::AccessPosition apos, TypePath path
|
||||
) {
|
||||
exists(MethodCallMatchingInput::Access a, string derefChainBorrow, TypePath path0 |
|
||||
result = inferMethodCallType0(a, apos, n, derefChainBorrow, path0)
|
||||
private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
|
||||
exists(
|
||||
MethodCallMatchingInput::Access a, MethodCallMatchingInput::AccessPosition apos,
|
||||
string derefChainBorrow, TypePath path0
|
||||
|
|
||||
result = inferMethodCallType0(a, apos, n, derefChainBorrow, path0) and
|
||||
if apos.isReturn() then isReturn = true else isReturn = false
|
||||
|
|
||||
(
|
||||
not apos.isSelf()
|
||||
@@ -2451,6 +2526,9 @@ private module NonMethodResolution {
|
||||
/**
|
||||
* A matching configuration for resolving types of calls like
|
||||
* `foo::bar(baz)` where the target is not a method.
|
||||
*
|
||||
* This also includes "calls" to tuple variants and tuple structs such
|
||||
* as `Result::Ok(42)`.
|
||||
*/
|
||||
private module NonMethodCallMatchingInput implements MatchingInputSig {
|
||||
import FunctionPositionMatchingInput
|
||||
@@ -2571,7 +2649,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig {
|
||||
class Access extends NonMethodResolution::NonMethodCall, ContextTyping::ContextTypedCallCand {
|
||||
pragma[nomagic]
|
||||
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
|
||||
result = getCallExprTypeArgument(this, apos).resolveTypeAt(path)
|
||||
result = getCallExprTypeArgument(this, apos, path)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2585,27 +2663,50 @@ private module NonMethodCallMatchingInput implements MatchingInputSig {
|
||||
Declaration getTarget() {
|
||||
result = this.resolveCallTarget() // potential mutual recursion; resolving some associated function calls requires resolving types
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the return type of this call at `path` may have to be inferred
|
||||
* from the context.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate isContextTypedAt(FunctionPosition pos, TypePath path) {
|
||||
exists(ImplOrTraitItemNode i |
|
||||
this.isContextTypedAt(i,
|
||||
[
|
||||
this.resolveCallTargetViaPathResolution().(NonMethodFunction),
|
||||
this.resolveCallTargetViaTypeInference(i),
|
||||
this.resolveTraitFunctionViaPathResolution(i)
|
||||
], pos, path)
|
||||
)
|
||||
or
|
||||
// Tuple declarations, such as `Result::Ok(...)`, may also be context typed
|
||||
exists(TupleDeclaration td, TypeParameter tp |
|
||||
td = this.resolveCallTargetViaPathResolution() and
|
||||
pos.isReturn() and
|
||||
tp = td.getReturnType(path) and
|
||||
not tp = td.getParameterType(_, _) and
|
||||
// check that no explicit type arguments have been supplied for `tp`
|
||||
not exists(TypeArgumentPosition tapos |
|
||||
exists(this.getTypeArgument(tapos, _)) and
|
||||
TTypeParamTypeParameter(tapos.asTypeParam()) = tp
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private module NonMethodCallMatching = Matching<NonMethodCallMatchingInput>;
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferNonMethodCallType0(
|
||||
AstNode n, NonMethodCallMatchingInput::AccessPosition apos, TypePath path
|
||||
) {
|
||||
exists(NonMethodCallMatchingInput::Access a | n = a.getNodeAt(apos) |
|
||||
private Type inferNonMethodCallType0(AstNode n, boolean isReturn, TypePath path) {
|
||||
exists(NonMethodCallMatchingInput::Access a, NonMethodCallMatchingInput::AccessPosition apos |
|
||||
n = a.getNodeAt(apos) and
|
||||
if apos.isReturn() then isReturn = true else isReturn = false
|
||||
|
|
||||
result = NonMethodCallMatching::inferAccessType(a, apos, path)
|
||||
or
|
||||
exists(ImplOrTraitItemNode i |
|
||||
a.isContextTypedAt(i,
|
||||
[
|
||||
a.resolveCallTargetViaPathResolution().(NonMethodFunction),
|
||||
a.resolveCallTargetViaTypeInference(i),
|
||||
a.resolveTraitFunctionViaPathResolution(i)
|
||||
], path, apos) and
|
||||
result = TContextType()
|
||||
)
|
||||
a.isContextTypedAt(apos, path) and
|
||||
result = TContextType()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2684,12 +2785,11 @@ private module OperationMatchingInput implements MatchingInputSig {
|
||||
private module OperationMatching = Matching<OperationMatchingInput>;
|
||||
|
||||
pragma[nomagic]
|
||||
private Type inferOperationType0(
|
||||
AstNode n, OperationMatchingInput::AccessPosition apos, TypePath path
|
||||
) {
|
||||
exists(OperationMatchingInput::Access a |
|
||||
private Type inferOperationType0(AstNode n, boolean isReturn, TypePath path) {
|
||||
exists(OperationMatchingInput::Access a, OperationMatchingInput::AccessPosition apos |
|
||||
n = a.getNodeAt(apos) and
|
||||
result = OperationMatching::inferAccessType(a, apos, path)
|
||||
result = OperationMatching::inferAccessType(a, apos, path) and
|
||||
if apos.isReturn() then isReturn = true else isReturn = false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3457,8 +3557,6 @@ private module Cached {
|
||||
or
|
||||
result = inferStructExprType(n, path)
|
||||
or
|
||||
result = inferPathExprType(n, path)
|
||||
or
|
||||
result = inferMethodCallType(n, path)
|
||||
or
|
||||
result = inferNonMethodCallType(n, path)
|
||||
|
||||
@@ -108,6 +108,20 @@ class AliasPathTypeMention extends PathTypeMention {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `i`th type argument of `p`.
|
||||
*
|
||||
* Takes into account that variants can have type arguments applied to both the
|
||||
* enum and the variant itself, e.g. `Option::<i32>::Some` is valid in addition
|
||||
* to `Option::Some::<i32>`.
|
||||
*/
|
||||
TypeMention getPathTypeArgument(Path p, int i) {
|
||||
result = p.getSegment().getGenericArgList().getTypeArg(i)
|
||||
or
|
||||
resolvePath(p) instanceof Variant and
|
||||
result = p.getQualifier().getSegment().getGenericArgList().getTypeArg(i)
|
||||
}
|
||||
|
||||
class NonAliasPathTypeMention extends PathTypeMention {
|
||||
TypeItemNode resolved;
|
||||
|
||||
@@ -143,18 +157,6 @@ class NonAliasPathTypeMention extends PathTypeMention {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the positional type argument at index `i` that occurs in this path, if
|
||||
* any.
|
||||
*/
|
||||
private TypeMention getPathPositionalTypeArgument(int i) {
|
||||
result = this.getSegment().getGenericArgList().getTypeArg(i)
|
||||
or
|
||||
// `Option::<i32>::Some` is valid in addition to `Option::Some::<i32>`
|
||||
resolvePath(this) instanceof Variant and
|
||||
result = this.getQualifier().getSegment().getGenericArgList().getTypeArg(i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type mention that instantiates the implicit `Self` type parameter
|
||||
* for this path, if it occurs in the position of a trait bound.
|
||||
@@ -173,7 +175,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
|
||||
private Type getDefaultPositionalTypeArgument(int i, TypePath path) {
|
||||
// If a type argument is not given in the path, then we use the default for
|
||||
// the type parameter if one exists for the type.
|
||||
not exists(this.getPathPositionalTypeArgument(i)) and
|
||||
not exists(getPathTypeArgument(this, i)) and
|
||||
// Defaults only apply to type mentions in type annotations
|
||||
this = any(PathTypeRepr ptp).getPath().getQualifier*() and
|
||||
exists(Type ty, TypePath prefix |
|
||||
@@ -191,7 +193,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
|
||||
}
|
||||
|
||||
private Type getPositionalTypeArgument(int i, TypePath path) {
|
||||
result = this.getPathPositionalTypeArgument(i).resolveTypeAt(path)
|
||||
result = getPathTypeArgument(this, i).resolveTypeAt(path)
|
||||
or
|
||||
result = this.getDefaultPositionalTypeArgument(i, path)
|
||||
}
|
||||
|
||||
@@ -2908,12 +2908,12 @@ mod context_typed {
|
||||
pub fn f() {
|
||||
let x = None; // $ type=x:T.i32
|
||||
let x: Option<i32> = x;
|
||||
let x = Option::<i32>::None; // $ MISSING: type=x:T.i32
|
||||
let x = Option::None::<i32>; // $ MISSING: type=x:T.i32
|
||||
let x = Option::<i32>::None; // $ type=x:T.i32
|
||||
let x = Option::None::<i32>; // $ type=x:T.i32
|
||||
|
||||
fn pin_option<T>(opt: Option<T>, x: T) {}
|
||||
|
||||
let x = None; // $ MISSING: type=x:T.i32
|
||||
let x = None; // $ type=x:T.i32
|
||||
pin_option(x, 0); // $ target=pin_option
|
||||
|
||||
enum MyEither<T1, T2> {
|
||||
@@ -2932,7 +2932,7 @@ mod context_typed {
|
||||
fn pin_my_either<T>(e: MyEither<T, String>, x: T) {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let x = MyEither::B { // $ type=x:T2.String $ MISSING: type=x:T1.i32
|
||||
let x = MyEither::B { // $ type=x:T1.i32 type=x:T2.String
|
||||
right: String::new(), // $ target=new
|
||||
};
|
||||
pin_my_either(x, 0); // $ target=pin_my_either
|
||||
@@ -2944,7 +2944,7 @@ mod context_typed {
|
||||
|
||||
fn pin_result<T, E>(res: Result<T, E>, x: E) {}
|
||||
|
||||
let x = Result::Ok(0); // $ type=x:T.i32 $ MISSING: type=x:E.bool
|
||||
let x = Result::Ok(0); // $ type=x:T.i32 type=x:E.bool
|
||||
pin_result(x, false); // $ target=pin_result
|
||||
|
||||
let mut x = Vec::new(); // $ type=x:T.i32 target=new
|
||||
|
||||
@@ -3115,9 +3115,12 @@ inferType
|
||||
| main.rs:1370:26:1370:27 | p3 | Snd | main.rs:1310:5:1311:14 | S3 |
|
||||
| main.rs:1372:9:1372:55 | g(...) | | file://:0:0:0:0 | () |
|
||||
| main.rs:1372:11:1372:54 | ...::PairSnd(...) | | main.rs:1285:5:1291:5 | PairOption |
|
||||
| main.rs:1372:11:1372:54 | ...::PairSnd(...) | Fst | main.rs:1307:5:1308:14 | S2 |
|
||||
| main.rs:1372:11:1372:54 | ...::PairSnd(...) | Snd | main.rs:1285:5:1291:5 | PairOption |
|
||||
| main.rs:1372:11:1372:54 | ...::PairSnd(...) | Snd.Fst | main.rs:1307:5:1308:14 | S2 |
|
||||
| main.rs:1372:11:1372:54 | ...::PairSnd(...) | Snd.Snd | main.rs:1310:5:1311:14 | S3 |
|
||||
| main.rs:1372:31:1372:53 | ...::PairSnd(...) | | main.rs:1285:5:1291:5 | PairOption |
|
||||
| main.rs:1372:31:1372:53 | ...::PairSnd(...) | Fst | main.rs:1307:5:1308:14 | S2 |
|
||||
| main.rs:1372:31:1372:53 | ...::PairSnd(...) | Snd | main.rs:1310:5:1311:14 | S3 |
|
||||
| main.rs:1372:51:1372:52 | S3 | | main.rs:1310:5:1311:14 | S3 |
|
||||
| main.rs:1374:13:1374:13 | x | | {EXTERNAL LOCATION} | Result |
|
||||
@@ -3551,7 +3554,6 @@ inferType
|
||||
| main.rs:1554:24:1554:39 | &... | &T | main.rs:1476:5:1479:5 | MyInt |
|
||||
| main.rs:1554:25:1554:39 | MyInt {...} | | main.rs:1476:5:1479:5 | MyInt |
|
||||
| main.rs:1554:36:1554:37 | 37 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:1554:36:1554:37 | 37 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1556:13:1556:13 | a | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1556:17:1556:24 | my_thing | | file://:0:0:0:0 | & |
|
||||
| main.rs:1556:17:1556:24 | my_thing | &T | main.rs:1476:5:1479:5 | MyInt |
|
||||
@@ -3567,7 +3569,6 @@ inferType
|
||||
| main.rs:1560:24:1560:39 | &... | &T | main.rs:1476:5:1479:5 | MyInt |
|
||||
| main.rs:1560:25:1560:39 | MyInt {...} | | main.rs:1476:5:1479:5 | MyInt |
|
||||
| main.rs:1560:36:1560:37 | 38 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:1560:36:1560:37 | 38 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1561:13:1561:13 | a | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1561:17:1561:24 | my_thing | | file://:0:0:0:0 | & |
|
||||
| main.rs:1561:17:1561:24 | my_thing | &T | main.rs:1476:5:1479:5 | MyInt |
|
||||
@@ -3823,6 +3824,7 @@ inferType
|
||||
| main.rs:1700:21:1700:25 | input | T | main.rs:1699:20:1699:27 | T |
|
||||
| main.rs:1700:21:1700:26 | TryExpr | | main.rs:1699:20:1699:27 | T |
|
||||
| main.rs:1701:22:1701:38 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:1701:22:1701:38 | ...::Ok(...) | E | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1701:22:1701:38 | ...::Ok(...) | T | main.rs:1699:20:1699:27 | T |
|
||||
| main.rs:1701:22:1704:10 | ... .and_then(...) | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:1701:22:1704:10 | ... .and_then(...) | E | main.rs:1667:5:1668:14 | S1 |
|
||||
@@ -3895,6 +3897,7 @@ inferType
|
||||
| main.rs:1722:37:1722:63 | try_complex(...) | E | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1722:37:1722:63 | try_complex(...) | T | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1722:49:1722:62 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:1722:49:1722:62 | ...::Ok(...) | E | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1722:49:1722:62 | ...::Ok(...) | T | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1722:60:1722:61 | S1 | | main.rs:1667:5:1668:14 | S1 |
|
||||
| main.rs:1722:65:1724:9 | { ... } | | file://:0:0:0:0 | () |
|
||||
@@ -3957,9 +3960,7 @@ inferType
|
||||
| main.rs:1769:30:1771:9 | { ... } | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:1770:13:1770:31 | Vec2 {...} | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:1770:23:1770:23 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:1770:23:1770:23 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1770:29:1770:29 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:1770:29:1770:29 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:1777:16:1777:19 | SelfParam | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:1777:22:1777:24 | rhs | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:1777:41:1782:9 | { ... } | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
@@ -4554,15 +4555,11 @@ inferType
|
||||
| main.rs:2065:13:2065:14 | v1 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2065:18:2065:36 | Vec2 {...} | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2065:28:2065:28 | 1 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2065:28:2065:28 | 1 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2065:34:2065:34 | 2 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2065:34:2065:34 | 2 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2066:13:2066:14 | v2 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2066:18:2066:36 | Vec2 {...} | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2066:28:2066:28 | 3 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2066:28:2066:28 | 3 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2066:34:2066:34 | 4 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2066:34:2066:34 | 4 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2069:13:2069:19 | vec2_eq | | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2069:23:2069:24 | v1 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2069:23:2069:30 | ... == ... | | {EXTERNAL LOCATION} | bool |
|
||||
@@ -4689,9 +4686,7 @@ inferType
|
||||
| main.rs:2128:30:2128:48 | Vec2 {...} | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2128:30:2128:63 | ... + ... | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2128:40:2128:40 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2128:40:2128:40 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2128:46:2128:46 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2128:46:2128:46 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2128:52:2128:63 | default_vec2 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2132:13:2132:24 | default_vec2 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2132:28:2132:45 | ...::default(...) | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
@@ -4699,9 +4694,7 @@ inferType
|
||||
| main.rs:2133:30:2133:48 | Vec2 {...} | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2133:30:2133:64 | ... == ... | | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2133:40:2133:40 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2133:40:2133:40 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2133:46:2133:46 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2133:46:2133:46 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2133:53:2133:64 | default_vec2 | | main.rs:1762:5:1767:5 | Vec2 |
|
||||
| main.rs:2143:18:2143:21 | SelfParam | | main.rs:2140:5:2140:14 | S1 |
|
||||
| main.rs:2143:24:2143:25 | { ... } | | file://:0:0:0:0 | () |
|
||||
@@ -6202,17 +6195,24 @@ inferType
|
||||
| main.rs:2910:30:2910:30 | x | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2910:30:2910:30 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2911:13:2911:13 | x | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2911:13:2911:13 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2911:17:2911:35 | ...::None | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2911:17:2911:35 | ...::None | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2912:13:2912:13 | x | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2912:13:2912:13 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2912:17:2912:35 | ...::None::<...> | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2912:17:2912:35 | ...::None::<...> | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2914:26:2914:28 | opt | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2914:26:2914:28 | opt | T | main.rs:2914:23:2914:23 | T |
|
||||
| main.rs:2914:42:2914:42 | x | | main.rs:2914:23:2914:23 | T |
|
||||
| main.rs:2914:48:2914:49 | { ... } | | file://:0:0:0:0 | () |
|
||||
| main.rs:2916:13:2916:13 | x | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2916:13:2916:13 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2916:17:2916:20 | None | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2916:17:2916:20 | None | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2917:9:2917:24 | pin_option(...) | | file://:0:0:0:0 | () |
|
||||
| main.rs:2917:20:2917:20 | x | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2917:20:2917:20 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2917:23:2917:23 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2924:13:2924:13 | x | | main.rs:2919:9:2922:9 | MyEither |
|
||||
| main.rs:2924:13:2924:13 | x | T1 | {EXTERNAL LOCATION} | i32 |
|
||||
@@ -6247,12 +6247,15 @@ inferType
|
||||
| main.rs:2932:53:2932:53 | x | | main.rs:2932:26:2932:26 | T |
|
||||
| main.rs:2932:59:2932:60 | { ... } | | file://:0:0:0:0 | () |
|
||||
| main.rs:2935:13:2935:13 | x | | main.rs:2919:9:2922:9 | MyEither |
|
||||
| main.rs:2935:13:2935:13 | x | T1 | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2935:13:2935:13 | x | T2 | {EXTERNAL LOCATION} | String |
|
||||
| main.rs:2935:17:2937:9 | ...::B {...} | | main.rs:2919:9:2922:9 | MyEither |
|
||||
| main.rs:2935:17:2937:9 | ...::B {...} | T1 | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2935:17:2937:9 | ...::B {...} | T2 | {EXTERNAL LOCATION} | String |
|
||||
| main.rs:2936:20:2936:32 | ...::new(...) | | {EXTERNAL LOCATION} | String |
|
||||
| main.rs:2938:9:2938:27 | pin_my_either(...) | | file://:0:0:0:0 | () |
|
||||
| main.rs:2938:23:2938:23 | x | | main.rs:2919:9:2922:9 | MyEither |
|
||||
| main.rs:2938:23:2938:23 | x | T1 | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2938:23:2938:23 | x | T2 | {EXTERNAL LOCATION} | String |
|
||||
| main.rs:2938:26:2938:26 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2940:13:2940:13 | x | | {EXTERNAL LOCATION} | Result |
|
||||
@@ -6288,12 +6291,15 @@ inferType
|
||||
| main.rs:2945:48:2945:48 | x | | main.rs:2945:26:2945:26 | E |
|
||||
| main.rs:2945:54:2945:55 | { ... } | | file://:0:0:0:0 | () |
|
||||
| main.rs:2947:13:2947:13 | x | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:2947:13:2947:13 | x | E | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2947:13:2947:13 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2947:17:2947:29 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:2947:17:2947:29 | ...::Ok(...) | E | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2947:17:2947:29 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2947:28:2947:28 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2948:9:2948:28 | pin_result(...) | | file://:0:0:0:0 | () |
|
||||
| main.rs:2948:20:2948:20 | x | | {EXTERNAL LOCATION} | Result |
|
||||
| main.rs:2948:20:2948:20 | x | E | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2948:20:2948:20 | x | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2948:23:2948:27 | false | | {EXTERNAL LOCATION} | bool |
|
||||
| main.rs:2950:17:2950:17 | x | | {EXTERNAL LOCATION} | Vec |
|
||||
|
||||
Reference in New Issue
Block a user