Skip to content

Instantly share code, notes, and snippets.

View agocke's full-sized avatar

Andy Gocke agocke

View GitHub Profile
public ref struct JsonSerializer
{
private Span<byte> _buffer;
private int _loc; // increments as we write
...
public void WriteToBuffer(string s) => ...; // moves _loc
public Seq SerializeEnumerable(int? count) => new Seq(ref this);
ref struct Lexer
{
private Span<char> _buffer;
private int _loc;
public Lexer(Span<char> buffer)
{
_buffer = buffer;
_loc = 0;
}

I have to insist on using explicit lifetimes for spec'ing. Both because I think it makes the rules a lot clearer, but also because it separates the safety rules from the language semantics. Let me introduce the description of lifetimes in a series of rules:

  1. All expressions with a storage location (things you can take a ref to) have an implicit, language-defined lifetime. These lifetimes tend to be pretty simple. If you say
void M() {
    int x;
} 

The lifetime of int x is the same as the lifetime of method M. This is true for all structs. For fields of types, if the type is a class then the lifetime is the "global" (heap) lifetime. If it's a field of a struct, it's the lifetime of the containing struct. You can think of lifetimes as being part of the type, so while it looks like the type of x is int, it's really (x, $M), where $M is the lifetime of the method M.

@agocke
agocke / analysis.md
Last active November 10, 2022 18:41 — forked from missymessa/analysis.md
Sample output from Build Analysis service.
interface IWebApplication<abstract TResult>
{
TResult MapGet(string route, Func<TResult, TResult> f);
}
class NotFound : IResult { }
class OK<TValue> : IResult { }
class MyWebApp : IWebApplication<IResult>
{
ref struct S<#a> {
public int Field;
public ref<#a> int RefField;
}
static int StaticField = 5;
public void M1() {
S s = default; // S<#global>
s = new S() { RefField = ref StaticField };
@agocke
agocke / IsRef.cs
Created May 27, 2021 01:29
Check if assembly is a ref assembly
using System;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
try
{
using var file = new FileStream(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using var pe = new PEReader(file);
@agocke
agocke / DefaultImplPrinter.cs
Created May 21, 2021 05:26
Prints signatures of implementations of interfaces in interfaces
using System;
using System.Collections.Immutable;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
namespace default_impl
{
using System;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
namespace misc_bench
{
[MemoryDiagnoser]
public class Benchmarks
@agocke
agocke / LoginResourceFull.cs
Created June 14, 2018 22:38
C# data class example
using System;
public class LoginResource : IEquatable<LoginResource>
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; } = false;
public override bool Equals(object obj)
=> obj is LoginResource resource && Equals(resource);