diff --git a/docs/_config.yml b/docs/_config.yml index 33a85609..fac90591 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,5 +1,6 @@ -remote_theme: "mmistakes/minimal-mistakes@4.22.0" +remote_theme: "mmistakes/minimal-mistakes@4.24.0" minimal_mistakes_skin: "default" #"air", "aqua", "contrast", "dark", "dirt", "neon", "mint", "plum" "sunrise" +minimal_mistakes_skin2: "dark" url: name: Roblox title: Luau diff --git a/docs/_includes/masthead.html b/docs/_includes/masthead.html new file mode 100644 index 00000000..b78c80f9 --- /dev/null +++ b/docs/_includes/masthead.html @@ -0,0 +1,73 @@ +{% capture logo_path %}{{ site.logo }}{% endcapture %} + +
+
+
+ +
+
+
+ + + + + \ No newline at end of file diff --git a/docs/_includes/repl.html b/docs/_includes/repl.html index e769643b..df27a792 100644 --- a/docs/_includes/repl.html +++ b/docs/_includes/repl.html @@ -2,11 +2,11 @@

- +
- +
@@ -26,31 +26,81 @@ padding: 7px 7px; vertical-align: middle; } + .line-error { background: #e65f55; } - - - + + + + + + + + + - + \ No newline at end of file diff --git a/docs/_pages/grammar.md b/docs/_pages/grammar.md index 96d40230..f9d9612d 100644 --- a/docs/_pages/grammar.md +++ b/docs/_pages/grammar.md @@ -28,7 +28,7 @@ laststat = 'return' [explist] | 'break' | 'continue' funcname = NAME {'.' NAME} [':' NAME] funcbody = ['<' GenericTypeList '>'] '(' [parlist] ')' [':' ReturnType] block 'end' -parlist = bindinglist [',' '...'] | '...' +parlist = bindinglist [',' '...'] | '...' [':' (Type | GenericTypePack)] explist = {exp ','} exp namelist = NAME {',' NAME} @@ -83,6 +83,7 @@ GenericTypeListWithDefaults = GenericTypePackParameterWithDefault {',' GenericTypePackParameterWithDefault} TypeList = Type [',' TypeList] | '...' Type +BoundTypeList = [NAME ':'] Type [',' BoundTypeList] | '...' Type TypeParams = (Type | TypePack | VariadicTypePack | GenericTypePack) [',' TypeParams] TypePack = '(' [TypeList] ')' GenericTypePack = NAME '...' @@ -92,6 +93,6 @@ TableIndexer = '[' Type ']' ':' Type TableProp = NAME ':' Type TablePropOrIndexer = TableProp | TableIndexer PropList = TablePropOrIndexer {fieldsep TablePropOrIndexer} [fieldsep] -TableType = '{' [PropList] '}' -FunctionType = ['<' GenericTypeList '>'] '(' [TypeList] ')' '->' ReturnType +TableType = '{' Type '}' | '{' [PropList] '}' +FunctionType = ['<' GenericTypeList '>'] '(' [BoundTypeList] ')' '->' ReturnType ``` diff --git a/docs/_posts/2023-07-28-luau-recap-july-2023.md b/docs/_posts/2023-07-28-luau-recap-july-2023.md new file mode 100644 index 00000000..cf09bf79 --- /dev/null +++ b/docs/_posts/2023-07-28-luau-recap-july-2023.md @@ -0,0 +1,93 @@ +--- +layout: single +title: "Luau Recap: July 2023" +--- + +Our team is still spending a lot of time working on upcoming replacement for our type inference engine as well as working on native code generation to improve runtime performance. + +However, we also worked on unrelated improvements during this time that are summarized here. + +[Cross-posted to the [Roblox Developer Forum](https://devforum.roblox.com/t/luau-recap-july-2023/).] + +## Analysis improvements + +Indexing table intersections using `x["prop"]` syntax has been fixed and no longer reports a false positive error: + +```lua +type T = { foo: string } & { bar: number } +local x: T = { foo = "1", bar = 2 } + +local y = x["bar"] -- This is no longer an error +``` + +Generic `T...` type is now convertible to `...any` variadic parameter. + +This solves issues people had with variadic functions and variadic argument: + +```lua +local function foo(...: any) + print(...) +end + +local function bar(...: T...) + foo(...) -- This is no longer an error +end +``` + +We have also improved our general typechecking performance by ~17% and by additional ~30% in modules with complex types. + +Other fixes include: + +* Fixed issue with type `T?` not being convertible to `T | T` or `T?` which could've generated confusing errors +* Return type of `os.date` is now inferred as `DateTypeResult` when argument is "*t" or "!*t" + +## Runtime improvements + +Out-of-memory exception handling has been improved. +`xpcall` handlers will now actually be called with a "not enough memory" string and whatever string/object they return will be correctly propagated. + +Other runtime improvements we've made: + +* Performance of `table.sort` was improved further. It now guarantees N*log(N) time complexity in the worst case +* Performance of `table.concat` was improved by ~5-7% +* Performance of `math.noise` was improved by ~30% +* Inlining of functions is now possible even when they used to compute their own arguments +* Improved logic for determining whether inlining a function or unrolling a loop is profitable + +## Autocomplete improvements + +An issue with exported types not being suggested is now fixed. + +## Debugger improvements + +We have fixed the search for the closest executable breakpoint line. + +Previously, breakpoints might have been skipped in `else` blocks at the end of a function. +This simplified example shows the issue: + +```lua +local function foo(isIt) + if isIt then + print("yes") + else + -- When 'true' block exits the function, breakpoint couldn't be placed here + print("no") + end +end +``` + +## Thanks + +A very special thanks to all of our open source contributors: + +* [Petri Häkkinen](https://github.com/petrihakkinen) +* [JohnnyMorganz](https://github.com/JohnnyMorganz) +* [Gael](https://github.com/TheGreatSageEqualToHeaven) +* [Jan](https://github.com/Jan200101) +* [Alex Orlenko](https://github.com/khvzak) +* [mundusnine](https://github.com/mundusnine) +* [Ben Mactavsin](https://github.com/BenMactavsin) +* [RadiatedExodus](https://github.com/RealEthanPlayzDev) +* [Lodinu Kalugalage](https://github.com/imlodinu) +* [MagelessMayhem](https://github.com/MagelessMayhem) +* [Someon1e](https://github.com/Someon1e) diff --git a/docs/assets/css/theme2.scss b/docs/assets/css/theme2.scss new file mode 100644 index 00000000..21710d40 --- /dev/null +++ b/docs/assets/css/theme2.scss @@ -0,0 +1,8 @@ +--- + +--- + +@charset "utf-8"; + +@import "minimal-mistakes/skins/{{ site.minimal_mistakes_skin2 | default: 'default' }}"; // skin +@import "minimal-mistakes"; // main partials \ No newline at end of file diff --git a/docs/assets/js/luau_mode.js b/docs/assets/js/luau_mode.js index 1e53143f..a5dcdc97 100644 --- a/docs/assets/js/luau_mode.js +++ b/docs/assets/js/luau_mode.js @@ -27,27 +27,24 @@ // long list of standard functions from lua manual var builtins = wordRE([ "_G","_VERSION","assert","error","getfenv","getmetatable","ipairs","load", "loadstring","next","pairs","pcall", - "print","rawequal","rawget","rawset","require","select","setfenv","setmetatable","tonumber","tostring","type", + "print","rawequal","rawget","rawset","require","select","setfenv","setmetatable","tonumber","tostring","type","typeof", "unpack","xpcall", "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield", - "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable", - "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable", - "debug.setupvalue","debug.traceback", + "debug.info","debug.traceback", "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg", "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max", "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh", "math.sqrt","math.tan","math.tanh", - "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale", - "os.time","os.tmpname", + "os.clock","os.date","os.difftime","os.time", - "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub", + "string.byte","string.char","string.find","string.format","string.gmatch","string.gsub", "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper", - "table.concat","table.insert","table.maxn","table.remove","table.sort" + "table.concat","table.clone","table.create","table.freeze","table.isfrozen","table.insert","table.maxn","table.move","table.remove","table.sort","table.unpack" ]); var keywords = wordRE(["and","break","elseif","false","nil","not","or","return", "true","function", "end", "if", "then", "else", "do", @@ -72,7 +69,7 @@ stream.skipToEnd(); return "comment"; } - if (ch == "\"" || ch == "'") + if (ch == "\"" || ch == "'" || ch == "`") return (state.cur = string(ch))(stream, state); if (ch == "[" && /[\[=]/.test(stream.peek())) return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);