Skip to content

Commit 882c538

Browse files
Merge pull request #4492 from swiftwasm/main
[pull] swiftwasm from main
2 parents 4a35de5 + 0157631 commit 882c538

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+664
-218
lines changed

SwiftCompilerSources/Sources/Parse/Regex.swift

Lines changed: 33 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ import AST
1515
import Basic
1616

1717
#if canImport(_CompilerRegexParser)
18-
import _CompilerRegexParser
18+
@_spi(CompilerInterface) import _CompilerRegexParser
1919

2020
public func registerRegexParser() {
2121
Parser_registerRegexLiteralParsingFn(_RegexLiteralParsingFn)
2222
Parser_registerRegexLiteralLexingFn(_RegexLiteralLexingFn)
2323
}
2424

25-
/// Bridging between C++ lexer and _CompilerRegexParser.lexRegex()
25+
/// Bridging between C++ lexer and swiftCompilerLexRegexLiteral.
2626
///
2727
/// Attempt to lex a regex literal string.
2828
///
@@ -50,47 +50,29 @@ private func _RegexLiteralLexingFn(
5050
) -> /*CompletelyErroneous*/ CBool {
5151
let inputPtr = curPtrPtr.pointee
5252

53-
do {
54-
let (_, _, endPtr) = try lexRegex(start: inputPtr, end: bufferEndPtr)
55-
curPtrPtr.pointee = endPtr.assumingMemoryBound(to: CChar.self)
53+
guard let (resumePtr, error) = swiftCompilerLexRegexLiteral(
54+
start: inputPtr, bufferEnd: bufferEndPtr, mustBeRegex: mustBeRegex
55+
) else {
56+
// Not a regex literal, fallback without advancing the pointer.
5657
return false
57-
} catch let error as DelimiterLexError {
58-
if !mustBeRegex {
59-
// This token can be something else. Let the client fallback.
60-
return false;
61-
}
62-
if error.kind == .unknownDelimiter {
63-
// An unknown delimiter should be recovered from, as we may want to try
64-
// lex something else.
65-
return false
66-
}
58+
}
6759

60+
// Advance the current pointer.
61+
curPtrPtr.pointee = resumePtr.assumingMemoryBound(to: CChar.self)
62+
63+
if let error = error {
64+
// Emit diagnostic if diagnostics are enabled.
6865
if let diagEngine = DiagnosticEngine(bridged: bridgedDiagnosticEngine) {
69-
// Emit diagnostic.
7066
let startLoc = SourceLoc(
71-
locationInFile: UnsafeRawPointer(inputPtr).assumingMemoryBound(to: UInt8.self))!
72-
diagEngine.diagnose(startLoc, .regex_literal_parsing_error, "\(error)")
73-
}
74-
75-
// Advance the current pointer.
76-
curPtrPtr.pointee = error.resumePtr.assumingMemoryBound(to: CChar.self)
77-
78-
switch error.kind {
79-
case .unterminated, .multilineClosingNotOnNewline:
80-
// These can be recovered from.
81-
return false
82-
case .unprintableASCII, .invalidUTF8:
83-
// We don't currently have good recovery behavior for these.
84-
return true
85-
case .unknownDelimiter:
86-
fatalError("Already handled")
67+
locationInFile: error.location.assumingMemoryBound(to: UInt8.self))!
68+
diagEngine.diagnose(startLoc, .regex_literal_parsing_error, error.message)
8769
}
88-
} catch {
89-
fatalError("Should be a DelimiterLexError")
70+
return error.completelyErroneous
9071
}
72+
return false
9173
}
9274

93-
/// Bridging between C++ parser and _CompilerRegexParser.parseWithDelimiters()
75+
/// Bridging between C++ parser and swiftCompilerParseRegexLiteral.
9476
///
9577
/// - Parameters:
9678
/// - inputPtr: A null-terminated C string.
@@ -103,6 +85,8 @@ private func _RegexLiteralLexingFn(
10385
/// greater than or equal to `strlen(inputPtr)`.
10486
/// - bridgedDiagnosticBaseLoc: Source location of the start of the literal
10587
/// - bridgedDiagnosticEngine: Diagnostic engine to emit diagnostics.
88+
///
89+
/// - Returns: `true` if there was a parse error, `false` otherwise.
10690
public func _RegexLiteralParsingFn(
10791
_ inputPtr: UnsafePointer<CChar>,
10892
_ versionOut: UnsafeMutablePointer<CUnsignedInt>,
@@ -111,30 +95,27 @@ public func _RegexLiteralParsingFn(
11195
_ bridgedDiagnosticBaseLoc: BridgedSourceLoc,
11296
_ bridgedDiagnosticEngine: BridgedDiagnosticEngine
11397
) -> Bool {
114-
versionOut.pointee = currentRegexLiteralFormatVersion
115-
11698
let str = String(cString: inputPtr)
99+
let captureBuffer = UnsafeMutableRawBufferPointer(
100+
start: captureStructureOut, count: Int(captureStructureSize))
117101
do {
118-
let ast = try parseWithDelimiters(str)
119-
// Serialize the capture structure for later type inference.
120-
assert(captureStructureSize >= str.utf8.count)
121-
let buffer = UnsafeMutableRawBufferPointer(
122-
start: captureStructureOut, count: Int(captureStructureSize))
123-
ast.captureStructure.encode(to: buffer)
124-
return false;
125-
} catch {
102+
// FIXME: We need to plumb through the 'regexToEmit' result to the caller.
103+
// For now, it is the same as the input.
104+
let (_, version) = try swiftCompilerParseRegexLiteral(
105+
str, captureBufferOut: captureBuffer)
106+
versionOut.pointee = CUnsignedInt(version)
107+
return false
108+
} catch let error as CompilerParseError {
126109
var diagLoc = SourceLoc(bridged: bridgedDiagnosticBaseLoc)
127110
let diagEngine = DiagnosticEngine(bridged: bridgedDiagnosticEngine)
128-
if let _diagLoc = diagLoc,
129-
let locatedError = error as? LocatedErrorProtocol {
130-
let offset = str.utf8.distance(from: str.startIndex,
131-
to: locatedError.location.start)
111+
if let _diagLoc = diagLoc, let errorLoc = error.location {
112+
let offset = str.utf8.distance(from: str.startIndex, to: errorLoc)
132113
diagLoc = _diagLoc.advanced(by: offset)
133114
}
134-
diagEngine.diagnose(
135-
diagLoc, .regex_literal_parsing_error,
136-
"cannot parse regular expression: \(String(describing: error))")
115+
diagEngine.diagnose(diagLoc, .regex_literal_parsing_error, error.message)
137116
return true
117+
} catch {
118+
fatalError("Expected CompilerParseError")
138119
}
139120
}
140121

include/swift/AST/NameLookup.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,17 @@ class AccessFilteringDeclConsumer final : public VisibleDeclConsumer {
420420
class UsableFilteringDeclConsumer final : public VisibleDeclConsumer {
421421
const SourceManager &SM;
422422
const DeclContext *DC;
423+
const DeclContext *typeContext;
423424
SourceLoc Loc;
425+
llvm::DenseMap<DeclBaseName, std::pair<ValueDecl *, DeclVisibilityKind>>
426+
SeenNames;
424427
VisibleDeclConsumer &ChainedConsumer;
425428

426429
public:
427430
UsableFilteringDeclConsumer(const SourceManager &SM, const DeclContext *DC,
428431
SourceLoc loc, VisibleDeclConsumer &consumer)
429-
: SM(SM), DC(DC), Loc(loc), ChainedConsumer(consumer) {}
432+
: SM(SM), DC(DC), typeContext(DC->getInnermostTypeContext()), Loc(loc),
433+
ChainedConsumer(consumer) {}
430434

431435
void foundDecl(ValueDecl *D, DeclVisibilityKind reason,
432436
DynamicLookupInfo dynamicLookupInfo) override;

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ using ContextHashField = IdentifierIDField;
5151
/// A bit that indicates whether or not a module is a framework
5252
using IsFrameworkField = BCFixed<1>;
5353

54-
/// Arrays of various identifiers, distinguised for readability
54+
/// Arrays of various identifiers, distinguished for readability
5555
using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;
5656

5757
/// Identifiers used to refer to the above arrays
@@ -102,7 +102,7 @@ using IdentifierNodeLayout = BCRecordLayout<IDENTIFIER_NODE, BCBlob>;
102102
//
103103
// These arrays are also referenced by their sequence number,
104104
// starting from 1, similar to identifiers above. Value 0 indicates an
105-
// empty array. This record is used because individiual array fields must
105+
// empty array. This record is used because individual array fields must
106106
// appear as the last field of whatever record they belong to, and several of
107107
// the below record layouts contain multiple arrays.
108108
using IdentifierArrayLayout =

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4588,6 +4588,7 @@ class ConstraintSystem {
45884588
/// Generate constraints for the given solution target.
45894589
///
45904590
/// \returns true if an error occurred, false otherwise.
4591+
LLVM_NODISCARD
45914592
bool generateConstraints(SolutionApplicationTarget &target,
45924593
FreeTypeVariableBinding allowFreeTypeVariables);
45934594

@@ -4596,18 +4597,21 @@ class ConstraintSystem {
45964597
/// \param closure the closure expression
45974598
///
45984599
/// \returns \c true if constraint generation failed, \c false otherwise
4600+
LLVM_NODISCARD
45994601
bool generateConstraints(ClosureExpr *closure);
46004602

46014603
/// Generate constraints for the given (unchecked) expression.
46024604
///
46034605
/// \returns a possibly-sanitized expression, or null if an error occurred.
4606+
LLVM_NODISCARD
46044607
Expr *generateConstraints(Expr *E, DeclContext *dc,
46054608
bool isInputExpression = true);
46064609

46074610
/// Generate constraints for binding the given pattern to the
46084611
/// value of the given expression.
46094612
///
46104613
/// \returns a possibly-sanitized initializer, or null if an error occurred.
4614+
LLVM_NODISCARD
46114615
Type generateConstraints(Pattern *P, ConstraintLocatorBuilder locator,
46124616
bool bindPatternVarsOneWay,
46134617
PatternBindingDecl *patternBinding,
@@ -4617,6 +4621,7 @@ class ConstraintSystem {
46174621
///
46184622
/// \returns true if there was an error in constraint generation, false
46194623
/// if generation succeeded.
4624+
LLVM_NODISCARD
46204625
bool generateConstraints(StmtCondition condition, DeclContext *dc);
46214626

46224627
/// Generate constraints for a case statement.
@@ -4626,6 +4631,7 @@ class ConstraintSystem {
46264631
///
46274632
/// \returns true if there was an error in constraint generation, false
46284633
/// if generation succeeded.
4634+
LLVM_NODISCARD
46294635
bool generateConstraints(CaseStmt *caseStmt, DeclContext *dc,
46304636
Type subjectType, ConstraintLocator *locator);
46314637

@@ -4669,6 +4675,7 @@ class ConstraintSystem {
46694675
/// \param propertyType The type of the wrapped property.
46704676
///
46714677
/// \returns true if there is an error.
4678+
LLVM_NODISCARD
46724679
bool generateWrappedPropertyTypeConstraints(VarDecl *wrappedVar,
46734680
Type initializerType,
46744681
Type propertyType);

lib/AST/NameLookup.cpp

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,150 @@ void UsableFilteringDeclConsumer::foundDecl(ValueDecl *D,
172172

173173
switch (reason) {
174174
case DeclVisibilityKind::LocalVariable:
175-
// Skip if Loc is before the found decl, unless its a TypeDecl (whose use
176-
// before its declaration is still allowed)
177-
if (!isa<TypeDecl>(D) && !SM.isBeforeInBuffer(D->getLoc(), Loc))
175+
case DeclVisibilityKind::FunctionParameter:
176+
// Skip if Loc is before the found decl if the decl is a var/let decl.
177+
// Type and func decls can be referenced before its declaration, or from
178+
// within nested type decls.
179+
if (isa<VarDecl>(D)) {
180+
if (reason == DeclVisibilityKind::LocalVariable) {
181+
// Workaround for fast-completion. A loc in the current context might be
182+
// in a loc
183+
auto tmpLoc = Loc;
184+
if (D->getDeclContext() != DC) {
185+
if (auto *contextD = DC->getAsDecl())
186+
tmpLoc = contextD->getStartLoc();
187+
}
188+
if (!SM.isBeforeInBuffer(D->getLoc(), Loc))
189+
return;
190+
}
191+
192+
// A type context cannot close over values defined in outer type contexts.
193+
if (D->getDeclContext()->getInnermostTypeContext() != typeContext)
194+
return;
195+
}
196+
break;
197+
198+
case DeclVisibilityKind::MemberOfOutsideNominal:
199+
// A type context cannot close over members of outer type contexts, except
200+
// for type decls.
201+
if (!isa<TypeDecl>(D) && !D->isStatic())
178202
return;
179203
break;
180-
default:
204+
205+
case DeclVisibilityKind::MemberOfCurrentNominal:
206+
case DeclVisibilityKind::MemberOfSuper:
207+
case DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal:
208+
case DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal:
209+
case DeclVisibilityKind::DynamicLookup:
210+
// Members on 'Self' including inherited/derived ones are always usable.
211+
break;
212+
213+
case DeclVisibilityKind::GenericParameter:
214+
// Generic params are type decls and are always usable from nested context.
215+
break;
216+
217+
case DeclVisibilityKind::VisibleAtTopLevel:
181218
// The rest of the file is currently skipped, so no need to check
182-
// decl location for VisibleAtTopLevel. Other visibility kinds are always
183-
// usable
219+
// decl location for VisibleAtTopLevel.
184220
break;
185221
}
186222

223+
// Filter out shadowed decls. Do this for only usable values even though
224+
// unusable values actually can shadow outer values, because compilers might
225+
// be able to diagnose it with fix-it to add the qualification. E.g.
226+
// func foo(global: T) {}
227+
// struct Outer {
228+
// func foo(outer: T) {}
229+
// func test() {
230+
// struct Inner {
231+
// func test() {
232+
// <HERE>
233+
// }
234+
// }
235+
// }
236+
// }
237+
// In this case 'foo(global:)' is shadowed by 'foo(outer:)', but 'foo(outer:)'
238+
// is _not_ usable because it's outside the current type context, whereas
239+
// 'foo(global:)' is still usable with 'ModuleName.' qualification.
240+
// FIXME: (for code completion,) If a global value or a static type member is
241+
// shadowd, we should suggest it with prefix (e.g. 'ModuleName.value').
242+
auto inserted = SeenNames.insert({D->getBaseName(), {D, reason}});
243+
if (!inserted.second) {
244+
auto shadowingReason = inserted.first->second.second;
245+
auto *shadowingD = inserted.first->second.first;
246+
247+
// A type decl cannot have overloads, and shadows everything outside the
248+
// scope.
249+
if (isa<TypeDecl>(shadowingD))
250+
return;
251+
252+
switch (shadowingReason) {
253+
case DeclVisibilityKind::LocalVariable:
254+
case DeclVisibilityKind::FunctionParameter:
255+
// Local func and var/let with a conflicting name.
256+
// func foo() {
257+
// func value(arg: Int) {}
258+
// var value = ""
259+
// }
260+
// In this case, 'var value' wins, regardless of their source order.
261+
// So, for confilicting local values in the same decl context, even if the
262+
// 'var value' is reported after 'func value', don't shadow it, but we
263+
// shadow everything with the name after that.
264+
if (reason == DeclVisibilityKind::LocalVariable &&
265+
isa<VarDecl>(D) && !isa<VarDecl>(shadowingD) &&
266+
shadowingD->getDeclContext() == D->getDeclContext()) {
267+
// Replace the shadowing decl so we shadow subsequent conflicting decls.
268+
inserted.first->second = {D, reason};
269+
break;
270+
}
271+
272+
// Otherwise, a local value shadows everything outside the scope.
273+
return;
274+
275+
case DeclVisibilityKind::GenericParameter:
276+
// A Generic parameter is a type name. It shadows everything outside the
277+
// generic context.
278+
return;
279+
280+
case DeclVisibilityKind::MemberOfCurrentNominal:
281+
case DeclVisibilityKind::MemberOfSuper:
282+
case DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal:
283+
case DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal:
284+
case DeclVisibilityKind::DynamicLookup:
285+
switch (reason) {
286+
case DeclVisibilityKind::MemberOfCurrentNominal:
287+
case DeclVisibilityKind::MemberOfSuper:
288+
case DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal:
289+
case DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal:
290+
case DeclVisibilityKind::DynamicLookup:
291+
// Members on the current type context don't shadow members with the
292+
// same base name on the current type contxt. They are overloads.
293+
break;
294+
default:
295+
// Members of a type context shadows values/types outside.
296+
return;
297+
}
298+
break;
299+
300+
case DeclVisibilityKind::MemberOfOutsideNominal:
301+
// For static values, it's unclear _which_ type context (i.e. this type,
302+
// super classes, conforming protocols) this decl was found in. For now,
303+
// consider all the outer nominals are the same.
304+
305+
if (reason == DeclVisibilityKind::MemberOfOutsideNominal)
306+
break;
307+
308+
// Values outside the nominal are shadowed.
309+
return;
310+
311+
case DeclVisibilityKind::VisibleAtTopLevel:
312+
// Top level decls don't shadow anything.
313+
// Well, that's not true. Decls in the current module shadows decls in
314+
// the imported modules. But we don't care them here.
315+
break;
316+
}
317+
}
318+
187319
ChainedConsumer.foundDecl(D, reason, dynamicLookupInfo);
188320
}
189321

0 commit comments

Comments
 (0)