boringlint

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 5 Imported by: 0

README

boringlint

boringlint enforces a deliberately restricted Go dialect: direct data and control flow over language machinery that hides either one.

This is opinionated policy, not a claim that the rejected features are invalid Go. The module is pre-v1 while the rules and public analyzer API settle.

Install and run

After publishing a tagged release, install the command with the same or a newer Go toolchain than the code it will analyze:

go install github.com/KrishRVH/boringlint/cmd/boringlint@latest
boringlint ./...

The command also implements the go vet tool protocol:

go vet ./...
go vet -vettool="$(command -v boringlint)" ./...

Run both commands. -vettool selects boringlint in place of the standard vet analyzers; it does not add checks to the standard set.

Go version support

boringlint's source-project floor is Go 1.23, which introduced range-over-function and iter. New Go releases are supported only after both command modes pass the compatibility gate; the current upper bound is Go 1.27, tested with the Go 1.27rc2 toolchain. Building, installing, or running boringlint requires Go 1.25 or newer. Importing its analyzers into a custom driver has the same floor because a module's go directive is a mandatory minimum. A standalone or vettool binary may analyze projects declaring Go 1.23 or 1.24, provided the binary was built with a supported toolchain at least as new as the source it analyzes.

nogenericmethod analyzes Go 1.27 syntax, so its binary must be built with Go 1.27 or newer. The repository currently tests that rule with Go 1.27rc2:

GOTOOLCHAIN=go1.27rc2 go install github.com/KrishRVH/boringlint/cmd/boringlint@latest

The Go 1.25 tool floor is deliberate. Analysis drivers consume compiler export data and implement the go vet -vettool protocol, so ordinary Go source compatibility does not make an old driver forward-compatible. x/tools v0.36.0 was the last release with a Go 1.23 floor before v0.37.0 raised it, but Go subrepositories generally support only the previous two Go releases and tip. Freezing the driver there would trade a lower build floor for unsupported compiler integration. The compatible x/tools v0.48.0 requires Go 1.25.

The floor will rise only when correct support for a newly supported Go release requires a newer analysis driver. Each increase must be explicit in go.mod and this section, and both standalone and vettool compatibility must pass before support for that source version is claimed.

Rules

noiterator

Rejects:

  • direct imports of iter;
  • Go 1.23 range-over-function;
  • iterator-shaped types in project type, function, and method declarations, including constraints, fields, parameters, and results.
import "iter" // rejected

type Sequence func(func(int) bool) // rejected

func Values(yield func(int) bool) { // rejected
	// ...
}

for value := range dependency.Values() { // rejected
	// ...
}

Range over arrays, slices, strings, maps, channels, and integers remains allowed. Values returned by dependencies are also allowed so they can be materialized without naming the iterator type:

values := slices.Collect(dependency.Values())

The rule intentionally governs imports, range statements, and iterator-shaped types in project type, function, and method declarations. Variable declarations remain allowed; the rule does not attempt an expression-level ban on every value whose type happens to be iterator-shaped.

nogenericmethod

Rejects method-local type parameters introduced in Go 1.27, in both method declarations and uses. Generic functions and methods that only use their receiver type's parameters remain allowed.

func (box Box[T]) Map[U any](convert func(T) U) U { // rejected
	return convert(box.value)
}

func Map[T, U any](box Box[T], convert func(T) U) U { // allowed
	return convert(box.value)
}

Use as a package

The analyzers are ordinary go/analysis values and can be composed into a custom driver:

package main

import (
	"github.com/KrishRVH/boringlint"
	"golang.org/x/tools/go/analysis/multichecker"
)

func main() {
	multichecker.Main(boringlint.NoIterator, boringlint.NoGenericMethod)
}

Development

mise is the developer interface:

mise run tasks
mise run standards
mise run standards:check

The full gate checks formatting, module integrity, static analysis, vulnerabilities, secrets, race behavior, command integration, Go 1.25 compatibility, and Go 1.27 behavior.

License

MIT

Documentation

Overview

Package boringlint enforces a deliberately restricted Go dialect.

Index

Constants

This section is empty.

Variables

View Source
var NoGenericMethod = &analysis.Analyzer{
	Name: "nogenericmethod",
	Doc: "reject generic method declarations and uses\n\n" +
		"nogenericmethod rejects method-local type parameters introduced in Go 1.27; " +
		"use a package-level generic function",
	URL: "https://github.com/KrishRVH/boringlint#nogenericmethod",
	Run: runNoGenericMethod,
}

NoGenericMethod rejects generic method declarations and uses.

View Source
var NoIterator = &analysis.Analyzer{
	Name: "noiterator",
	Doc: "reject range-over-function and iterator-shaped types in project type, function, and method declarations\n\n" +
		"noiterator rejects direct iter imports, range-over-function, and " +
		"iterator-shaped types in project type, function, and method declarations",
	URL: "https://github.com/KrishRVH/boringlint#noiterator",
	Run: runNoIterator,
}

NoIterator rejects direct iter imports, iterator-shaped types in project type, function, and method declarations, and range-over-function.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
boringlint command
Command boringlint is a vet tool for a deliberately restricted Go dialect.
Command boringlint is a vet tool for a deliberately restricted Go dialect.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL