Merge: Fix type adaptation when there is loops
authorJean Privat <jean@pryen.org>
Tue, 14 Apr 2015 09:33:40 +0000 (16:33 +0700)
committerJean Privat <jean@pryen.org>
Tue, 14 Apr 2015 09:33:40 +0000 (16:33 +0700)
Basically one of the oldest bug of Nit.

The point of adaptive typing is that the static types of variables follows the static types of the assigned values, type tests and comparison to null.
This is a great feature of the language but was buggy because loops where not taken in account (old TODO), until the present PR.

The basic idea is just to track if a type adaptation occurs, if yes replay the whole typing phase.
The immediate drawback is that now typing require 2 passes most of the time, and sometime more.

This PR was a roller-coaster of emotions to develop since a lot a surprise issues were discovered.

* bug in flow that give me hours of despair.
* duplication of error messages; because multiple passes.
* premature warning/error messages; because some error conditions on types are detected at the first pass but a second pass find it is fine in fact... but too late the error message was printed.
* almost work at the first time (modulo the previous issues)
* only two bugs found in the whole code, quite impressive, and one of them is not a real bug but an autocast issue.

The issue about error duplication and premature errors is only workadounded (or fixme) in most places.
But proper solutions will be required in future PR.

close #647 and close #86, then reopen it again, then reclose it.

Pull-Request: #1257
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

13 files changed:
lib/pthreads/README.md
lib/pthreads/examples/threaded_example.nit
misc/README.md
misc/vim/plugin/nit.vim
src/compiler/abstract_compiler.nit
src/frontend/parallelization_phase.nit
src/interpreter/naive_interpreter.nit
src/platform/ios.nit
src/platform/xcode_templates.nit
src/semantize/typing.nit
tests/base_new_intern.nit [new file with mode: 0644]
tests/sav/base_new_intern.res [new file with mode: 0644]
tests/sav/threaded_example.res

index e612dbe..4a117b4 100644 (file)
@@ -11,6 +11,9 @@ This group also provides two optional modules with thread-safe collections:
 
 Theses services are implemented using the POSIX threads.
 
+You can also use the `is threaded` annotation on methods, which makes them run on their own thread.
+Methods with return value or self calls are not supported.
+
 ## Known limitations:
 
 * Most services from the Nit library are not thread-safe. You must manage
index 175c753..9a0af4b 100644 (file)
@@ -19,12 +19,20 @@ module threaded_example
 
 import pthreads
 
-# the "is threaded" annotation makes this fun run on an other thread
+# the `is threaded` annotation makes this method run on an other thread
 fun foo is threaded do
        sys.nanosleep(1,0)
        print "threaded"
 end
 
+# Parameterized `threaded` method, same as foo, but with parameters
+fun bar(i : Int, s : String) is threaded do
+       sys.nanosleep(2, 0)
+       print i
+       print s
+end
+
 foo
+bar(10, "parameterized and threaded")
 print "main"
-sys.nanosleep(2,0)
+sys.nanosleep(5,0)
index 1661f43..9b4bf06 100644 (file)
@@ -98,13 +98,15 @@ the environment variable `NIT_VIM_DIR`.
 
 ## Documentation in preview window
 
-You can display the documentation for the entity under the cursor with `:call Nitdoc()`.
-It will use the same metadata files as the omnifunc and the preview window.
+The command `:Nitdoc` searches the documentation for the word under the cursor.
+The results are displayed in the preview window in order of relevance.
+You can search for any word by passing it as an argument, as in `:Nitdoc modulo`.
+The Nitdoc command uses the same metadata files as the omnifunc.
 You may want to map the function to a shortcut by adding the following code to `~/.vimrc`.
 
 ~~~
 " Map displaying Nitdoc to Ctrl-D
-map <C-d> :call Nitdoc()<enter>
+map <C-d> :Nitdoc<enter>
 ~~~
 
 ## Search declarations and usages of the word under the cursor
index f19224a..86d5e45 100644 (file)
@@ -84,7 +84,7 @@ endfunction
 " Get path to the best metadata file named `name`
 "
 " Returns an empty string if not found.
-fun NitMetadataFile(name)
+fun s:NitMetadataFile(name)
        " Where are the generated metadata files?
        if empty($NIT_VIM_DIR)
                let metadata_dir = $HOME . '/.vim/nit'
@@ -122,7 +122,7 @@ fun NitOmnifuncAddFromFile(base, matches, path)
        let synopsis_matches = []
        let doc_matches = []
 
-       let path = NitMetadataFile(a:path)
+       let path = s:NitMetadataFile(a:path)
        if empty(path)
                return
        endif
@@ -134,19 +134,19 @@ fun NitOmnifuncAddFromFile(base, matches, path)
                " Add?
                if name == a:base
                        " Exact match
-                       call NitOmnifuncAddAMatch(a:matches, words, name)
+                       call s:NitOmnifuncAddAMatch(a:matches, words, name)
                elseif name =~? '^'.a:base
                        " Common-prefix match
-                       call NitOmnifuncAddAMatch(prefix_matches, words, name)
+                       call s:NitOmnifuncAddAMatch(prefix_matches, words, name)
                elseif name =~? a:base
                        " Substring match
-                       call NitOmnifuncAddAMatch(substring_matches, words, name)
+                       call s:NitOmnifuncAddAMatch(substring_matches, words, name)
                elseif get(words, 2, '') =~? a:base
                        " Match in the synopsis
-                       call NitOmnifuncAddAMatch(synopsis_matches, words, name)
+                       call s:NitOmnifuncAddAMatch(synopsis_matches, words, name)
                elseif get(words, 3, '') =~? a:base
                        " Match in the longer doc
-                       call NitOmnifuncAddAMatch(synopsis_matches, words, name)
+                       call s:NitOmnifuncAddAMatch(doc_matches, words, name)
                endif
        endfor
 
@@ -158,7 +158,7 @@ fun NitOmnifuncAddFromFile(base, matches, path)
 endfun
 
 " Internal function to search parse the information from a metadata line
-fun NitOmnifuncAddAMatch(matches, words, name)
+fun s:NitOmnifuncAddAMatch(matches, words, name)
        let pretty = get(a:words, 1, '')
        let synopsis = get(a:words, 2, '')
        let desc = get(a:words, 3, '')
@@ -266,16 +266,24 @@ fun NitOmnifunc(findstart, base)
 endfun
 
 " Show doc for the entity under the cursor in the preview window
-fun Nitdoc()
-       " Word under cursor
-       let word = expand("<cword>")
+fun Nitdoc(...)
+       if a:0 == 0 || empty(a:1)
+               " Word under cursor
+               let word = expand("<cword>")
+       else
+               let word = join(a:000, ' ')
+       endif
 
        " All possible docs (there may be more than one entity with the same name)
        let docs = []
+       let prefix_matches = []
+       let substring_matches = []
+       let synopsis_matches = []
+       let doc_matches = []
 
        " Search in all metadata files
        for file in ['modules', 'classes', 'properties']
-               let path = NitMetadataFile(file.'.txt')
+               let path = s:NitMetadataFile(file.'.txt')
                if empty(path)
                        continue
                endif
@@ -283,17 +291,34 @@ fun Nitdoc()
                for line in readfile(path)
                        let words = split(line, '#====#', 1)
                        let name = get(words, 0, '')
-                       if name =~ '^' . word . '\>'
-                               " It fits our word, get long doc
-                               let desc = get(words,3,'')
-                               let desc = join(split(desc, '#nnnn#', 1), "\n")
-                               call add(docs, desc)
+                       if name =~ '^'.word.'\>'
+                               " Exact match
+                               call s:NitdocAdd(docs, words)
+                       elseif name =~? '^'.word
+                               " Common-prefix match
+                               call s:NitdocAdd(prefix_matches, words)
+                       elseif name =~? word
+                               " Substring match
+                               call s:NitdocAdd(substring_matches, words)
+                       elseif get(words, 2, '') =~? word
+                               " Match in the synopsis
+                               call s:NitdocAdd(synopsis_matches, words)
+                       elseif get(words, 3, '') =~? word
+                               " Match in the longer doc
+                               call s:NitdocAdd(doc_matches, words)
                        endif
                endfor
        endfor
 
+       " Unite all results in prefered order
+       call extend(docs, sort(prefix_matches))
+       call extend(docs, sort(substring_matches))
+       call extend(docs, sort(synopsis_matches))
+       call extend(docs, sort(doc_matches))
+
        " Found no doc, give up
        if empty(docs) || !(join(docs, '') =~ '\w')
+               echo 'Nitdoc found nothing for "' . word . '"'
                return
        endif
 
@@ -310,6 +335,8 @@ fun Nitdoc()
                        silent put = ''
                endif
        endfor
+       execute 0
+       delete " the first empty line
 
        " Set options
        setlocal buftype=nofile
@@ -322,6 +349,13 @@ fun Nitdoc()
        redraw!
 endfun
 
+" Internal function to search parse the information from a metadata line
+fun s:NitdocAdd(matches, words)
+       let desc = get(a:words, 3, '')
+       let desc = join(split(desc, '#nnnn#', 1), "\n")
+       call add(a:matches, desc)
+endfun
+
 " Call `git grep` on the word under the cursor
 "
 " Shows declarations first, then all matches, in the preview window.
@@ -351,4 +385,7 @@ endfun
 " Activate the omnifunc on Nit files
 autocmd FileType nit set omnifunc=NitOmnifunc
 
+" Define the user command Nitdoc for ease of use
+command -nargs=* Nitdoc call Nitdoc("<args>")
+
 let s:script_dir = fnamemodify(resolve(expand('<sfile>:p')), ':h')
index f579a32..8c9e4b7 100644 (file)
@@ -3039,7 +3039,9 @@ redef class ANewExpr
 
                var recv = v.init_instance_or_extern(mtype)
 
-               var callsite = self.callsite.as(not null)
+               var callsite = self.callsite
+               if callsite == null then return recv
+
                var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs)
                var res2 = v.compile_callsite(callsite, args)
                if res2 != null then
index 7da80ff..8cd7965 100644 (file)
@@ -39,10 +39,9 @@ private class ParallelizationPhase
                        toolcontext.error(nmethdef.location, "Syntax error: only a method can be threaded.")
                        return
                end
-               if nmethdef.n_signature.n_params.length != 0 then
-                       toolcontext.error(nmethdef.location, "Syntax error: parametrized method not supported yet.")
-                       return
-               end
+
+               #TODO: check for self calls
+
                if nmethdef.n_signature.n_type != null then
                        toolcontext.error(nmethdef.location, "Syntax error: method with a return value not supported yet.")
                        return
@@ -66,11 +65,24 @@ private class ParallelizationPhase
                        classname += nmethdef.n_methid.as(AIdMethid).n_id.text
                end
 
-               # Create a string corresponding to the threaded class
-               var s ="""
+
+               var params = new Array[String]
+               # case if the method has parameters
+               if nmethdef.n_signature.n_params.not_empty then
+                       for param in nmethdef.n_signature.n_params do
+                               params.add("""
+var {{{param.n_id.text}}} : {{{param.n_type.n_id.text}}}
+
+""")
+                       end
+               end
+
+               # String corresponding to the generated class
+               var s="""
 class {{{classname}}}
        super Thread
 
+       {{{params.join("\n")}}}
        redef fun main do
        end
 end
@@ -95,11 +107,24 @@ end
                assert nullreturn isa AExpr
                mainfun.n_block.as(ABlockExpr).n_expr.add(nullreturn)
 
+
                # Create new body for the annotated fun
-               var s_newbody ="""
+               var s_newbody : String
+               if nmethdef.n_signature.n_params.not_empty then
+                       var init_params = new Array[String]
+                       for param in nmethdef.n_signature.n_params do
+                               init_params.add(param.n_id.text)
+                       end
+                       s_newbody ="""
+var thread = new {{{classname}}}({{{init_params.join(",")}}})
+thread.start
+"""
+               else
+                       s_newbody = """
 var thread = new {{{classname}}}
 thread.start
 """
+               end
 
                var newbody = toolcontext.parse_something(s_newbody)
                nmethdef.n_block = newbody.as(ABlockExpr)
index 4cab2e5..3168c76 100644 (file)
@@ -1807,6 +1807,9 @@ redef class ANewExpr
                var mtype = v.unanchor_type(self.recvtype.as(not null))
                var recv: Instance = new MutableInstance(mtype)
                v.init_instance(recv)
+               var callsite = self.callsite
+               if callsite == null then return recv
+
                var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs)
                if args == null then return null
                var res2 = v.callsite(callsite, args)
index f81b5d2..27c05c6 100644 (file)
@@ -36,6 +36,12 @@ private class IOSPlatform
        redef fun toolchain(toolcontext, compiler) do return new IOSToolchain(toolcontext, compiler)
 end
 
+private class IosProject
+       super AppProject
+
+       redef fun namespace do return super.to_camel_case
+end
+
 private class IOSToolchain
        super MakefileToolchain
 
@@ -43,7 +49,7 @@ private class IOSToolchain
        var ios_project_root: String is noinit
 
        # `app.nit` project for the current compilation target
-       var app_project = new AppProject(compiler.modelbuilder, compiler.mainmodule) is lazy
+       var app_project = new IosProject(compiler.modelbuilder, compiler.mainmodule) is lazy
 
        redef fun default_outname do return "{super}.app"
 
index e4ebbdf..aa6cc5b 100644 (file)
@@ -221,25 +221,6 @@ class PbxprojectTemplate
                        path = Base.lproj/LaunchScreen.xib;
                        sourceTree = "<group>";
                        };
-               AF9F83E91A5F0D21004B62C0 /* {{{name}}}Tests.xctest */ = {
-                       isa = PBXFileReference;
-                       explicitFileType = wrapper.cfbundle;
-                       includeInIndex = 0;
-                       path = {{{name}}}Tests.xctest;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-                       };
-               AF9F83EE1A5F0D21004B62C0 /* Info.plist */ = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist.xml;
-                       path = Info.plist;
-                       sourceTree = "<group>";
-                       };
-               AF9F83EF1A5F0D21004B62C0 /* {{{name}}}Tests.m */ = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = {{{name}}}Tests.m;
-                       sourceTree = "<group>";
-                       };
 
        /* Changing generated files */
 """
@@ -257,13 +238,6 @@ class PbxprojectTemplate
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               AF9F83E61A5F0D21004B62C0 /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
@@ -271,7 +245,6 @@ class PbxprojectTemplate
                        isa = PBXGroup;
                        children = (
                                AF9F83CE1A5F0D21004B62C0 /* {{{name}}} */,
-                               AF9F83EC1A5F0D21004B62C0 /* {{{name}}}Tests */,
                                AF9F83CD1A5F0D21004B62C0 /* Products */,
                        );
                        sourceTree = "<group>";
@@ -280,7 +253,6 @@ class PbxprojectTemplate
                        isa = PBXGroup;
                        children = (
                                AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */,
-                               AF9F83E91A5F0D21004B62C0 /* {{{name}}}Tests.xctest */,
                        );
                        name = Products;
                        sourceTree = "<group>";
@@ -308,23 +280,6 @@ class PbxprojectTemplate
                        name = "Supporting Files";
                        sourceTree = "<group>";
                };
-               AF9F83EC1A5F0D21004B62C0 /* {{{name}}}Tests */ = {
-                       isa = PBXGroup;
-                       children = (
-                               AF9F83EF1A5F0D21004B62C0 /* {{{name}}}Tests.m */,
-                               AF9F83ED1A5F0D21004B62C0 /* Supporting Files */,
-                       );
-                       path = {{{name}}}Tests;
-                       sourceTree = "<group>";
-               };
-               AF9F83ED1A5F0D21004B62C0 /* Supporting Files */ = {
-                       isa = PBXGroup;
-                       children = (
-                               AF9F83EE1A5F0D21004B62C0 /* Info.plist */,
-                       );
-                       name = "Supporting Files";
-                       sourceTree = "<group>";
-               };
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -345,24 +300,6 @@ class PbxprojectTemplate
                        productReference = AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */;
                        productType = "com.apple.product-type.application";
                };
-               AF9F83E81A5F0D21004B62C0 /* {{{name}}}Tests */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = AF9F83F61A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}Tests" */;
-                       buildPhases = (
-                               AF9F83E51A5F0D21004B62C0 /* Sources */,
-                               AF9F83E61A5F0D21004B62C0 /* Frameworks */,
-                               AF9F83E71A5F0D21004B62C0 /* Resources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                               AF9F83EB1A5F0D21004B62C0 /* PBXTargetDependency */,
-                       );
-                       name = {{{name}}}Tests;
-                       productName = {{{name}}}Tests;
-                       productReference = AF9F83E91A5F0D21004B62C0 /* {{{name}}}Tests.xctest */;
-                       productType = "com.apple.product-type.bundle.unit-test";
-               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
@@ -374,10 +311,6 @@ class PbxprojectTemplate
                                        AF9F83CB1A5F0D21004B62C0 = {
                                                CreatedOnToolsVersion = 6.1.1;
                                        };
-                                       AF9F83E81A5F0D21004B62C0 = {
-                                               CreatedOnToolsVersion = 6.1.1;
-                                               TestTargetID = AF9F83CB1A5F0D21004B62C0;
-                                       };
                                };
                        };
                        buildConfigurationList = AF9F83C71A5F0D21004B62C0 /* Build configuration list for PBXProject "{{{name}}}" */;
@@ -394,7 +327,6 @@ class PbxprojectTemplate
                        projectRoot = "";
                        targets = (
                                AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */,
-                               AF9F83E81A5F0D21004B62C0 /* {{{name}}}Tests */,
                        );
                };
 /* End PBXProject section */
@@ -414,13 +346,6 @@ class PbxprojectTemplate
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               AF9F83E71A5F0D21004B62C0 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
@@ -437,24 +362,8 @@ class PbxprojectTemplate
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               AF9F83E51A5F0D21004B62C0 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               AF9F83F01A5F0D21004B62C0 /* {{{name}}}Tests.m in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
 /* End PBXSourcesBuildPhase section */
 
-/* Begin PBXTargetDependency section */
-               AF9F83EB1A5F0D21004B62C0 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */;
-                       targetProxy = AF9F83EA1A5F0D21004B62C0 /* PBXContainerItemProxy */;
-               };
-/* End PBXTargetDependency section */
-
 /* Begin PBXVariantGroup section */
                AF9F83DD1A5F0D21004B62C0 /* Main.storyboard */ = {
                        isa = PBXVariantGroup;
@@ -553,40 +462,6 @@ class PbxprojectTemplate
                        };
                        name = Release;
                };
-               AF9F83F71A5F0D21004B62C0 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               BUNDLE_LOADER = "$(TEST_HOST)";
-                               FRAMEWORK_SEARCH_PATHS = (
-                                       "$(SDKROOT)/Developer/Library/Frameworks",
-                                       "$(inherited)",
-                               );
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "DEBUG=1",
-                                       "$(inherited)",
-                               );
-                               INFOPLIST_FILE = {{{name}}}Tests/Info.plist;
-                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
-                               PRODUCT_NAME = "$(TARGET_NAME)";
-                               TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{{name}}}.app/{{{name}}}";
-                       };
-                       name = Debug;
-               };
-               AF9F83F81A5F0D21004B62C0 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               BUNDLE_LOADER = "$(TEST_HOST)";
-                               FRAMEWORK_SEARCH_PATHS = (
-                                       "$(SDKROOT)/Developer/Library/Frameworks",
-                                       "$(inherited)",
-                               );
-                               INFOPLIST_FILE = {{{name}}}Tests/Info.plist;
-                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
-                               PRODUCT_NAME = "$(TARGET_NAME)";
-                               TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{{name}}}.app/{{{name}}}";
-                       };
-                       name = Release;
-               };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -607,14 +482,6 @@ class PbxprojectTemplate
                        );
                        defaultConfigurationIsVisible = 0;
                };
-               AF9F83F61A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}Tests" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               AF9F83F71A5F0D21004B62C0 /* Debug */,
-                               AF9F83F81A5F0D21004B62C0 /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-               };
 /* End XCConfigurationList section */
        };
        rootObject = AF9F83C41A5F0D21004B62C0 /* Project object */;
index 6727d02..a46f632 100644 (file)
@@ -1875,6 +1875,7 @@ redef class ANewExpr
                end
 
                self.recvtype = recvtype
+               var kind = recvtype.mclass.kind
 
                var name: String
                var nid = self.n_id
@@ -1883,11 +1884,24 @@ redef class ANewExpr
                else
                        name = "new"
                end
+               if name == "intern" then
+                       if kind != concrete_kind then
+                               v.error(self, "Type Error: Cannot instantiate {kind} {recvtype}.")
+                               return
+                       end
+                       if n_args.n_exprs.not_empty then
+                               v.error(n_args, "Type Error: the intern constructor expects no arguments.")
+                               return
+                       end
+                       # Our job is done
+                       self.mtype = recvtype
+                       return
+               end
+
                var callsite = v.get_method(self, recvtype, name, false)
                if callsite == null then return
 
                if not callsite.mproperty.is_new then
-                       var kind = recvtype.mclass.kind
                        if kind != concrete_kind then
                                v.error(self, "Type Error: Cannot instantiate {kind} {recvtype}.")
                                return
diff --git a/tests/base_new_intern.nit b/tests/base_new_intern.nit
new file mode 100644 (file)
index 0000000..76819f0
--- /dev/null
@@ -0,0 +1,30 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class A
+       var i: Int
+       new do
+               var res = new A.intern
+               res.i = 1
+               return res
+       end
+       init do
+               0.output # not called
+       end
+end
+
+var a = new A
+a.i.output
diff --git a/tests/sav/base_new_intern.res b/tests/sav/base_new_intern.res
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
index 050d79d..e90aa48 100644 (file)
@@ -1,2 +1,4 @@
 main
 threaded
+10
+parameterized and threaded