From 66f7f7d8a9e6e524468f5d84e73b438274c20dbb Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Sat, 6 Feb 2021 13:16:37 +0100 Subject: [PATCH 01/26] Added `try_exists()` method to `std::path::Path` This method is similar to the existing `exists()` method, except it doesn't silently ignore the errors, leading to less error-prone code. This change intentionally does NOT touch the documentation of `exists()` nor recommend people to use this method while it's unstable. Such changes are reserved for stabilization to prevent confusing people. Apart from that it avoids conflicts with #80979. --- library/std/src/path.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 1889e54933867..4dd37f76efcb1 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2468,6 +2468,36 @@ impl Path { fs::metadata(self).is_ok() } + /// Returns `Ok(true)` if the path points at an existing entity. + /// + /// This function will traverse symbolic links to query information about the + /// destination file. In case of broken symbolic links this will return `Ok(false)`. + /// + /// As opposed to the `exists()` method, this one doesn't silently ignore errors + /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission + /// denied on some of the parent directories.) + /// + /// # Examples + /// + /// ```no_run + /// #![feature(path_try_exists)] + /// + /// use std::path::Path; + /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt")); + /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err()); + /// ``` + // FIXME: stabilization should modify documentation of `exists()` to recommend this method + // instead. + #[unstable(feature = "path_try_exists", issue = "none")] + #[inline] + pub fn try_exists(&self) -> io::Result { + match fs::metadata(self) { + Ok(_) => Ok(true), + Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false), + Err(error) => Err(error), + } + } + /// Returns `true` if the path exists on disk and is pointing at a regular file. /// /// This function will traverse symbolic links to query information about the From 81d1d8259611f8ab6f83afe465ea21a5aa87bcc2 Mon Sep 17 00:00:00 2001 From: Henry Boisdequin Date: Sat, 13 Mar 2021 07:58:03 +0530 Subject: [PATCH 02/26] Update `Vec` docs --- library/alloc/src/vec/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 0028e290fac4e..f59e363e17561 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -126,7 +126,7 @@ use self::spec_extend::SpecExtend; mod spec_extend; -/// A contiguous growable array type, written `Vec` but pronounced 'vector'. +/// A contiguous growable array type, written as `Vec` and pronounced 'vector'. /// /// # Examples /// @@ -215,7 +215,7 @@ mod spec_extend; /// /// # Slicing /// -/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects. +/// A `Vec` can be mutable. On the other hand, slices are read-only objects. /// To get a [slice][prim@slice], use [`&`]. Example: /// /// ``` @@ -352,7 +352,7 @@ mod spec_extend; /// not break, however: using `unsafe` code to write to the excess capacity, /// and then increasing the length to match, is always valid. /// -/// `Vec` does not currently guarantee the order in which elements are dropped. +/// Currently, `Vec` does not guarantee the order in which elements are dropped. /// The order has changed in the past and may change again. /// /// [`get`]: ../../std/vec/struct.Vec.html#method.get From 5fe3b8703482a132c628c102f3c188657668080e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 12 Mar 2021 22:59:16 -0700 Subject: [PATCH 03/26] Get rid of the garbage produced by getObjectFromId There is no reason for this function to return an object, since it is always used for getting at the name anyhow. It's used in the inner loop for some popular functions, so we want to avoid allocating in it. --- src/librustdoc/html/static/main.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ac2da5f779bd1..24170837e3aa7 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -833,11 +833,11 @@ function defocusSearchBar() { }; } - function getObjectFromId(id) { + function getObjectNameFromId(id) { if (typeof id === "number") { - return searchIndex[id]; + return searchIndex[id].name; } - return {'name': id}; + return id; } function checkGenerics(obj, val) { @@ -854,9 +854,9 @@ function defocusSearchBar() { var vlength = val.generics.length; for (var y = 0; y < vlength; ++y) { var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; - var firstGeneric = getObjectFromId(val.generics[y]).name; + var firstGeneric = getObjectNameFromId(val.generics[y]); for (var x = 0, elength = elems.length; x < elength; ++x) { - var tmp_lev = levenshtein(getObjectFromId(elems[x]).name, + var tmp_lev = levenshtein(getObjectNameFromId(elems[x]), firstGeneric); if (tmp_lev < lev.lev) { lev.lev = tmp_lev; @@ -892,10 +892,10 @@ function defocusSearchBar() { len = val.generics.length; for (y = 0; allFound === true && y < len; ++y) { allFound = false; - firstGeneric = getObjectFromId(val.generics[y]).name; + firstGeneric = getObjectNameFromId(val.generics[y]); e_len = elems.length; for (x = 0; allFound === false && x < e_len; ++x) { - allFound = getObjectFromId(elems[x]).name === firstGeneric; + allFound = getObjectNameFromId(elems[x]) === firstGeneric; } if (allFound === true) { elems.splice(x - 1, 1); From d7971e587c948ce943d962073ea3caa7f6830c1d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 12 Mar 2021 23:23:42 -0700 Subject: [PATCH 04/26] In checkGenerics and checkType, don't use Array.prototype.splice so much Every time splice() is called, another temporary object is created. This version, which uses plain objects as a sort of Hash Bag, should only produce one temporary object each time it's called. --- src/librustdoc/html/static/main.js | 94 ++++++++++++++++++------------ 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 24170837e3aa7..7254f5f465c24 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -846,26 +846,38 @@ function defocusSearchBar() { if (val.generics.length > 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { - var elems = obj[GENERICS_DATA].slice(0); + var elems = {}; + var elength = object[GENERICS_DATA].length; + for (var x = 0; x < elength; ++x) { + elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; + } var total = 0; var done = 0; // We need to find the type that matches the most to remove it in order // to move forward. var vlength = val.generics.length; - for (var y = 0; y < vlength; ++y) { - var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; - var firstGeneric = getObjectNameFromId(val.generics[y]); - for (var x = 0, elength = elems.length; x < elength; ++x) { - var tmp_lev = levenshtein(getObjectNameFromId(elems[x]), - firstGeneric); - if (tmp_lev < lev.lev) { - lev.lev = tmp_lev; - lev.pos = x; + for (var x = 0; x < vlength; ++x) { + var lev = MAX_LEV_DISTANCE + 1; + var firstGeneric = getObjectNameFromId(val.generics[x]); + var match = undefined; + if (elems[firstGeneric]) { + match = firstGeneric; + lev = 0; + } else { + for (var elem_name in elems) { + var tmp_lev = levenshtein(elem_name, firstGeneric); + if (tmp_lev < lev) { + lev = tmp_lev; + match = elem_name; + } } } - if (lev.pos !== -1) { - elems.splice(lev.pos, 1); - total += lev.lev; + if (match !== undefined) { + elems[match] -= 1; + if (elems[match] == 0) { + delete elems[match]; + } + total += lev; done += 1; } else { return MAX_LEV_DISTANCE + 1; @@ -880,25 +892,27 @@ function defocusSearchBar() { // Check for type name and type generics (if any). function checkType(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - var len, x, y, e_len, firstGeneric; + var len, x, firstGeneric; if (obj[NAME] === val.name) { if (literalSearch === true) { if (val.generics && val.generics.length !== 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { - var elems = obj[GENERICS_DATA].slice(0); - var allFound = true; + var elems = {}; + len = obj[GENERICS_DATA].length; + for (x = 0; x < len; ++x) { + elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; + } + var allFound = true; len = val.generics.length; - for (y = 0; allFound === true && y < len; ++y) { - allFound = false; - firstGeneric = getObjectNameFromId(val.generics[y]); - e_len = elems.length; - for (x = 0; allFound === false && x < e_len; ++x) { - allFound = getObjectNameFromId(elems[x]) === firstGeneric; - } - if (allFound === true) { - elems.splice(x - 1, 1); + for (x = 0; x < len; ++x) { + firstGeneric = getObjectNameFromId(val.generics[x]); + if (elems[firstGeneric]) { + elems[firstGeneric] -= 1; + } else { + allFound = false; + break; } } if (allFound === true) { @@ -1066,13 +1080,6 @@ function defocusSearchBar() { return false; } - function generateId(ty) { - if (ty.parent && ty.parent.name) { - return itemTypes[ty.ty] + ty.path + ty.parent.name + ty.name; - } - return itemTypes[ty.ty] + ty.path + ty.name; - } - function createAliasFromItem(item) { return { crate: item.crate, @@ -1158,7 +1165,7 @@ function defocusSearchBar() { in_args = findArg(searchIndex[i], val, true, typeFilter); returned = checkReturned(searchIndex[i], val, true, typeFilter); ty = searchIndex[i]; - fullId = generateId(ty); + fullId = ty.id; if (searchWords[i] === val.name && typePassesFilter(typeFilter, searchIndex[i].ty) @@ -1208,7 +1215,7 @@ function defocusSearchBar() { if (!type) { continue; } - fullId = generateId(ty); + fullId = ty.id; returned = checkReturned(ty, output, true, NO_TYPE_FILTER); if (output.name === "*" || returned === true) { @@ -1292,7 +1299,7 @@ function defocusSearchBar() { var index = -1; // we want lev results to go lower than others lev = MAX_LEV_DISTANCE + 1; - fullId = generateId(ty); + fullId = ty.id; if (searchWords[j].indexOf(split[i]) > -1 || searchWords[j].indexOf(val) > -1 || @@ -1825,6 +1832,13 @@ function defocusSearchBar() { showResults(execSearch(query, index, filterCrates)); } + function generateId(ty) { + if (ty.parent && ty.parent.name) { + return itemTypes[ty.ty] + ty.path + ty.parent.name + ty.name; + } + return itemTypes[ty.ty] + ty.path + ty.name; + } + function buildIndex(rawSearchIndex) { searchIndex = []; var searchWords = []; @@ -1837,14 +1851,18 @@ function defocusSearchBar() { var crateSize = 0; searchWords.push(crate); - searchIndex.push({ + var crateRow = { crate: crate, ty: 1, // == ExternCrate name: crate, path: "", desc: rawSearchIndex[crate].doc, + parent: undefined, type: null, - }); + id: "", + }; + crateRow.id = generateId(crateRow); + searchIndex.push(crateRow); currentIndex += 1; // an array of (Number) item types @@ -1890,7 +1908,9 @@ function defocusSearchBar() { desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: itemFunctionSearchTypes[i], + id: "", }; + row.id = generateId(row); searchIndex.push(row); if (typeof row.name === "string") { var word = row.name.toLowerCase(); From 3f70bfa79cdd94a60e6ed17f7d7c46aab3df1414 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 12 Mar 2021 23:52:46 -0700 Subject: [PATCH 05/26] Eagerly generate the underscore-less name to search on Basically, it doesn't make sense to generate those things every time you search. That generates a bunch of stuff for the GC to clean up, when, if the user wanted to do another search, it would just need to re-do it again. --- src/librustdoc/html/static/main.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 7254f5f465c24..6302c357c8f26 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1303,11 +1303,11 @@ function defocusSearchBar() { if (searchWords[j].indexOf(split[i]) > -1 || searchWords[j].indexOf(val) > -1 || - searchWords[j].replace(/_/g, "").indexOf(val) > -1) + ty.nameWithoutUnderscores.indexOf(val) > -1) { // filter type: ... queries if (typePassesFilter(typeFilter, ty.ty) && results[fullId] === undefined) { - index = searchWords[j].replace(/_/g, "").indexOf(val); + index = ty.nameWithoutUnderscores.indexOf(val); } } if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { @@ -1860,6 +1860,7 @@ function defocusSearchBar() { parent: undefined, type: null, id: "", + nameWithoutUnderscores: crate.replace(/_/g, ""), }; crateRow.id = generateId(crateRow); searchIndex.push(crateRow); @@ -1909,6 +1910,7 @@ function defocusSearchBar() { parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: itemFunctionSearchTypes[i], id: "", + nameWithoutUnderscores: itemNames[i].replace(/_/g, ""), }; row.id = generateId(row); searchIndex.push(row); From b76a3d3592f1b7c495501a892f537635a7a313c3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 09:32:40 -0700 Subject: [PATCH 06/26] Update src/librustdoc/html/static/main.js Co-authored-by: Guillaume Gomez --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6302c357c8f26..6ec97f2e924d8 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -856,7 +856,7 @@ function defocusSearchBar() { // We need to find the type that matches the most to remove it in order // to move forward. var vlength = val.generics.length; - for (var x = 0; x < vlength; ++x) { + for (x = 0; x < vlength; ++x) { var lev = MAX_LEV_DISTANCE + 1; var firstGeneric = getObjectNameFromId(val.generics[x]); var match = undefined; From ca04ce364552b58ce8cb5dabcbec6ca88cb1b1e0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 09:34:37 -0700 Subject: [PATCH 07/26] Use null instead of undefined here --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6ec97f2e924d8..38f244ba89f96 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -859,7 +859,7 @@ function defocusSearchBar() { for (x = 0; x < vlength; ++x) { var lev = MAX_LEV_DISTANCE + 1; var firstGeneric = getObjectNameFromId(val.generics[x]); - var match = undefined; + var match = null; if (elems[firstGeneric]) { match = firstGeneric; lev = 0; @@ -872,7 +872,7 @@ function defocusSearchBar() { } } } - if (match !== undefined) { + if (match !== null) { elems[match] -= 1; if (elems[match] == 0) { delete elems[match]; From b7d14b1b4d75f6f7ea1cd1801c933f0d4f76c222 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 09:54:19 -0700 Subject: [PATCH 08/26] Fix jslint warnings --- src/librustdoc/html/static/main.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 38f244ba89f96..d444bc2f25762 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -843,6 +843,7 @@ function defocusSearchBar() { function checkGenerics(obj, val) { // The names match, but we need to be sure that all generics kinda // match as well. + var tmp_lev, elem_name; if (val.generics.length > 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { @@ -864,8 +865,8 @@ function defocusSearchBar() { match = firstGeneric; lev = 0; } else { - for (var elem_name in elems) { - var tmp_lev = levenshtein(elem_name, firstGeneric); + for (elem_name in elems) { + tmp_lev = levenshtein(elem_name, firstGeneric); if (tmp_lev < lev) { lev = tmp_lev; match = elem_name; From 7834aeb95c5ddebdfadcf5cbc035912c117cc106 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 10:12:17 -0700 Subject: [PATCH 09/26] Add comments regarding object shapes in buildIndex --- src/librustdoc/html/static/main.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d444bc2f25762..72aa985dc59af 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1852,6 +1852,9 @@ function defocusSearchBar() { var crateSize = 0; searchWords.push(crate); + // This object should have exactly the same set of fields as the "row" + // object defined below. Your JavaScript runtime will thank you. + // https://mathiasbynens.be/notes/shapes-ics var crateRow = { crate: crate, ty: 1, // == ExternCrate @@ -1902,6 +1905,8 @@ function defocusSearchBar() { len = itemTypes.length; var lastPath = ""; for (i = 0; i < len; ++i) { + // This object should have exactly the same set of fields as the "crateRow" + // object defined above. var row = { crate: crate, ty: itemTypes[i], From 26f85cc1729cc7e324ae7675fb8e1f03014a062f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 10:28:36 -0700 Subject: [PATCH 10/26] Avoid potential collisions with `constructor` and the search query --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 72aa985dc59af..b7ed355c2e706 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -847,7 +847,7 @@ function defocusSearchBar() { if (val.generics.length > 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { - var elems = {}; + var elems = Object.create(null); var elength = object[GENERICS_DATA].length; for (var x = 0; x < elength; ++x) { elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; @@ -899,7 +899,7 @@ function defocusSearchBar() { if (val.generics && val.generics.length !== 0) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length >= val.generics.length) { - var elems = {}; + var elems = Object.create(null); len = obj[GENERICS_DATA].length; for (x = 0; x < len; ++x) { elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; From d92f8405ce8cb6fd3b2967d0624902c8260a890f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Mar 2021 10:29:21 -0700 Subject: [PATCH 11/26] Remove tab character --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b7ed355c2e706..d6d0f98fa7b87 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1905,8 +1905,8 @@ function defocusSearchBar() { len = itemTypes.length; var lastPath = ""; for (i = 0; i < len; ++i) { - // This object should have exactly the same set of fields as the "crateRow" - // object defined above. + // This object should have exactly the same set of fields as the "crateRow" + // object defined above. var row = { crate: crate, ty: itemTypes[i], From 0bfd1429266518d86d28c29f86c30bca063706f0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 14 Mar 2021 09:48:48 -0700 Subject: [PATCH 12/26] Avoid generating new strings for names that have no undescores This should have negligible effect on time, but it cuts about 1MiB off of resident memory usage. --- src/librustdoc/html/static/main.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d6d0f98fa7b87..729a129732495 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1852,6 +1852,9 @@ function defocusSearchBar() { var crateSize = 0; searchWords.push(crate); + var nameWithoutUnderscores = crate.indexOf("_") === -1 + ? crate + : crate.replace(/_/g, ""); // This object should have exactly the same set of fields as the "row" // object defined below. Your JavaScript runtime will thank you. // https://mathiasbynens.be/notes/shapes-ics @@ -1864,7 +1867,7 @@ function defocusSearchBar() { parent: undefined, type: null, id: "", - nameWithoutUnderscores: crate.replace(/_/g, ""), + nameWithoutUnderscores: nameWithoutUnderscores, }; crateRow.id = generateId(crateRow); searchIndex.push(crateRow); @@ -1907,6 +1910,9 @@ function defocusSearchBar() { for (i = 0; i < len; ++i) { // This object should have exactly the same set of fields as the "crateRow" // object defined above. + var nameWithoutUnderscores = itemNames[i].indexOf("_") === -1 + ? itemNames[i] + : itemNames[i].replace(/_/g, ""); var row = { crate: crate, ty: itemTypes[i], @@ -1916,7 +1922,7 @@ function defocusSearchBar() { parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: itemFunctionSearchTypes[i], id: "", - nameWithoutUnderscores: itemNames[i].replace(/_/g, ""), + nameWithoutUnderscores: nameWithoutUnderscores, }; row.id = generateId(row); searchIndex.push(row); From f57d71533eb6199b04f62bb54c8f19d655d3c824 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 14 Mar 2021 09:57:37 -0700 Subject: [PATCH 13/26] Use a number for row.id, instead of a string There's no reason for it to be a string, since it's only used for de-duplicating the results arrays anyhow. --- src/librustdoc/html/static/main.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 729a129732495..68a7ed9a90537 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1833,18 +1833,12 @@ function defocusSearchBar() { showResults(execSearch(query, index, filterCrates)); } - function generateId(ty) { - if (ty.parent && ty.parent.name) { - return itemTypes[ty.ty] + ty.path + ty.parent.name + ty.name; - } - return itemTypes[ty.ty] + ty.path + ty.name; - } - function buildIndex(rawSearchIndex) { searchIndex = []; var searchWords = []; var i; var currentIndex = 0; + var id = 0; for (var crate in rawSearchIndex) { if (!hasOwnProperty(rawSearchIndex, crate)) { continue; } @@ -1866,10 +1860,10 @@ function defocusSearchBar() { desc: rawSearchIndex[crate].doc, parent: undefined, type: null, - id: "", + id: id, nameWithoutUnderscores: nameWithoutUnderscores, }; - crateRow.id = generateId(crateRow); + id += 1; searchIndex.push(crateRow); currentIndex += 1; @@ -1921,10 +1915,10 @@ function defocusSearchBar() { desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: itemFunctionSearchTypes[i], - id: "", + id: id, nameWithoutUnderscores: nameWithoutUnderscores, }; - row.id = generateId(row); + id += 1; searchIndex.push(row); if (typeof row.name === "string") { var word = row.name.toLowerCase(); From 8eba927a3e732ee3bf992ac31d587294f81e8c46 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 14 Mar 2021 14:43:10 -0700 Subject: [PATCH 14/26] Make nameWithoutUndescores lowercased This basically fixes a search bug introduced by earlier changes. --- src/librustdoc/html/static/main.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 68a7ed9a90537..fe1791e4b0723 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1304,11 +1304,11 @@ function defocusSearchBar() { if (searchWords[j].indexOf(split[i]) > -1 || searchWords[j].indexOf(val) > -1 || - ty.nameWithoutUnderscores.indexOf(val) > -1) + ty.normalizedName.indexOf(val) > -1) { // filter type: ... queries if (typePassesFilter(typeFilter, ty.ty) && results[fullId] === undefined) { - index = ty.nameWithoutUnderscores.indexOf(val); + index = ty.normalizedName.indexOf(val); } } if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { @@ -1846,7 +1846,7 @@ function defocusSearchBar() { var crateSize = 0; searchWords.push(crate); - var nameWithoutUnderscores = crate.indexOf("_") === -1 + var normalizedName = crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""); // This object should have exactly the same set of fields as the "row" @@ -1861,7 +1861,7 @@ function defocusSearchBar() { parent: undefined, type: null, id: id, - nameWithoutUnderscores: nameWithoutUnderscores, + normalizedName: normalizedName, }; id += 1; searchIndex.push(crateRow); @@ -1904,9 +1904,16 @@ function defocusSearchBar() { for (i = 0; i < len; ++i) { // This object should have exactly the same set of fields as the "crateRow" // object defined above. - var nameWithoutUnderscores = itemNames[i].indexOf("_") === -1 - ? itemNames[i] - : itemNames[i].replace(/_/g, ""); + if (typeof itemNames[i] === "string") { + var word = itemNames[i].toLowerCase(); + searchWords.push(word); + } else { + var word = ""; + searchWords.push(""); + } + var normalizedName = word.indexOf("_") === -1 + ? word + : word.replace(/_/g, ""); var row = { crate: crate, ty: itemTypes[i], @@ -1916,16 +1923,10 @@ function defocusSearchBar() { parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: itemFunctionSearchTypes[i], id: id, - nameWithoutUnderscores: nameWithoutUnderscores, + normalizedName: normalizedName, }; id += 1; searchIndex.push(row); - if (typeof row.name === "string") { - var word = row.name.toLowerCase(); - searchWords.push(word); - } else { - searchWords.push(""); - } lastPath = row.path; crateSize += 1; } From 7134b0ee6721d25d2e211f01c2f344b0d8e68004 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 15 Mar 2021 19:20:15 +0200 Subject: [PATCH 15/26] Fall-back to sans-serif if Arial is not available Otherwise on systems where Arial is not available the system will fallback to a serif font, rather than a sans-serif one. This is especially relevant on acessibility-conscious setups (such as is mine) that have web-fonts disabled and a limited set of fonts available on the system. --- src/librustdoc/html/static/rustdoc.css | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 27f1ea78ad2f4..4f287cde73b1b 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -136,11 +136,12 @@ h1, h2, h3, h4, #source-sidebar, #sidebar-toggle, /* This selector is for the items listed in the "all items" page. */ #main > ul.docblock > li > a { - font-family: "Fira Sans", Arial; + font-family: "Fira Sans", Arial, sans-serif; } .content ul.crate a.crate { - font: 16px/1.6 "Fira Sans"; + font-size: 16px/1.6; + font-family: "Fira Sans", Arial, sans-serif; } ol, ul { @@ -482,7 +483,7 @@ h4 > code, h3 > code, .invisible > code { } #main > .since { top: inherit; - font-family: "Fira Sans", Arial; + font-family: "Fira Sans", Arial, sans-serif; } .content table:not(.table-display) { @@ -1301,7 +1302,7 @@ h4 > .notable-traits { .help-button { right: 30px; - font-family: "Fira Sans", Arial; + font-family: "Fira Sans", Arial, sans-serif; text-align: center; font-size: 17px; } From 9aa48ba13ba4b51893133be19cb9fc54f605b49a Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 15 Mar 2021 19:34:21 +0200 Subject: [PATCH 16/26] No background for code in portability snippets This better matches the appearance of this kind of snippet in the full item view and is less jarring to read due to repeated foreground-background changes. --- src/librustdoc/html/static/themes/ayu.css | 2 +- src/librustdoc/html/static/themes/dark.css | 5 +---- src/librustdoc/html/static/themes/light.css | 5 +---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index fd8153519afaf..7374aee71f8f8 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -266,7 +266,7 @@ a { .stab.portability > code { color: #e6e1cf; - background-color: transparent; + background: none; } #help > div { diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 9eeccd038a2ff..88ac3252bb4b2 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -222,10 +222,7 @@ a.test-arrow { .stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #2f2f2f; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #2f2f2f; } - -.stab.portability > code { - color: #ddd; -} +.stab.portability > code { background: none; } #help > div { background: #4d4d4d; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 814043b35ae61..9bc21102aaae6 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -220,10 +220,7 @@ a.test-arrow { .stab.unstable { background: #FFF5D6; border-color: #FFC600; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; } - -.stab.portability > code { - color: #000; -} +.stab.portability > code { background: none; } #help > div { background: #e9e9e9; From dcba95f43ee7b3d7a282f4d96f98d3a1deeafcd2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 15 Mar 2021 11:58:34 -0700 Subject: [PATCH 17/26] Declare `word` outside the loop, as recommended by eslint --- src/librustdoc/html/static/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index fe1791e4b0723..0a63fc589ae79 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1836,7 +1836,7 @@ function defocusSearchBar() { function buildIndex(rawSearchIndex) { searchIndex = []; var searchWords = []; - var i; + var i, word; var currentIndex = 0; var id = 0; @@ -1905,10 +1905,10 @@ function defocusSearchBar() { // This object should have exactly the same set of fields as the "crateRow" // object defined above. if (typeof itemNames[i] === "string") { - var word = itemNames[i].toLowerCase(); + word = itemNames[i].toLowerCase(); searchWords.push(word); } else { - var word = ""; + word = ""; searchWords.push(""); } var normalizedName = word.indexOf("_") === -1 From ff8717b56dfe71f371566db52d72684088da8e61 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Mon, 15 Mar 2021 20:14:56 +0100 Subject: [PATCH 18/26] Specify *.woff2 files as binary This prevents older git versions to change the "line endings". --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index ac0a71232efc9..4038db6f7dab1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,6 +8,7 @@ *.mir linguist-language=Rust src/etc/installer/gfx/* binary *.woff binary +*.woff2 binary src/vendor/** -text Cargo.lock linguist-generated=false From 924e522d16488f95eaa9a8eae7e0460781d87b85 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 15 Mar 2021 19:44:40 +0100 Subject: [PATCH 19/26] Deprecate RustcEncodable and RustcDecodable. --- library/core/src/macros/mod.rs | 8 ++++++++ library/core/src/prelude/v1.rs | 2 +- library/std/src/prelude/v1.rs | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 28fed9b8a14cd..99894b5605e6d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1468,6 +1468,10 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)] + #[rustc_deprecated( + since = "1.52.0", + reason = "rustc-serialize is deprecated and no longer supported" + )] pub macro RustcDecodable($item:item) { /* compiler built-in */ } @@ -1476,6 +1480,10 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(core_intrinsics)] + #[rustc_deprecated( + since = "1.52.0", + reason = "rustc-serialize is deprecated and no longer supported" + )] pub macro RustcEncodable($item:item) { /* compiler built-in */ } diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index c7cb2a69ff73c..7d33ca8bb698e 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -61,7 +61,7 @@ pub use crate::{ }; #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow(deprecated)] +#[allow(deprecated, deprecated_in_future)] #[doc(no_inline)] pub use crate::macros::builtin::{ bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable, diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index ec89bb6d2a48f..c5b871edbf25f 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -48,7 +48,7 @@ pub use core::prelude::v1::{ // FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates // dead links which fail link checker testing. #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow(deprecated)] +#[allow(deprecated, deprecated_in_future)] #[doc(hidden)] pub use core::prelude::v1::{ bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable, From 62cf2445633c03a927b7fef4abe82ea480df4078 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 13 Mar 2021 19:45:48 +0100 Subject: [PATCH 20/26] Constify copy_to and copy_from --- library/core/src/ptr/const_ptr.rs | 6 ++++-- library/core/src/ptr/mut_ptr.rs | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 62ca07fc5a4e2..b511466acd639 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -819,9 +819,10 @@ impl *const T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_to(self, dest: *mut T, count: usize) + pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, { @@ -837,9 +838,10 @@ impl *const T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) + pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index a365b66d8fcf4..fa09cf854353d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -926,9 +926,10 @@ impl *mut T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_to(self, dest: *mut T, count: usize) + pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, { @@ -944,9 +945,10 @@ impl *mut T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) + pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, { @@ -962,9 +964,10 @@ impl *mut T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_from(self, src: *const T, count: usize) + pub const unsafe fn copy_from(self, src: *const T, count: usize) where T: Sized, { @@ -980,9 +983,10 @@ impl *mut T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) + pub const unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) where T: Sized, { From 64e2248794caada12469a0bd31d883eb6370b095 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 13 Mar 2021 20:33:27 +0100 Subject: [PATCH 21/26] Constify mem::swap and ptr::swap[_nonoverlapping] --- library/core/src/intrinsics.rs | 12 ------------ library/core/src/lib.rs | 1 + library/core/src/mem/mod.rs | 3 ++- library/core/src/ptr/mod.rs | 23 +++++++++-------------- 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 634ed87b0910e..4c2472ed82c5e 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1902,18 +1902,6 @@ pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { !ptr.is_null() && ptr as usize % mem::align_of::() == 0 } -/// Checks whether the regions of memory starting at `src` and `dst` of size -/// `count * size_of::()` do *not* overlap. -pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { - let src_usize = src as usize; - let dst_usize = dst as usize; - let size = mem::size_of::().checked_mul(count).unwrap(); - let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; - // If the absolute distance between the ptrs is at least as big as the size of the buffer, - // they do not overlap. - diff >= size -} - /// Sets `count * size_of::()` bytes of memory starting at `dst` to /// `val`. /// diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index e10e1738de55c..8e35adcbd9ef5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -98,6 +98,7 @@ #![feature(const_slice_from_raw_parts)] #![feature(const_slice_ptr_len)] #![feature(const_size_of_val)] +#![feature(const_swap)] #![feature(const_align_of_val)] #![feature(const_type_id)] #![feature(const_type_name)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 84edbd30a5dc1..c01730b655133 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -682,7 +682,8 @@ pub unsafe fn uninitialized() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub fn swap(x: &mut T, y: &mut T) { +#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: the raw pointers have been created from safe mutable references satisfying all the // constraints on `ptr::swap_nonoverlapping_one` unsafe { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5ac260fc883c2..155a64345e997 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -67,7 +67,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::hash; -use crate::intrinsics::{self, abort, is_aligned_and_not_null, is_nonoverlapping}; +use crate::intrinsics::{self, abort, is_aligned_and_not_null}; use crate::mem::{self, MaybeUninit}; #[stable(feature = "rust1", since = "1.0.0")] @@ -394,7 +394,8 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn swap(x: *mut T, y: *mut T) { +#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +pub const unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. let mut tmp = MaybeUninit::::uninit(); @@ -451,16 +452,8 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { /// ``` #[inline] #[stable(feature = "swap_nonoverlapping", since = "1.27.0")] -pub unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { - if cfg!(debug_assertions) - && !(is_aligned_and_not_null(x) - && is_aligned_and_not_null(y) - && is_nonoverlapping(x, y, count)) - { - // Not panicking to keep codegen impact smaller. - abort(); - } - +#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { let x = x as *mut u8; let y = y as *mut u8; let len = mem::size_of::() * count; @@ -470,7 +463,8 @@ pub unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { } #[inline] -pub(crate) unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { +#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +pub(crate) const unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { // For types smaller than the block optimization below, // just swap directly to avoid pessimizing codegen. if mem::size_of::() < 32 { @@ -488,7 +482,8 @@ pub(crate) unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { } #[inline] -unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { +#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { // The approach here is to utilize simd to swap x & y efficiently. Testing reveals // that swapping either 32 bytes or 64 bytes at a time is most efficient for Intel // Haswell E processors. LLVM is more able to optimize if we give a struct a From 45988ee438e684ec9d58c21bba72ad0c6d860691 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 13 Mar 2021 20:38:43 +0100 Subject: [PATCH 22/26] Constify mem::replace and ptr::replace --- library/core/src/mem/mod.rs | 3 ++- library/core/src/ptr/mod.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index c01730b655133..a02c400557b48 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -813,7 +813,8 @@ pub fn take(dest: &mut T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] -pub fn replace(dest: &mut T, src: T) -> T { +#[rustc_const_unstable(feature = "const_replace", issue = "83164")] +pub const fn replace(dest: &mut T, src: T) -> T { // SAFETY: We read from `dest` but directly write `src` into it afterwards, // such that the old value is not duplicated. Nothing is dropped and // nothing here can panic. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 155a64345e997..3a27f01444be8 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -584,7 +584,8 @@ const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn replace(dst: *mut T, mut src: T) -> T { +#[rustc_const_unstable(feature = "const_replace", issue = "83164")] +pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be // cast to a mutable reference (valid for writes, aligned, initialized), // and cannot overlap `src` since `dst` must point to a distinct From db9a53b5d7dcf2be60496a6ee19f03476d354344 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 13 Mar 2021 20:43:47 +0100 Subject: [PATCH 23/26] Constify mem::transmute_copy --- library/core/src/mem/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a02c400557b48..37e8d65db6a38 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -933,7 +933,8 @@ pub fn drop(_x: T) {} /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn transmute_copy(src: &T) -> U { +#[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")] +pub const unsafe fn transmute_copy(src: &T) -> U { // If U has a higher alignment requirement, src may not be suitably aligned. if align_of::() > align_of::() { // SAFETY: `src` is a reference which is guaranteed to be valid for reads. From 335427a3db8fcdbddece8c7257e0ab40c8230d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 16 Mar 2021 00:00:00 +0000 Subject: [PATCH 24/26] Use delay_span_bug instead of panic in layout_scalar_valid_range 83054 introduced validation of scalar range attributes, but panicking code that uses the attribute remained reachable. Use `delay_span_bug` instead to avoid the ICE. --- compiler/rustc_middle/src/ty/context.rs | 15 +++++++++------ .../invalid_rustc_layout_scalar_valid_range.rs | 7 +++++++ ...invalid_rustc_layout_scalar_valid_range.stderr | 8 +++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e1d79248171a8..d5ad459126070 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1091,13 +1091,16 @@ impl<'tcx> TyCtxt<'tcx> { None => return Bound::Unbounded, }; debug!("layout_scalar_valid_range: attr={:?}", attr); - for meta in attr.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") { - match meta.literal().expect("attribute takes lit").kind { - ast::LitKind::Int(a, _) => return Bound::Included(a), - _ => span_bug!(attr.span, "rustc_layout_scalar_valid_range expects int arg"), - } + if let Some( + &[ast::NestedMetaItem::Literal(ast::Lit { kind: ast::LitKind::Int(a, _), .. })], + ) = attr.meta_item_list().as_deref() + { + Bound::Included(a) + } else { + self.sess + .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute"); + Bound::Unbounded } - span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute"); }; ( get(sym::rustc_layout_scalar_valid_range_start), diff --git a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs index 25fe4be660b24..06cf8c0f0f6d5 100644 --- a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs +++ b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs @@ -15,6 +15,13 @@ enum E { Y = 14, } +#[rustc_layout_scalar_valid_range_start(rustc_layout_scalar_valid_range_start)] //~ ERROR +struct NonZero(T); + +fn not_field() -> impl Send { + NonZero(false) +} + fn main() { let _ = A(0); let _ = B(0); diff --git a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr index 7e95fedebdfc6..7879e7358c00a 100644 --- a/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr +++ b/src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr @@ -27,5 +27,11 @@ LL | | Y = 14, LL | | } | |_- not a struct -error: aborting due to 4 previous errors +error: expected exactly one integer literal argument + --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:18:1 + | +LL | #[rustc_layout_scalar_valid_range_start(rustc_layout_scalar_valid_range_start)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors From d6de60fb322828ec3b828278f05598f2db282142 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 15 Mar 2021 17:37:06 -0400 Subject: [PATCH 25/26] Make bootstrap be more informative when one does `x.py test` on a beta checkout without other mods. To be clear, by default running `x.py test` on a checkout of the beta branch currently fails, and with this change will continue to fail, because `x.py tests` runs `x.py test src/tools/tidy` which tries to run `rustfmt` and that will fail because the `rustfmt` binary is pinned to the current nighlty and we do not attempt to distribute one for the beta builds. This change gives a better error message than the current message, which is just "./x.py fmt is not supported on this channel" without providing any hint about what one might do about that problem. (update: placated tidy.) --- src/bootstrap/test.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 5d836c6bb6232..86d940cd733da 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -791,6 +791,19 @@ impl Step for Tidy { if builder.config.channel == "dev" || builder.config.channel == "nightly" { builder.info("fmt check"); + if builder.config.initial_rustfmt.is_none() { + let inferred_rustfmt_dir = builder.config.initial_rustc.parent().unwrap(); + eprintln!( + "\ +error: no `rustfmt` binary found in {PATH} +info: `rust.channel` is currently set to \"{CHAN}\" +help: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file +help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` to `x.py test`", + PATH = inferred_rustfmt_dir.display(), + CHAN = builder.config.channel, + ); + std::process::exit(1); + } crate::format::format(&builder.build, !builder.config.cmd.bless()); } } From 4330268181c3de234457138f23bb821afd0c181e Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Tue, 16 Mar 2021 08:41:14 +0100 Subject: [PATCH 26/26] Filled tracking issue for path_try_exists This adds the ID of the tracking issue to the feature. --- library/std/src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 4dd37f76efcb1..e5e4ccac921b2 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2488,7 +2488,7 @@ impl Path { /// ``` // FIXME: stabilization should modify documentation of `exists()` to recommend this method // instead. - #[unstable(feature = "path_try_exists", issue = "none")] + #[unstable(feature = "path_try_exists", issue = "83186")] #[inline] pub fn try_exists(&self) -> io::Result { match fs::metadata(self) {