Skip to content

Commit c09b28d

Browse files
authored
Merge branch 'main' into rustup
2 parents b168b47 + 19beae8 commit c09b28d

8 files changed

Lines changed: 190 additions & 34 deletions

File tree

extensions/bindgen/private/bindgen.bzl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,18 @@ def _rust_bindgen_impl(ctx):
243243
args.add_all(ctx.attr.bindgen_flags)
244244

245245
rust_toolchain = ctx.toolchains[Label("@rules_rust//rust:toolchain_type")]
246-
if "--rust-edition" not in [f.split("=")[0] for f in ctx.attr.bindgen_flags]:
246+
user_flags = [f.split("=")[0] for f in ctx.attr.bindgen_flags]
247+
248+
# Ignore `nightly` or `beta` versions.
249+
if rust_toolchain.version and rust_toolchain.version[0].isdigit():
250+
# Pass `--rust-target` so bindgen knows the actual toolchain version.
251+
# Without this, bindgen defaults to it's built-in `LATEST_STABLE_RUST`
252+
# which may be older than the actual toolchain version and would
253+
# reject newer editions (e.g. edition 2024 requires `rust-target >= 1.85.0`).
254+
if "--rust-target" not in user_flags:
255+
args.add("--rust-target=%s" % rust_toolchain.version)
256+
257+
if "--rust-edition" not in user_flags:
247258
args.add("--rust-edition=%s" % rust_toolchain.default_edition)
248259

249260
args.add(header)

rust/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package(default_visibility = ["//visibility:public"])
44

55
exports_files([
66
"known_shas.bzl",
7+
"nightly_versions.bzl",
78
"repositories.bzl",
89
"defs.bzl",
910
"toolchain.bzl",

rust/nightly_versions.bzl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""A module containing a mapping of nightly iso dates to Rust versions.
2+
3+
This is a generated file -- see //util/fetch_shas
4+
"""
5+
6+
# Each entry marks the first tracked nightly date where the Rust
7+
# version changed. To resolve a given iso_date, find the latest
8+
# entry whose date is <= the target date.
9+
NIGHTLY_VERSION_TRANSITIONS = {
10+
"2023-09-19": "1.74.0",
11+
"2023-10-05": "1.75.0",
12+
"2023-11-16": "1.76.0",
13+
"2023-12-28": "1.77.0",
14+
"2024-02-08": "1.78.0",
15+
"2024-03-21": "1.79.0",
16+
"2024-05-02": "1.80.0",
17+
"2024-06-13": "1.81.0",
18+
"2024-07-25": "1.82.0",
19+
"2024-09-05": "1.83.0",
20+
"2024-10-17": "1.84.0",
21+
"2024-11-28": "1.85.0",
22+
"2025-01-09": "1.86.0",
23+
"2025-02-20": "1.87.0",
24+
"2025-04-03": "1.88.0",
25+
"2025-05-13": "1.89.0",
26+
"2025-08-07": "1.91.0",
27+
"2025-09-18": "1.92.0",
28+
"2025-10-30": "1.93.0",
29+
"2025-12-11": "1.94.0",
30+
"2026-01-22": "1.95.0",
31+
"2026-03-05": "1.96.0",
32+
}

rust/private/repository_utils.bzl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ rust_toolchain(
369369
opt_level = {opt_level},
370370
strip_level = {strip_level},
371371
version = "{version}",
372+
channel = "{channel}",
373+
iso_date = {iso_date},
372374
tags = ["rust_version={version}"],
373375
)
374376
"""
@@ -378,12 +380,14 @@ def BUILD_for_rust_toolchain(
378380
exec_triple,
379381
target_triple,
380382
version,
381-
allocator_library,
382-
global_allocator_library,
383-
default_edition,
384-
include_rustfmt,
385-
include_llvm_tools,
386-
include_linker,
383+
channel,
384+
iso_date = None,
385+
allocator_library = None,
386+
global_allocator_library = None,
387+
default_edition = "",
388+
include_rustfmt = False,
389+
include_llvm_tools = False,
390+
include_linker = False,
387391
include_objcopy = False,
388392
stdlib_linkflags = None,
389393
extra_rustc_flags = None,
@@ -396,7 +400,9 @@ def BUILD_for_rust_toolchain(
396400
name (str): The name of the toolchain declaration
397401
exec_triple (triple): The rust-style target that this compiler runs on
398402
target_triple (triple): The rust-style target triple of the tool
399-
version (str): The Rust version for the toolchain.
403+
version (str): The semver Rust version for the toolchain (e.g. `1.94.1`).
404+
channel (str): The Rust release channel (`stable`, `nightly`, or `beta`).
405+
iso_date (str, optional): The ISO date of the nightly or beta release (e.g. `2026-03-26`).
400406
allocator_library (str, optional): Target that provides allocator functions when rust_library targets are embedded in a cc_binary.
401407
global_allocator_library (str, optional): Target that provides allocator functions when a global allocator is used with cc_common_link.
402408
This target is only used in the target configuration; exec builds still use the symbols provided
@@ -476,6 +482,8 @@ def BUILD_for_rust_toolchain(
476482
opt_level = opt_level,
477483
strip_level = strip_level,
478484
version = version,
485+
channel = channel,
486+
iso_date = repr(iso_date),
479487
)
480488

481489
_build_file_for_toolchain_template = """\

rust/repositories.bzl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Repository rules for defining Rust dependencies and toolchains.
55

66
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
77
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
8+
load("//rust:nightly_versions.bzl", "NIGHTLY_VERSION_TRANSITIONS")
89
load("//rust/platform:triple.bzl", "get_host_triple", "triple")
910
load("//rust/platform:triple_mappings.bzl", "triple_to_constraint_set")
1011
load("//rust/private:common.bzl", "rust_common")
@@ -447,6 +448,32 @@ def _include_rust_objcopy(version, iso_date):
447448

448449
return False
449450

451+
def _resolve_nightly_version(iso_date):
452+
"""Resolve a nightly iso_date to its underlying Rust semver version.
453+
454+
First tries a direct lookup, then falls back to scanning sorted
455+
transition dates for the last entry whose date is <= the requested
456+
iso_date.
457+
458+
Args:
459+
iso_date (str): The nightly ISO date (e.g. "2026-03-26").
460+
461+
Returns:
462+
str: The resolved Rust version (e.g. "1.96.0"), or None if
463+
the date precedes all tracked transitions.
464+
"""
465+
direct = NIGHTLY_VERSION_TRANSITIONS.get(iso_date)
466+
if direct:
467+
return direct
468+
469+
result = None
470+
for transition_date in sorted(NIGHTLY_VERSION_TRANSITIONS):
471+
if transition_date <= iso_date:
472+
result = NIGHTLY_VERSION_TRANSITIONS[transition_date]
473+
else:
474+
break
475+
return result
476+
450477
def _rust_toolchain_tools_repository_impl(ctx):
451478
"""The implementation of the rust toolchain tools repository rule."""
452479
sha256s = dict(ctx.attr.sha256s)
@@ -459,6 +486,17 @@ def _rust_toolchain_tools_repository_impl(ctx):
459486

460487
check_version_valid(ctx.attr.version, iso_date)
461488

489+
if version in ("nightly", "beta"):
490+
channel = version
491+
else:
492+
channel = "stable"
493+
494+
toolchain_version = version
495+
if channel == "nightly" and iso_date:
496+
resolved = _resolve_nightly_version(iso_date)
497+
if resolved:
498+
toolchain_version = resolved
499+
462500
exec_triple = triple(ctx.attr.exec_triple)
463501

464502
include_linker = True
@@ -556,7 +594,9 @@ def _rust_toolchain_tools_repository_impl(ctx):
556594
extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags,
557595
opt_level = ctx.attr.opt_level if ctx.attr.opt_level else None,
558596
strip_level = ctx.attr.strip_level if ctx.attr.strip_level else None,
559-
version = ctx.attr.version,
597+
version = toolchain_version,
598+
channel = channel,
599+
iso_date = iso_date,
560600
))
561601

562602
# Not all target triples are expected to have dev components

rust/toolchain.bzl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,13 +571,15 @@ def _rust_toolchain_impl(ctx):
571571
all_files = depset(transitive = all_files_depsets),
572572
binary_ext = ctx.attr.binary_ext,
573573
cargo = sysroot.cargo,
574+
channel = ctx.attr.channel,
574575
clippy_driver = sysroot.clippy,
575576
cargo_clippy = sysroot.cargo_clippy,
576577
compilation_mode_opts = compilation_mode_opts,
577578
default_edition = ctx.attr.default_edition,
578579
dylib_ext = ctx.attr.dylib_ext,
579580
env = ctx.attr.env,
580581
exec_triple = exec_triple,
582+
iso_date = ctx.attr.iso_date,
581583
libstd_and_allocator_ccinfo = make_local_ccinfo(ctx.attr.allocator_library[CcInfo], "std"),
582584
libstd_and_global_allocator_ccinfo = make_local_ccinfo(ctx.attr.global_allocator_library[CcInfo], "std"),
583585
nostd_and_global_allocator_ccinfo = make_local_ccinfo(ctx.attr.global_allocator_library[CcInfo], "no_std_with_alloc"),
@@ -657,6 +659,10 @@ rust_toolchain = rule(
657659
allow_single_file = True,
658660
cfg = "exec",
659661
),
662+
"channel": attr.string(
663+
doc = "The Rust release channel (`stable`, `nightly`, or `beta`).",
664+
default = "",
665+
),
660666
"clippy_driver": attr.label(
661667
doc = "The location of the `clippy-driver` binary. Can be a direct source or a filegroup containing one item.",
662668
allow_single_file = True,
@@ -724,6 +730,10 @@ rust_toolchain = rule(
724730
doc = "Target that provides allocator functions for when a global allocator is present.",
725731
default = Label("//rust/private/cc:global_allocator_library"),
726732
),
733+
"iso_date": attr.string(
734+
doc = "The ISO date of the nightly or beta release (e.g. `2026-03-26`). Empty for stable releases.",
735+
default = "",
736+
),
727737
"linker": attr.label(
728738
doc = "The label to an explicit linker to use (e.g. rust-lld, ld, link-ld.exe, etc.). Linker binaries must be runnable in the exec configuration, so cfg = \"exec\" is used. To choose a linker based on the target platform, use a select() when providing this attribute. The select() will be evaluated against the target platform before the exec transition is applied, allowing platform-specific linker selection while ensuring the selected linker is built for the exec platform.",
729739
cfg = "exec",
@@ -844,7 +854,7 @@ rust_toolchain = rule(
844854
),
845855
),
846856
"version": attr.string(
847-
doc = "The version of the Rust compiler. (E.g. `1.94.1`, nightly/2026-03-26`)",
857+
doc = "The version of the Rust compiler (e.g. `1.94.1`).",
848858
default = "",
849859
),
850860
"_codegen_units": attr.label(

test/unit/windows_stdlib/windows_stdlib_test.bzl

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,14 @@ def _build_for_rust_toolchain_windows_flags_test_impl(ctx):
4646
exec_triple = msvc_triple,
4747
target_triple = msvc_triple,
4848
version = "1.75.0",
49-
allocator_library = None,
50-
global_allocator_library = None,
51-
default_edition = "2021",
52-
include_rustfmt = False,
53-
include_llvm_tools = False,
54-
include_linker = False,
55-
stdlib_linkflags = None,
56-
extra_rustc_flags = None,
57-
extra_exec_rustc_flags = None,
58-
opt_level = None,
59-
strip_level = None,
49+
channel = "stable",
6050
)
6151
rendered_gnu = BUILD_for_rust_toolchain(
6252
name = "tc_gnu",
6353
exec_triple = gnu_triple,
6454
target_triple = gnu_triple,
6555
version = "1.75.0",
66-
allocator_library = None,
67-
global_allocator_library = None,
68-
default_edition = "2021",
69-
include_rustfmt = False,
70-
include_llvm_tools = False,
71-
include_linker = False,
72-
stdlib_linkflags = None,
73-
extra_rustc_flags = None,
74-
extra_exec_rustc_flags = None,
75-
opt_level = None,
76-
strip_level = None,
56+
channel = "stable",
7757
)
7858

7959
asserts.true(

util/fetch_shas/fetch_shas.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
#!/usr/bin/env python3.11
2-
"""A script for generating the `//rust:known_shas.bzl` file."""
2+
"""A script for generating the `//rust:known_shas.bzl` and `//rust:nightly_versions.bzl` files."""
33

44
import json
55
import logging
66
import os
7+
import re
78
import shutil
89
import subprocess
910
import sys
1011
import tempfile
1112
import tomllib
1213
from pathlib import Path
13-
from typing import Any, Dict, Sequence
14+
from typing import Any, Dict, List, Sequence, Tuple
1415

1516
KNOWN_SHAS_TEMPLATE = """\
1617
\"\"\"A module containing a mapping of Rust tools to checksums
@@ -21,6 +22,20 @@
2122
FILE_KEY_TO_SHA = {}
2223
"""
2324

25+
NIGHTLY_VERSIONS_TEMPLATE = """\
26+
\"\"\"A module containing a mapping of nightly iso dates to Rust versions.
27+
28+
This is a generated file -- see //util/fetch_shas
29+
\"\"\"
30+
31+
# Each entry marks the first tracked nightly date where the Rust
32+
# version changed. To resolve a given iso_date, find the latest
33+
# entry whose date is <= the target date.
34+
NIGHTLY_VERSION_TRANSITIONS = {{
35+
{}
36+
}}
37+
"""
38+
2439

2540
def download_manifest_data(
2641
stable_versions: Sequence[str], nightly_versions: Sequence[str], output_dir: Path
@@ -214,6 +229,53 @@ def download_direct_sha256s(
214229
}
215230

216231

232+
def extract_nightly_version_transitions(
233+
manifest_data: Dict[str, Dict[str, Any]],
234+
) -> List[Tuple[str, str]]:
235+
"""Extract a transition table mapping nightly iso dates to Rust versions.
236+
237+
Only includes entries where the version changed from the previous entry,
238+
keeping the table compact.
239+
240+
Args:
241+
manifest_data: The parsed manifest data from download_manifest_data.
242+
243+
Returns:
244+
A sorted list of (iso_date, version) tuples at transition points.
245+
"""
246+
nightly_info = manifest_data.get("nightly", {})
247+
date_to_version = {}
248+
249+
for iso_date, info in nightly_info.items():
250+
rustc_pkg = info.get("pkg", {}).get("rustc", {})
251+
rustc_version_str = rustc_pkg.get("version", "")
252+
if not rustc_version_str:
253+
logging.warning("No rustc version found for nightly %s", iso_date)
254+
continue
255+
256+
match = re.match(r"^(\d+\.\d+\.\d+)", rustc_version_str)
257+
if not match:
258+
logging.warning(
259+
"Could not parse version from %r for nightly %s",
260+
rustc_version_str,
261+
iso_date,
262+
)
263+
continue
264+
265+
date_to_version[iso_date] = match.group(1)
266+
267+
sorted_dates = sorted(date_to_version.keys())
268+
transitions = []
269+
prev_version = None
270+
for date in sorted_dates:
271+
version = date_to_version[date]
272+
if version != prev_version:
273+
transitions.append((date, version))
274+
prev_version = version
275+
276+
return transitions
277+
278+
217279
def load_data(file: Path) -> Sequence[str]:
218280
"""Load a `fetch_shas_*.txt` file
219281
@@ -357,6 +419,11 @@ def main() -> None:
357419
)
358420
)
359421

422+
nightly_transitions = extract_nightly_version_transitions(manifest_data)
423+
logging.info(
424+
"Identified %s nightly version transitions.", len(nightly_transitions)
425+
)
426+
360427
finally:
361428
if not "RULES_RUST_FETCH_SHAS_DEBUG" in os.environ:
362429
shutil.rmtree(tmp_dir)
@@ -371,6 +438,13 @@ def main() -> None:
371438
)
372439
logging.info("Done. Wrote %s", known_shas_file.relative_to(workspace_dir))
373440

441+
nightly_versions_file = workspace_dir / "rust/nightly_versions.bzl"
442+
transitions_str = "\n".join(
443+
' "{}": "{}",'.format(date, ver) for date, ver in nightly_transitions
444+
)
445+
nightly_versions_file.write_text(NIGHTLY_VERSIONS_TEMPLATE.format(transitions_str))
446+
logging.info("Done. Wrote %s", nightly_versions_file.relative_to(workspace_dir))
447+
374448

375449
if __name__ == "__main__":
376450
main()

0 commit comments

Comments
 (0)