Document not found (404)
+This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..f17311098 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/404.html b/404.html new file mode 100644 index 000000000..0db925d4e --- /dev/null +++ b/404.html @@ -0,0 +1,171 @@ + + +
+ + +This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +The Rust Team likes to occasionally +recognize people who have made outstanding contributions to The Rust Project, +its ecosystem, and its community. These people are ‘Friends of the Tree’, +archived here for eternal glory.
+This week we would like to nominate @mitaa as Friend of the Tree. Recently @mitaa +has sent a wave of fixes to +rustdoc (yes those are all separate links) with even more on the way! +Rustdoc has historically been a tool in need of some love, and the extra help in +fixing bugs is especially appreciated. Thanks @mitaa!
+This week’s friend of the tree is Jeffrey Seyfried (@jseyfried)!
+Jeffrey Seyfried (@jseyfried) has made some awesome contributions to name +resolution. He has fixed a ton of bugs, reported previously unknown edge cases, +and done some big refactorings, all of which have helped improve a complex and +somewhat neglected part of the compiler.
+This week we’d like to nominate @petrochenkov for Friend of the Tree. Vadim has
+been doing some absolutely amazing compiler work recently such as fixing
+privacy bugs, fixing hygiene bugs, fixing pattern bugs,
+paving the way and implementing #[deprecated]
,
+fixing and closing many privacy holes, refactoring
+and improving the HIR, and reviving the old type ascription
+PR. The list of outstanding bugs and projects in the compiler is
+growing ever smaller now; thanks @petrochenkov!
In his own words, WindowsBunny is “a hopping encyclopedia of all the issues +windows users might run into and how to solve them.” One of the heroes that make +Rust work on Windows, he actively pushes the frontiers of what Rust can do on +the platform. He is also notably the maintainer of the +winapi family of crates, a comprehensive set +of bindings to the Windows system APIs. You da bunny, WindowsBunny. Also, a +friend of the tree.
+ +Today @nrc would like to nominated @marcusklaas as Friend of the Tree:
+Marcus is one of the primary authors of +rustfmt. He has been involved since the early +days and is now the +top contributor. He has +fixed innumerable bugs, implemented new features, reviewed a tonne of PRs, and +contributed to the design of the project. Rustfmt would not be the software it +is today without his hard work; he is indeed a Friend Of The Tree.
+nmatsakis would also like to declare Ryan Prichard a Friend of the Tree. +Over the last few months, Ryan has been comparing the Rust compiler’s parsing +behavior with that of the rust-grammar project, which aims to create a LALR(1) +grammar for parsing Rust. Ryan has found a number of inconsistencies and bugs +between the two. This kind of work is useful for two reasons: it finds bugs, +obviously, which are often hard to uncover any other way. Second, it helps pave +the way for a true Rust reference grammar outside of the compiler source itself. +So Ryan Prichard, thanks!
+Vikrant Chaudhary (nasa42) is an individual who +believes in the Rust community. Since June he has been contributing to +This Week in Rust, coordinating its publication +on +urlo, +and stirring up contributions. He recently rolled out an overhaul to the site’s +design that brings it more inline with the main website. Today Vikrant is the +main editor on the weekly newsletter, assisted by +llogiq and other contributors. Thanks for keeping +TWiR running, Vikrant, you friend of the tree.
+ +@Gankra has nominated +@tshepang for Friend of the Tree this week:
+Over the last year Tshepang has landed over 100 improvements to our +documentation. Tshepang saw where documentation was not, and said “No. This will +not do.”
+We should all endeavor to care about docs as much as Tshepang.
+ +I’d like to nominate Chris Morgan (@chris-morgan) for Friend of the Tree today. +Chris recently redesigned the play.rust-lang.org site for the 1.0 release, +giving the site a more modern and rustic feel to it. Chris has been contributing +to Rust for quite some time now, his first contribution dating back to July 2013 +and also being one of the early pioneers in the space of HTTP libraries written +in Rust. Chris truly is a friend of the tree!
+BurntSushi is an individual who practically needs no introduction. He’s +written many of the world’s most popular crates, including docopt.rs, regex, +quickcheck, cbor, and byteorder. Don’t forget his CSV swiss-army-knife, +xsv, built on rust-csv. Feedback from his early work on libraries helped +informed the evolution of Rust during a critical time in its development, and +BurntSushi continues to churn out the kind of Rust gems that can only come from +someone who is a skilled friendofthetree.
+Manish started working on Servo as part of the GSoC program in 2014, where he +implemented XMLHttpRequest. Since then he’s become in integral part of the Servo +team while finishing his university studies and organizing Rust community +events. In 2015 he took an interest in bors’ queue and started making rollup PRs +to accelerate the integration process. Nursing the PR queue is the kind of +time-consuming labor that creates friends of the tree like Manish, the rollup +friend of the tree.
+Today I would like to nominate Toby Scrace as Friend of the Tree. Toby emailed +me over the weekend about a login vulnerability on crates.io where you could log +in to whomever the previously logged in user was regardless of whether the +GitHub authentication was successful or not. I very much appreciate Toby +emailing me privately ahead of time, and I definitely feel that Toby has earned +becoming Friend of the Tree.
+Jonathan Reem has been making an impact on Rust since May 2014. His primary
+contribution has been as the main author of the prominent Iron web
+framework, though he has also created several other popular projects including
+the testing framework stainless. His practical experience with these projects
+has led to several improvements in upstream rust, most notably his complete
+rewrite of the TaskPool
type. Reem is doing everything he can to advance the
+Rust cause.
Today I would like to nominate Barosl Lee (@barosl) for Friend of the Tree. +Barosl has recently rewritten our bors cron job in a new project called homu. +Homu has a number of benefits including:
+Homu was recently deployed for rust-lang/rust thanks to a number of issues being +closed out by Barosl, and it’s been working fantastically so far! Barosl has +also been super responsive to any new issues cropping up. Barosl truly is a +Friend of the Tree!
+Seonghoon has been an active member of the Rust community since early 2013, and +although he has made a number of valuable contributions to Rust itself, his +greatest work has been in developing key libraries out of tree. rust-encoding, +one of the most popular crates in Cargo, performs character encoding, and +rust-chrono date / time handling, both of which fill critical holes in the +functionality of the standard library. rust-strconv is a prototype of +efficient numerical string conversions that is a candidate for future inclusion +in the standard library. He maintains a blog where he discusses his +work.
+I nominate Jorge Aparicio (japaric) for Friend of the Tree (for the second time, +no less!). japaric has done tremendous work porting the codebase to use the new +language features that are now available. First, he converted APIs in the +standard library to take full advantage of DST after it landed. Next, he +converted APIs to use unboxed closures. Then, he converted a large portion of +the libraries to use associated types. Finally, he removed boxed closures from +the compiler entirely. He has also worked to roll out RFCs changing the +overloaded operators and comparison traits, including both their definitions and +their impact on the standard library. And this list excludes a number of smaller +changes, like deprecating older syntax. The alpha release would not be where it +is without him; Japaric is simply one of the best friends the tree has ever had.
+This is a belated recognition of Kevin Ballard (aka @kballard, aka Eridius) as a +friend of the tree. Kevin put a lot of work into Unicode issues in Rust, +especially as related to platform-specific constraints. He wrote the current +path module in part to accommodate these constraints, and participated in the +recent redesign of the module. He has also been a dedicated and watchful +reviewer. Thanks, Kevin, for your contributions!
+Gabor’s major contributions to Rust have been in the area of language design. In +the last year he has produced a number of very high quality RFCs, and though +many of them of not yet been accepted, his ideas are often thought-provoking and +have had a strong influence on the direction of the language. His trait based +exception handling RFC was particularly innovative, as well that for +future-proofing checked arithmetic. Gabor is an exceedingly clever +Friend of the Tree.
+In the last few weeks, he has fixed many, many tricky ICEs all over the +compiler, but particularly in the area of unboxed closures and the borrow +checker. He has also completely rewritten how unboxed closures interact with +monomorphization and had a huge impact on making them usable. Brian Koropoff is +truly a Friend of the Tree.
+Alexis Beingessner (aka @Gankra) began contributing to Rust in July, and has +already had a major impact on several library-related areas. Her main focus has +been collections. She completely rewrote BTree, providing a vastly more complete +and efficient implementation. She proposed and implemented the new Entry API. +She’s written extensive new documentation for the collections crate. She pitched +in on collections reform.
+And she added collapse-all to rustdoc!
+Alexis is, without a doubt, a FOTT.
+Jorge has made several high-impact contributions to the wider Rust community. He +is the primary author of rustbyexample.com, and last week published “eulermark”, +a comparison of language performance on project Euler problems, which happily +showed Rust performing quite well. As part of his benchmarking work he has +ported the ‘criterion’ benchmarking framework to Rust.
+Contributing since April 2013. Björn has done many optimizations for Rust,
+including removing allocation bloat in iterators, fmt, and managed boxes;
+optimizing fail!
; adding strategic inlining in the libraries; speeding up data
+structures in the compiler; eliminating quadratic blowup in translation, and
+other IR bloat problems.
He’s really done an amazing number of optimizations to Rust.
+Most recently he earned huge kudos by teaching LLVM about the lifetime of +variables, allowing Rust to make much more efficient use of the stack.
+Björn is a total FOTT.
+Jonas Hietala, aka @treeman, has been contributing a large amount of +documentation examples recently for modules such as hashmap, treemap, +priority_queue, collections, bigint, and vec. He has also additionally been +fixing UI bugs in the compiler such as those related to format!
+Jonas continues to add new examples/documentation every day, making +documentation more approachable and understandable for all newcomers. Jonas +truly is a friend of the tree!
+Sven Nilson has done a great deal of work to build up the Rust crate ecosystem, +starting with the well-regarded rust-empty project that provides boilerplate +build infrastructure and - crucially - integrates well with other tools like +Cargo.
+His Piston project is one of the most promising Rust projects, and its one that +integrates a number of crates, stressing Rust’s tooling at just the right time: +when we need to start learning how to support large-scale external projects.
+Sven is a friend of the tree.
+jakub-, otherwise known as Jakub Wieczorek, has recently been working very hard +to improve and fix lots of match-related functionality, a place where very few +dare to venture! Most of this code appears to be untouched for quite some time +now, and it’s receiving some well-deserved love now.
+Jakub has fixed 10 bugs this month alone, many of which have been long-standing +problems in the compiler. He has also been very responsive in fixing bugs as +well as triaging issues that come up from fun match assertions.
+Jakub truly is a friend of the tree!
+klutzy has been doing an amazing amount of Windows work for years now. He picks +up issues that affect our quality on Windows and picks them off 1 by 1. It’s +tedious and doesn’t get a ton of thanks, but is hugely appreciated by us. As +part of the Korean community, he has also done a lot of work for the local +community there. He is a friend of the tree. Thank you!
+This week’s friend of the tree is Clark Gaebel. He just landed a huge first +contribution to Rust. He dove in and made our hashmaps significantly faster by +implementing Robin Hood hashing. He is an excellent friend of the tree.
+This section is for content that has become outdated, but that we want to keep +available to be read for historical/archival reasons.
+ +This is an archive of Rust release artifacts from 0.1–1.7.0. Each release is +signed with the Rust GPG signing key (older key, even +older key).
+In addition to the included short-form release in the mailing list, each +0.x release has a longer explanation in the release notes.
+This was an OS X bugfix release.
+Redirecting to... /release/backporting.html.
+ + diff --git a/bibliography.html b/bibliography.html new file mode 100644 index 000000000..20527dea3 --- /dev/null +++ b/bibliography.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... https://rustc-dev-guide.rust-lang.org/appendix/bibliography.html.
+ + diff --git a/book.js b/book.js new file mode 100644 index 000000000..627a368e3 --- /dev/null +++ b/book.js @@ -0,0 +1,687 @@ +"use strict"; + +// Fix back button cache problem +window.onunload = function () { }; + +// Global variable, shared between modules +function playground_text(playground) { + let code_block = playground.querySelector("code"); + + if (window.ace && code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + return editor.getValue(); + } else { + return code_block.innerText; + } +} + +(function codeSnippets() { + function fetch_with_timeout(url, options, timeout = 6000) { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) + ]); + } + + var playgrounds = Array.from(document.querySelectorAll(".playground")); + if (playgrounds.length > 0) { + fetch_with_timeout("https://play.rust-lang.org/meta/crates", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + }) + .then(response => response.json()) + .then(response => { + // get list of crates available in the rust playground + let playground_crates = response.crates.map(item => item["id"]); + playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); + }); + } + + function handle_crate_list_update(playground_block, playground_crates) { + // update the play buttons after receiving the response + update_play_button(playground_block, playground_crates); + + // and install on change listener to dynamically update ACE editors + if (window.ace) { + let code_block = playground_block.querySelector("code"); + if (code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + editor.addEventListener("change", function (e) { + update_play_button(playground_block, playground_crates); + }); + // add Ctrl-Enter command to execute rust code + editor.commands.addCommand({ + name: "run", + bindKey: { + win: "Ctrl-Enter", + mac: "Ctrl-Enter" + }, + exec: _editor => run_rust_code(playground_block) + }); + } + } + } + + // updates the visibility of play button based on `no_run` class and + // used crates vs ones available on http://play.rust-lang.org + function update_play_button(pre_block, playground_crates) { + var play_button = pre_block.querySelector(".play-button"); + + // skip if code is `no_run` + if (pre_block.querySelector('code').classList.contains("no_run")) { + play_button.classList.add("hidden"); + return; + } + + // get list of `extern crate`'s from snippet + var txt = playground_text(pre_block); + var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; + var snippet_crates = []; + var item; + while (item = re.exec(txt)) { + snippet_crates.push(item[1]); + } + + // check if all used crates are available on play.rust-lang.org + var all_available = snippet_crates.every(function (elem) { + return playground_crates.indexOf(elem) > -1; + }); + + if (all_available) { + play_button.classList.remove("hidden"); + } else { + play_button.classList.add("hidden"); + } + } + + function run_rust_code(code_block) { + var result_block = code_block.querySelector(".result"); + if (!result_block) { + result_block = document.createElement('code'); + result_block.className = 'result hljs language-bash'; + + code_block.append(result_block); + } + + let text = playground_text(code_block); + let classes = code_block.querySelector('code').classList; + let edition = "2015"; + if(classes.contains("edition2018")) { + edition = "2018"; + } else if(classes.contains("edition2021")) { + edition = "2021"; + } + var params = { + version: "stable", + optimize: "0", + code: text, + edition: edition + }; + + if (text.indexOf("#![feature") !== -1) { + params.version = "nightly"; + } + + result_block.innerText = "Running..."; + + fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + body: JSON.stringify(params) + }) + .then(response => response.json()) + .then(response => { + if (response.result.trim() === '') { + result_block.innerText = "No output"; + result_block.classList.add("result-no-output"); + } else { + result_block.innerText = response.result; + result_block.classList.remove("result-no-output"); + } + }) + .catch(error => result_block.innerText = "Playground Communication: " + error.message); + } + + // Syntax highlighting Configuration + hljs.configure({ + tabReplace: ' ', // 4 spaces + languages: [], // Languages used for auto-detection + }); + + let code_nodes = Array + .from(document.querySelectorAll('code')) + // Don't highlight `inline code` blocks in headers. + .filter(function (node) {return !node.parentElement.classList.contains("header"); }); + + if (window.ace) { + // language-rust class needs to be removed for editable + // blocks or highlightjs will capture events + code_nodes + .filter(function (node) {return node.classList.contains("editable"); }) + .forEach(function (block) { block.classList.remove('language-rust'); }); + + Array + code_nodes + .filter(function (node) {return !node.classList.contains("editable"); }) + .forEach(function (block) { hljs.highlightBlock(block); }); + } else { + code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); + } + + // Adding the hljs class gives code blocks the color css + // even if highlighting doesn't apply + code_nodes.forEach(function (block) { block.classList.add('hljs'); }); + + Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) { + + var lines = Array.from(block.querySelectorAll('.boring')); + // If no lines were hidden, return + if (!lines.length) { return; } + block.classList.add("hide-boring"); + + var buttons = document.createElement('div'); + buttons.className = 'buttons'; + buttons.innerHTML = ""; + + // add expand button + var pre_block = block.parentNode; + pre_block.insertBefore(buttons, pre_block.firstChild); + + pre_block.querySelector('.buttons').addEventListener('click', function (e) { + if (e.target.classList.contains('fa-eye')) { + e.target.classList.remove('fa-eye'); + e.target.classList.add('fa-eye-slash'); + e.target.title = 'Hide lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.remove('hide-boring'); + } else if (e.target.classList.contains('fa-eye-slash')) { + e.target.classList.remove('fa-eye-slash'); + e.target.classList.add('fa-eye'); + e.target.title = 'Show hidden lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.add('hide-boring'); + } + }); + }); + + if (window.playground_copyable) { + Array.from(document.querySelectorAll('pre code')).forEach(function (block) { + var pre_block = block.parentNode; + if (!pre_block.classList.contains('playground')) { + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var clipButton = document.createElement('button'); + clipButton.className = 'fa fa-copy clip-button'; + clipButton.title = 'Copy to clipboard'; + clipButton.setAttribute('aria-label', clipButton.title); + clipButton.innerHTML = ''; + + buttons.insertBefore(clipButton, buttons.firstChild); + } + }); + } + + // Process playground code blocks + Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { + // Add play button + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var runCodeButton = document.createElement('button'); + runCodeButton.className = 'fa fa-play play-button'; + runCodeButton.hidden = true; + runCodeButton.title = 'Run this code'; + runCodeButton.setAttribute('aria-label', runCodeButton.title); + + buttons.insertBefore(runCodeButton, buttons.firstChild); + runCodeButton.addEventListener('click', function (e) { + run_rust_code(pre_block); + }); + + if (window.playground_copyable) { + var copyCodeClipboardButton = document.createElement('button'); + copyCodeClipboardButton.className = 'fa fa-copy clip-button'; + copyCodeClipboardButton.innerHTML = ''; + copyCodeClipboardButton.title = 'Copy to clipboard'; + copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); + + buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); + } + + let code_block = pre_block.querySelector("code"); + if (window.ace && code_block.classList.contains("editable")) { + var undoChangesButton = document.createElement('button'); + undoChangesButton.className = 'fa fa-history reset-button'; + undoChangesButton.title = 'Undo changes'; + undoChangesButton.setAttribute('aria-label', undoChangesButton.title); + + buttons.insertBefore(undoChangesButton, buttons.firstChild); + + undoChangesButton.addEventListener('click', function () { + let editor = window.ace.edit(code_block); + editor.setValue(editor.originalCode); + editor.clearSelection(); + }); + } + }); +})(); + +(function themes() { + var html = document.querySelector('html'); + var themeToggleButton = document.getElementById('theme-toggle'); + var themePopup = document.getElementById('theme-list'); + var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + var stylesheets = { + ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), + tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), + highlight: document.querySelector("[href$='highlight.css']"), + }; + + function showThemes() { + themePopup.style.display = 'block'; + themeToggleButton.setAttribute('aria-expanded', true); + themePopup.querySelector("button#" + get_theme()).focus(); + } + + function updateThemeSelected() { + themePopup.querySelectorAll('.theme-selected').forEach(function (el) { + el.classList.remove('theme-selected'); + }); + themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected'); + } + + function hideThemes() { + themePopup.style.display = 'none'; + themeToggleButton.setAttribute('aria-expanded', false); + themeToggleButton.focus(); + } + + function get_theme() { + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (theme === null || theme === undefined) { + return default_theme; + } else { + return theme; + } + } + + function set_theme(theme, store = true) { + let ace_theme; + + if (theme == 'coal' || theme == 'navy') { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = false; + stylesheets.highlight.disabled = true; + + ace_theme = "ace/theme/tomorrow_night"; + } else if (theme == 'ayu') { + stylesheets.ayuHighlight.disabled = false; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = true; + ace_theme = "ace/theme/tomorrow_night"; + } else { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = false; + ace_theme = "ace/theme/dawn"; + } + + setTimeout(function () { + themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor; + }, 1); + + if (window.ace && window.editors) { + window.editors.forEach(function (editor) { + editor.setTheme(ace_theme); + }); + } + + var previousTheme = get_theme(); + + if (store) { + try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } + } + + html.classList.remove(previousTheme); + html.classList.add(theme); + updateThemeSelected(); + } + + // Set theme + var theme = get_theme(); + + set_theme(theme, false); + + themeToggleButton.addEventListener('click', function () { + if (themePopup.style.display === 'block') { + hideThemes(); + } else { + showThemes(); + } + }); + + themePopup.addEventListener('click', function (e) { + var theme; + if (e.target.className === "theme") { + theme = e.target.id; + } else if (e.target.parentElement.className === "theme") { + theme = e.target.parentElement.id; + } else { + return; + } + set_theme(theme); + }); + + themePopup.addEventListener('focusout', function(e) { + // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) + if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { + hideThemes(); + } + }); + + // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 + document.addEventListener('click', function(e) { + if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { + hideThemes(); + } + }); + + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (!themePopup.contains(e.target)) { return; } + + switch (e.key) { + case 'Escape': + e.preventDefault(); + hideThemes(); + break; + case 'ArrowUp': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.previousElementSibling) { + li.previousElementSibling.querySelector('button').focus(); + } + break; + case 'ArrowDown': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.nextElementSibling) { + li.nextElementSibling.querySelector('button').focus(); + } + break; + case 'Home': + e.preventDefault(); + themePopup.querySelector('li:first-child button').focus(); + break; + case 'End': + e.preventDefault(); + themePopup.querySelector('li:last-child button').focus(); + break; + } + }); +})(); + +(function sidebar() { + var html = document.querySelector("html"); + var sidebar = document.getElementById("sidebar"); + var sidebarLinks = document.querySelectorAll('#sidebar a'); + var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); + var firstContact = null; + + function showSidebar() { + html.classList.remove('sidebar-hidden') + html.classList.add('sidebar-visible'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', 0); + }); + sidebarToggleButton.setAttribute('aria-expanded', true); + sidebar.setAttribute('aria-hidden', false); + try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { } + } + + + var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle'); + + function toggleSection(ev) { + ev.currentTarget.parentElement.classList.toggle('expanded'); + } + + Array.from(sidebarAnchorToggles).forEach(function (el) { + el.addEventListener('click', toggleSection); + }); + + function hideSidebar() { + html.classList.remove('sidebar-visible') + html.classList.add('sidebar-hidden'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', -1); + }); + sidebarToggleButton.setAttribute('aria-expanded', false); + sidebar.setAttribute('aria-hidden', true); + try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { } + } + + // Toggle sidebar + sidebarToggleButton.addEventListener('click', function sidebarToggle() { + if (html.classList.contains("sidebar-hidden")) { + var current_width = parseInt( + document.documentElement.style.getPropertyValue('--sidebar-width'), 10); + if (current_width < 150) { + document.documentElement.style.setProperty('--sidebar-width', '150px'); + } + showSidebar(); + } else if (html.classList.contains("sidebar-visible")) { + hideSidebar(); + } else { + if (getComputedStyle(sidebar)['transform'] === 'none') { + hideSidebar(); + } else { + showSidebar(); + } + } + }); + + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + html.classList.add('sidebar-resizing'); + } + function resize(e) { + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (html.classList.contains("sidebar-hidden")) { + showSidebar(); + } + pos = Math.min(pos, window.innerWidth - 100); + document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + } + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + html.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + + document.addEventListener('touchstart', function (e) { + firstContact = { + x: e.touches[0].clientX, + time: Date.now() + }; + }, { passive: true }); + + document.addEventListener('touchmove', function (e) { + if (!firstContact) + return; + + var curX = e.touches[0].clientX; + var xDiff = curX - firstContact.x, + tDiff = Date.now() - firstContact.time; + + if (tDiff < 250 && Math.abs(xDiff) >= 150) { + if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) + showSidebar(); + else if (xDiff < 0 && curX < 300) + hideSidebar(); + + firstContact = null; + } + }, { passive: true }); + + // Scroll sidebar to current active section + var activeSection = document.getElementById("sidebar").querySelector(".active"); + if (activeSection) { + // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView + activeSection.scrollIntoView({ block: 'center' }); + } +})(); + +(function chapterNavigation() { + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (window.search && window.search.hasFocus()) { return; } + + switch (e.key) { + case 'ArrowRight': + e.preventDefault(); + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + break; + case 'ArrowLeft': + e.preventDefault(); + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + break; + } + }); +})(); + +(function clipboard() { + var clipButtons = document.querySelectorAll('.clip-button'); + + function hideTooltip(elem) { + elem.firstChild.innerText = ""; + elem.className = 'fa fa-copy clip-button'; + } + + function showTooltip(elem, msg) { + elem.firstChild.innerText = msg; + elem.className = 'fa fa-copy tooltipped'; + } + + var clipboardSnippets = new ClipboardJS('.clip-button', { + text: function (trigger) { + hideTooltip(trigger); + let playground = trigger.closest("pre"); + return playground_text(playground); + } + }); + + Array.from(clipButtons).forEach(function (clipButton) { + clipButton.addEventListener('mouseout', function (e) { + hideTooltip(e.currentTarget); + }); + }); + + clipboardSnippets.on('success', function (e) { + e.clearSelection(); + showTooltip(e.trigger, "Copied!"); + }); + + clipboardSnippets.on('error', function (e) { + showTooltip(e.trigger, "Clipboard error!"); + }); +})(); + +(function scrollToTop () { + var menuTitle = document.querySelector('.menu-title'); + + menuTitle.addEventListener('click', function () { + document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); + }); +})(); + +(function controllMenu() { + var menu = document.getElementById('menu-bar'); + + (function controllPosition() { + var scrollTop = document.scrollingElement.scrollTop; + var prevScrollTop = scrollTop; + var minMenuY = -menu.clientHeight - 50; + // When the script loads, the page can be at any scroll (e.g. if you reforesh it). + menu.style.top = scrollTop + 'px'; + // Same as parseInt(menu.style.top.slice(0, -2), but faster + var topCache = menu.style.top.slice(0, -2); + menu.classList.remove('sticky'); + var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster + document.addEventListener('scroll', function () { + scrollTop = Math.max(document.scrollingElement.scrollTop, 0); + // `null` means that it doesn't need to be updated + var nextSticky = null; + var nextTop = null; + var scrollDown = scrollTop > prevScrollTop; + var menuPosAbsoluteY = topCache - scrollTop; + if (scrollDown) { + nextSticky = false; + if (menuPosAbsoluteY > 0) { + nextTop = prevScrollTop; + } + } else { + if (menuPosAbsoluteY > 0) { + nextSticky = true; + } else if (menuPosAbsoluteY < minMenuY) { + nextTop = prevScrollTop + minMenuY; + } + } + if (nextSticky === true && stickyCache === false) { + menu.classList.add('sticky'); + stickyCache = true; + } else if (nextSticky === false && stickyCache === true) { + menu.classList.remove('sticky'); + stickyCache = false; + } + if (nextTop !== null) { + menu.style.top = nextTop + 'px'; + topCache = nextTop; + } + prevScrollTop = scrollTop; + }, { passive: true }); + })(); + (function controllBorder() { + menu.classList.remove('bordered'); + document.addEventListener('scroll', function () { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + }, { passive: true }); + })(); +})(); diff --git a/channel-layout.html b/channel-layout.html new file mode 100644 index 000000000..280ce8cb4 --- /dev/null +++ b/channel-layout.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /infra/channel-layout.html.
+ + diff --git a/chat/discord.html b/chat/discord.html new file mode 100644 index 000000000..17c067673 --- /dev/null +++ b/chat/discord.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/discord.html.
+ + diff --git a/chat/email.html b/chat/email.html new file mode 100644 index 000000000..0f690b21d --- /dev/null +++ b/chat/email.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/email.html.
+ + diff --git a/chat/index.html b/chat/index.html new file mode 100644 index 000000000..d1d4265df --- /dev/null +++ b/chat/index.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/index.html.
+ + diff --git a/chat/zulip.html b/chat/zulip.html new file mode 100644 index 000000000..09fcc2409 --- /dev/null +++ b/chat/zulip.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/zulip.html.
+ + diff --git a/chat/zulip/index.html b/chat/zulip/index.html new file mode 100644 index 000000000..d1df703b7 --- /dev/null +++ b/chat/zulip/index.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/zulip/index.html.
+ + diff --git a/clipboard.min.js b/clipboard.min.js new file mode 100644 index 000000000..02c549e35 --- /dev/null +++ b/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;nThis section documents the processes of the community team, and related projects.
+In this FAQ we try to answer common questions about the Annual State of the Rust Language Community Survey. If in your opinion there is a missing question or if you have a concern about this document, please do not hesitate to contact the Rust Community Team or open an issue with the Community Team.
+Rust is an Open Source project. As such, we want to hear both from people inside and outside our ecosystem about the language, how it is perceived, and how we can make the language more accessible and our community more welcoming. This feedback will give our community the opportunity to participate on shaping the future of the project. We want to focus in the requirements of the language current and potential users to offer a compelling tool for them to solve real world problems in a safe, efficient and modern way.
+In average, it should take from 10 to 15 minutes.
+It includes some basic questions about how do responders use Rust, their opinion the ecosystem’s tools and libraries, some basic questions regarding the responders’ employer or organization and their intention to use Rust, technical background and demographic questions and some feedback related to the Rust project’s community activities and general priorities.
+The answers from the survey will be anonymized, aggregated, and summarized. A high level writeup will be posted to https://blog.rust-lang.org.
+Nearly every question in the survey is optional. You are welcome to share as much or as little information as you are comfortable with. Only the Community Team Survey Leads will have access to the raw data from the survey. All the answers are anonymized prior to be shared with the rest of the teams and prior to the results publication.
+The survey optionally collects contact information for the following cases if you expressed interest in:
+If you would like to be contacted about any of this, or any other concerns, but you don’t want to associate your email with your survey responses, you can instead email the Rust Community Team at community-team@rust-lang.org, and we will connect you to the right people.
+We expect to publish results from the survey within a month or two of the survey completion. The survey results will be posted to project’s blog.
+Redirecting to... https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html.
+ + diff --git a/compiler/cross-compilation/index.html b/compiler/cross-compilation/index.html new file mode 100644 index 000000000..81ee569e2 --- /dev/null +++ b/compiler/cross-compilation/index.html @@ -0,0 +1,182 @@ + + + + + +This subsection documents cross compiling your code on one platform to another.
+ +C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.24728\lib
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3
lib
in
+the above paths with include
to get the appropriate headers.[target.x86_64-pc-windows-msvc] linker = "lld-link"
+or whatever your lld pretending to be link.exe is called.--target=x86_64-pc-windows-msvc
while building. Hopefully it works. If it
+doesn’t, well… I don’t know.If you are a member of another team and would like to raise an issue with the +compiler team..
+Write a comment on a GitHub issue describing the reason for the nomination
+(i.e. what decision needs to be made/what opinion is sought; what are the
+relevant parts to the compiler team, etc) and add the I-compiler-nominated
+label to a issue (you can include @rustbot label +I-compiler-nominated
in
+your comment to do this).
Once nominated, the issue will be discussed in a upcoming triage +meeting. The compiler team doesn’t always get through +all nominated issues each week, so it can take more than one meeting for your +issue to be discussed.
+Once discussed, a member of the team will comment on the issue with the +conclusion of the discussion and linking to the relevant Zulip chat.
+If there is an existing working relationship between a member of the requesting +team and a contributor to the compiler, then the first option that a team has +for requesting tasks be completed is to ping that contributor and ask if they +can complete the task. It is recommended that pings take place in public Zulip +channels so that..
+It is worth considering the available bandwidth of the contributor that the +request is being made of, and whether their areas of expertise in the compiler +are relevant.
+When there is not a appropriate contact in the compiler team to reach out to +directly, write a comment on a GitHub issue (or create an issue) describing the +task that needs completed. Teams should nominate issues for the compiler team +when issues..
+I-prioritize
label and it will be enqueued for prioritization.A detailed description of the feature being requested or the bug to be fixed is +helpful wherever possible (so that the compiler contributor does not need to +make a guess as to a solution that would solve the problem for the requesting +team). If a member of the requesting team isn’t explicitly listed as the +point-of-contact for the issue, then the author of the comment will be assumed +to be the point-of-contact.
+Add the I-compiler-nominated
label to a issue (you can use @rustbot label +I-compiler-nominated
to do this).
Once nominated, the issue will be discussed in a upcoming triage +meeting. The compiler team doesn’t always get through +all nominated issues each week, so it can take more than one meeting for your +issue to be discussed. In the compiler team’s discussion, the issue may..
+Redirecting to... https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-codes.html.
+ + diff --git a/compiler/index.html b/compiler/index.html new file mode 100644 index 000000000..fcd4edaf4 --- /dev/null +++ b/compiler/index.html @@ -0,0 +1,192 @@ + + + + + +This section documents the Rust compiler itself, its APIs, and how to +contribute and provide bug fixes for the compiler.
+FIXME
comments in the Rust compiler.Introduced in RFC 2904, a “major change proposal” is a lightweight
+form of RFC that the compiler team uses for architectural changes that
+are not end-user facing. (It can also be used for small user-facing
+changes like adding new compiler flags, though in that case we also
+require an rfcbot fcp
to get full approval from the team.) Larger
+changes or modifications to the Rust language itself require a full
+RFC (the latter fall under the lang team’s purview).
As the compiler grows in complexity, it becomes harder and harder to track what’s going on. We don’t currently have a clear channel for people to signal their intention to make “major changes” that may impact other developers in a lightweight way (and potentially receive feedback).
+Our goal is to create a channel for signaling intentions that lies somewhere between opening a PR (and perhaps cc’ing others on that PR) and creating a compiler team design meeting proposal or RFC.
+Our goals with the MCP are as follows:
+If you would like to make a major change to the compiler, the process is as follows:
+#t-compiler/major changes
will automatically be created for you by a bot.rfcbot fcp merge
comment.Some major change proposals will be conditionally accepted. This indicates that we’d like to see the work land, but we’d like to re-evaluate the decision of whether to commit to the design after we’ve had time to gain experience. We should try to be clear about the things we’d like to evaluate, and ideally a timeline.
+Some proposals will not be accepted. Some of the possible reasons:
+The PR should be closed or marked as blocked, with a request to create +a major change proposal first.
+If the PR description already contains suitable text that could serve +as an MCP, then simply copy and paste that into an MCP issue. Using an +issue consistently helps to ensure that the tooling and process works +smoothly.
+Of course! You are free to work on PRs or write code. But those PRs should be marked as experimental and they should not land, nor should anyone be expected to review them (unless folks want to).
+The rough intuition is “something that would require updates to the rustc-dev-guide or the rustc book”. In other words:
+Note that, in some cases, the change may be deemed too big and a full FCP or RFC may be required to move forward. This could occur with significant public facing change or with sufficiently large changes to the architecture. The compiler team leads can make this call.
+Note that whether something is a major change proposal is not necessarily related to the number of lines of code that are affected. Renaming a method can affect a large number of lines, and even require edits to the rustc-dev-guide, but it may not be a major change. At the same time, changing names that are very broadly used could constitute a major change (for example, renaming from the tcx
context in the compiler to something else would be a major change).
The MCP “seconding” process is only meant to be used to get agreement
+on the technical architecture we plan to use. It is not sufficient to
+stabilize new features or make public-facing changes like adding a -C
+flag. For that, an rfcbot fcp
is required (or perhaps an RFC, if the
+change is large enough).
For landing compiler flags in particular, a good approach is to start
+with an MCP introducing a -Z
flag and then “stabilize” the flag by
+moving it to -C
in a PR later (which would require rfcbot fcp
).
Major change proposals are not sufficient for language changes or +changes that affect cargo.
+#t-compiler/major changes
:
+Please direct technical conversation to the Zulip stream.
+The compiler-team repo issues are intended to be low traffic and used for procedural purposes. Note that to “second” a design or offer to review, you should be someone who is familiar with the code, typically but not necessarily a compiler team member or contributor.
+These types of procedural comments can be left on the issue (it’s also good to leave a message in Zulip). See the previous section.
+Usually the experts in the given area will reach a consensus here. But if there is some need for a “tie breaker” vote or judgment call, the compiler-team leads make the final call.
+Here are some examples of changes that were made in the past that would warrant the major change process:
+Ty
type-C
flag that exposes some minor variantHere are some examples of changes that are too big for the major change process, or which at least would require auxiliary design meetings or a more fleshed out design before they can proceed:
+Here are some examples of things that don’t merit any MCP:
+Major Change Proposals can be closed:
+This team discusses membership in the compiler team. There are currently two levels of membership:
+People who are looking to contribute to the compiler typically start +in one of two ways. They may tackle “one off” issues, or they may get +involved in some kind of existing working group. They don’t know much +about the compiler yet and have no particular privileges. They are +assigned to issues using the triagebot and (typically) work with a +mentor or mentoring instructions.
+Once a working group participant has been contributing regularly for +some time, they can be promoted to the level of a compiler team +contributor (see the section on how decisions are made +below). This title indicates that they are someone who contributes +regularly.
+It is hard to define the precise conditions when such a promotion is +appropriate. Being promoted to contributor is not just a function of +checking various boxes. But the general sense is that someone is ready +when they have demonstrated three things:
+Being promoted to contributor implies a number of privileges:
+It also implies some obligations (in some cases, optional obligations):
+As a contributor gains in experience, they may be asked to become a +compiler team member. This implies that they are not only a +regular contributor, but are actively helping to shape the direction +of the team or some part of the compiler (or multiple parts).
+Promotion decisions (from participant to contributor, and from
+contributor to member) are made by having an active team member send
+an e-mail to the alias compiler-private@rust-lang.org
. This e-mail
+should include:
Compiler-team members should send e-mail giving their explicit assent, +or with objections. Objections should always be resolved before the +decision is made final. E-mails can also include edits or additions for the +public announcement.
+To make the final decision:
+We do not require all team members to send e-mail, as historically +these decisions are not particularly controversial. For promotion to a +contributor, the only requirement is that the compiler team lead +agrees. For promotion to a full member, more explicit mails in favor +are recommended.
+Once we have decided to promote, then the announcement can be posted +to internals, and the person added to the team repository.
+It is worth emphasizing that becoming a contributor or member of the +compiler team does not necessarily imply writing PRs. There are a wide +variety of tasks that need to be done to support the compiler and +which should make one eligible for membership. Such tasks would +include organizing meetings, participating in meetings, bisecting and +triaging issues, writing documentation, working on the rustc-dev-guide. +The most important criteria for elevation to contributor, +in particular, is regular and consistent participation. The most +important criteria for elevation to member is actively shaping the +direction of the team or compiler.
+If at any time a current contributor or member wishes to take a break +from participating, they can opt to put themselves into alumni status. +When in alumni status, they will be removed from Github aliases and +the like, so that they need not be bothered with pings and messages. +They will also not have r+ privileges. Alumni members will however +still remain members of the GitHub org overall.
+People in alumni status can ask to return to “active” status at any +time. This request would ordinarily be granted automatically barring +extraordinary circumstances.
+People in alumni status are still members of the team at the level +they previously attained and they may publicly indicate that, though +they should indicate the time period for which they were active as +well.
+If desired, a team member may also ask to move back to contributor +status. This would indicate a continued desire to be involved in +rustc, but that they do not wish to be involved in some of the +weightier decisions, such as who to add to the team. Like full alumni, +people who were once full team members but who went back to +contributor status may ask to return to full team member status. This +request would ordinarily be granted automatically barring +extraordinary circumstances.
+If a contributor or a member has been inactive in the compiler for 6 +months, then we will ask them if they would like to go to alumni +status. If they respond yes or do not respond, they can be placed on +alumni status. If they would prefer to remain active, that is also +fine, but they will get asked again periodically if they continue to +be inactive.
+ +So you want to add a new command-line flag to rustc. What is the procedure?
+The first question to ask yourself is:
+-Ztreat-err-as-bug
)?If so, you can just add it in a PR, no check-off is required beyond ordinary review.
+If this option is meant to be used by end-users or to be exposed on the stable channel, however, it represents a “public commitment” on the part of rustc that we will have to maintain, and hence there are a few more details to take care of.
+There are two main things to take care of, and they can proceed in either order, but both must be completed:
+Finally, some options begin as unstable and only get stabilized over time, in which case you will also need:
+The “proposal” part describes the motivation and design of the new option you wish to add. It doesn’t necessarily have to be very long. It takes the form of a Major Change Proposal.
+The proposal should include the following:
+Note that it is fine if you don’t have any implementation notes, precedent, or alternatives to discuss.
+Also, one good approach to writing the MCP is basically to write the documentation you will have to write anyway to explain to users how the option works, and then add any additional notes on alternatives and so forth that are required.
+Once you’ve written up the proposal, you can open a MCP issue. But note that since this MCP is promoting a permanent change, a full compiler-team FCP is required, and not just a “second”. This can be done by @rfcbot fcp merge
by a team member.
Naturally your new option will also have to be implemented. You can implement the option and open up a PR. Often, this implementation work actually happens before the MCP is created, and that’s fine – we’ll just ask you to open an MCP with the write-up.
+See the Command-line Arguments chapter in the rustc dev guide for guidelines on how to name and define a new argument.
+A few notes that are sometimes overlooked:
+-Z
or because they require -Zunstable-options
to use.Typically options begin as unstable, meaning that they are either used with -Z
or require -Zunstable-options
.
Once the issue lands we should create a tracking issue that links to the MCP and where stabilization can be proposed.
+Stabilization generally proceeds when the option has a seen a bit of use and the implementation seems to be working as expected for its intended purpose.
+Remember that when stabilization occurs, documentation should be moved from the Unstable Book to the Rustc Book.
+ +The compiler team has a number of notification groups that we use to +ping people and draw their attention to issues. Notification groups +are setup so that anyone can join them if they want.
+If you’d like to create a notification group, here are the steps. +First, you want to get approval from the compiler team:
+O-Windows
.Once the MCP is accepted, here are the steps to actually create the group. +In some cases we include an example PR from some other group.
+This section documents the processes of the prioritization WG.
+ +As the compiler team’s resources are limited, the prioritization working group’s main goal is to identify the most relevant issues to work on, so that the compiler team can focus on what matters the most.
+issue
refers to bugs and feature requests that are nominated for prioritization, by flagging the I-prioritize
label as described below.
This document will define what each label means, and what strategy for each label will be used.
+Labeling an issue as I-prioritize
starts the prioritization process, which will end by removing the I-prioritize
label and appending one of the 4 labels we will discuss below:
Each of these labels defines a strategy the team will adopt regarding:
+A P-critical
issue is a potentially blocker issue.
The Working Group will keep track of these issues and will remind the compiler team on a weekly basis during the triage meeting.
+Examples of things we typically judge to be “critical” bugs:
+std::vec::Vec
docs state order in which it drops its elements is subject to change)A P-critical issue will receive the most attention. It must be assigned one or several people as soon as possible, and the rest of the team should do their best to help them out if/when applicable.
+P-high
issues are issues that need attention from the compiler team, but not to the point that they need to be discussed at every meeting.
+They can be P-critical
issues that have a mitigating condition as defined above, or important issues that aren’t deemed blockers.
Because there are too many P-high
issues to fit in every compiler meeting, they should rather be handled asynchronously by the Prioritization WG, in order to help them move forward. They can still occasionally be brought up at meetings when it is deemed necessary.
The effectiveness of the Prioritization WG will be a direct consequence of our ability to draw the line between P-critical
and P-high
issues. There shouldn’t be too many P-critical
issues that compiler meetings become unmanageable, but critical issues shouldn’t get lost in the list of P-high issues.
P-high issues are issues the teams will mostly work on. We want to make sure they’re assigned, and keep an eye on them.
+P-medium
refer to issues that aren’t a priority for the team, and that will be resolved in the long run. Eg issues that will be fixed after a specific feature has landed.
+They are issues we would mentor someone interested in fixing.
+They will remain in this state until someone complains, a community member fixes it, or it gets fixed by accident.
P-low
refer to issues issue that the compiler team doesn’t plan to resolve, but are still worth fixing.
This document details the procedure the WG-prioritization follows to fill the agenda for the weekly meeting of T-compiler
.
+The working group focuses mainly on triaging T-compiler
regressions, identifying possibly critical (and thus potential release blocker) issues and building the agenda for the weekly T-compiler
meeting summarizing the main points to be discussed.
regression-*
labels)A-*
labels)The T-compiler
agenda is generated from a template (available on HackMD or Github). We suggest working the following steps in this order:
T-compiler
labels where appropriateI-prioritize
I-compiler-nominated
(i.e. needing a T-compiler discussion)P-high
Regressions labeled with I-prioritize
are signaling that a priority assessment is waiting. When this label is added to an issue, the triagebot
creates automatically a notification for @WG-prioritization members on the Zulip stream.
To assign a priority, we replace the I-prioritize
label with one of P-critical
, P-high
, P-medium
or P-low
and adding a succinct comment to link the Zulip discussion where the issue prioritization occurred, example of a template for the comment:
++WG-prioritization assigning priority (Zulip discussion).
+@rustbot label -I-prioritize +P-XXX
+
Ideally, we want all T-compiler
issues with a I-prioritize
label to have a priority assigned, or strive to reach this goal: sometimes different factors are blocking issues from being assigned a priority label, either because the report or the context is unclear or because cannot be reproduced and an MCVE would help. Don’t hesitate to ask for clarifications to the issue reporter or ping the ICEbreaker
team when an ICE (“Internal Compiler Errors”) needs a reduction (add a comment on the issue with @rustbot ping icebreakers-cleanup-crew
)
Keep an eye also on regressions (stable, beta and nightly), ideally they should an assignee.
+An MCP is a Major Change Proposal, in other words a change to the rust compiler that needs a bit more thought and discussion within the compiler team than a pull request. The life cycle of an MCP is described in the documentation. The relevant part for the WG-Prioritization is keeping an eye on them and accept all MCPs that have been on final-comment-period
for 10 or more days.
To accept an MCP, remove final-comment-period
label, add major-change-accepted
label and close the issue. A notification to the relevant Zulip topic (in this stream) will be automatically sent by the triagebot
.
Run triagebot’s CLI to generate the agenda. You need to clone https://github.com/rust-lang/triagebot (there is no official prepackaged release for this tool) and export two environment variables: GITHUB_API_TOKEN
and optionally a GOOGLE_API_KEY
to access a public Google calendar (if this env var is not found, meetings should be manually copy&pasted from here).
To generate the meeting’s agenda, run:
+$ cargo run --bin prioritization-agenda
+
+Copy the content of the generated agenda on HackMD. This will be our starting point.
+Paste the markdown file of this week performance triage logs to the agenda and clean it up a little bit removing emojis (to make the text readable when pasted on Zulip).
+About two hours before the scheduled meeting, create a new topic on the Zulip stream #t-compiler/meetings
titled “[weekly] YYYY-MM-DD” using the the following message template:
Hi @*T-compiler/meeting*; the triage meeting will happen tomorrow in about 2 hours.
+*WG-prioritization* has done pre-triage in #**t-compiler/wg-prioritization/alerts**
+@*WG-prioritization* has prepared the [meeting agenda](link_to_hackmd_agenda)
+
+Working group checkins for today:
+- @**WG-foo** by @**person1**
+- @**WG-bar** by @**person2**
+
+Working Group checkins rotation are generated by a script at this page (TODO: script is outdated and could probably be merged into the triagebot
CLI code).
Checkins about the progress of working groups are not mandatory but we rotate them all to be sure we don’t miss on important progresses.
+These are pull requests that the compiler team might want to backport to a release channel. Example a stable-to-beta-regression
fix might want to be backported to the beta release channel. A stable-to-stable-regression
fix particularly annoying might warrant a point release (i.e. release a 1.67.1
after a 1.67.0
).
Follow the General issues review process.
+These are pull requests waiting on a discussion / decision from T-compiler
(sometimes more than one team).
Try to follow the General issues review process. Explicitly nominate any issue that can be quickly resolved in a triage meeting.
+This is probably the less automatable part of the agenda (and likely the least fun). The triagebot
will emit a list of 50 pull requests ordering them by least recent update. The idea is to issue mentions to assigned reviewers during the meeting ensuring that they stay on top of them. We usually try to keep the number of these mentions to around 5 for each meeting.
There are two human factors here to keep in consideration:
+Striking a balance between these two diverging forces requires some empathy and “tribal knowledge” that comes with practice. Other factors can be blocking a pull request progress:
+S-waiting-on-review
and S-waiting-on author
handling the life cycle of a pull request are not promptly applied. A pull request that is ready to be reviewed but it’s not labeled S-waiting-on-review
is idling for no purpose.P-critical
and P-high
regressions without an assigneeTry to follow the General issues review process.
+Issues labeled with I-compiler-nominated
generally are nominated to specifically have the compiler team dedicate them a special slice of the meeting (generally towards the end). After the discussion, add a comment on Github linking the Zulip message where the discussion started (so everyone can read). T-compiler
sometimes writes a summary of the discussion on the issue itself.
Try to follow the General issues review process:
+I-compiler-nominated
Re-run the triagebot CLI script and update the agenda on HackMD with new data (if any). This is useful when there are last second changes affecting the agenda content.
+The meeting is over! Time to cleanup a little bit.
+Lock the agenda file on HackMD assigning write permissions to Owners
. Download the markdown file and commit it to this repository.
Remove the to-announce
label from MCPs, unless this label was added exactly during the meeting (and therefore will be seen during the following meeting).
Remove to-announce
FCPs from rust repo, compiler-team repo and forge repo, same disclaimer as before.
Accept or decline beta nominated
and stable nominated
backports that have been accepted during the meeting. For more info check T-release backporting docs
{beta,stable}-accepted
label and keep the {beta,stable}-nominated
label. Other automated procedures will process these pull requests, it’s important to leave both labels. Add a comment on Github linking the Zulip discussion.{beta,stable}-nominated
label. Add a comment on Github explaining why the backport was declined and link the Zulip discussion.Remove I-compiler-nominated
label from issues that were discussed. Sometimes not all nominated issues are discussed (because of time constraints). In this case the I-compiler-nominated
will stick until next meeting.
Create a new agenda stub for the following week using our template and post the link on Zulip, so it’s available for people if they want to add content during the week.
+Redirecting to... https://rustc-dev-guide.rust-lang.org/queries/profiling.html.
+ + diff --git a/compiler/revert-button.png b/compiler/revert-button.png new file mode 100644 index 000000000..7868a5335 Binary files /dev/null and b/compiler/revert-button.png differ diff --git a/compiler/reviews.html b/compiler/reviews.html new file mode 100644 index 000000000..3b5c6e269 --- /dev/null +++ b/compiler/reviews.html @@ -0,0 +1,377 @@ + + + + + +Every PR that lands in the compiler and its associated crates must be +reviewed by at least one person who is knowledgeable with the code in +question.
+When a PR is opened, you can request a reviewer by including r? @username
in the PR description. If you don’t do so, rustbot
+will automatically assign someone.
It is common to leave a r? @username
comment at some later point to
+request review from someone else. This will also reassign the PR.
We never merge PRs directly. Instead, we use bors. A qualified
+reviewer with bors privileges (e.g., a compiler
+contributor) will leave a comment like @bors r+
.
+This indicates that they approve the PR.
People with bors privileges may also leave a @bors r=username
+command. This indicates that the PR was already approved by
+@username
. This is commonly done after rebasing.
Finally, in some cases, PRs can be “delegated” by writing @bors delegate+
or @bors delegate=username
. This will allow the PR author
+to approve the PR by issuing @bors
commands like the ones above
+(but this privilege is limited to the single PR).
If a merged PR is found to have caused a meaningful unanticipated regression, +the best policy is to revert it quickly and re-land it later once a fix and +regression test are added.
+A “meaningful regression” in this case is up to the judgment of the person +approving the revert. As a rule of thumb, this would be a bug in a stable +or otherwise important feature that causes code to stop compiling, changes +runtime behavior, or triggers a (warn-by-default or higher) lint incorrectly in +real-world code.
+When these criteria are in doubt, and especially if real-world code is affected, +revert the PR. This allows bleeding edge users to continue to use and report +bugs on HEAD with a higher degree of certainty about where new bugs are introduced.
+Before being reverted, a PR should be shown to cause a regression with a fairly +high degree of certainty (e.g. bisection on commits, or bisection on nightlies +with one or more compiler team members pointing to this PR, or it’s simply +obvious to everyone involved). Only revert with lower certainty if the issue is +particularly critical or urgent to fix.
+The easiest method for creating a revert is to use the “Revert” button on +Github. This appears next to the “bors merged commit abcd” message on a pull +request, and creates a new pull request.
+ +Alternatively, a revert commit can be created using the git CLI and then +uploaded as a pull request:
+$ git revert -m 1 62d5bee
+
+It’s polite to tag the author and reviewer of the original PR so they know +what’s going on. You can use the following message template:
+Reverts rust-lang/rust#123456
+cc @author @reviewer
+
+This revert is based on the following report of a regression caused by this PR:
+<link to issue or comment(s)>
+
+In accordance with the compiler team [revert policy], PRs that cause meaningful
+regressions should be reverted and re-landed once the regression has been fixed
+(and a regression test has been added, where appropriate).
+[revert policy]: https://forge.rust-lang.org/compiler/reviews.html#reverts
+
+Fear not! Regressions happen. Please rest assured that this does not
+represent a negative judgment of your contribution or ability to contribute
+positively to Rust in the future. We simply want to prioritize keeping existing
+use cases working, and keep the compiler more stable for everyone.
+
+r? compiler
+
+If you have r+ privileges, you can self-approve a revert.
+Generally speaking, reverts should have elevated priority and match the rollup
+status of the PR they are reverting. If a non-rollup PR is shown to have no
+impact on performance, it can be marked rollup=always
.
Often it is tempting to address a regression by posting a follow-up PR that, +rather than reverting the regressing PR, instead augments the original in +small ways without reverting its changes overall. However, if real-world users +have reported being affected, this practice is strongly discouraged unless one +of the following is true:
+r+
it.While it can feel like a significant step backward to have your PR reverted, in +most cases it is much easier to land the PR a second time once a fix can be +confirmed. Allowing a revert to land takes pressure off of you and your +reviewers to act quickly and gives you time to address the issue fully.
+All reviewers are strongly encouraged to explicitly mark a PR as to whether or +not it should be part of a rollup with one of the following:
+rollup=always
: These PRs are very unlikely to break tests or have performance
+implications. Example scenarios:
+rollup=maybe
: This is the default if you do not specify a rollup
+status. Use this if you don’t have much confidence that it won’t break
+tests. This can be used if you aren’t sure if it should be one of the other
+categories. Since this is the default, there is usually no need to
+explicitly specify this, unless you are un-marking the rollup level from a
+previous command.rollup=iffy
: Use this for mildly risky PRs (more risky than “maybe”).
+Example scenarios:
+rollup=never
: This should never be included in a rollup (please
+include a comment explaining why you have chosen this). Example scenarios:
+++Note:
+
+@bors rollup
is equivalent to@bors rollup=always
+@bors rollup-
is equivalent to@bors rollup=never
Reviewers are encouraged to set one of the rollup statuses listed above +instead of setting priority. Bors automatically sorts based on the rollup +status (never is the highest priority, always is the lowest), and also by PR +age. If you do change the priority, please use your best judgment to balance +fairness with other PRs.
+The following is some guidance for setting priorities:
+bors privileges are binary: the bot doesn’t know which code you are +familiar with and what code you are not. They must therefore be used +with discretion. Do not r+ code that you do not know well – you can +definitely review such code, but try to hand off reviewing to +someone else for the final r+.
+Similarly, never issue a r=username
command unless that person has
+done the review, and the code has not changed substantially since the
+review was done. Rebasing is fine, but changes in functionality
+typically require re-review (though it’s a good idea to try and
+highlight what has changed, to help the reviewer).
The “steering meeting” is a weekly meeting dedicated to planning and +high-level discussion. The meeting operates on a repeating schedule:
+The first meeting of the 4-week cycle is used for planning. The +primary purpose of this meeting is to select the topics for the next +three meetings. The topics are selected from a set of topic +proposals, which must be uploaded and available for perusal before the +meeting starts. The planning meeting is also an opportunity to check +on the “overall balance” of our priorities.
+The remaining meetings are used for design or general discussion. +Weeks 2 and 3 can be used for technical or non-technical +discussion; it is also possible to use both weeks to discuss the same +topic, if that topic is complex. Week 4 is reserved for +non-technical topics, so as to ensure that we are keeping an eye on +the overall health and functioning of the team.
+The team accepts proposals via an open submission process, +which is documented on its own page
+After each planning meeting, the topics for the next three weeks are +added to the compiler-team meeting calendar and a blog post is +posted to the Inside Rust blog.
+See the compiler team meeting calendar for the canonical date and +time. The meetings take place in the #t-compiler stream on the +rust-lang Zulip.
+ +design meeting YYYY.MM.DD
topic
+@t-compiler/meeting
, ideally 1h or so before the meeting actually starts,
+to remind people@t-compiler/meeting
to let people know the meeting is startingTo guide the meeting, create a shared hackmd document everyone can +view (or adapt an existing one, if there is a write-up). Use this to +help structure the meeting, document consensus, and take live +notes. Try to ensure that the meeting ends with sort of consensus +statement, even if that consensus is just “here are the problems, here +is a space of solutions and their pros/cons, but we don’t have +consensus on which solution to take”.
+minutes/design-meeting
directory in the compiler-team
+repositorydesign meeting YYYY.MM.DD
topic
+@t-compiler/meeting
, ideally 1h or so before the meeting actually starts,
+to remind people@t-compiler/meeting
to let people know the meeting is startingTo actually make the final selection, we recommend
+For each scheduled meeting, create a calendar event:
+#t-compiler, Zulip
In the relevant issues, add the meeting-scheduled
label and add a
+message like:
In today's [planning meeting], we decided to schedule this meeting for **DATE**.
+
+[Calendar event]
+
+[planning meeting]: XXX link to Zulip topic
+[Calendar event]: XXX link to calendar event
+
+You can get the link to the calendar event by clicking on the event in +google calendar and selecting “publish”.
+Add a blog post to the Inside Rust blog using the template found on +the compiler-team repository.
+ +If you would like to submit a proposal to the steering meeting for +group discussion, read on! This page has all the details.
+In short, all you have to do is
+You don’t have to have a lot of details to start: just a few sentences +is enough. But, especially for technical design discussions, we will +typically expect that some form of more detailed overview be made +available by the time the meeting takes place.
+Here are some examples of possible technical topics that would be +suitable for the steering meeting:
+Steering meetings are also a good place to discuss other kinds of proposals:
+Note that a steering meeting is not required to create a new +working group or an out-of-tree crate, but it can be useful if the +proposal is complex or controversial, and you would like a dedicated +time to talk out the plans in more detail.
+When deciding the topics for upcoming meetings, we must balance a number of things:
+It is perfectly acceptable to choose not to schedule a particular +slot. This could happen if (e.g.) there are no proposals available or +if nothing seems important enough to discuss at this moment. Note +that, to keep the “time expectations” under control, we should +generally stick to the same 4-week cycle and simply opt to skip +meetings, rather than (e.g.) planning things at the last minute.
+Proposals can be added by opening an issue on the compiler-team +repository. There is an issue template for meeting +proposals that gives directions. The basic idea is that you open an +issue with a few sentences describing what you would like to talk +about.
+Some details that might be useful to include:
+By the time the meeting takes place, we generally would prefer to have +a more detailed write-up or proposal. You can find a template for +such a proposal here. This should be created in the form of a hackmd +document – usually we will then update this document with the minutes +and consensus from the meeting. The final notes are then stored in the +minutes directory of the compiler-team repository.
+The requirements for non-technical proposals are somewhat looser. A +few sentences or paragraphs may well suffice, if it is sufficient to +understand the aims of the discussion.
+What happens if there are not enough proposals? As noted above, +meetings are not mandatory. If there aren’t enough proposals in some +particular iteration, then we can just opt to not discuss anything.
+ +The triage meeting is a weekly meeting where we go over the open +issues, look at regressions, consider beta backports, and other such +business. In the tail end of the meeting, we also do brief check-ins +with active working groups to get an idea what they’ve been working +on.
+See the compiler team meeting calendar for the canonical date and +time. The meetings take place in the #t-compiler stream on the +rust-lang Zulip.
+The meeting procedure is documented in rust-lang/rust#54818.
+The working group check-in schedule is available on the compiler-team website.
+ +Redirecting to... /platforms/blogs.html.
+ + diff --git a/core/index.html b/core/index.html new file mode 100644 index 000000000..8203f6fb9 --- /dev/null +++ b/core/index.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /governance/council.html.
+ + diff --git a/crates-io/crate-removal.html b/crates-io/crate-removal.html new file mode 100644 index 000000000..a0bc95349 --- /dev/null +++ b/crates-io/crate-removal.html @@ -0,0 +1,229 @@ + + + + + +If we get a DMCA takedown notice, here’s what needs to happen:
+Before removing the crates, get in touch with legal support, +and ask an opinion from them on the received request and +whether we have to comply with it.
+Remove it from the database:
+heroku run -a crates-io -- target/release/crates-admin delete-crate [crate-name]
+
+or
+heroku run -a crates-io -- target/release/crates-admin delete-version [crate-name] [version-number]
+
+Remove the crate or version from the index. To remove an entire crate, remove +the entire crate file. For a version, remove the line corresponding to the +relevant version.
+Remove the crate archive(s) and readme file(s) from S3.
+Invalidate the CloudFront cache:
+aws cloudfront create-invalidation --distribution-id EJED5RT0WA7HA --paths '/*'
+
+The docs.rs application supports deleting all the documentation ever published +of a crate, by running a CLI command. The people who currently have permissions +to access the server and run it are:
+You can find the documentation on how to run the command here.
+ +There are times when Heroku needs to perform a maintenance on our database +instances, for example to apply system updates or upgrade to a newer database +server.
+We must not let Heroku run maintenances during the maintenance window to +avoid disrupting production users (move the maintenance window if necessary). +This page contains the instructions on how to perform the maintenance with the +minimum amount of disruption.
+Performing maintenance on the primary database requires us to temporarily put +the application in read-only mode. Heroku performs maintenances by creating a +hidden database follower and switching over to it, so we need to prevent writes +on the primary to let the follower catch up.
+Maintenance should take less than 5 minutes of read-only time, but we should +still announce it ahead of time on our status page. This is a sample message we +can use:
+++The crates.io team will perform a database maintenance on YYYY-MM-DD from +hh:mm to hh:mm UTC.
+We expect this to take less than 5 minutes to complete. During maintenance +crates.io will only be available in read-only mode: downloading crates and +visiting the website will still work, but logging in, publishing crates, +yanking crates or changing owners will not work.
+
1 hour before the maintenance
+5 minutes before the maintenance
+Scale the background worker to 0 instances:
+heroku ps:scale -a crates-io background_worker=0
+
+At the start of the maintenance
+Update the status page with this message:
+++Scheduled maintenance on our database is starting.
+We expect this to take less than 5 minutes to complete. During maintenance +crates.io will only be available in read-only mode: downloading crates and +visiting the website will still work, but logging in, publishing crates, +yanking crates or changing owners will not work.
+
Configure the application to be in read-only mode without the follower:
+heroku config:set -a crates-io READ_ONLY_MODE=1 DB_OFFLINE=follower
+
+The follower is removed because while Heroku tries to prevent connections to +the primary database from failing during maintenance we observed that the +same does not apply to the follower database, and there could be brief +periods while the follower is not available.
+Wait for the application to be redeployed with the new configuration:
+heroku ps:wait -a crates-io
+
+Run the database maintenance:
+heroku pg:maintenance:run --force -a crates-io
+
+Wait for the maintenance to finish:
+heroku pg:wait -a crates-io
+
+Confirm all the databases are online:
+heroku pg:info -a crates-io
+
+Confirm the primary database fully recovered (should output false
):
echo "SELECT pg_is_in_recovery();" | heroku pg:psql -a crates-io DATABASE
+
+Switch off read-only mode:
+heroku config:unset -a crates-io READ_ONLY_MODE
+
+WARNING: the Heroku Dashboard’s UI is misleading when removing an +environment variable. A red badge with a “-” (minus) in it means the +variable was successfully removed, it doesn’t mean removing the variable +failed. Failures are indicated with a red badge with a “x” (cross) in it.
+Wait for the application to be redeployed with the new configuration:
+heroku ps:wait -a crates-io
+
+Update the status page and mark the maintenance as completed with this +message:
+++Scheduled maintenance finished successfully.
+
The message is posted right now and not at the end because this is when +production users are not impacted by the maintenance anymore.
+Scale the background worker up again:
+heroku ps:scale -a crates-io background_worker=1
+
+Confirm the follower database is available:
+echo "SELECT 1;" | heroku pg:psql -a crates-io READ_ONLY_REPLICA
+
+Enable connections to the follower:
+heroku config:unset -a crates-io DB_OFFLINE
+
+Re-enable the background job disabled during step 1.
+Performing maintenance on the follower database doesn’t require any external +communication nor putting the application in read-only mode, as we can just +redirect all of the follower’s traffic to the primary database. It shouldn’t be +done during peak traffic periods though, as we’ll increase the primary database +load by doing this.
+At the start of the maintenance
+Configure the application to operate without the follower:
+heroku config:set -a crates-io DB_OFFLINE=follower
+
+Wait for the application to be redeployed with the new configuration:
+heroku ps:wait -a crates-io
+
+Start the database maintenance:
+heroku pg:maintenance:run --force -a crates-io READ_ONLY_REPLICA
+
+Wait for the maintenance to finish:
+heroku pg:wait -a crates-io READ_ONLY_REPLICA
+
+Confirm the follower database is ready:
+heroku pg:info -a crates-io
+
+Confirm the follower database is responding to queries:
+echo "SELECT 1;" | heroku pg:psql -a crates-io READ_ONLY_REPLICA
+
+Enable connections to the follower:
+heroku config:unset -a crates-io DB_OFFLINE
+
+Wait for the application to be redeployed with the new configuration.
+heroku ps:wait -a crates-io
+
+This section documents the processes of the crates.io team.
+ +Redirecting to... https://rustc-dev-guide.rust-lang.org/compiler-debugging.html.
+ + diff --git a/docs-rs/add-dependencies.html b/docs-rs/add-dependencies.html new file mode 100644 index 000000000..7bb9aad8a --- /dev/null +++ b/docs-rs/add-dependencies.html @@ -0,0 +1,250 @@ + + + + + +Rustwide internally uses rustops/crates-build-env
as the build environment for the crate. If you want to add a system package for crates to link to, this is place you’re looking for.
Docker and docker-compose must be installed. For example, on Debian or Ubuntu:
+sudo apt-get install docker.io docker-compose
+
+First, clone the crates-build-env and the docs.rs repos:
+git clone https://github.com/rust-lang/crates-build-env
+git clone https://github.com/rust-lang/docs.rs
+
+Set the path to the directory of your crate. This must be an absolute path, not a relative path! On platforms with coreutils, you can instead use $(realpath ../relative/path)
(relative to the docs.rs directory).
YOUR_CRATE=/path/to/your/crate
+
+Next, add the package to crates-build-env/linux/packages.txt
in the correct alphabetical order. This should be the name of a package in the Ubuntu 20.04 Repositories. See the package home page for a full list/search bar, or use apt search
locally.
Now build the image. This will take a very long time, probably 10-20 minutes.
+cd crates-build-env/linux
+docker build --tag build-env .
+
+Use the image to build your crate.
+cd ../../docs.rs
+cp .env.sample .env
+docker-compose build
+# avoid docker-compose creating the volume if it doesn't exist
+if [ -e "$YOUR_CRATE" ]; then
+ docker-compose run -e DOCSRS_DOCKER_IMAGE=build-env \
+ -e RUST_BACKTRACE=1 \
+ -v "$YOUR_CRATE":/opt/rustwide/workdir \
+ web build crate --local /opt/rustwide/workdir
+else
+ echo "$YOUR_CRATE does not exist";
+fi
+
+If your build fails even after your changes, it will be annoying to rebuild the image from scratch just to add a single package. Instead, you can make changes directly to the Dockerfile so that the existing packages are cached. Be sure to move these new packages from the Dockerfile to packages.txt
once you are sure they work.
On line 7 of the Dockerfile, add this line: RUN apt-get install -y your_second_package
.
+Rerun the build and start the container; it should take much less time now:
cd ../crates-build-env/linux
+docker build --tag build-env .
+cd ../../docs.rs
+docker-compose run -e DOCSRS_DOCKER_IMAGE=build-env \
+ -e RUST_BACKTRACE=1 \
+ -v "$YOUR_CRATE":/opt/rustwide/workdir \
+ web build crate --local /opt/rustwide/workdir
+
+Before you make a PR, run the shell script lint.sh
and make sure it passes. It ensures packages.txt
is in order and will tell you exactly what changes you need to make if not.
cd ../crates-build-env
+./lint.sh
+
+Once you are sure your package builds, you can make a pull request to get it adopted upstream for docs.rs and crater. Go to https://github.com/rust-lang/crates-build-env and click ‘Fork’ in the top right. Locally, add your fork as a remote in git and push your changes:
+git remote add personal https://github.com/<your_username_here>/crates-build-env
+git add -u
+git commit -m 'add packages necessary for <your_package_here> to compile'
+git push personal
+
+Back on github, make a pull request:
+Hopefully your changes will be merged quickly! After that you can either publish a point release (rebuilds your docs immediately) or request for a member of the docs.rs team to schedule a new build (may take a while depending on their schedules).
+ +docs.rs is a website that hosts documentation for crates published to crates.io.
+docsrs.infra.rust-lang.org
(behind the bastion – how to connect)It might happen that a crate fails to build repeatedly due to a docs.rs bug, +clogging up the queue and preventing other crates to build. In this case it’s +possible to temporarily remove the crate from the queue until the docs.rs’s bug +is fixed. To do that, log into the machine and open a PostgreSQL shell with:
+$ psql
+
+Then you can run this SQL query to remove the crate:
+UPDATE queue SET attempt = 100 WHERE name = '<CRATE_NAME>';
+
+To add the crate back in the queue you can run in the PostgreSQL shell this +query:
+UPDATE queue SET attempt = 0 WHERE name = '<CRATE_NAME>';
+
+Sometimes the latest nightly might be broken, causing doc builds to fail. In
+those cases it’s possible to tell docs.rs to stop updating to the latest
+nightly and instead pin a specific release. To do that you need to edit the
+/home/cratesfyi/.docs-rs-env
file, adding or changing this environment
+variable:
CRATESFYI_TOOLCHAIN=nightly-YYYY-MM-DD
+
+Once the file changed docs.rs needs to be restarted:
+systemctl restart docs.rs
+
+To return to the latest nightly simply remove the environment variable and +restart docs.rs again.
+If a bug was recently fixed, you may want to rebuild a crate so that it builds with the latest version. +From the docs.rs machine:
+cratesfyi queue add <crate> <version>
+
+This will add the crate with a lower priority than new crates by default, you can change the priority with the -p
option.
Occasionally crates will ask for their build limits to be raised.
+You can raise them from the docs.rs machine with psql
.
Raising a memory limit to 8 GB:
+# memory is measured in bytes
+cratesfyi=> INSERT INTO sandbox_overrides (crate_name, max_memory_bytes)
+ VALUES ('crate name', 8589934592);
+
+Raising a timeout to 15 minutes:
+cratesfyi=> INSERT INTO sandbox_overrides (crate_name, timeout_seconds)
+ VALUES ('crate name', 900);
+
+Raising limits for multiple crates at once:
+cratesfyi=> INSERT INTO sandbox_overrides (crate_name, max_memory_bytes)
+ VALUES ('stm32f4', 8589934592), ('stm32h7', 8589934592), ('stm32g4', 8589934592);
+
+When many crates from the same project are published at once, they take up a +lot of space in the queue. You can de-prioritize groups of crates at once like +this:
+cratesfyi=> INSERT INTO crate_priorities (pattern, priority)
+ VALUES ('group-%', 1);
+
+The pattern
should be a LIKE
pattern as documented on
+https://www.postgresql.org/docs/current/functions-matching.html.
Note that this only sets the default priority for crates with that name. +If there are crates already in the queue, you’ll have to update those manually:
+cratesfyi=> UPDATE queue SET priority = 1 WHERE name LIKE 'group-%';
+
+After an outage you might want to add all the failed builds back to the queue. +To do that, log into the machine and open a PostgreSQL shell with:
+psql
+
+Then you can run this SQL query to add all the crates failed after YYYY-MM-DD HH:MM:SS
back in the queue:
UPDATE queue SET attempt = 0 WHERE attempt >= 5 AND build_time > 'YYYY-MM-DD HH:MM:SS';
+
+Sometimes it might be needed to remove all the content related to a crate from +docs.rs (for example after receiving a DMCA). To do that, log into the server +and run:
+cratesfyi database delete-crate CRATE_NAME
+
+The command will remove all the data from the database, and then remove the +files from S3.
+Occasionally it might be needed to prevent a crate from being built on docs.rs, +for example if we can’t legally host the content of those crates. To add a +crate to the blacklist, preventing new builds for it, you can run:
+cratesfyi database blacklist add <CRATE_NAME>
+
+Other operations (such as list
and remove
) are also supported.
++ +Warning: blacklisting a crate doesn’t remove existing content from the +website, it just prevents new versions from being built!
+
These are instructions for deploying the server in a production environment. For instructions on developing locally without docker-compose, see Developing without docker-compose.
+ +Here is a breakdown of what it takes to turn a regular server into its own version of docs.rs.
+Beware: This process is rather rough! Attempts at cleaning it up, automating setup components, etc, would be greatly appreciated!
+The commands and package names on this page will assume an Ubuntu server running systemd, but hopefully the explanatory text should give enough information to adapt to other systems. Note that docs.rs depends on the host being x86_64-unknown-linux-gnu
.
Docs.rs has a few basic requirements:
+rustup
)pkg-config
(to build dependencies for crates and docs.rs itself)libmagic
(to link against)$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly
+$ source $HOME/.cargo/env
+# apt install build-essential git curl cmake gcc g++ pkg-config libmagic-dev libssl-dev zlib1g-dev postgresql lxc-utils
+
+cratesfyi
userTo help things out later on, we can create a new unprivileged user that will run the server process. This user will own all the files required by the docs.rs process. This user will need to be able to run lxc-attach
through sudo
to be able to run docs builds, so give it a sudoers file at the same time:
# adduser --disabled-login --disabled-password --gecos "" cratesfyi
+# echo 'cratesfyi ALL=(ALL) NOPASSWD: /usr/bin/lxc-attach' > /etc/sudoers.d/cratesfyi
+
+(The name cratesfyi
is a historical one: Before the site was called “docs.rs”, it was called “crates.fyi” instead. If you want to update the name of the user, feel free! Just be aware that the name cratesfyi
will be used throughout this document.)
In addition to the LXC container, docs.rs also stores several related files in a “prefix” directory. This directory can be stored anywhere, but the cratesfyi
user needs to be able to access it:
# mkdir /cratesfyi-prefix
+# chown cratesfyi:cratesfyi /cratesfyi-prefix
+
+Now we can set up some required folders. To make sure they all have proper ownership, run them all as cratesfyi
:
$ sudo -u cratesfyi mkdir -vp /cratesfyi-prefix/documentations /cratesfyi-prefix/public_html /cratesfyi-prefix/sources
+$ sudo -u cratesfyi git clone https://github.com/rust-lang/crates.io-index.git /cratesfyi-prefix/crates.io-index
+$ sudo -u cratesfyi git --git-dir=/cratesfyi-prefix/crates.io-index/.git branch crates-index-diff_last-seen
+
+(That last command is used to set up the crates-index-diff
crate, so we can start monitoring new crate releases.)
To help contain what crates’ build scripts can access, documentation builds run inside an LXC container. To create one inside the prefix directory:
+# LANG=C lxc-create -n cratesfyi-container -P /cratesfyi-prefix -t download -- --dist ubuntu --release bionic --arch amd64
+# ln -s /cratesfyi-prefix/cratesfyi-container /var/lib/lxc
+# chmod 755 /cratesfyi-prefix/cratesfyi-container
+# chmod 755 /var/lib/lxc
+
+(To make deployment simpler, it’s important that the OS the container is using is the same as the host! In this case, the host is assumed to be running 64-bit Ubuntu 18.04. If you make the container use a different release or distribution, you’ll need to build docs.rs separately inside the container when deploying.)
+You’ll also need to configure networking for the container. The following is a sample /etc/default/lxc-net
that enables NAT networking for the container:
USE_LXC_BRIDGE="true"
+LXC_BRIDGE="lxcbr0"
+LXC_ADDR="10.0.3.1"
+LXC_NETMASK="255.255.255.0"
+LXC_NETWORK="10.0.3.0/24"
+LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
+LXC_DHCP_MAX="253"
+LXC_DHCP_CONFILE=""
+LXC_DOMAIN=""
+
+In addition, you’ll need to set the container’s configuration to use this. Add the following lines to /cratesfyi-prefix/cratesfyi-container/config
:
lxc.net.0.type = veth
+lxc.net.0.link = lxcbr0
+
+Now you can reload the LXC network configuration, start up the container, and set it up to auto-start when the host boots:
+# systemctl restart lxc-net
+# systemctl enable lxc@cratesfyi-container.service
+# systemctl start lxc@cratesfyi-container.service
+
+Now we need to do some setup inside this container. You can either copy all these commands so that each one attaches on its own, or you can run lxc-console -n cratesfyi-container
to open a root shell inside the container and skip the lxc-attach
prefix.
# lxc-attach -n cratesfyi-container -- apt update
+# lxc-attach -n cratesfyi-container -- apt upgrade
+# lxc-attach -n cratesfyi-container -- apt install curl ca-certificates binutils gcc libc6-dev libmagic1 pkg-config build-essential
+
+Inside the container, we also need to set up a cratesfyi
user, and install Rust for it. In addition to the base Rust installation, we also need to install all the default targets so that we can build docs for all the Tier 1 platforms. The Rust compiler installed inside the container is the one that builds all the docs, so if you want to use a new Rustdoc feature, this is the compiler to update.
lxc-attach -n cratesfyi-container -- adduser --disabled-login --disabled-password --gecos "" cratesfyi
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly'
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup target add i686-apple-darwin'
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup target add i686-pc-windows-msvc'
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup target add i686-unknown-linux-gnu'
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup target add x86_64-apple-darwin'
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup target add x86_64-pc-windows-msvc'
+
+Now that we have Rust installed inside the container, we can use a trick to give the cratesfyi
user on the host the same Rust compiler as the container. By symlinking the following directories into its user directory, we don’t need to track a third toolchain.
for directory in .cargo .rustup .multirust; do [[ -h /home/cratesfyi/$directory ]] || sudo -u cratesfyi ln -vs /var/lib/lxc/cratesfyi-container/rootfs/home/cratesfyi/$directory /home/cratesfyi/; done
+
+cratesfyi
userTo ensure that the docs.rs server is configured properly, we need to set a few environment variables. The primary ones are going into a separate environment file, so we can load them into the systemd service that will manage the server.
+Write the following into /home/cratesfyi/.cratesfyi.env
. If you have a GitHub access token that the site can use to collect repository information, add it here, but otherwise leave it blank. The variables need to exist, but they can be blank to skip that collection.
CRATESFYI_PREFIX=/cratesfyi-prefix
+CRATESFYI_DATABASE_URL=postgresql://cratesfyi:password@localhost
+CRATESFYI_CONTAINER_NAME=cratesfyi-container
+CRATESFYI_GITHUB_USERNAME=
+CRATESFYI_GITHUB_ACCESSTOKEN=
+RUST_LOG=cratesfyi
+
+Now add the following to /home/cratesfyi/.profile
:
export $(cat $HOME/.cratesfyi.env | xargs -d '\n')
+export PATH="$HOME/.cargo/bin:$PATH"
+export PATH="$PATH:$HOME/docs.rs/target/release"
+
+Now we can actually clone and build the docs.rs source! The location of it doesn’t matter much, but again, we want it to be owned by cratesfyi
so it can build and run the final executable. In addition, we copy the built cratesfyi
binary into the container so that it can be used to arrange builds on the inside.
sudo -u cratesfyi git clone https://github.com/rust-lang-nursery/docs.rs.git ~cratesfyi/docs.rs
+sudo su - cratesfyi -c 'cd ~/docs.rs && cargo build --release'
+cp -v /home/cratesfyi/docs.rs/target/release/cratesfyi /var/lib/lxc/cratesfyi-container/rootfs/usr/local/bin
+
+Now that we have the repository built, we can use it to set up the database. Docs.rs uses a Postgres database to store information about crates and their documentation. To set one up, we first need to ask Postgres to create the database, and then run the docs.rs command to create the initial tables and content:
+sudo -u postgres sh -c "psql -c \"CREATE USER cratesfyi WITH PASSWORD 'password';\""
+sudo -u postgres sh -c "psql -c \"CREATE DATABASE cratesfyi OWNER cratesfyi;\""
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- database init"
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build add-essential-files"
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build crate rand 0.5.5"
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- database update-search-index"
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- database update-release-activity"
+
+We’re almost there! At this point, we’ve got all the pieces in place to run the site. Now we can set up a systemd service that will run the daemon that will collect crate information, orchestrate builds, and serve the website. The following systemd service file can be placed in /etc/systemd/system/cratesfyi.service
:
[Unit]
+Description=Cratesfyi daemon
+After=network.target postgresql.service
+
+[Service]
+User=cratesfyi
+Group=cratesfyi
+Type=forking
+PIDFile=/cratesfyi-prefix/cratesfyi.pid
+EnvironmentFile=/home/cratesfyi/.cratesfyi.env
+ExecStart=/home/cratesfyi/docs.rs/target/release/cratesfyi daemon
+WorkingDirectory=/home/cratesfyi/docs.rs
+
+[Install]
+WantedBy=multi-user.target
+
+Enabling and running that will serve the website on http://localhost:3000
, so if you want to route public traffic to it, you’ll need to set up something like nginx to proxy the connections to it.
If you want to update the Rust compiler used to build crates (and the Rustdoc that comes with it), you need to make sure you don’t interrupt any existing crate builds. The daemon waits for 60 seconds between checking for new crates, so you need to make sure you catch it during that window. Since we hooked the daemon into systemd, the logs will be available in its journal. Running journalctl -efu cratesfyi
(it may need to be run as root if nothing appears) will show the latest log output and show new entries as they appear. You’re looking for a message like “Finished building new crates, going back to sleep” or “Queue is empty, going back to sleep”, which indicates that the crate-building thread is waiting.
To prevent the queue from building more crates, run the following:
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build lock"
+
+This will create a lock file in the prefix directory that will prevent more crates from being built. At this point, you can update the rustc inside the container and add the rustdoc static files to the database:
+lxc-attach -n cratesfyi-container -- su - cratesfyi -c 'rustup update'
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build add-essential-files"
+
+Once this is done, you can unlock the queue to allow crates to build again:
+sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build unlock"
+
+And we’re done! New crates will start being built with the new rustc. If you want to rebuild any existing docs with the new rustdoc, you need to manually build them - there’s no automated way to rebuild failed docs or docs from a certain rust version yet.
+To update the code for docs.rs itself, you can follow a similar approach. First, watch the logs so you can stop the daemon from building more crates. (You can replace the lock command with a systemctl stop cratesfyi
if you don’t mind the web server being down while you build.)
# journalctl -efu cratesfyi
+(wait for build daemon to sleep)
+$ sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build lock"
+
+Once the daemon has stopped, you can start updating the code and rebuilding:
+$ sudo su - cratesfyi -c "cd ~/docs.rs && git pull"
+$ sudo su - cratesfyi -c "cd ~/docs.rs && cargo build --release"
+
+Now that we have a shiny new build, we need to make sure the service is using it:
+# cp -v /home/cratesfyi/docs.rs/target/release/cratesfyi /var/lib/lxc/cratesfyi-container/rootfs/usr/local/bin
+# systemctl restart cratesfyi
+
+Next, we can unlock the builder so it can start checking new crates:
+$ sudo su - cratesfyi -c "cd ~/docs.rs && cargo run --release -- build unlock"
+
+And we’re done! Changes to the site or the build behavior should be visible now.
+ +Redirecting to... https://rustc-dev-guide.rust-lang.org/implementing_new_features.html.
+ + diff --git a/fonts/OPEN-SANS-LICENSE.txt b/fonts/OPEN-SANS-LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/fonts/OPEN-SANS-LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/fonts/SOURCE-CODE-PRO-LICENSE.txt b/fonts/SOURCE-CODE-PRO-LICENSE.txt new file mode 100644 index 000000000..366206f54 --- /dev/null +++ b/fonts/SOURCE-CODE-PRO-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/fonts.css b/fonts/fonts.css new file mode 100644 index 000000000..858efa598 --- /dev/null +++ b/fonts/fonts.css @@ -0,0 +1,100 @@ +/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ +/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ + +/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), + url('open-sans-v17-all-charsets-300.woff2') format('woff2'); +} + +/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), + url('open-sans-v17-all-charsets-300italic.woff2') format('woff2'); +} + +/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans Regular'), local('OpenSans-Regular'), + url('open-sans-v17-all-charsets-regular.woff2') format('woff2'); +} + +/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), + url('open-sans-v17-all-charsets-italic.woff2') format('woff2'); +} + +/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), + url('open-sans-v17-all-charsets-600.woff2') format('woff2'); +} + +/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 600; + src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), + url('open-sans-v17-all-charsets-600italic.woff2') format('woff2'); +} + +/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), + url('open-sans-v17-all-charsets-700.woff2') format('woff2'); +} + +/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), + url('open-sans-v17-all-charsets-700italic.woff2') format('woff2'); +} + +/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 800; + src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), + url('open-sans-v17-all-charsets-800.woff2') format('woff2'); +} + +/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 800; + src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), + url('open-sans-v17-all-charsets-800italic.woff2') format('woff2'); +} + +/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 500; + src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2'); +} diff --git a/fonts/open-sans-v17-all-charsets-300.woff2 b/fonts/open-sans-v17-all-charsets-300.woff2 new file mode 100644 index 000000000..9f51be370 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-300.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-300italic.woff2 b/fonts/open-sans-v17-all-charsets-300italic.woff2 new file mode 100644 index 000000000..2f5454484 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-300italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-600.woff2 b/fonts/open-sans-v17-all-charsets-600.woff2 new file mode 100644 index 000000000..f503d558d Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-600.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-600italic.woff2 b/fonts/open-sans-v17-all-charsets-600italic.woff2 new file mode 100644 index 000000000..c99aabe80 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-600italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-700.woff2 b/fonts/open-sans-v17-all-charsets-700.woff2 new file mode 100644 index 000000000..421a1ab25 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-700.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-700italic.woff2 b/fonts/open-sans-v17-all-charsets-700italic.woff2 new file mode 100644 index 000000000..12ce3d20d Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-700italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-800.woff2 b/fonts/open-sans-v17-all-charsets-800.woff2 new file mode 100644 index 000000000..c94a223b0 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-800.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-800italic.woff2 b/fonts/open-sans-v17-all-charsets-800italic.woff2 new file mode 100644 index 000000000..eed7d3c63 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-800italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-italic.woff2 b/fonts/open-sans-v17-all-charsets-italic.woff2 new file mode 100644 index 000000000..398b68a08 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-regular.woff2 b/fonts/open-sans-v17-all-charsets-regular.woff2 new file mode 100644 index 000000000..8383e94c6 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-regular.woff2 differ diff --git a/fonts/source-code-pro-v11-all-charsets-500.woff2 b/fonts/source-code-pro-v11-all-charsets-500.woff2 new file mode 100644 index 000000000..722245682 Binary files /dev/null and b/fonts/source-code-pro-v11-all-charsets-500.woff2 differ diff --git a/fott.html b/fott.html new file mode 100644 index 000000000..67d271296 --- /dev/null +++ b/fott.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /archive/fott.html.
+ + diff --git a/github.html b/github.html new file mode 100644 index 000000000..63cbfcdc5 --- /dev/null +++ b/github.html @@ -0,0 +1,12 @@ + + + + +Redirecting to... /platforms/github.html.
+ + diff --git a/governance/council.html b/governance/council.html new file mode 100644 index 000000000..4d6c35ea5 --- /dev/null +++ b/governance/council.html @@ -0,0 +1,591 @@ + + + + + +This document defines the authority1 and policies of the Rust Leadership Council (“Council”) to ensure successful operation of the Rust Project.
+This document serves as a living document defining the current accepted set of policies governing the Council. +The basis of this document started with the text of RFC 3392 which established the Council, +and may be updated via the RFC process.
+The Council delegates much of this authority to teams (which includes subteams, +working groups, etc.2) who autonomously make decisions concerning their purviews. +However, the Council retains some decision-making authority, outlined and delimited by this document.
+The Council maintains a separate home site at https://github.com/rust-lang/leadership-council where they document their internal processes, and coordinate their work.
+The Council is composed of representatives delegated to the Council from each top-level team.
+The Council is charged with the success of the Rust Project as a whole. +The Council identifies work that needs to be done but does not yet have a clear owner, +creates new teams to accomplish this work, +holds existing teams accountable for the work in their purview, +and coordinates and adjusts the organizational structure of Project teams.
+The Rust project consists of hundreds of globally distributed people, organized into teams with various purviews. However, a great deal of work falls outside the purview of any established team, and still needs to get done.
+The Council focuses on identifying and prioritizing work outside of team purviews. The Council primarily delegates that work, rather than doing that work itself. The Council can also serve as a coordination, organization, and accountability body between teams, such as for cross-team efforts, roadmaps, and the long-term success of the Project.
+At a high-level, the Council is only in charge of the following duties:
+In addition to these duties, the Council has additional expectations and constraints, to help determine if the Council is functioning properly:
+Council representatives, moderation team members, and other Project members serve as examples for those around them and the broader community. All of these roles represent positions of responsibility and leadership; their actions carry weight and can exert great force within the community, and should be wielded with due care. People choosing to serve in these roles should thus recognize that those around them will hold them to a correspondingly high standard.
+The Council consists of a set of team representatives, each representing one top-level team and its subteams.
+Each top-level team designates exactly one representative, by a process of their choice.
+Any member of the top-level team or a member of any of their subteams is eligible to be the representative. Teams should provide members of their subteams with an opportunity for input and feedback on potential candidates.
+Each representative represents at most one top-level team, even if they’re also a member of other teams. The primary responsibility of representing any Rust team falls to the representative of the top-level team they fall under.3
+All teams in the Rust Project must ultimately fall under at least one top-level team. +The Launching Pad team serves as a temporary home for teams that do not currently have a parent team. +This ensures that all teams have representation on the Council.
+The Council establishes top-level teams via public policy decisions. In general, top-level teams should meet the following criteria:
+There must be between 4 and 9 top-level teams (inclusive), preferably between 5 and 8. This number balances the desire for a diverse and relatively shallow structure while still being practical for productive conversation and consent.4
+When the Council creates a new top-level team, that team then designates a Council representative.5 When creating a new top-level team, the Council must provide justification for why it should not be a subteam or other governance structure.
+The set of top-level teams is:
+The Launching Pad team temporarily accepts subteams that otherwise do not have a top-level team to slot underneath of. This ensures that all teams have representation on the Council, while more permanent parent teams are found or established.
+The Launching Pad team is an umbrella team: it has no direct members, only subteam representatives.
+The Council should work to find or create a more appropriate parent for each subteam of the Launching Pad, and subsequently move those subteams to their new parent team.
+In some cases, an appropriate parent team may exist but not yet be ready to accept subteams; the Launching Pad can serve as an interim home in such cases.
+The Launching Pad also serves as a default home for subteams of a team that’s removed or reorganized away, if that removal or reorganization does not explicitly place those subteams somewhere else in the organization.
+The Council must review subteam membership in the Launching Pad every 6 months to ensure that proper progress is being made on finding all subteams new parent teams. As with other top-level teams, the Launching Pad team can be retired (and have its representation within the Council removed) if the Council finds it to be no longer necessary. The process for retiring the Launching Pad team is the same as with other top-level teams. Alternatively, the Council is free to give the Launching Pad team its own purview.
+Any decision to remove a team’s top-level designation (or otherwise affect eligibility for the Council) requires the consent of all Council representatives, with the exception of the representative of the top-level team being removed. Despite this caveat, the representative of the team under consideration must be invited to Council deliberations concerning the team’s removal, and the Council should only remove a team over their objections in extreme cases.
+The Council cannot remove the moderation team. The Council cannot change the moderation team’s purview without the agreement of the moderation team.
+A representative may end their term early if necessary, such as due to changes in their availability or circumstances. The respective top-level team must then begin selecting a new representative. The role of representative is a volunteer position. No one is obligated to fill that role, and no team is permitted to make serving as a representative a necessary obligation of membership in a team. However, a representative is obligated to fulfill the duties of the position of representative, or resign that position.
+A top-level team may decide to temporarily relinquish their representation, such as if the team is temporarily understaffed and they have no willing representative. However, if the team does not designate a Council representative, they forgo their right to actively participate in decision-making at a Project-wide level. All Council procedures including decision-making should not be blocked due to this omission. The Council is still obligated to consider new information and objections from all Project members. However, the Council is not obligated to block decisions to specially consider or collate a non-represented team’s feedback.
+Sending a representative to the Council is considered a duty of a top-level team, and not being able to regularly do so means the team is not fulfilling its duties. However, a Council representative does not relinquish their role in cases of short absence due to temporary illness, vacation, etc.
+A top-level team can designate an alternate representative to serve in the event their primary representative is unavailable. This alternate assumes the full role of Council representative until the return of the primary representative. Alternate representatives do not regularly attend meetings when the primary representative is present (to avoid doubling the number of attendees).
+If a team’s representative and any alternates fail to participate in any Council proceedings for 3 consecutive weeks, the team’s representative ceases to count towards the decision-making quorum requirements of the Council until the team can provide a representative able to participate. The Council must notify the team of this before it takes effect. If a team wishes to ensure the Council does not make decisions without their input or without an ability for objections to be made on their behalf, they should ensure they have an alternate representative available.
+A top-level team may change their representative before the end of their term, if necessary. However, as maintaining continuity incurs overhead, teams should avoid changing their representatives more than necessary. Teams have the primary responsibility for briefing their representative and alternates on team-specific issues or positions they wish to handle on an ongoing basis. The Council and team share the responsibilities of maintaining continuity for ongoing issues within the Council, and of providing context to alternates and other new representatives.
+For private matters, the Council should exercise discretion on informing alternates, to avoid spreading private information unnecessarily; the Council can brief alternates if they need to step in.
+Council representatives’ terms are one year in length. Each representative has a soft limit of three consecutive full terms for any given representative delegation (the delegation from a particular top-level team). A representative may exceed this soft limit if and only if the Council receives explicit confirmation from the respective team that they are unable to produce a different team member as a representative (for example, due to lack of a willing alternative candidate, or due to team members having blocking objections to any other candidate).
+Beyond this, there is no hard limit on the number of terms a representative can serve for other top-level teams or non-consecutive terms for a single top-level team. Teams should strive for a balance between continuity of experience and rotating representatives to provide multiple people with such experience.6
+Half of the representative appointments shall happen at the end of March while half shall happen at the end of September. This avoids changing all Council representatives at the same time. For the initial Council, and anytime the set of top-level teams is changed, the Council and top-level teams should work together to keep term end-dates roughly evenly divided between March and September. However, each term should last for a minimum of 6 months (temporary imbalance is acceptable to avoid excessively short terms).
+If the Council and top-level teams cannot agree on appropriate term end-date changes, representatives are randomly assigned to one or the other end date (at least 6 months out) to maintain balance.
+Council representatives must not disproportionately come from any one company, legal entity, or closely related set of legal entities, to avoid impropriety or the appearance of impropriety. If the Council has 5 or fewer representatives, no more than 1 representative may have any given affiliation; if the Council has 6 or more representatives, no more than 2 representatives may have any given affiliation.
+Closely related legal entities include branches/divisions/subsidiaries of the same entity, entities connected through substantial ownership interests, or similar. The Council may make a judgment call in unusual cases, taking care to avoid conflicts of interest in that decision.
+A Council representative is affiliated with a company or other legal entity if they derive a substantive fraction of their income from that entity (such as from an employer, client, or major sponsor). Representatives must promptly disclose changes in their affiliations.
+If this constraint does not hold, whether by a representative changing affiliation, top-level teams appointing new representatives, or the Council size changing, restore the constraint as follows:
+The following are criteria for deciding ideal candidates. These are similar to but not the same as the criteria for an effective team lead or co-lead. While a team lead might also make a good Council representative, serving as a team lead and serving as a Council representative both require a substantial time investment, which likely motivates dividing those roles among different people. The criteria are not hard requirements but can be used for determining who is best positioned to be a team’s representative. In short, the representative should have:
+While some teams may not currently have an abundance of candidates who fit this criteria, the Council should actively foster such skills within the larger Project, as these are helpful not only for Council membership but across the entire Project.
+The Council does not have privileged access to administrative credentials for the project. +This access solely resides with the infrastructure team7. +The infrastructure team’s responsibilities include ensuring teams have the tools and access needed to do their work effectively, while balancing against security and maintainability of our infrastructure. +The Council can help coordinate which teams should have access through policy.
+The Council is responsible for establishing the process for selecting Project directors. The Project directors are the mechanism by which the Rust Project’s interests are reflected on the Rust Foundation board.
+The Council delegates a purview to the Project directors to represent the Project’s interests on the Foundation Board and to make certain decisions on Foundation-related matters. The exact boundaries of that purview are not yet specified.
+The Council make decisions of two different types: operational decisions and policy decisions. Certain considerations may be placed on a given decision depending on its classification. However, by default, the Council uses a consent decision-making process for all decisions regardless of classification.
+Operational decisions are made on a daily basis by the Council to carry out their aims, including regular actions taking place outside of meetings (based on established policy). Policy decisions provide general reusable patterns or frameworks, meant to frame, guide, and support operations. In particular, policy decisions can provide partial automation for operational decisions or other aspects of operations. The council defaults to the consent decision making process for all decisions unless otherwise specified.
+It is not defined precisely which decisions are operations versus policy; rather, they fall somewhere along a continuum. The purpose of this distinction is not to direct or constrain the council’s decision-making procedures. Instead, this distinction provides guidance to the Council, and clarifies how the Council intends to record, review, and refine its decisions over time. For the purposes of any requirements or guidance associated with the operational/policy classification, anything not labeled as either operational or policy in this or future policy defaults to policy.
+Policy decisions often systematically address what might otherwise require repeated operational decisions. The Council should strive to recognize when repeated operational decisions indicate the need for a policy decision, or a policy change. In particular, the Council should avoid allowing repeated operational decisions to constitute de facto policy.
+Exceptions to existing policy cannot be made via an operational decision unless such exceptions are explicitly allowed in said policy. Avoiding ad-hoc exceptions helps avoid “normalization of deviance”.
+Consent means that no representative’s requirements (and thus those of the top-level team and subteams they represent) can be disregarded. The Council hears all relevant input and sets a good foundation for working together equitably with all voices weighted equally.
+The Council uses consent decision-making where instead of being asked “do you agree?”, representatives are asked “do you object?”. This eliminates “pocket vetoes” where people have fully reviewed a proposal but decide against approving it without giving clear feedback as to the reason. Concerns, feedback, preferences, and other less critical forms of feedback do not prevent making a decision, but should still be considered for incorporation earlier in drafting and discussion. Objections, representing an unmet requirement or need, must be considered and resolved to proceed with a decision.
+The consent decision-making process has the following approval criteria:
+The approval criteria provides a quorum mechanism, as well as sufficient time for representatives to have seen the proposal. Allowing for two non-signoffs is an acknowledgement of the volunteer nature of the Project, based on experience balancing the speed of decisions with the amount of confirmation needed for consent and non-objection; this assumes that those representatives have had time to object if they wished to do so. (This is modeled after the process used today for approval of RFCs.)
+The decision-making process can end at any time if the representative proposing it decides to retract their proposal. Another representative can always adopt a proposal to keep it alive.
+If conflicts of interest result in the Council being unable to meet the N-2 quorum for a decision, the Council cannot make that decision unless it follows the process documented in the “Conflicts of interest” section for how a decision may proceed with conflicts documented. In such a case, the Council should consider appropriate processes and policies to avoid future recurrences of a similar conflict.
+Using the public policy process, the Council can establish different decision-making processes for classes of decisions.
+When deciding on which decision-making process to adopt for a particular class of decision, the Council balances the need for quick decisions with the importance of confidence in full alignment. Consent decision-making processes fall on the following spectrum:
+Any policy that defines decision-making processes must at a minimum address where the proposal may be posted, quorum requirements, number of reviews required, and minimum time delay for feedback. A lack of objections is part of the approval criteria for all decision-making processes.
+If conflicts of interest prevent more than a third of the Council from participating in a decision, the Council cannot make that decision unless it follows the process documented in the “Conflicts of interest” section for how a decision may proceed with conflicts documented. (This is true regardless of any other quorum requirements for the decision-making process in use.) In such a case, the Council should consider appropriate processes and policies to avoid future recurrences of a similar conflict.
+The Council may also delegate subsets of its own decision-making purviews via a public policy decision, to teams, other governance structures, or roles created and filled by the Council, such as operational lead, meeting facilitator, or scribe/secretary.
+Note that the Council may delegate the drafting of a proposal without necessarily delegating the decision to approve that proposal. This may be necessary in cases of Project-wide policy that intersects the purviews of many teams, or falls outside the purview of any team. This may also help when bootstrapping a new team incrementally.
+The Council’s agenda and backlog are the primary interface through which the Council tracks and gives progress updates on issues raised by Project members throughout the Project.
+To aid in the fairness and effectiveness of the agenda and backlog, the Council must:
+In some situations the Council might need to make an decision urgently and not feel it can construct a proposal in that time that everyone will consent to. In such cases, if everyone agrees that a timely decision they disagree with would be a better outcome than no timely decision at all, the Council may use an alternative decision-making method to attempt to resolve the deadlock. The alternative process is informal, and the council members must still re-affirm their consent to the outcome through the existing decision making process. Council members may still raise objections at any time.
+For example, the Council can consent to a vote, then once the vote is complete all of the council members would consent to whatever decision the vote arrived to. The Council should strive to document the perceived advantages and disadvantages for choosing a particular alternative decision-making model.
+There is, by design, no mandatory mechanism for deadlock resolution. If the representatives do not all consent to making a decision even if they don’t prefer the outcome of that decision, or if any representative feels it is still possible to produce a proposal that will garner the Council’s consent, they may always maintain their objections.
+If a representative withdraws an objection, or consents to a decision they do not fully agree with (whether as a result of an alternative decision-making process or otherwise), the Council should schedule an evaluation or consider shortening the time until an already scheduled evaluation, and should establish a means of measuring/evaluating the concerns voiced. The results of this review are intended to determine whether the Council should consider changing its prior decision.
+All policy decisions should have an evaluation date as part of the policy. Initial evaluation periods should be shorter in duration than subsequent evaluation periods. The length of evaluation periods should be adjusted based on the needs of the situation. Policies that seem to be working well and require few changes should be extended so less time is spent on unnecessary reviews. Policies that have been recently adjusted or called into question should have shortened evaluation periods to ensure they’re iterating towards stability more quickly. The Council should establish standardized periods for classes of policy to use as defaults when determining periods for new policy. For instance, roles could have an evaluation date of 3 months initially then 1 year thereafter, while general policy could default to 6 months initially and 2 years thereafter.
+Decisions made by the Council will necessarily require varying levels of transparency and oversight based on the kind of decision being made. This section gives guidance on how the Council will seek oversight for its decisions, and what qualifies decisions to be made in private or in public.
+This RFC places certain decisions into each category. All decisions not specifically enumerated must use the public policy process. The Council may evolve the categorization through the public policy process.
+Decisions made by the Council fall into one of three categories, based on the level of oversight possible and necessary:
+Some types of operational decisions can be made internally by the Council, with the provision that the Council has a mechanism for community feedback on the decision after it has been made.
+Adding a new decision to the list of decisions the Council can make internally requires a public policy decision. Any decisions that impact the structure, decision-makers, or oversight of the Council itself should not be added to this list.
+The Council should also strive to avoid establishing de facto unwritten policy via repeated internal decisions in an effort to avoid public proposal. See “Repetition and exceptions” for more details.
+This list exhaustively enumerates the set of decisions that the Council may make internally:
+See the accountability section for details on the feedback mechanism for Council decisions.
+Some decisions necessarily involve private details of individuals or other entities, and making these details public would have a negative impact both on those individuals or entities (e.g. safety) and on the Project (eroding trust).
+This additional constraint should be considered an exceptional case. This does not permit making decisions that would require a public proposal per the next section. However, this does permit decisions that the Council makes internally to be kept private, without full information provided for public oversight.
+The Council may also decline to make a decision privately, such as if the Council considers the matter outside their purview (and chooses to defer to another team) or believes the matter should be handled publicly. However, even in such a case, the Council still cannot publicly reveal information shared with it in confidence (since otherwise the Council would not be trusted to receive such information). Obvious exceptions exist for imminent threats to safety.
+Private decisions must not establish policy. The Council should also strive to avoid establishing de facto unwritten policy via repeated private decisions in an effort to avoid public proposal. See “Repetition and exceptions” for more details.
+This list exhaustively enumerates the set of decisions that the Council may make either partly or entirely in private:
+The Council may pull in members of other teams for private discussions leading to either a private or public decision, unless doing so would more broadly expose private information disclosed to the Council without permission. When possible, the Council should attempt to pull in people or teams affected by a decision. This also provides additional oversight.
+Some matters may not be fit for full public disclosure while still being fine to share in smaller, more trusted circles (such as with all Project members, with team leads, or with involved/affected parties). The Council should strive to share information with the largest appropriate audiences for that information.
+The Council may decide to withhold new decisions or aspects of decisions when it’s unclear whether the information is sensitive. However, as time progresses and it becomes clearer who the appropriate audience is or that the appropriate audience has expanded, the council should revisit its information-sharing decisions.
+The Council should always loop in the moderation team for matters involving interpersonal conflict/dispute, both because such matters are the purview of the moderation team, and to again provide additional oversight.
+The council should evaluate which portions of a decision or its related discussions necessarily need to be private, and should consider whether it can feasibly make non-sensitive portions public, rather than keeping an entire matter private just because one portion of it needs to be. This may include the existence of the discussion, or the general topic, if those details are not themselves sensitive.
+Private matters may potentially be able to become public, or partially public, at a later date if they’re no longer sensitive. However, some matters may potentially never be able to become public, which means they will never become subject to broader review and oversight. Thus, the Council must exercise caution and prudence before making a private decision.
+The Council should make every effort to not make private decisions. The Council should have appropriate additional processes in place to encourage representatives to collectively review such decisions and consider their necessity.
+Decisions in this category require the Council to publicly seek feedback from the broader Rust Project in advance of the decision being made. Such decisions are proposed and decided via the appropriate public decision process, currently the RFC process (though the Council may adopt a different public proposal process in the future). The public decision process must require the consent of representatives (either affirmatively or via non-objection), must allow for blocking objections by Council representatives, must provide reasonable time for public evaluation and discussion, and must provide a clear path for public feedback to the Council.
+Following the existing RFC process, public proposals must have a minimum time-delay for feedback before the decision takes effect. Any representative may request that the feedback period for a particular decision is extended to at most 20 days total. The Council may make an internal operational decision to extend the feedback period beyond 20 days. The time-delay for feedback starts only when the necessary threshold for approval is otherwise met, including there not being any raised objections. If objections are raised and resolved during the time-delay, the waiting period starts again.
+The Council is expected to evolve over time to meet the evolving needs of the teams, the Rust Project, and the community. Such evolutionary changes may be small or large in scope and require corresponding amounts of oversight. Changes that materially impact the shape of the Council would need to be part of a public decision process.
+As an exception to the above, modifications or removals of a single top-level team (other than the moderation team) may occur with the unanimous agreement of the Council absent the representative delegated by that top-level team.
+The Council is permitted to have private discussions even on something that ultimately ends up as a public proposal or a publicly disclosed internal decision. The Council may wish to do this if the discussions are sensitive to allow decision participants to speak more frankly and freely. Additionally, in some cases, private information that can’t be disclosed may impact an otherwise public decision/proposal; the Council should strive to be as transparent and non-misleading as possible and avoid having opaque decisions where all rationale is private.
+Note that all decisions fall into this category unless explicitly designated (via this document or future public proposals) to fall into another category, so this list (unlike those in the other two categories) is intentionally vague/broad: it is intended to give guidance on what likely should belong in this category without necessarily being prescriptive.
+A Council representative must not take part in or influence a decision in which they have a conflict of interest.
+Potential sources of conflicts of interest include, but are not limited to:
+Council representatives must promptly disclose conflicts of interest and recuse themselves from affected decisions. Council representatives must also proactively disclose likely sources of potential conflict annually to other representatives and to the moderation team.
+Note that conflicts of interest can arise even if a proposal does not name a specific entity. Council representatives cannot, for instance, use their position to tailor requirements in a proposal to disproportionately benefit their employer.
+A proposal favored widely across the Rust community does not automatically represent a conflict of interest for a representative merely because that representative’s employer or equivalent also favors the general area of that proposal, as long as the proposal does not favor any particular entities. For example, a proposal to improve the security of a particular Rust component is not a conflict of interest for representatives just because their employers generally care about Rust security; however, a proposal to engage specific developers or security experts, or one’s compensation being predicated on such a proposal, might still raise a conflict.
+The Council may not waive a conflict of interest if one applies, even if the Council considers it minor. However, the Council may evaluate whether a conflict exists at all. Council representatives must raise potential conflicts so that the Council can make such a determination.
+The Council may request specific information from a recused representative, and the recused representative may provide that information upon request.
+Where possible and practical, the Council should separate decisions to reduce the scope of a conflict of interest. For instance, the Council could separate a decision to arrange access to a class of hardware (without setting specific requirements or selecting vendors) from the decision of which exact hardware to purchase and where to purchase it, if doing so made a conflict of interest only apply to the latter decision.
+A representative simultaneously considering the interests of the Rust Project and the interests of any Project team is not necessarily a conflict of interest. In particular, representatives are expected to regularly take part in decisions involving their teams, as delegates from those teams.
+In the unlikely event that a proposed decision produces a conflict of interest with enough representatives that the remainder cannot meet a previously established quorum requirement, and the decision must still be made, then either top-level teams must provide alternate representatives for the purposes of the specific decision, or (for public decisions only) the Council may elect to proceed with the decision while publicly documenting all conflicts of interest. (Note that proceeding with a public decision, even with conflicts documented, does not actually eliminate the conflicts or prevent them from influencing the decision; it only allows the public to judge whether the conflicts might have influenced the decision. Eliminating the conflicts entirely is always preferable.) In such a case, the Council should consider appropriate processes and policies to avoid future recurrences of a similar conflict.
+The Council can move an area or activity between the purviews of top-level teams either already existing or newly created (other than the moderation team). Though the purview of a given top-level team may be further sub-divided by that team, the Council only moves or adjusts top-level purviews. If a sub-divided purview is moved, the Council will work with the involved teams to coordinate the appropriate next steps. This mechanism should be used when the Council believes the existing team’s purview is too broad, such that it is not feasible to expect the team to fulfill the full purview under the current structure. However, this should not happen when a team only currently lacks resources to perform part of its duties.
+The Council also must approve expansions of a top-level team’s purview, and must be notified of reductions in a top-level team’s purview. This most often happens when a team self-determines that they wish to expand or reduce their purview. This could also happen as part of top-level teams agreeing to adjust purviews between themselves. Council awareness of changes to a purview is necessary, in part, to ensure that the purview can be re-assigned elsewhere or intentionally left unassigned by the Council.
+However, teams (individually or jointly) may further delegate their purviews to subteams without approval from the Council. Top-level teams remain accountable for the full purviews assigned to them, even if they delegate (in other words, teams are responsible for ensuring the delegation is successful).
+The Council should favor working with teams on alternative strategies prior to shifting purviews between teams, as this is a relatively heavyweight step. It’s also worth noting that one of the use cases for this mechanism is shifting a purview previously delegated to a team that functionally no longer exists (for instance, because no one on the team has time), potentially on a relatively temporary basis until people arrive with the time and ability to re-create that team. This section intentionally does not put constraints on the Council for exactly how (or whether) this consultation should happen.
+The following are various mechanisms that the Council uses to keep itself and others accountable.
+The Council must publicly ensure that the wider Project and community’s expectations of the Council are consistently being met. This should be done both by adjusting the policies, procedures, and outcomes of the Council as well as education of the Project and community when their expectations are not aligned with the reality.
+To achieve this, in addition to rotating representatives and adopting a “public by default” orientation, the Council must regularly (at least on a quarterly basis) provide some sort of widely available public communication on their activities as well as an evaluation of how well the Council is functioning using the list of duties, expectations, and constraints as the criteria for this evaluation.
+Each year, the Council must solicit feedback on whether the Council is serving its purpose effectively from all willing and able Project members and openly discuss this feedback in a forum that allows and encourages active participation from all Project members. To do so, the Council and other Project members consult the high-level duties, expectations, and constraints listed in this document and any subsequent revisions thereof to determine if the Council is meeting its duties and obligations.
+In addition, it is every representative’s individual responsibility to watch for, call out, and refuse to go along with failures to follow this document, other Council policies and procedures, or any other aspects of Council accountability. Representatives should strive to actively avoid “diffusion of responsibility”, the phenomenon in which a group of people collectively fail to do something because each individual member (consciously or subconsciously) believes that someone else will do so. The Council may also wish to designate a specific role with the responsibility of handling and monitoring procedural matters, and in particular raising procedural points of order, though others can and should still do so as well.
+If any part of the above process comes to the conclusion that the Council is not meeting its obligations, then a plan for how the Council will change to better be able to meet their obligations must be presented as soon as possible. This may require an RFC changing charter or similar, a rotation of representatives, or other substantive changes. Any plan should have concrete measures for how the Council and/or Rust governance as a whole will evolve in light of the previous year’s experience.
+Council representatives should participate in regular feedback with each other and with their respective top-level team (the nature of which is outside the scope of this document) to reflect on how well they are fulfilling their duties as representatives. The goal of the feedback session is to help representatives better understand how they can better serve the Project. This feedback must be shared with all representatives, all members of the representative’s top-level team, and with the moderation team. This feedback should ask for both what representatives have done well and what they could have done better.
+Separately, representatives should also be open to private feedback from their teams and fellow representatives at any time, and should regularly engage in self-reflection about their role and efficacy on the Council.
+Artifacts from these feedback processes must never be made public to ensure a safe and open process. The Council should also reflect on and adjust the feedback process if the results do not lead to positive change.
+If other members of the Council feel that a Council representative is not collaborating well with the rest of the Council, they should talk to that representative, and if necessary to that representative’s team. Council representatives should bring in moderation/mediation resources as needed to facilitate those conversations. Moderation can help resolve the issue, and/or determine if the issue is actionable and motivates some level of escalation.
+While it is out of scope for this document to specify how individual teams ensure their representatives are held accountable, we encourage teams to use the above mechanisms as inspiration for their own policies and procedures.
+Teams regularly coordinate and cooperate with each other, and have conversations about their needs; under normal circumstances the Council must respect the autonomy of individual teams.
+However, the Council serves as a means for teams to jointly hold each other accountable, to one another and to the Project as a whole. The Council can:
+The accountability process must not be punitive, and the process must be done with the active collaboration of the teams in question.
+In extreme circumstances where teams are willfully choosing to not act in good faith with regards to the wider Project, the Council has the authority to change a team’s purview, move some subset of a team’s purview to another team, or remove a team entirely. This is done through the Council’s regular decision making process. (This does not apply to the moderation team; see the next section for accountability between the Council and moderation team.)
+The term ‘authority’ here refers to the powers and responsibilities the Council has to ensure the success of the Rust Project. This document lays out the limits of these powers, so that the Council will delegate the authority it has to teams responsible for the concerns of the Project. These concerns may include - but are not limited to - product vision, day-to-day procedures, engineering decisions, mentoring, and marketing.
+Throughout this document, “teams” includes subteams, working groups, project groups, initiatives, and all other forms of official collaboration structures within the Project. “Subteams” includes all forms of collaboration structures that report up through a team.
+Subteams or individuals that fall under multiple top-level teams should not get disproportionate representation by having multiple representatives speaking for them on the Council. Whenever a “diamond” structure like this exists anywhere in the organization, the teams involved in that structure should strive to avoid ambiguity or diffusion of responsibility, and ensure people and teams know what paths they should use to raise issues and provide feedback.
+The Council consists only of the representatives provided to it by top-level teams, and cannot appoint new ad hoc members to itself. However, if the Council identifies a gap in the project, it can create a new top-level team. In particular, the Council can bootstrap the creation of a team to address a problem for which the Project doesn’t currently have coordinated/organized expertise and for which the Council doesn’t know the right solution structure to charter a team solving it. In that case, the Council could bring together a team whose purview is to explore the solution-space for that problem, determine the right solution, and to return to the Council with a proposal and charter. That team would then provide a representative to the Council, who can work with the Council on aspects of that problem and solution.
+This also effectively constrains the number of Council representatives to the same range. Note that this constraint is independently important.
+Being a Council representative is ultimately a position of service to the respective team and to the Project as a whole. While we hope that the position is fulfilling and engaging to whomever fills it, we also hope that it is not viewed as a position of status to vie for.
+The Council is not required to assign such roles exclusively to Council representatives; the Council may appoint any willing Project member. Such roles do not constitute membership in the Council for purposes such as decision-making.
+In practice the infrastructure team as a whole does not have access to all credentials and internally strives to meet the principle of least privilege.
+The Leadership Council is a representative group of the teams within the Rust Project, +tasked with coordinating between teams and to ensure successful operation of the Rust Project.
+The policies governing the Leadership Council are specified in the Leadership Council chapter.
+The Moderation team is responsible for dealing with violations of the Rust Code of Conduct.
+The policies governing the Moderation team are specified in the Moderation chapter.
+ +This section describes the roles of the Leadership Council and the moderation team in helping resolve disagreements and conflicts, as well as the interactions between those teams.
+Disagreements and conflicts fall on a spectrum of interpersonal interaction. Disagreements are more factual and/or technical misalignments, while conflicts are more social or relational roadblocks to collaboration. Many interactions might display aspects of both disagreement and conflict. The Council can help with aspects of disagreement, while aspects of conflict are the purview of the moderation team.
+This document does not specify moderation policy in general, only the portion of it necessary to specify interactions with the Council and the checks and balances between the Council and the moderation team. General moderation policy is out of scope for this document.
+Much of the work of the Rust Project involves collaboration with other people, all of whom care deeply about their work. It’s normal for people to disagree, and to feel strongly about that disagreement. Disagreement can also be a powerful tool for surfacing and addressing issues, and ideally, people who disagree can collaboratively and (mostly) amicably explore those disagreements without escalating into interpersonal conflicts.
+Situations where disagreements and conflicts arise may be complex. Disagreements can escalate into conflicts, and conflicts can de-escalate into disagreements. If the distinction between a disagreement and a conflict is not clear in the situation, or if participants disagree, assume the situation is a conflict.
+In the event of a conflict, involved parties should reach out to the moderation team to help resolve the conflict as soon as possible. Time is a critical resource in attempting to resolve a conflict before it gets worse or causes more harm.
+Where possible, teams should attempt to resolve disagreements on their own, with assistance from the Council as needed. The Council can make judgment calls to settle disagreements, but teams need to maintain good working relationships with each other to avoid persistent disagreements or escalations into conflicts.
+Potential resolution paths for disagreements between teams could include selecting a previously discussed option, devising a new option, deciding whose purview the decision falls in, or deciding that the decision is outside the purviews of both teams and leaving it to the Council to find a new home for that work.
+Conflicts involving teams or Project members should be brought to the moderation team as soon as possible. The Council can help mitigate the impact of those conflicts on pending/urgent decisions, but the moderation team is responsible for helping with conflicts and interpersonal issues, across teams or otherwise.
+Individuals or teams may also voluntarily engage in other processes to address conflicts or interpersonal issues, such as non-binding external mediation. Individuals or teams should keep the moderation team in the loop when doing so, and should seek guidance from the moderation team regarding appropriate resources or approaches for doing so. Individuals or teams must not use resources that would produce a conflict of interest.
+The moderation team must at all times maintain a publicly documented list of “contingent moderators”, who must be approved by both the moderation team and the Council via internal consent decision. The moderation team and contingent moderation team should both consist of at least three members each. The contingent moderators must be:
+The need for contingent moderators arises in a high-tension situation, and the Project and Council must be prepared to trust them to step into that situation. Choosing people known and trusted by the rest of the Project helps lower tensions in that situation.
+Moderation is a high-burnout activity, and individual moderators or the moderation team may find itself wishing to step away from that work. Note that one or more individual moderators may always choose to step down, in which case the moderation team should identify and bring in new moderators to fill any gaps or shortfalls; if the moderation team asks a contingent moderator to become a full moderator, the team should then appoint a new contingent moderator. An individual moderator who stepped down may be selected as a contingent moderator. If the moderation team as a whole becomes simultaneously unavailable (as determined jointly by the Council and contingent moderators via internal consent decision), or chooses to step down simultaneously, the contingent moderators become the interim moderation team and must promptly appoint new contingent moderators and start seeking new full moderators.
+As the contingent moderator role does not have any regular required activities outside of exceptional situations, those appointed to that role must have regular check-ins with the moderation team, to reconfirm that they’re still willing to serve in that role, and to avoid a circumstance in which the contingent moderators are abruptly needed and turn out to be unavailable.
+The moderation team has a duty to have robust policies and procedures in place. The Council provides oversight and assistance to ensure that the moderation team has those policies and procedures and that they are sufficiently robust.
+The Council may provide feedback to the moderation team and the moderation team is required to consider all feedback received. If the Council feels the moderation team has not followed moderation policies and procedures, the Council may require an audit by the contingent moderators. However, the Council may not overrule a moderation decision or policy.
+If any Council member believes a moderation decision (or series of decisions) has not followed the moderation team’s policies and procedures, they should promptly inform the moderation team. The Council and moderation team should then engage with each other, discuss and understand these concerns, and work to address them.
+One of the mechanisms this document provides for checking the moderation team’s actions in a privacy-preserving manner is an audit mechanism. In any case where any Council member believes moderation team actions have not followed documented policies or procedures, the Council member may decide to initiate the audit process. (In particular, they might do this in response to a report from a community member involved in a moderation situation.) This happens in addition to the above engagement and conversation; it is not a replacement for direct communication between the Council and the moderation team.
+In an audit, the contingent moderation team works with the moderation team to establish whether the moderation team followed documented policies and procedures. This mechanism necessarily involves the contingent moderation team using their own judgment to evaluate moderation policy, specific evidence or communications, and corresponding moderation actions or proposed actions. However, this mechanism is not intended to second-guess the actions themselves; the audit mechanism focuses on establishing whether the moderation team is acting according to its established policy and procedures, as well as highlighting unintended negative consequences of the policies and procedures themselves.
+The contingent moderators also reach out to the Council to find out any additional context they might need.
+Moderation processes and audits both take time, and must be performed with diligence. However, the Council, contingent moderators, and moderation team should all aim to communicate their concerns and expectations to each other in a reasonably timely fashion and maintain open lines of communication.
+Contingent moderators must not take part in decisions or audits for which they have a conflict of interest. Contingent moderators must not have access to private information provided to moderation before the contingent moderator was publicly listed as part of the contingent moderation team; this gives people speaking with the moderation team the opportunity to evaluate potential concerns or conflicts of interest.
+The discussions with the Council and the contingent moderation team may discover that the moderation team had to make an exception in policy for a particular case, as there was an unexpected condition in policies or that there was contextual information that couldn’t be incorporated in policy. This is an expected scenario that merits additional scrutiny by the contingent moderation team on the rationale for making an exception and the process for deciding the necessity to make an exception, but is not inherently a violation of moderation team responsibilities.
+As the audit process and the Council/moderation discussions proceed, the moderation team may decide to alter moderation policies and/or change the outcome of specific moderation decisions or proposed decisions. This is solely a decision for the moderation team to make.
+The contingent moderation team must report the results of the audit to the moderation team and the Council for their review. This must not include any details that may reveal private information, either directly or indirectly. Together with the discussions with the moderation team, this should aim to address the concerns of the Council.
+The Leadership Council and moderation team each have substantial power within the Rust Project. This document provides many tools by which they can work out conflicts. This section outlines the last-resort mechanisms by which those teams can hold each other accountable. This section is written in the hopes that it will never be needed, and that teams will make every possible effort to resolve conflicts without reaching this point.
+If the Council believes there is a systemic problem with the moderation team (whether based on an audit report from the contingent moderation team or otherwise), and the Council and moderation team cannot voluntarily come to agreement on how to address the situation, then as a last resort, the Council (by unanimous decision) may simultaneously dissolve itself and the moderation team. The top-level teams must then appoint new representatives to the Council, and the contingent moderation team becomes the new interim moderation team.
+Conversely, if the moderation team believes the Council has a systemic problem, and the Council and moderation team cannot voluntarily come to agreement on how to address the situation, then as a last resort, the moderation team (by unanimous decision) may simultaneously dissolve itself and the Council. This process can only be enacted if there are at least three moderation team members. The top-level teams must then appoint new representatives to the Council, and the contingent moderation team becomes the new interim moderation team.
+The moderation team’s representative is recused from the decision to dissolve the Council and moderation team to avoid conflicts of interest, though that representative must still step down as well.
+The removed representatives and moderators may not serve on either the Council or the moderation team for at least one year.
+By default, the new Council and interim moderation team will take responsibility for clearly communicating the transition.
+This mechanism is an absolute last resort. It will almost certainly produce suboptimal outcomes, to say the least. If situations escalate to this outcome, many things have gone horribly wrong, and those cleaning up the aftermath should endeavor to prevent it from ever happening again. The indication (by either the moderation team or the Council) that the situation might escalate to this point should be considered a strong signal to come to the table and find a way to do “Something Else which is Not That” to avoid the situation.
+The moderation team, in the course of doing moderation work, necessarily requires the ability to take action not just against members of the Rust community but also against members of the Rust Project. Those actions may span the ladder of escalation all the way from a conversation to removal from the Project. This puts the moderation team in a position of power and trust. This document seeks to provide appropriate accountability and cross-checks for the moderation team, as well as for the Council.
+If the moderation team plans to enact externally visible sanctions against any member of the Rust Project (anything that would create a conspicuous absence, such as removal from a role, or exclusion from participation in a Project space for more than a week), then any party may request that an audit take place by reaching out to either the Council or contingent moderators, and that audit will be automatically granted.
+Until June 2024, audits are automatically performed even without a request, to ensure the process is functional. After that time, the Council and moderation team will jointly review and decide whether to renew this provision.
+When the moderation team sends a warning to a Project member, or sends a notification of moderation action regarding a Project member, that message will mention the option of requesting an audit.
+Conflicts regarding Project members should be brought to the moderation team as soon as possible.
+Conflicts involving Council representatives, or alternates, follow the same process as conflicts involving Project members. The moderation team has the same ability to moderate representatives or alternates as any other member of the Project, including the required audit by the contingent moderators for any externally visible sanction. This remains subject to the same accountability mechanisms as for other decisions of the moderation team.
+In addition to the range of moderation actions already available, the moderation team may take the following additional actions for representatives or alternates as a near-last resort, as a lesser step on the ladder of escalation than removing a member from the Project entirely. These actions are not generally specific to the Council, and apply to other Rust teams as well.
+All of these also trigger a required audit. The Council must also be notified of any moderation actions involving representatives or alternates, or actions directly preventing people from becoming representatives.
+Conflicts involving a member of the moderation team will be handled by the remaining members of the moderation team (minus any with a conflict of interest), together with the contingent moderation team to provide additional oversight. Any member of the moderation or contingent moderation team should confer with the Council if there is a more systemic issue within the moderation team. The contingent moderators must audit this decision and must provide an audit report to the Council and moderation team.
+ +Welcome to the Rust Forge! Rust Forge serves as a repository of supplementary +documentation useful for members of The Rust Programming Language. If +you find any mistakes, typos, or want to add to the Rust Forge, feel free to +file an issue or PR on the Rust Forge GitHub.
+Want to contribute to Rust, but don’t know where to start? Here’s a list of
+rust-lang
projects that have marked issues that need help and issues that are
+good first issues.
Repository | Description |
---|---|
rust | The Rust Language & Compiler |
cargo | The Rust package manager |
crates.io | Source code for crates.io |
www.rust-lang.org | The Rust website |
Channel | Version | Will be stable on | Will branch from master on |
---|---|---|---|
Stable | |||
Beta | |||
Nightly | |||
Nightly +1 |
See the release process documentation for details on +what happens in the days leading up to a release.
+To ensure the beta release includes all the tools, no tool breakages are +allowed in the week before the beta cutoff (except for nightly-only tools).
+Beta Cut | No Breakage Week |
---|---|