Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TY: infer type of default type parameters for known stdlib items #6643

Merged
merged 1 commit into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ fun RsPat.extractBindings(fcx: RsTypeInferenceWalker, type: Ty, defBm: RsBinding
}
is RsPatFieldKind.Shorthand -> {
val bindingType = if (fieldType is TyAdt && kind.isBox) {
fieldType.typeArguments.singleOrNull() ?: return
fieldType.typeArguments.firstOrNull() ?: return
} else {
fieldType
}
Expand All @@ -116,7 +116,7 @@ fun RsPat.extractBindings(fcx: RsTypeInferenceWalker, type: Ty, defBm: RsBinding
val (expected, bm) = type.stripReferences(defBm)
fcx.writePatTy(this, expected)
if (expected is TyAdt && expected.isBox) {
val boxed = expected.typeArguments.singleOrNull() ?: return
val boxed = expected.typeArguments.firstOrNull() ?: return
pat.extractBindings(fcx, boxed, bm)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1438,19 +1438,9 @@ val RsFunction.type: TyFunction
private fun Sequence<Ty>.infiniteWithTyUnknown(): Sequence<Ty> =
this + generateSequence { TyUnknown }

private fun KnownItems.findVecForElementTy(elementTy: Ty): Ty {
val ty = Vec?.declaredType ?: TyUnknown
private fun KnownItems.findVecForElementTy(elementTy: Ty): Ty = Vec.makeTy("T", elementTy)

val typeParameter = ty.getTypeParameter("T") ?: return ty
return ty.substitute(mapOf(typeParameter to elementTy).toTypeSubst())
}

private fun KnownItems.findOptionForElementTy(elementTy: Ty): Ty {
val ty = Option?.declaredType ?: TyUnknown

val typeParameter = ty.getTypeParameter("T") ?: return ty
return ty.substitute(mapOf(typeParameter to elementTy).toTypeSubst())
}
private fun KnownItems.findOptionForElementTy(elementTy: Ty): Ty = Option.makeTy("T", elementTy)

private fun KnownItems.findRangeTy(rangeName: String, indexType: Ty?): Ty {
val ty = findItem<RsNamedElement>("core::ops::$rangeName")?.asTy() ?: TyUnknown
Expand All @@ -1461,10 +1451,32 @@ private fun KnownItems.findRangeTy(rangeName: String, indexType: Ty?): Ty {
return ty.substitute(mapOf(typeParameter to indexType).toTypeSubst())
}

private fun KnownItems.makeBox(innerTy: Ty): Ty {
val box = Box ?: return TyUnknown
val boxTy = TyAdt.valueOf(box)
return boxTy.substitute(mapOf(boxTy.typeArguments[0] as TyTypeParameter to innerTy).toTypeSubst())
private fun KnownItems.makeBox(innerTy: Ty): Ty = Box.makeTy("T", innerTy)

private fun <T> T?.makeTy(typeParamName: String, innerTy: Ty): Ty where T : RsTypeDeclarationElement,
T : RsGenericDeclaration {
if (this == null) return TyUnknown
val itemTy = declaredType

val typeParameter = itemTy.getTypeParameter(typeParamName) ?: return itemTy
val substitutionMap = mutableMapOf(typeParameter to innerTy)

val typeParameters = typeParameters
if (typeParameters.size > 1) {
// Potentially, it's O(n^2) if item contains O(n) type parameters with default value.
// But all known stdlib items contain at most one type parameter with default value
// so it doesn't matter
for (param in typeParameters) {
val name = param.name ?: continue
val typeReference = param.typeReference ?: continue
if (name != typeParamName) {
val typeParam = itemTy.getTypeParameter(name) ?: continue
substitutionMap[typeParam] = typeReference.type
}
}
}

return itemTy.substitute(substitutionMap.toTypeSubst())
}

private fun KnownItems.makeGenerator(yieldTy: Ty, returnTy: Ty): Ty {
Expand Down