diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java index b6ea15aa364..8af5d8c831c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java @@ -7,10 +7,10 @@ public interface CompilationErrorHandler { CompilationErrorHandler THROW_EXCEPTION = new CompilationErrorHandler() { @Override - public void reportError(String message, String fileUrl) { - throw new IllegalStateException(message); + public void reportException(Throwable exception, String fileUrl) { + throw new IllegalStateException(exception); } }; - void reportError(String message, String fileUrl); + void reportException(Throwable exception, String fileUrl); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index b2097c462e1..0002b318992 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -112,7 +112,7 @@ public class GenerationState { generateNamespace(namespace); } catch (Throwable e) { - errorHandler.reportError("Exception: " + e.getClass().getCanonicalName() + ": " + e.getMessage(), namespace.getContainingFile().getVirtualFile().getUrl()); + errorHandler.reportException(e, namespace.getContainingFile().getVirtualFile().getUrl()); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java index 536d0e11600..d02bbb786af 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java @@ -144,7 +144,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement defaultType = new JetTypeImpl( Collections.emptyList(), getTypeConstructor(), - TypeUtils.hasNullableBound(this), + TypeUtils.hasNullableLowerBound(this), Collections.emptyList(), new LazyScopeAdapter(new LazyValue() { @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 012932b4653..5fd39256dfe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -78,7 +78,7 @@ public class TypeResolver { result[0] = new JetTypeImpl( annotations, typeParameterDescriptor.getTypeConstructor(), - nullable || TypeUtils.hasNullableBound(typeParameterDescriptor), + nullable || TypeUtils.hasNullableLowerBound(typeParameterDescriptor), Collections.emptyList(), getScopeForTypeParameter(typeParameterDescriptor) ); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 6573f54fc19..d06f37c4841 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -97,12 +97,14 @@ public class JetTypeChecker { if (!supertype.isNullable() && subtype.isNullable()) { return false; } + subtype = TypeUtils.makeNotNullable(subtype); + supertype = TypeUtils.makeNotNullable(supertype); if (JetStandardClasses.isNothingOrNullableNothing(subtype)) { return true; } @Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype); if (closestSupertype == null) { - if (!constraintBuilder.noCorrespondingSupertype(subtype, supertype)) return false; + return constraintBuilder.noCorrespondingSupertype(subtype, supertype); // if this returns true, there still isn't any supertype to continue with } return checkSubtypeForTheSameConstructor(closestSupertype, supertype); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index 48699139afd..dac071017cd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -130,7 +130,7 @@ public class TypeSubstitutor { if (value != null) { assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor; - return substitutionResult((TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType(); + return TypeUtils.makeNullableIfNeeded(substitutionResult((TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType(), type.isNullable()); // if (!allows(howThisTypeIsUsed, value.getProjectionKind())) { // throw new SubstitutionException("!!" + value.toString()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java index cb6360ab21d..6304adf84db 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -385,8 +385,8 @@ public class TypeUtils { return result; } - public static boolean hasNullableBound(@NotNull TypeParameterDescriptor typeParameterDescriptor) { - for (JetType bound : typeParameterDescriptor.getUpperBounds()) { + public static boolean hasNullableLowerBound(@NotNull TypeParameterDescriptor typeParameterDescriptor) { + for (JetType bound : typeParameterDescriptor.getLowerBounds()) { if (bound.isNullable()) { return true; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java index db786b2b28d..e693c3dddf1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java @@ -209,7 +209,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { boolean result = delegate.noCorrespondingSupertype(subtype, supertype); if (!result) { - println("-- " + subtype + " has supertype corresponding to " + supertype); + println("-- " + subtype + " has no supertype corresponding to " + supertype); } return result; } @@ -273,9 +273,12 @@ public class ConstraintSystemImpl implements ConstraintSystem { DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof TypeParameterDescriptor) { TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor; - UnknownType unknownType = unknownTypes.get(typeParameterDescriptor); - if (unknownType != null) { - return unknownType; + // Checking that this is not a T?, but exactly T + if (typeParameterDescriptor.getDefaultType().isNullable() == type.isNullable()) { + UnknownType unknownType = unknownTypes.get(typeParameterDescriptor); + if (unknownType != null) { + return unknownType; + } } } diff --git a/compiler/testData/checkerWithErrorTypes/full/Variance.jet b/compiler/testData/checkerWithErrorTypes/full/Variance.jet index 9b6531ffd02..0607a6f0a13 100644 --- a/compiler/testData/checkerWithErrorTypes/full/Variance.jet +++ b/compiler/testData/checkerWithErrorTypes/full/Variance.jet @@ -18,8 +18,8 @@ fun foo(c: Consumer, p: Producer, u: Usual) { } //Arrays copy example -class Array(val length : Int) { - fun get(index : Int) : T { return null } +class Array(val length : Int, val t : T) { + fun get(index : Int) : T { return t } fun set(index : Int, value : T) { /* ... */ } } diff --git a/compiler/testData/checkerWithErrorTypes/full/regression/kt313.jet b/compiler/testData/checkerWithErrorTypes/full/regression/kt313.jet new file mode 100644 index 00000000000..d22f0dc4f2e --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/regression/kt313.jet @@ -0,0 +1,11 @@ +// KT-313 Bug in substitutions in a function returning its type parameter T + +fun Iterable.join(separator : String?) : String { + return separator.npe() +} + +fun T?.npe() : T { + if (this == null) + throw NullPointerException() + return this; +} diff --git a/compiler/testData/codegen/regressions/kt326.jet b/compiler/testData/codegen/regressions/kt326.jet index 8afc31e7eab..3d9b4ad8e54 100644 --- a/compiler/testData/codegen/regressions/kt326.jet +++ b/compiler/testData/codegen/regressions/kt326.jet @@ -1,7 +1,7 @@ namespace test class List(len: Int) { - val a : Array = Array(len) + val a : Array = Array(len) fun reverse() { var i = 0 @@ -29,7 +29,7 @@ fun box() : String { val c = List>(1) c.a[0] = Array(4,{-1}) - println(c.a[0].size) + println(c.a[0]?.size) val e = List(5) e.a[0] = 0 diff --git a/compiler/testData/codegen/traits/stdlib.jet b/compiler/testData/codegen/traits/stdlib.jet index aa9fe5d5072..af0db549b40 100644 --- a/compiler/testData/codegen/traits/stdlib.jet +++ b/compiler/testData/codegen/traits/stdlib.jet @@ -36,8 +36,8 @@ trait WriteOnlyArray : ISized { } } -class MutableArray(length: Int) : ReadOnlyArray, WriteOnlyArray { - private val array = Array(length) +class MutableArray(length: Int, init : fun(Int) : T) : ReadOnlyArray, WriteOnlyArray { + private val array = Array(length, init) override fun get(index : Int) : T = array[index] override fun set(index : Int, value : T) : Unit { array[index] = value } @@ -47,7 +47,7 @@ class MutableArray(length: Int) : ReadOnlyArray, WriteOnlyArray { } fun box() : String { - var a = MutableArray (4) + var a = MutableArray (4, {0}) a [0] = 10 a.set(1, 2, 13) a [3] = 40 diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index de66903a8e9..7a1b926962c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -38,7 +38,7 @@ public class ArrayGenTest extends CodegenTestCase { } public void testCreateMultiGenerics () throws Exception { - loadText("class L() { val a = Array(5) } fun foo() = L.a"); + loadText("class L() { val a = Array(5) } fun foo() = L.a"); System.out.println(generateToText()); Method foo = generateFunction(); Object invoke = foo.invoke(null); diff --git a/docs/exPuzzlers/kotlin/std.kt b/docs/exPuzzlers/kotlin/std.kt index ba01f1845f8..797a7540927 100644 --- a/docs/exPuzzlers/kotlin/std.kt +++ b/docs/exPuzzlers/kotlin/std.kt @@ -56,6 +56,6 @@ namespace io { namespace string { fun String.replaceAll(pattern : String, replacement : String) : String { - return java.util.regex.Pattern.compile(pattern).matcher(this).replaceAll(replacement).npe() + return (this as java.lang.String).replace(pattern as CharSequence, replacement as CharSequence).npe() } } \ No newline at end of file diff --git a/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt b/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt index 0462cfba23e..e9012cc3994 100644 --- a/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt +++ b/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt @@ -15,5 +15,4 @@ fun main(args : Array) { // Note: \u000A is Unicode representation of linefeed (LF) val c : Char = 0x000A .chr; println(c); - println("a\u \u0 \u00 \u000 \u0000 \u0AaA \u0AAz.length( ) + \u0022b") } diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index f09506cd271..0a16cb56f58 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -104,8 +104,8 @@ public class JetCompiler implements TranslatingCompiler { if (!errors) { generationState.compileCorrectNamespaces(bindingContext, namespaces, new CompilationErrorHandler() { @Override - public void reportError(String message, String fileUrl) { - compileContext.addMessage(CompilerMessageCategory.WARNING, message, fileUrl, 0, 0); + public void reportException(Throwable exception, String fileUrl) { + compileContext.addMessage(CompilerMessageCategory.WARNING, exception.getClass().getCanonicalName() + ": " + exception.getMessage(), fileUrl, 0, 0); } }); /////////// diff --git a/idea/testData/checker/Variance.jet b/idea/testData/checker/Variance.jet index 0f27cbc73ff..0d173e86dc8 100644 --- a/idea/testData/checker/Variance.jet +++ b/idea/testData/checker/Variance.jet @@ -18,8 +18,8 @@ fun foo(c: Consumer, p: Producer, u: Usual) { } //Arrays copy example -class Array(val length : Int) { - fun get(index : Int) : T { return null } +class Array(val length : Int, val t : T) { + fun get(index : Int) : T { return t } fun set(index : Int, value : T) { /* ... */ } }