mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
# What's Changed? Hi there, folks! It's been another busy week in the type mines, trying to bring you all the very best type inference system we can. We've got a bunch of updates to large pain points across the new type solver, and our next big update (currently under a debug flag) improving type generalization is finally nearing completion (and should hopefully eliminate quite a lot of "type solver failed to complete" errors). We've also continued polishing both the CST Parser and the `Luau.Require` library we introduced a few releases ago based on user feedback and bug reports, and we're really happy with how they're turning out. # Parser - Fixes a bug in the CST tooling where the spacing on return type annotations for functions was not being printed correctly. - Resolves some issues with the JSON encoding of `AstGenericType` and `AstGenericTypePack` # Runtime - Implements support for yielding requires in `Luau.Require` library. - Improves the error messages for require-by-string to include the chunk name that was problematic where possible and the overall require path that failed to be required. - Fixes a bug that prevented the use of `require` within C functions and `pcall`. - Adds an API to support selectively removing chunks from the require cache in `Luau.Require` - Adds an API to support clearing the entire require cache in `Luau.Require` # New Type Solver - Fixes a crash in the new non-strict mode when visiting function return types in incomplete ASTs (e.g. during editing). - Improves type simplification to support intersections of tables with extern types, resolving _one_ of the causes of frequent refinements unexpectedly leading to `never`. - Improves type inference to better understand diverging branches in functions, reducing false negatives where the type system fails to learn that a binding must now always be initialized. - Fixes a typo in the type definitions for user-defined function types where the `intersection` tag was misspelled. - Improves the overall accuracy of free type tracking during constraint solving, leading to better inference results overall. - Implements `types.optional` as a new library function for user-defined type functions to make it easier to union a type with `nil`. - Resolves a number of bugs caused by local type inference expanding the domain of upvalues # Internal Contributors Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com> Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Talha Pathan <tpathan@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> --------- Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com> Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com> Co-authored-by: Menarul Alam <malam@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: Vighnesh <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com>
128 lines
3.6 KiB
C++
128 lines
3.6 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
#include "Navigation.h"
|
|
|
|
#include "Luau/Require.h"
|
|
#include "lua.h"
|
|
#include "lualib.h"
|
|
|
|
#include <string>
|
|
|
|
static constexpr size_t initalFileBufferSize = 1024;
|
|
static constexpr size_t initalIdentifierBufferSize = 64;
|
|
|
|
namespace Luau::Require
|
|
{
|
|
|
|
static NavigationContext::NavigateResult convertNavigateResult(luarequire_NavigateResult result)
|
|
{
|
|
if (result == NAVIGATE_SUCCESS)
|
|
return NavigationContext::NavigateResult::Success;
|
|
if (result == NAVIGATE_AMBIGUOUS)
|
|
return NavigationContext::NavigateResult::Ambiguous;
|
|
|
|
return NavigationContext::NavigateResult::NotFound;
|
|
}
|
|
|
|
RuntimeNavigationContext::RuntimeNavigationContext(luarequire_Configuration* config, lua_State* L, void* ctx, std::string requirerChunkname)
|
|
: config(config)
|
|
, L(L)
|
|
, ctx(ctx)
|
|
, requirerChunkname(std::move(requirerChunkname))
|
|
{
|
|
}
|
|
|
|
std::string RuntimeNavigationContext::getRequirerIdentifier() const
|
|
{
|
|
return requirerChunkname;
|
|
}
|
|
|
|
NavigationContext::NavigateResult RuntimeNavigationContext::reset(const std::string& requirerChunkname)
|
|
{
|
|
return convertNavigateResult(config->reset(L, ctx, requirerChunkname.c_str()));
|
|
}
|
|
|
|
NavigationContext::NavigateResult RuntimeNavigationContext::jumpToAlias(const std::string& path)
|
|
{
|
|
return convertNavigateResult(config->jump_to_alias(L, ctx, path.c_str()));
|
|
}
|
|
|
|
NavigationContext::NavigateResult RuntimeNavigationContext::toParent()
|
|
{
|
|
return convertNavigateResult(config->to_parent(L, ctx));
|
|
}
|
|
|
|
NavigationContext::NavigateResult RuntimeNavigationContext::toChild(const std::string& component)
|
|
{
|
|
return convertNavigateResult(config->to_child(L, ctx, component.c_str()));
|
|
}
|
|
|
|
bool RuntimeNavigationContext::isModulePresent() const
|
|
{
|
|
return config->is_module_present(L, ctx);
|
|
}
|
|
|
|
std::optional<std::string> RuntimeNavigationContext::getContents() const
|
|
{
|
|
return getStringFromCWriter(config->get_contents, initalFileBufferSize);
|
|
}
|
|
|
|
std::optional<std::string> RuntimeNavigationContext::getChunkname() const
|
|
{
|
|
return getStringFromCWriter(config->get_chunkname, initalIdentifierBufferSize);
|
|
}
|
|
|
|
std::optional<std::string> RuntimeNavigationContext::getCacheKey() const
|
|
{
|
|
return getStringFromCWriter(config->get_cache_key, initalIdentifierBufferSize);
|
|
}
|
|
|
|
bool RuntimeNavigationContext::isConfigPresent() const
|
|
{
|
|
return config->is_config_present(L, ctx);
|
|
}
|
|
|
|
std::optional<std::string> RuntimeNavigationContext::getConfig() const
|
|
{
|
|
return getStringFromCWriter(config->get_config, initalFileBufferSize);
|
|
}
|
|
|
|
std::optional<std::string> RuntimeNavigationContext::getStringFromCWriter(
|
|
luarequire_WriteResult (*writer)(lua_State* L, void* ctx, char* buffer, size_t buffer_size, size_t* size_out),
|
|
size_t initalBufferSize
|
|
) const
|
|
{
|
|
std::string buffer;
|
|
buffer.resize(initalBufferSize);
|
|
|
|
size_t size;
|
|
luarequire_WriteResult result = writer(L, ctx, buffer.data(), buffer.size(), &size);
|
|
if (result == WRITE_BUFFER_TOO_SMALL)
|
|
{
|
|
buffer.resize(size);
|
|
result = writer(L, ctx, buffer.data(), buffer.size(), &size);
|
|
}
|
|
|
|
if (result == WRITE_SUCCESS)
|
|
{
|
|
buffer.resize(size);
|
|
return buffer;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
|
|
RuntimeErrorHandler::RuntimeErrorHandler(lua_State* L, std::string requiredPath)
|
|
: L(L)
|
|
, errorPrefix("error requiring module \"" + std::move(requiredPath) + "\": ")
|
|
{
|
|
}
|
|
|
|
void RuntimeErrorHandler::reportError(std::string message)
|
|
{
|
|
std::string fullError = errorPrefix + std::move(message);
|
|
luaL_errorL(L, "%s", fullError.c_str());
|
|
}
|
|
|
|
} // namespace Luau::Require
|