Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Rename LifetimeAnnotationAttribute to ScopedRefAttribute and simplify (#63009)" #63185

Merged
merged 1 commit into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType, bool inExpressionTr
}

ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, lambdaParameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureScopedRefAttributeExists(compilation, lambdaParameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(compilation, lambdaParameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureNullableAttributeExists(compilation, lambdaSymbol, lambdaParameters, diagnostics, modifyCompilation: false);
// Note: we don't need to warn on annotations used in #nullable disable context for lambdas, as this is handled in binding already

Expand Down
29 changes: 15 additions & 14 deletions src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal abstract class PEAssemblyBuilderBase : PEModuleBuilder, Cci.IAssemblyRe
private SynthesizedEmbeddedNullableContextAttributeSymbol _lazyNullableContextAttribute;
private SynthesizedEmbeddedNullablePublicOnlyAttributeSymbol _lazyNullablePublicOnlyAttribute;
private SynthesizedEmbeddedNativeIntegerAttributeSymbol _lazyNativeIntegerAttribute;
private SynthesizedEmbeddedScopedRefAttributeSymbol _lazyScopedRefAttribute;
private SynthesizedEmbeddedLifetimeAnnotationAttributeSymbol _lazyLifetimeAnnotationAttribute;

/// <summary>
/// The behavior of the C# command-line compiler is as follows:
Expand Down Expand Up @@ -99,7 +99,7 @@ internal sealed override ImmutableArray<NamedTypeSymbol> GetEmbeddedTypes(Bindin
builder.AddIfNotNull(_lazyNullableContextAttribute);
builder.AddIfNotNull(_lazyNullablePublicOnlyAttribute);
builder.AddIfNotNull(_lazyNativeIntegerAttribute);
builder.AddIfNotNull(_lazyScopedRefAttribute);
builder.AddIfNotNull(_lazyLifetimeAnnotationAttribute);

return builder.ToImmutableAndFree();
}
Expand Down Expand Up @@ -251,17 +251,17 @@ internal override SynthesizedAttributeData SynthesizeNativeIntegerAttribute(Well
return base.SynthesizeNativeIntegerAttribute(member, arguments);
}

internal override SynthesizedAttributeData SynthesizeScopedRefAttribute(WellKnownMember member)
internal override SynthesizedAttributeData SynthesizeLifetimeAnnotationAttribute(WellKnownMember member, ImmutableArray<TypedConstant> arguments)
{
if ((object)_lazyScopedRefAttribute != null)
if ((object)_lazyLifetimeAnnotationAttribute != null)
{
return new SynthesizedAttributeData(
_lazyScopedRefAttribute.Constructors[0],
ImmutableArray<TypedConstant>.Empty,
_lazyLifetimeAnnotationAttribute.Constructors[0],
arguments,
ImmutableArray<KeyValuePair<string, TypedConstant>>.Empty);
}

return base.SynthesizeScopedRefAttribute(member);
return base.SynthesizeLifetimeAnnotationAttribute(member, arguments);
}

protected override SynthesizedAttributeData TrySynthesizeIsReadOnlyAttribute()
Expand Down Expand Up @@ -389,13 +389,13 @@ private void CreateEmbeddedAttributesIfNeeded(BindingDiagnosticBag diagnostics)
CreateNativeIntegerAttributeSymbol);
}

if ((needsAttributes & EmbeddableAttributes.ScopedRefAttribute) != 0)
if ((needsAttributes & EmbeddableAttributes.LifetimeAnnotationAttribute) != 0)
{
CreateAttributeIfNeeded(
ref _lazyScopedRefAttribute,
ref _lazyLifetimeAnnotationAttribute,
diagnostics,
AttributeDescription.ScopedRefAttribute,
CreateScopedRefAttributeSymbol);
AttributeDescription.LifetimeAnnotationAttribute,
CreateLifetimeAnnotationAttributeSymbol);
}
}

Expand Down Expand Up @@ -438,12 +438,13 @@ private SynthesizedEmbeddedNativeIntegerAttributeSymbol CreateNativeIntegerAttri
GetWellKnownType(WellKnownType.System_Attribute, diagnostics),
GetSpecialType(SpecialType.System_Boolean, diagnostics));

private SynthesizedEmbeddedScopedRefAttributeSymbol CreateScopedRefAttributeSymbol(string name, NamespaceSymbol containingNamespace, BindingDiagnosticBag diagnostics)
=> new SynthesizedEmbeddedScopedRefAttributeSymbol(
private SynthesizedEmbeddedLifetimeAnnotationAttributeSymbol CreateLifetimeAnnotationAttributeSymbol(string name, NamespaceSymbol containingNamespace, BindingDiagnosticBag diagnostics)
=> new SynthesizedEmbeddedLifetimeAnnotationAttributeSymbol(
name,
containingNamespace,
SourceModule,
GetWellKnownType(WellKnownType.System_Attribute, diagnostics));
GetWellKnownType(WellKnownType.System_Attribute, diagnostics),
GetSpecialType(SpecialType.System_Boolean, diagnostics));

private void CreateAttributeIfNeeded<T>(
ref T symbol,
Expand Down
18 changes: 12 additions & 6 deletions src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1710,7 +1710,7 @@ internal virtual SynthesizedAttributeData SynthesizeNativeIntegerAttribute(WellK
return Compilation.TrySynthesizeAttribute(member, arguments, isOptionalUse: true);
}

internal SynthesizedAttributeData SynthesizeScopedRefAttribute(ParameterSymbol symbol, DeclarationScope scope)
internal SynthesizedAttributeData SynthesizeLifetimeAnnotationAttribute(ParameterSymbol symbol, DeclarationScope scope)
{
Debug.Assert(scope != DeclarationScope.Unscoped);
Debug.Assert(symbol.RefKind != RefKind.Out || scope == DeclarationScope.ValueScoped);
Expand All @@ -1722,14 +1722,20 @@ internal SynthesizedAttributeData SynthesizeScopedRefAttribute(ParameterSymbol s
return null;
}

return SynthesizeScopedRefAttribute(WellKnownMember.System_Runtime_CompilerServices_ScopedRefAttribute__ctor);
var booleanType = Compilation.GetSpecialType(SpecialType.System_Boolean);
Debug.Assert((object)booleanType != null);
return SynthesizeLifetimeAnnotationAttribute(
WellKnownMember.System_Runtime_CompilerServices_LifetimeAnnotationAttribute__ctor,
ImmutableArray.Create(
new TypedConstant(booleanType, TypedConstantKind.Primitive, scope == DeclarationScope.RefScoped),
new TypedConstant(booleanType, TypedConstantKind.Primitive, scope == DeclarationScope.ValueScoped)));
}

internal virtual SynthesizedAttributeData SynthesizeScopedRefAttribute(WellKnownMember member)
internal virtual SynthesizedAttributeData SynthesizeLifetimeAnnotationAttribute(WellKnownMember member, ImmutableArray<TypedConstant> arguments)
{
// For modules, this attribute should be present. Only assemblies generate and embed this type.
// https://github.com/dotnet/roslyn/issues/30062 Should not be optional.
return Compilation.TrySynthesizeAttribute(member, isOptionalUse: true);
return Compilation.TrySynthesizeAttribute(member, arguments, isOptionalUse: true);
}

internal bool ShouldEmitNullablePublicOnlyAttribute()
Expand Down Expand Up @@ -1805,9 +1811,9 @@ internal void EnsureNativeIntegerAttributeExists()
EnsureEmbeddableAttributeExists(EmbeddableAttributes.NativeIntegerAttribute);
}

internal void EnsureScopedRefAttributeExists()
internal void EnsureLifetimeAnnotationAttributeExists()
{
EnsureEmbeddableAttributeExists(EmbeddableAttributes.ScopedRefAttribute);
EnsureEmbeddableAttributeExists(EmbeddableAttributes.LifetimeAnnotationAttribute);
}

#nullable enable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private void EnsureAttributesExist(TypeCompilationState compilationState)
ParameterHelpers.EnsureNativeIntegerAttributeExists(moduleBuilder, Parameters);
}

ParameterHelpers.EnsureScopedRefAttributeExists(moduleBuilder, Parameters);
ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(moduleBuilder, Parameters);

if (compilationState.Compilation.ShouldEmitNullableAttributes(this))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ internal override ITypeSymbolInternal CommonGetWellKnownType(WellKnownType wellk
ImmutableArray<KeyValuePair<WellKnownMember, TypedConstant>> namedArguments = default,
bool isOptionalUse = false)
{
var ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, useSiteInfo: out _, isOptional: true);
UseSiteInfo<AssemblySymbol> info;
var ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, out info, isOptional: true);

if ((object)ctorSymbol == null)
{
Expand All @@ -412,7 +413,7 @@ internal override ITypeSymbolInternal CommonGetWellKnownType(WellKnownType wellk
var builder = new ArrayBuilder<KeyValuePair<string, TypedConstant>>(namedArguments.Length);
foreach (var arg in namedArguments)
{
var wellKnownMember = Binder.GetWellKnownTypeMember(this, arg.Key, useSiteInfo: out _, isOptional: true);
var wellKnownMember = Binder.GetWellKnownTypeMember(this, arg.Key, out info, isOptional: true);
if (wellKnownMember == null || wellKnownMember is ErrorTypeSymbol)
{
// if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
Expand Down Expand Up @@ -543,9 +544,9 @@ internal void EnsureNativeIntegerAttributeExists(BindingDiagnosticBag? diagnosti
EnsureEmbeddableAttributeExists(EmbeddableAttributes.NativeIntegerAttribute, diagnostics, location, modifyCompilation);
}

internal void EnsureScopedRefAttributeExists(BindingDiagnosticBag? diagnostics, Location location, bool modifyCompilation)
internal void EnsureLifetimeAnnotationAttributeExists(BindingDiagnosticBag? diagnostics, Location location, bool modifyCompilation)
{
EnsureEmbeddableAttributeExists(EmbeddableAttributes.ScopedRefAttribute, diagnostics, location, modifyCompilation);
EnsureEmbeddableAttributeExists(EmbeddableAttributes.LifetimeAnnotationAttribute, diagnostics, location, modifyCompilation);
}

internal bool CheckIfAttributeShouldBeEmbedded(EmbeddableAttributes attribute, BindingDiagnosticBag? diagnosticsOpt, Location locationOpt)
Expand Down Expand Up @@ -606,12 +607,12 @@ internal bool CheckIfAttributeShouldBeEmbedded(EmbeddableAttributes attribute, B
WellKnownMember.System_Runtime_CompilerServices_NativeIntegerAttribute__ctor,
WellKnownMember.System_Runtime_CompilerServices_NativeIntegerAttribute__ctorTransformFlags);

case EmbeddableAttributes.ScopedRefAttribute:
case EmbeddableAttributes.LifetimeAnnotationAttribute:
return CheckIfAttributeShouldBeEmbedded(
diagnosticsOpt,
locationOpt,
WellKnownType.System_Runtime_CompilerServices_ScopedRefAttribute,
WellKnownMember.System_Runtime_CompilerServices_ScopedRefAttribute__ctor);
WellKnownType.System_Runtime_CompilerServices_LifetimeAnnotationAttribute,
WellKnownMember.System_Runtime_CompilerServices_LifetimeAnnotationAttribute__ctor);

default:
throw ExceptionUtilities.UnexpectedValue(attribute);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
// https://github.com/dotnet/roslyn/issues/61647: Internally, scope is represented with this enum,
// but the public API uses a pair of IsRefScoped and IsValueScoped bools (see ILocalSymbol,
// IParameterSymbol, and ScopedRefAttribute). We should have a common representation.
// IParameterSymbol, and LifetimeAnnotationAttribute). We should have a common representation.
// And we should use common terms for the attribute and enum names.
internal enum DeclarationScope : byte
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ internal enum EmbeddableAttributes
NullableContextAttribute = 0x10,
NullablePublicOnlyAttribute = 0x20,
NativeIntegerAttribute = 0x40,
ScopedRefAttribute = 0x80,
LifetimeAnnotationAttribute = 0x80,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ private PEParameterSymbol(
if (inOutFlags == ParameterAttributes.Out)
{
refKind = RefKind.Out;
scope = DeclarationScope.RefScoped;
}
else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle))
{
Expand All @@ -293,24 +294,16 @@ private PEParameterSymbol(
typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, handle, moduleSymbol, accessSymbol: accessSymbol, nullableContext: nullableContext);
typeWithAnnotations = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithAnnotations, handle, moduleSymbol);

if (refKind == RefKind.Out)
{
scope = DeclarationScope.RefScoped;
}
else if (_moduleSymbol.Module.HasScopedRefAttribute(_handle))
if (_moduleSymbol.Module.HasLifetimeAnnotationAttribute(_handle, out var pair))
{
if (isByRef)
{
Debug.Assert(refKind != RefKind.None);
scope = DeclarationScope.RefScoped;
}
else if (typeWithAnnotations.Type.IsRefLikeType)
var scopeOpt = GetScope(refKind, typeWithAnnotations.Type, pair.IsRefScoped, pair.IsValueScoped);
if (scopeOpt is null)
{
scope = DeclarationScope.ValueScoped;
isBad = true;
}
else
{
isBad = true;
scope = scopeOpt.GetValueOrDefault();
}
}
}
Expand Down Expand Up @@ -987,6 +980,16 @@ public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences

internal sealed override DeclarationScope Scope => _packedFlags.Scope;

private static DeclarationScope? GetScope(RefKind refKind, TypeSymbol type, bool isRefScoped, bool isValueScoped)
{
return (isRefScoped, isValueScoped) switch
{
(false, false) => DeclarationScope.Unscoped,
(true, false) => refKind != RefKind.None ? DeclarationScope.RefScoped : null,
(_, true) => type.IsRefLikeType ? DeclarationScope.ValueScoped : null,
};
}

public override ImmutableArray<CSharpAttributeData> GetAttributes()
{
if (_lazyCustomAttributes.IsDefault)
Expand Down Expand Up @@ -1028,7 +1031,7 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
out _,
filterIsReadOnlyAttribute ? AttributeDescription.IsReadOnlyAttribute : default,
out _,
AttributeDescription.ScopedRefAttribute,
AttributeDescription.LifetimeAnnotationAttribute,
out _,
default);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ private void ComputeParameters()
var compilation = DeclaringCompilation;
ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureScopedRefAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false);
ParameterHelpers.EnsureNullableAttributeExists(compilation, this, parameters, diagnostics, modifyCompilation: false);
// Note: we don't need to warn on annotations used in #nullable disable context for local functions, as this is handled in binding already

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ private static void EnsureNativeIntegerAttributeExists(CSharpCompilation compila
}
}

internal static bool RequiresScopedRefAttribute(ParameterSymbol parameter)
internal static bool RequiresLifetimeAnnotationAttribute(ParameterSymbol parameter)
{
Debug.Assert(!parameter.IsThis);

Expand All @@ -322,12 +322,12 @@ internal static bool RequiresScopedRefAttribute(ParameterSymbol parameter)
return true;
}

internal static void EnsureScopedRefAttributeExists(PEModuleBuilder moduleBuilder, ImmutableArray<ParameterSymbol> parameters)
internal static void EnsureLifetimeAnnotationAttributeExists(PEModuleBuilder moduleBuilder, ImmutableArray<ParameterSymbol> parameters)
{
EnsureScopedRefAttributeExists(moduleBuilder.Compilation, parameters, diagnostics: null, modifyCompilation: false, moduleBuilder);
EnsureLifetimeAnnotationAttributeExists(moduleBuilder.Compilation, parameters, diagnostics: null, modifyCompilation: false, moduleBuilder);
}

internal static void EnsureScopedRefAttributeExists(CSharpCompilation? compilation, ImmutableArray<ParameterSymbol> parameters, BindingDiagnosticBag diagnostics, bool modifyCompilation)
internal static void EnsureLifetimeAnnotationAttributeExists(CSharpCompilation? compilation, ImmutableArray<ParameterSymbol> parameters, BindingDiagnosticBag diagnostics, bool modifyCompilation)
{
// These parameters might not come from a compilation (example: lambdas evaluated in EE).
// During rewriting, lowering will take care of flagging the appropriate PEModuleBuilder instead.
Expand All @@ -336,22 +336,22 @@ internal static void EnsureScopedRefAttributeExists(CSharpCompilation? compilati
return;
}

EnsureScopedRefAttributeExists(compilation, parameters, diagnostics, modifyCompilation, moduleBuilder: null);
EnsureLifetimeAnnotationAttributeExists(compilation, parameters, diagnostics, modifyCompilation, moduleBuilder: null);
}

private static void EnsureScopedRefAttributeExists(CSharpCompilation compilation, ImmutableArray<ParameterSymbol> parameters, BindingDiagnosticBag? diagnostics, bool modifyCompilation, PEModuleBuilder? moduleBuilder)
private static void EnsureLifetimeAnnotationAttributeExists(CSharpCompilation compilation, ImmutableArray<ParameterSymbol> parameters, BindingDiagnosticBag? diagnostics, bool modifyCompilation, PEModuleBuilder? moduleBuilder)
{
foreach (var parameter in parameters)
{
if (RequiresScopedRefAttribute(parameter))
if (RequiresLifetimeAnnotationAttribute(parameter))
{
if (moduleBuilder is { })
{
moduleBuilder.EnsureScopedRefAttributeExists();
moduleBuilder.EnsureLifetimeAnnotationAttributeExists();
}
else
{
compilation.EnsureScopedRefAttributeExists(diagnostics, GetParameterLocation(parameter), modifyCompilation);
compilation.EnsureLifetimeAnnotationAttributeExists(diagnostics, GetParameterLocation(parameter), modifyCompilation);
}
}
}
Expand Down
Loading