From 2f7672faec4a1005ae01f5db51c8eeaae02c065e Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sat, 9 Jan 2021 22:54:21 +0000 Subject: [PATCH 01/32] run-make: Specify --target to rustc Resolves #78911 The target's linker was used but rustc wasn't told to build for that target (instead defaulting to the host). This led to the host instead of the target getting tested and to the linker getting inappropriate arguments. --- src/test/run-make/incr-prev-body-beyond-eof/Makefile | 7 ++----- src/test/run-make/issue-36710/Makefile | 5 +---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/test/run-make/incr-prev-body-beyond-eof/Makefile b/src/test/run-make/incr-prev-body-beyond-eof/Makefile index 49a7ee5f900fd..ae447e1bd9cda 100644 --- a/src/test/run-make/incr-prev-body-beyond-eof/Makefile +++ b/src/test/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,8 +1,5 @@ include ../../run-make-fulldeps/tools.mk -# FIXME https://github.com/rust-lang/rust/issues/78911 -# ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) - # Tests that we don't ICE during incremental compilation after modifying a # function span such that its previous end line exceeds the number of lines # in the new file, but its start line/column and length remain the same. @@ -14,6 +11,6 @@ all: mkdir $(SRC) mkdir $(INCR) cp a.rs $(SRC)/main.rs - $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs + $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) cp b.rs $(SRC)/main.rs - $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs + $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index b0e8451ff5d01..3d93b2f696129 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,13 +1,10 @@ include ../../run-make-fulldeps/tools.mk -# FIXME https://github.com/rust-lang/rust/issues/78911 -# ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) - all: foo $(call RUN,foo) foo: foo.rs $(call NATIVE_STATICLIB,foo) - $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) + $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) --target $(TARGET) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<) From 1b556541965fb1925304aea4c030d5e653939c38 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 11 Jan 2021 18:24:54 +0000 Subject: [PATCH 02/32] run-make: skip issue-36710 on riscv64 The test assumes it can run target binaries on the host. This not true for riscv64 CI (or for other platforms using remote-test-server). --- src/test/run-make/issue-36710/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index 3d93b2f696129..df4c18f5dd4c3 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,3 +1,6 @@ +# ignore-riscv64 $(call RUN,foo) expects to run the target executable natively +# so it won't work with remote-test-server + include ../../run-make-fulldeps/tools.mk all: foo From f69d9543d42be95ab26d8b94fb1b0336c8d4c545 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sat, 20 Feb 2021 19:31:28 +0000 Subject: [PATCH 03/32] ci: docker: riscv64gc: specify host explicitly --- src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile index f3f52ed61d133..4377608700b0c 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile @@ -98,6 +98,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs -ENV SCRIPT python3 ../x.py --stage 2 test --target riscv64gc-unknown-linux-gnu +ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target riscv64gc-unknown-linux-gnu ENV NO_CHANGE_USER=1 From b71573bd71771b2ab77be8a8991f6b64490d06b8 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sun, 21 Feb 2021 11:19:50 +0000 Subject: [PATCH 04/32] bootstrap: don't run linkcheck when crosscompiling When we cross compile, some things (and their documentation) are built for the host (e.g. rustc), while others (and their documentation) are built for the target. This generated documentation will have broken links between documentation for different platforms e.g. between rustc and cargo. --- src/bootstrap/test.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 7830dc8239464..46d2787b9b209 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -122,7 +122,21 @@ impl Step for Linkcheck { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.path("src/tools/linkchecker").default_condition(builder.config.docs) + let run = run.path("src/tools/linkchecker"); + let hosts = &builder.hosts; + let targets = &builder.targets; + + // if we have different hosts and targets, some things may be built for + // the host (e.g. rustc) and others for the target (e.g. std). The + // documentation built for each will contain broken links to + // docs built for the other platform (e.g. rustc linking to cargo) + if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { + panic!( + "Linkcheck currently does not support builds with different hosts and targets. +You can skip linkcheck with --exclude src/tools/linkchecker" + ); + } + run.default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { From 9b23df14e49addfb580b7f141a7edb4719aa1201 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sun, 21 Feb 2021 19:32:16 +0000 Subject: [PATCH 05/32] ci: docker: x86_64: specify host explicitly --- src/ci/docker/host-x86_64/x86_64-gnu-llvm-9/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-9/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-9/Dockerfile index 38eac6588b02c..35588a62fa163 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-9/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-9/Dockerfile @@ -46,6 +46,7 @@ ENV SCRIPT python2.7 ../x.py --stage 2 test --exclude src/tools/tidy && \ # This is intended to make sure that both `--pass=check` continues to # work. # - python2.7 ../x.py --stage 2 test src/test/ui --pass=check --target=i686-unknown-linux-gnu && \ + python2.7 ../x.py --stage 2 test src/test/ui --pass=check \ + --host='' --target=i686-unknown-linux-gnu && \ # Run tidy at the very end, after all the other tests. python2.7 ../x.py --stage 2 test src/tools/tidy From 81d1d8259611f8ab6f83afe465ea21a5aa87bcc2 Mon Sep 17 00:00:00 2001 From: Henry Boisdequin Date: Sat, 13 Mar 2021 07:58:03 +0530 Subject: [PATCH 06/32] 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 07/32] 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 08/32] 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 09/32] 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 10/32] 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 11/32] 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 12/32] 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 13/32] 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 14/32] 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 15/32] 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 fa3694fada38ba1d1b0657a739736b314904ec20 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 6 Mar 2021 19:00:04 +0000 Subject: [PATCH 16/32] Always lower asm! to valid HIR --- compiler/rustc_ast_lowering/src/expr.rs | 89 ++++++++++++------------- compiler/rustc_codegen_llvm/src/asm.rs | 3 + compiler/rustc_target/src/asm/mod.rs | 14 ++++ src/test/rustdoc-ui/asm-foreign.rs | 19 ++++++ 4 files changed, 80 insertions(+), 45 deletions(-) create mode 100644 src/test/rustdoc-ui/asm-foreign.rs diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 43b93d03ff6fb..584257936027e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1331,84 +1331,83 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_expr_asm(&mut self, sp: Span, asm: &InlineAsm) -> hir::ExprKind<'hir> { - if self.sess.asm_arch.is_none() { + // Rustdoc needs to support asm! from foriegn architectures: don't try + // lowering the register contraints in this case. + let asm_arch = if self.sess.opts.actually_rustdoc { None } else { self.sess.asm_arch }; + if asm_arch.is_none() && !self.sess.opts.actually_rustdoc { struct_span_err!(self.sess, sp, E0472, "asm! is unsupported on this target").emit(); } if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) - && !matches!( - self.sess.asm_arch, - Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64) - ) + && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)) + && !self.sess.opts.actually_rustdoc { self.sess .struct_span_err(sp, "the `att_syntax` option is only supported on x86") .emit(); } - // Lower operands to HIR, filter_map skips any operands with invalid - // register classes. + // Lower operands to HIR. We use dummy register classes if an error + // occurs during lowering because we still need to be able to produce a + // valid HIR. let sess = self.sess; let operands: Vec<_> = asm .operands .iter() - .filter_map(|(op, op_sp)| { - let lower_reg = |reg| { - Some(match reg { - InlineAsmRegOrRegClass::Reg(s) => asm::InlineAsmRegOrRegClass::Reg( + .map(|(op, op_sp)| { + let lower_reg = |reg| match reg { + InlineAsmRegOrRegClass::Reg(s) => { + asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse( - sess.asm_arch?, + asm_arch, |feature| sess.target_features.contains(&Symbol::intern(feature)), &sess.target, s, ) - .map_err(|e| { + .unwrap_or_else(|e| { let msg = format!("invalid register `{}`: {}", s.as_str(), e); sess.struct_span_err(*op_sp, &msg).emit(); + asm::InlineAsmReg::Err }) - .ok()?, - ), - InlineAsmRegOrRegClass::RegClass(s) => { - asm::InlineAsmRegOrRegClass::RegClass( - asm::InlineAsmRegClass::parse(sess.asm_arch?, s) - .map_err(|e| { - let msg = format!( - "invalid register class `{}`: {}", - s.as_str(), - e - ); - sess.struct_span_err(*op_sp, &msg).emit(); - }) - .ok()?, - ) - } - }) + } else { + asm::InlineAsmReg::Err + }) + } + InlineAsmRegOrRegClass::RegClass(s) => { + asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch { + asm::InlineAsmRegClass::parse(asm_arch, s).unwrap_or_else(|e| { + let msg = format!("invalid register class `{}`: {}", s.as_str(), e); + sess.struct_span_err(*op_sp, &msg).emit(); + asm::InlineAsmRegClass::Err + }) + } else { + asm::InlineAsmRegClass::Err + }) + } }; - // lower_reg is executed last because we need to lower all - // sub-expressions even if we throw them away later. let op = match *op { InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In { + reg: lower_reg(reg), expr: self.lower_expr_mut(expr), - reg: lower_reg(reg)?, }, InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out { + reg: lower_reg(reg), late, expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)), - reg: lower_reg(reg)?, }, InlineAsmOperand::InOut { reg, late, ref expr } => { hir::InlineAsmOperand::InOut { + reg: lower_reg(reg), late, expr: self.lower_expr_mut(expr), - reg: lower_reg(reg)?, } } InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => { hir::InlineAsmOperand::SplitInOut { + reg: lower_reg(reg), late, in_expr: self.lower_expr_mut(in_expr), out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)), - reg: lower_reg(reg)?, } } InlineAsmOperand::Const { ref expr } => { @@ -1418,17 +1417,11 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) } } }; - Some((op, *op_sp)) + (op, *op_sp) }) .collect(); - // Stop if there were any errors when lowering the register classes - if operands.len() != asm.operands.len() || sess.asm_arch.is_none() { - return hir::ExprKind::Err; - } - // Validate template modifiers against the register classes for the operands - let asm_arch = sess.asm_arch.unwrap(); for p in &asm.template { if let InlineAsmTemplatePiece::Placeholder { operand_idx, @@ -1443,7 +1436,10 @@ impl<'hir> LoweringContext<'_, 'hir> { | hir::InlineAsmOperand::InOut { reg, .. } | hir::InlineAsmOperand::SplitInOut { reg, .. } => { let class = reg.reg_class(); - let valid_modifiers = class.valid_modifiers(asm_arch); + if class == asm::InlineAsmRegClass::Err { + continue; + } + let valid_modifiers = class.valid_modifiers(asm_arch.unwrap()); if !valid_modifiers.contains(&modifier) { let mut err = sess.struct_span_err( placeholder_span, @@ -1506,7 +1502,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // features. We check that at least one type is available for // the current target. let reg_class = reg.reg_class(); - for &(_, feature) in reg_class.supported_types(asm_arch) { + if reg_class == asm::InlineAsmRegClass::Err { + continue; + } + for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) { if let Some(feature) = feature { if self.sess.target_features.contains(&Symbol::intern(feature)) { required_features.clear(); diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 38c8ae711a4cb..e7d359c4f149c 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -528,6 +528,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>) InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } + InlineAsmRegClass::Err => unreachable!(), } .to_string(), } @@ -594,6 +595,7 @@ fn modifier_to_llvm( InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } + InlineAsmRegClass::Err => unreachable!(), } } @@ -637,6 +639,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } + InlineAsmRegClass::Err => unreachable!(), } } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index dfc0989a9f8df..1d0013bcd2c23 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -229,6 +229,8 @@ pub enum InlineAsmReg { Mips(MipsInlineAsmReg), SpirV(SpirVInlineAsmReg), Wasm(WasmInlineAsmReg), + // Placeholder for invalid register constraints for the current target + Err, } impl InlineAsmReg { @@ -240,6 +242,7 @@ impl InlineAsmReg { Self::RiscV(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), + Self::Err => "", } } @@ -251,6 +254,7 @@ impl InlineAsmReg { Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()), Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()), Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), + Self::Err => InlineAsmRegClass::Err, } } @@ -309,6 +313,7 @@ impl InlineAsmReg { Self::RiscV(r) => r.emit(out, arch, modifier), Self::Hexagon(r) => r.emit(out, arch, modifier), Self::Mips(r) => r.emit(out, arch, modifier), + Self::Err => unreachable!(), } } @@ -320,6 +325,7 @@ impl InlineAsmReg { Self::RiscV(_) => cb(self), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), Self::Mips(_) => cb(self), + Self::Err => unreachable!(), } } } @@ -346,6 +352,8 @@ pub enum InlineAsmRegClass { Mips(MipsInlineAsmRegClass), SpirV(SpirVInlineAsmRegClass), Wasm(WasmInlineAsmRegClass), + // Placeholder for invalid register constraints for the current target + Err, } impl InlineAsmRegClass { @@ -360,6 +368,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.name(), Self::SpirV(r) => r.name(), Self::Wasm(r) => r.name(), + Self::Err => rustc_span::symbol::sym::reg, } } @@ -377,6 +386,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm), + Self::Err => unreachable!(), } } @@ -401,6 +411,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.suggest_modifier(arch, ty), Self::SpirV(r) => r.suggest_modifier(arch, ty), Self::Wasm(r) => r.suggest_modifier(arch, ty), + Self::Err => unreachable!(), } } @@ -421,6 +432,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.default_modifier(arch), Self::SpirV(r) => r.default_modifier(arch), Self::Wasm(r) => r.default_modifier(arch), + Self::Err => unreachable!(), } } @@ -440,6 +452,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), + Self::Err => unreachable!(), } } @@ -476,6 +489,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.valid_modifiers(arch), Self::SpirV(r) => r.valid_modifiers(arch), Self::Wasm(r) => r.valid_modifiers(arch), + Self::Err => unreachable!(), } } } diff --git a/src/test/rustdoc-ui/asm-foreign.rs b/src/test/rustdoc-ui/asm-foreign.rs new file mode 100644 index 0000000000000..dfd731474179d --- /dev/null +++ b/src/test/rustdoc-ui/asm-foreign.rs @@ -0,0 +1,19 @@ +// check-pass +// Make sure rustdoc accepts asm! for a foreign architecture. + +#![feature(asm)] + +pub unsafe fn aarch64(a: f64, b: f64) { + let c; + asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { + || {}; + b + }); + c +} + +pub unsafe fn x86(a: f64, b: f64) { + let c; + asm!("addsd {}, {}, xmm0", out(xmm_reg) c, in(xmm_reg) a, in("xmm0") b); + c +} From 0bfd1429266518d86d28c29f86c30bca063706f0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 14 Mar 2021 09:48:48 -0700 Subject: [PATCH 17/32] 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 18/32] 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 3612953487bd37208de9a9df9ee5e3d40e957db8 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 Mar 2021 20:02:35 +0100 Subject: [PATCH 19/32] Do not insert impl_trait_in_bindings opaque definitions twice. --- compiler/rustc_ast_lowering/src/lib.rs | 53 ++++++++------------------ 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3a97321ceb691..80ccf727809f1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1788,14 +1788,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } - fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) { - let mut ids = SmallVec::<[NodeId; 1]>::new(); - if self.sess.features_untracked().impl_trait_in_bindings { - if let Some(ref ty) = l.ty { - let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids }; - visitor.visit_ty(ty); - } - } + fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> { let ty = l.ty.as_ref().map(|t| { let mut capturable_lifetimes; self.lower_ty( @@ -1814,17 +1807,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let init = l.init.as_ref().map(|e| self.lower_expr(e)); let hir_id = self.lower_node_id(l.id); self.lower_attrs(hir_id, &l.attrs); - ( - hir::Local { - hir_id, - ty, - pat: self.lower_pat(&l.pat), - init, - span: l.span, - source: hir::LocalSource::Normal, - }, - ids, - ) + hir::Local { + hir_id, + ty, + pat: self.lower_pat(&l.pat), + init, + span: l.span, + source: hir::LocalSource::Normal, + } } fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] { @@ -2438,27 +2428,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> { let (hir_id, kind) = match s.kind { StmtKind::Local(ref l) => { - let (l, item_ids) = self.lower_local(l); - let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids - .into_iter() - .map(|item_id| { - let item_id = hir::ItemId { - // All the items that `lower_local` finds are `impl Trait` types. - def_id: self.lower_node_id(item_id).expect_owner(), - }; - self.stmt(s.span, hir::StmtKind::Item(item_id)) - }) - .collect(); + let l = self.lower_local(l); let hir_id = self.lower_node_id(s.id); self.alias_attrs(hir_id, l.hir_id); - ids.push({ - hir::Stmt { - hir_id, - kind: hir::StmtKind::Local(self.arena.alloc(l)), - span: s.span, - } - }); - return ids; + return smallvec![hir::Stmt { + hir_id, + kind: hir::StmtKind::Local(self.arena.alloc(l)), + span: s.span, + }]; } StmtKind::Item(ref it) => { // Can only use the ID once. From 17d3308d3fe64bf402a6bfabcc16a62a702a2ba7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 Mar 2021 21:28:39 +0100 Subject: [PATCH 20/32] Remove dead code. --- compiler/rustc_ast_lowering/src/lib.rs | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 80ccf727809f1..241c942f72ccb 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -438,31 +438,6 @@ impl<'a> TokenStreamLowering<'a> { } } -struct ImplTraitTypeIdVisitor<'a> { - ids: &'a mut SmallVec<[NodeId; 1]>, -} - -impl Visitor<'_> for ImplTraitTypeIdVisitor<'_> { - fn visit_ty(&mut self, ty: &Ty) { - match ty.kind { - TyKind::Typeof(_) | TyKind::BareFn(_) => return, - - TyKind::ImplTrait(id, _) => self.ids.push(id), - _ => {} - } - visit::walk_ty(self, ty); - } - - fn visit_path_segment(&mut self, path_span: Span, path_segment: &PathSegment) { - if let Some(ref p) = path_segment.args { - if let GenericArgs::Parenthesized(_) = **p { - return; - } - } - visit::walk_path_segment(self, path_span, path_segment) - } -} - impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> { /// Full-crate AST visitor that inserts into a fresh From e8b2e7b01ce9415f448318e4acc161195efcfbb6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 Mar 2021 21:29:34 +0100 Subject: [PATCH 21/32] Assert there is no duplicate node. --- compiler/rustc_middle/src/hir/map/collector.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index b1dd405a6be68..7c2c2d13e9814 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -52,6 +52,7 @@ fn insert_vec_map(map: &mut IndexVec>, k: K, v: V if i >= len { map.extend(repeat(None).take(i - len + 1)); } + debug_assert!(map[k].is_none()); map[k] = Some(v); } @@ -216,9 +217,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { // Overwrite the dummy hash with the real HIR owner hash. nodes.hash = hash; - // FIXME: feature(impl_trait_in_bindings) broken and trigger this assert - //assert!(data.signature.is_none()); - + debug_assert!(data.signature.is_none()); data.signature = Some(self.arena.alloc(Owner { parent: entry.parent, node: entry.node })); } else { From 8eba927a3e732ee3bf992ac31d587294f81e8c46 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 14 Mar 2021 14:43:10 -0700 Subject: [PATCH 22/32] 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 ba00ddc39a99ed70ba107902767db8d4837af921 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 14 Mar 2021 23:19:16 +0000 Subject: [PATCH 23/32] Address review comments --- compiler/rustc_target/src/asm/mod.rs | 14 +++++------ .../{rustdoc-ui => rustdoc}/asm-foreign.rs | 7 +++--- src/test/rustdoc/asm-foreign2.rs | 11 +++++++++ src/test/ui/issues/issue-82869.rs | 23 ++++++++++++++++++ src/test/ui/issues/issue-82869.stderr | 24 +++++++++++++++++++ 5 files changed, 69 insertions(+), 10 deletions(-) rename src/test/{rustdoc-ui => rustdoc}/asm-foreign.rs (65%) create mode 100644 src/test/rustdoc/asm-foreign2.rs create mode 100644 src/test/ui/issues/issue-82869.rs create mode 100644 src/test/ui/issues/issue-82869.stderr diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 1d0013bcd2c23..a09c87b3ec2b2 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -313,7 +313,7 @@ impl InlineAsmReg { Self::RiscV(r) => r.emit(out, arch, modifier), Self::Hexagon(r) => r.emit(out, arch, modifier), Self::Mips(r) => r.emit(out, arch, modifier), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } @@ -325,7 +325,7 @@ impl InlineAsmReg { Self::RiscV(_) => cb(self), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), Self::Mips(_) => cb(self), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } } @@ -386,7 +386,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -411,7 +411,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.suggest_modifier(arch, ty), Self::SpirV(r) => r.suggest_modifier(arch, ty), Self::Wasm(r) => r.suggest_modifier(arch, ty), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -432,7 +432,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.default_modifier(arch), Self::SpirV(r) => r.default_modifier(arch), Self::Wasm(r) => r.default_modifier(arch), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -452,7 +452,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -489,7 +489,7 @@ impl InlineAsmRegClass { Self::Mips(r) => r.valid_modifiers(arch), Self::SpirV(r) => r.valid_modifiers(arch), Self::Wasm(r) => r.valid_modifiers(arch), - Self::Err => unreachable!(), + Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } } diff --git a/src/test/rustdoc-ui/asm-foreign.rs b/src/test/rustdoc/asm-foreign.rs similarity index 65% rename from src/test/rustdoc-ui/asm-foreign.rs rename to src/test/rustdoc/asm-foreign.rs index dfd731474179d..570ed043dd9e8 100644 --- a/src/test/rustdoc-ui/asm-foreign.rs +++ b/src/test/rustdoc/asm-foreign.rs @@ -1,9 +1,9 @@ -// check-pass // Make sure rustdoc accepts asm! for a foreign architecture. #![feature(asm)] -pub unsafe fn aarch64(a: f64, b: f64) { +// @has asm_foreign/fn.aarch64.html +pub unsafe fn aarch64(a: f64, b: f64) -> f64 { let c; asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { || {}; @@ -12,7 +12,8 @@ pub unsafe fn aarch64(a: f64, b: f64) { c } -pub unsafe fn x86(a: f64, b: f64) { +// @has asm_foreign/fn.x86.html +pub unsafe fn x86(a: f64, b: f64) -> f64 { let c; asm!("addsd {}, {}, xmm0", out(xmm_reg) c, in(xmm_reg) a, in("xmm0") b); c diff --git a/src/test/rustdoc/asm-foreign2.rs b/src/test/rustdoc/asm-foreign2.rs new file mode 100644 index 0000000000000..34e313e7eaceb --- /dev/null +++ b/src/test/rustdoc/asm-foreign2.rs @@ -0,0 +1,11 @@ +// only-aarch64 +// Make sure rustdoc accepts options(att_syntax) asm! on non-x86 targets. + +#![feature(asm)] + +// @has asm_foreign2/fn.x86.html +pub unsafe fn x86(x: i64) -> i64 { + let y; + asm!("movq {}, {}", in(reg) x, out(reg) y, options(att_syntax)); + y +} diff --git a/src/test/ui/issues/issue-82869.rs b/src/test/ui/issues/issue-82869.rs new file mode 100644 index 0000000000000..a8e688cbe1ff3 --- /dev/null +++ b/src/test/ui/issues/issue-82869.rs @@ -0,0 +1,23 @@ +// only-x86_64 +// Make sure rustc doesn't ICE on asm! for a foreign architecture. + +#![feature(asm)] +#![crate_type = "rlib"] + +pub unsafe fn aarch64(a: f64, b: f64) -> f64 { + let c; + asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { + || {}; + b + }); + //~^^^^ invalid register class + //~^^^^^ invalid register class + //~^^^^^^ invalid register + c +} + +pub unsafe fn x86(a: f64, b: f64) -> f64 { + let c; + asm!("addsd {}, {}, xmm0", out(xmm_reg) c, in(xmm_reg) a, in("xmm0") b); + c +} diff --git a/src/test/ui/issues/issue-82869.stderr b/src/test/ui/issues/issue-82869.stderr new file mode 100644 index 0000000000000..d05714ea6f215 --- /dev/null +++ b/src/test/ui/issues/issue-82869.stderr @@ -0,0 +1,24 @@ +error: invalid register class `vreg`: unknown register class + --> $DIR/issue-82869.rs:9:32 + | +LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { + | ^^^^^^^^^^^ + +error: invalid register class `vreg`: unknown register class + --> $DIR/issue-82869.rs:9:45 + | +LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { + | ^^^^^^^^^^ + +error: invalid register `d0`: unknown register + --> $DIR/issue-82869.rs:9:57 + | +LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { + | _________________________________________________________^ +LL | | || {}; +LL | | b +LL | | }); + | |_____^ + +error: aborting due to 3 previous errors + From 7134b0ee6721d25d2e211f01c2f344b0d8e68004 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 15 Mar 2021 19:20:15 +0200 Subject: [PATCH 24/32] 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 25/32] 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 db14627342e6d58c6a031e4a547c1a3c4e1a77d5 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 15 Mar 2021 18:00:14 +0000 Subject: [PATCH 26/32] test: run-make: flag tests which won't work in no-std environments --- src/test/run-make/incr-prev-body-beyond-eof/Makefile | 2 ++ src/test/run-make/issue-36710/Makefile | 1 + 2 files changed, 3 insertions(+) diff --git a/src/test/run-make/incr-prev-body-beyond-eof/Makefile b/src/test/run-make/incr-prev-body-beyond-eof/Makefile index ae447e1bd9cda..c57ce9c53e7a0 100644 --- a/src/test/run-make/incr-prev-body-beyond-eof/Makefile +++ b/src/test/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,3 +1,5 @@ +# ignore-none no-std is not supported + include ../../run-make-fulldeps/tools.mk # Tests that we don't ICE during incremental compilation after modifying a diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index df4c18f5dd4c3..7d9a46e7107de 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,5 +1,6 @@ # ignore-riscv64 $(call RUN,foo) expects to run the target executable natively # so it won't work with remote-test-server +# ignore-none no-std is not supported include ../../run-make-fulldeps/tools.mk From dcba95f43ee7b3d7a282f4d96f98d3a1deeafcd2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 15 Mar 2021 11:58:34 -0700 Subject: [PATCH 27/32] 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 7e66e9d6b04d0aa0f7ddaf24b8de379bb431fe6f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Mar 2021 19:14:18 +0300 Subject: [PATCH 28/32] More precise spans for HIR paths --- compiler/rustc_ast/src/ast.rs | 8 ++++++++ compiler/rustc_ast_lowering/src/path.rs | 13 ++++++++----- compiler/rustc_hir/src/hir.rs | 2 +- .../rustc_infer/src/traits/error_reporting/mod.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 9 +++++++-- compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- src/test/ui/bad/bad-sized.rs | 1 + src/test/ui/bad/bad-sized.stderr | 15 ++++++++++++++- .../cfg-attr-multi-true.stderr | 2 +- src/test/ui/issues/issue-78622.stderr | 2 +- src/test/ui/mir/issue-80742.stderr | 2 +- .../issue-75361-mismatched-impl.stderr | 2 +- .../associated-item-privacy-inherent.stderr | 2 +- src/test/ui/privacy/private-inferred-type.stderr | 2 +- src/test/ui/regions/issue-28848.stderr | 2 +- .../generics-default-stability.stderr | 8 ++++---- .../ui/structs/struct-path-associated-type.stderr | 4 ++-- .../suggestions/mut-borrow-needed-by-trait.stderr | 2 +- .../suggest-std-when-using-type.stderr | 4 ++-- src/test/ui/traits/item-privacy.stderr | 2 +- src/test/ui/unspecified-self-in-trait-ref.stderr | 2 +- src/test/ui/wf/wf-static-method.stderr | 2 +- 22 files changed, 60 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index a934bdd79801b..005ac8e4521ef 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -149,9 +149,17 @@ impl PathSegment { pub fn from_ident(ident: Ident) -> Self { PathSegment { ident, id: DUMMY_NODE_ID, args: None } } + pub fn path_root(span: Span) -> Self { PathSegment::from_ident(Ident::new(kw::PathRoot, span)) } + + pub fn span(&self) -> Span { + match &self.args { + Some(args) => self.ident.span.to(args.span()), + None => self.ident.span, + } + } } /// The arguments of a path segment. diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index cb4d5ea6ee650..46dac2f1af4f4 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -30,6 +30,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let partial_res = self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); + let path_span_lo = p.span.shrink_to_lo(); let proj_start = p.segments.len() - partial_res.unresolved_segments(); let path = self.arena.alloc(hir::Path { res: self.lower_res(partial_res.base_res()), @@ -108,7 +109,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }, )), - span: p.span, + span: p.segments[..proj_start] + .last() + .map_or(path_span_lo, |segment| path_span_lo.to(segment.span())), }); // Simple case, either no projections, or only fully-qualified. @@ -127,7 +130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // e.g., `Vec` in `Vec::new` or `::Item` in // `::Item::default`. let new_id = self.next_id(); - self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))) + self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path))) }; // Anything after the base path are associated "extensions", @@ -141,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // 3. `<>::IntoIter>::Item` // * final path is `<<>::IntoIter>::Item>::clone` for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { - let segment = self.arena.alloc(self.lower_path_segment( + let hir_segment = self.arena.alloc(self.lower_path_segment( p.span, segment, param_mode, @@ -150,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx.reborrow(), None, )); - let qpath = hir::QPath::TypeRelative(ty, segment); + let qpath = hir::QPath::TypeRelative(ty, hir_segment); // It's finished, return the extension of the right node type. if i == p.segments.len() - 1 { @@ -159,7 +162,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Wrap the associated extension in another type node. let new_id = self.next_id(); - ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath)); + ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath)); } // We should've returned in the for loop above. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8f61adcd8e288..20935231274f7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1809,7 +1809,7 @@ impl<'hir> QPath<'hir> { pub fn span(&self) -> Span { match *self { QPath::Resolved(_, path) => path.span, - QPath::TypeRelative(_, ps) => ps.ident.span, + QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span), QPath::LangItem(_, span) => span, } } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 835f75ec8ef06..ad15af9ab3f2d 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -104,7 +104,7 @@ pub fn report_object_safety_error( ", ); - if tcx.sess.trait_methods_not_found.borrow().contains(&span) { + if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) { // Avoid emitting error caused by non-existing method (#58734) err.cancel(); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 89501d9ce9725..a973b56f7d62c 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1414,8 +1414,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { name: Symbol, ) { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); - if let (Some(_), Ok(snippet)) = ( - self.tcx().sess.confused_type_with_std_module.borrow().get(&span), + if let (true, Ok(snippet)) = ( + self.tcx() + .sess + .confused_type_with_std_module + .borrow() + .keys() + .any(|full_span| full_span.contains(span)), self.tcx().sess.source_map().span_to_snippet(span), ) { err.span_suggestion( diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 5b8b25c210018..528a6d1bd52e2 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath: &QPath<'_>, hir_id: hir::HirId, ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { - let path_span = qpath.qself_span(); + let path_span = qpath.span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); let variant = match def { Res::Err => { diff --git a/src/test/ui/bad/bad-sized.rs b/src/test/ui/bad/bad-sized.rs index b899c59ff2ea7..a15219679788d 100644 --- a/src/test/ui/bad/bad-sized.rs +++ b/src/test/ui/bad/bad-sized.rs @@ -5,4 +5,5 @@ pub fn main() { //~^ ERROR only auto traits can be used as additional traits in a trait object //~| ERROR the size for values of type //~| ERROR the size for values of type + //~| ERROR the size for values of type } diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr index 260d78b543a4c..768893d6e25d4 100644 --- a/src/test/ui/bad/bad-sized.stderr +++ b/src/test/ui/bad/bad-sized.stderr @@ -31,7 +31,20 @@ LL | let x: Vec = Vec::new(); = help: the trait `Sized` is not implemented for `dyn Trait` = note: required by `Vec::::new` -error: aborting due to 3 previous errors +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/bad-sized.rs:4:37 + | +LL | let x: Vec = Vec::new(); + | ^^^ doesn't have a size known at compile-time + | + ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec { + | - required by this bound in `Vec` + | + = help: the trait `Sized` is not implemented for `dyn Trait` + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0225, E0277. For more information about an error, try `rustc --explain E0225`. diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index 21b3a6f1f33b6..5f278f94b93bd 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -10,7 +10,7 @@ warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:19:5 | LL | MustUseDeprecated::new(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:13:17 diff --git a/src/test/ui/issues/issue-78622.stderr b/src/test/ui/issues/issue-78622.stderr index f13073da0a36e..f7d44f21d3bec 100644 --- a/src/test/ui/issues/issue-78622.stderr +++ b/src/test/ui/issues/issue-78622.stderr @@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type --> $DIR/issue-78622.rs:5:5 | LL | S::A:: {} - | ^^^^^^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ help: use fully-qualified syntax: `::A` error: aborting due to previous error diff --git a/src/test/ui/mir/issue-80742.stderr b/src/test/ui/mir/issue-80742.stderr index 8cbd0220e6768..8400aab308e06 100644 --- a/src/test/ui/mir/issue-80742.stderr +++ b/src/test/ui/mir/issue-80742.stderr @@ -56,7 +56,7 @@ LL | struct Inline | - required by this bound in `Inline` ... LL | let dst = Inline::::new(0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Debug` help: consider relaxing the implicit `Sized` restriction diff --git a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr index 4b86a1fede163..a64cb82305a48 100644 --- a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr +++ b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr @@ -13,7 +13,7 @@ help: the lifetime requirements from the `impl` do not correspond to the require --> $DIR/issue-75361-mismatched-impl.rs:12:55 | LL | fn adjacent_edges(&self) -> Box>; - | ^^^^^^^^^^^^^^ consider borrowing this type parameter in the trait + | ^^^^ consider borrowing this type parameter in the trait error: aborting due to previous error diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.stderr b/src/test/ui/privacy/associated-item-privacy-inherent.stderr index 1e94e7c620d03..f8585014fd6d8 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.stderr +++ b/src/test/ui/privacy/associated-item-privacy-inherent.stderr @@ -222,7 +222,7 @@ error: type `priv_parent_substs::Priv` is private --> $DIR/associated-item-privacy-inherent.rs:101:9 | LL | Pub::CONST; - | ^^^^^^^^^^ private type + | ^^^ private type ... LL | priv_parent_substs::mac!(); | --------------------------- in this macro invocation diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr index 8c8163d3906b3..11bcb9074d097 100644 --- a/src/test/ui/privacy/private-inferred-type.stderr +++ b/src/test/ui/privacy/private-inferred-type.stderr @@ -56,7 +56,7 @@ error: type `Priv` is private --> $DIR/private-inferred-type.rs:104:5 | LL | m::Pub::INHERENT_ASSOC_CONST; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type + | ^^^^^^ private type error: type `Priv` is private --> $DIR/private-inferred-type.rs:105:5 diff --git a/src/test/ui/regions/issue-28848.stderr b/src/test/ui/regions/issue-28848.stderr index 726844a31841f..83313b34316b4 100644 --- a/src/test/ui/regions/issue-28848.stderr +++ b/src/test/ui/regions/issue-28848.stderr @@ -2,7 +2,7 @@ error[E0478]: lifetime bound not satisfied --> $DIR/issue-28848.rs:10:5 | LL | Foo::<'a, 'b>::xmute(u) - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16 --> $DIR/issue-28848.rs:9:16 diff --git a/src/test/ui/stability-attribute/generics-default-stability.stderr b/src/test/ui/stability-attribute/generics-default-stability.stderr index a5df70bb8b3dd..45194413cceec 100644 --- a/src/test/ui/stability-attribute/generics-default-stability.stderr +++ b/src/test/ui/stability-attribute/generics-default-stability.stderr @@ -100,7 +100,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test --> $DIR/generics-default-stability.rs:160:28 | LL | let _: Alias4 = Alias4::Some(1); - | ^^^^^^^^^^^^ + | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test --> $DIR/generics-default-stability.rs:160:12 @@ -124,7 +124,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test --> $DIR/generics-default-stability.rs:166:28 | LL | let _: Alias4 = Alias4::Some(0); - | ^^^^^^^^^^^^ + | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test --> $DIR/generics-default-stability.rs:166:12 @@ -136,7 +136,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test --> $DIR/generics-default-stability.rs:171:28 | LL | let _: Alias5 = Alias5::Some(1); - | ^^^^^^^^^^^^ + | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test --> $DIR/generics-default-stability.rs:171:12 @@ -160,7 +160,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test --> $DIR/generics-default-stability.rs:178:28 | LL | let _: Alias5 = Alias5::Some(0); - | ^^^^^^^^^^^^ + | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test --> $DIR/generics-default-stability.rs:178:12 diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr index f8a2c7c6b6c20..0b1b6a5e3af28 100644 --- a/src/test/ui/structs/struct-path-associated-type.stderr +++ b/src/test/ui/structs/struct-path-associated-type.stderr @@ -14,7 +14,7 @@ error[E0071]: expected struct, variant or union type, found associated type --> $DIR/struct-path-associated-type.rs:14:13 | LL | let z = T::A:: {}; - | ^^^^^^^^^^ not a struct + | ^^^^ not a struct error[E0071]: expected struct, variant or union type, found associated type --> $DIR/struct-path-associated-type.rs:18:9 @@ -38,7 +38,7 @@ error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:33:13 | LL | let z = S::A:: {}; - | ^^^^^^^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ help: use fully-qualified syntax: `::A` error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:35:9 diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 3120b739c0295..b8ef230b44bb7 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -11,7 +11,7 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satis --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | LL | let fp = BufWriter::new(fp); - | ^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` + | ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` | ::: $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL | diff --git a/src/test/ui/suggestions/suggest-std-when-using-type.stderr b/src/test/ui/suggestions/suggest-std-when-using-type.stderr index 5199faa5c8ec6..7f4c80f50e267 100644 --- a/src/test/ui/suggestions/suggest-std-when-using-type.stderr +++ b/src/test/ui/suggestions/suggest-std-when-using-type.stderr @@ -2,12 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/suggest-std-when-using-type.rs:2:14 | LL | let pi = f32::consts::PI; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | help: you are looking for the module in `std`, not the primitive type | LL | let pi = std::f32::consts::PI; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope --> $DIR/suggest-std-when-using-type.rs:5:14 diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr index 6fd82142d61f7..b7dad54a6d3a9 100644 --- a/src/test/ui/traits/item-privacy.stderr +++ b/src/test/ui/traits/item-privacy.stderr @@ -113,7 +113,7 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/item-privacy.rs:101:5 | LL | C::A; - | ^^^^ `assoc_const::C` cannot be made into an object + | ^ `assoc_const::C` cannot be made into an object | = help: consider moving `C` to another trait = help: consider moving `B` to another trait diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr index 9310b3d7ede00..c9518170222c0 100644 --- a/src/test/ui/unspecified-self-in-trait-ref.stderr +++ b/src/test/ui/unspecified-self-in-trait-ref.stderr @@ -31,7 +31,7 @@ LL | | } | |_- type parameter `A` must be specified for this ... LL | let e = Bar::::lol(); - | ^^^^^^^^^^^^^^^^^ missing reference to `A` + | ^^^^^^^^^^^^ missing reference to `A` | = note: because of the default `Self` reference, type parameters must be specified on object types diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr index 93d16514a5078..0c98a809025ac 100644 --- a/src/test/ui/wf/wf-static-method.stderr +++ b/src/test/ui/wf/wf-static-method.stderr @@ -19,7 +19,7 @@ error[E0478]: lifetime bound not satisfied --> $DIR/wf-static-method.rs:26:18 | LL | let me = Self::make_me(); - | ^^^^^^^^^^^^^ + | ^^^^ | note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 23:10 --> $DIR/wf-static-method.rs:23:10 From ff8717b56dfe71f371566db52d72684088da8e61 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Mon, 15 Mar 2021 20:14:56 +0100 Subject: [PATCH 29/32] 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 30/32] 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 d6a7c1d47fdf68626b5535ff24bd115e4aba7d71 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 15 Mar 2021 15:54:25 -0400 Subject: [PATCH 31/32] Extend `proc_macro_back_compat` lint to `procedural-masquerade` We now lint on *any* use of `procedural-masquerade` crate. While this crate still exists, its main reverse dependency (`cssparser`) no longer depends on it. Any crates still depending off should stop doing so, as it only exists to support very old Rust versions. If a crate actually needs to support old versions of rustc via `procedural-masquerade`, then they'll just need to accept the warning until we remove it entirely (at the same time as the back-compat hack). The latest version of `procedural-masquerade` does not work with the latest rustc, but trying to check for the version seems like more trouble than it's worth. While working on this, I realized that the `proc-macro-hack` check was never actually doing anything. The corresponding enum variant in `proc-macro-hack` is named `Value` or `Nested` - it has never been called `Input`. Due to a strange Crater issue, the Crater run that tested adding this did *not* end up testing it - some of the crates that would have failed did not actually have their tests checked, making it seem as though the `proc-macro-hack` check was working. The Crater issue is being discussed at https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/Nearly.20identical.20Crater.20runs.20processed.20a.20crate.20differently/near/230406661 Despite the `proc-macro-hack` check not actually doing anything, we haven't gotten any reports from users about their build being broken. I went ahead and removed it entirely, since it's clear that no one is being affected by the `proc-macro-hack` regression in practice. --- compiler/rustc_ast/src/token.rs | 27 ------------- compiler/rustc_expand/src/base.rs | 40 +++++++++++++++++++ compiler/rustc_expand/src/proc_macro.rs | 3 +- .../rustc_expand/src/proc_macro_server.rs | 2 +- .../issue-73933-procedural-masquerade.rs | 13 ++++++ .../issue-73933-procedural-masquerade.stderr | 25 ++++++++++++ .../issue-73933-procedural-masquerade.stdout | 22 ++++++++++ 7 files changed, 103 insertions(+), 29 deletions(-) create mode 100644 src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs create mode 100644 src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr create mode 100644 src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 093f7f2668c46..7e58426d27de4 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -784,33 +784,6 @@ impl Nonterminal { NtTT(tt) => tt.span(), } } - - /// This nonterminal looks like some specific enums from - /// `proc-macro-hack` and `procedural-masquerade` crates. - /// We need to maintain some special pretty-printing behavior for them due to incorrect - /// asserts in old versions of those crates and their wide use in the ecosystem. - /// See issue #73345 for more details. - /// FIXME(#73933): Remove this eventually. - pub fn pretty_printing_compatibility_hack(&self) -> bool { - let item = match self { - NtItem(item) => item, - NtStmt(stmt) => match &stmt.kind { - ast::StmtKind::Item(item) => item, - _ => return false, - }, - _ => return false, - }; - - let name = item.ident.name; - if name == sym::ProceduralMasqueradeDummyType || name == sym::ProcMacroHack { - if let ast::ItemKind::Enum(enum_def, _) = &item.kind { - if let [variant] = &*enum_def.variants { - return variant.ident.name == sym::Input; - } - } - } - false - } } impl PartialEq for Nonterminal { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index dd93fe8350e42..ce65793051837 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -10,6 +10,8 @@ use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{DiagnosticBuilder, ErrorReported}; +use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; +use rustc_lint_defs::BuiltinLintDiagnostics; use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS}; use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::DefId; @@ -1241,3 +1243,41 @@ pub fn get_exprs_from_tts( } Some(es) } + +/// This nonterminal looks like some specific enums from +/// `proc-macro-hack` and `procedural-masquerade` crates. +/// We need to maintain some special pretty-printing behavior for them due to incorrect +/// asserts in old versions of those crates and their wide use in the ecosystem. +/// See issue #73345 for more details. +/// FIXME(#73933): Remove this eventually. +pub(crate) fn pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool { + let item = match nt { + Nonterminal::NtItem(item) => item, + Nonterminal::NtStmt(stmt) => match &stmt.kind { + ast::StmtKind::Item(item) => item, + _ => return false, + }, + _ => return false, + }; + + let name = item.ident.name; + if name == sym::ProceduralMasqueradeDummyType { + if let ast::ItemKind::Enum(enum_def, _) = &item.kind { + if let [variant] = &*enum_def.variants { + if variant.ident.name == sym::Input { + sess.buffer_lint_with_diagnostic( + &PROC_MACRO_BACK_COMPAT, + item.ident.span, + ast::CRATE_NODE_ID, + "using `procedural-masquerade` crate", + BuiltinLintDiagnostics::ProcMacroBackCompat( + "The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. \ + Versions of this crate below 0.1.7 will eventually stop compiling.".to_string()) + ); + return true; + } + } + } + } + false +} diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 8cbaa7c945a81..61b776ff2d280 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -90,7 +90,8 @@ impl MultiItemModifier for ProcMacroDerive { } _ => unreachable!(), }; - let input = if item.pretty_printing_compatibility_hack() { + let input = if crate::base::pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess) + { TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into() } else { nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::Yes) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 837fad905800a..67edfe19da383 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -187,7 +187,7 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec)> delimiter: Delimiter::None, stream, span: DelimSpan::from_single(span), - flatten: nt.pretty_printing_compatibility_hack(), + flatten: crate::base::pretty_printing_compatibility_hack(&nt, sess), }) } } diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs new file mode 100644 index 0000000000000..abc3d2691a307 --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs @@ -0,0 +1,13 @@ +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[derive(Print)] +enum ProceduralMasqueradeDummyType { //~ WARN using +//~| WARN this was previously + Input +} + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr new file mode 100644 index 0000000000000..0b930705e3510 --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr @@ -0,0 +1,25 @@ +warning: using `procedural-masquerade` crate + --> $DIR/issue-73933-procedural-masquerade.rs:8:6 + | +LL | enum ProceduralMasqueradeDummyType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(proc_macro_back_compat)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + +warning: 1 warning emitted + +Future incompatibility report: Future breakage date: None, diagnostic: +warning: using `procedural-masquerade` crate + --> $DIR/issue-73933-procedural-masquerade.rs:8:6 + | +LL | enum ProceduralMasqueradeDummyType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(proc_macro_back_compat)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout new file mode 100644 index 0000000000000..8edd68f8a3b84 --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout @@ -0,0 +1,22 @@ +PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, } +PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input } +PRINT-DERIVE INPUT (DEBUG): TokenStream [ + Ident { + ident: "enum", + span: #0 bytes(100..104), + }, + Ident { + ident: "ProceduralMasqueradeDummyType", + span: #0 bytes(105..134), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Ident { + ident: "Input", + span: #0 bytes(186..191), + }, + ], + span: #0 bytes(135..193), + }, +] From e98b7d1bcf7031447bd569dfe4798203e4c3ccda Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 15 Mar 2021 23:52:57 +0300 Subject: [PATCH 32/32] Update clippy tests --- src/tools/clippy/tests/ui/use_self.fixed | 23 ++++++++++--------- src/tools/clippy/tests/ui/use_self.rs | 23 ++++++++++--------- src/tools/clippy/tests/ui/use_self.stderr | 16 ++----------- .../ui/zero_sized_btreemap_values.stderr | 2 +- .../tests/ui/zero_sized_hashmap_values.stderr | 2 +- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed index a630936e3b1d0..b94d5448d9238 100644 --- a/src/tools/clippy/tests/ui/use_self.fixed +++ b/src/tools/clippy/tests/ui/use_self.fixed @@ -312,17 +312,18 @@ mod issue4140 { fn try_from(value: T) -> Result>; } - impl TryFrom for T - where - T: From, - { - type From = Self; - type To = Self; - - fn try_from(value: F) -> Result> { - Ok(From::from(value)) - } - } + // FIXME: Suggested fix results in infinite recursion. + // impl TryFrom for T + // where + // T: From, + // { + // type From = Self::From; + // type To = Self::To; + + // fn try_from(value: F) -> Result> { + // Ok(From::from(value)) + // } + // } impl From for i64 { type From = bool; diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs index f3e081dd20328..ac99c6d9d7bb1 100644 --- a/src/tools/clippy/tests/ui/use_self.rs +++ b/src/tools/clippy/tests/ui/use_self.rs @@ -312,17 +312,18 @@ mod issue4140 { fn try_from(value: T) -> Result>; } - impl TryFrom for T - where - T: From, - { - type From = T::From; - type To = T::To; - - fn try_from(value: F) -> Result> { - Ok(From::from(value)) - } - } + // FIXME: Suggested fix results in infinite recursion. + // impl TryFrom for T + // where + // T: From, + // { + // type From = Self::From; + // type To = Self::To; + + // fn try_from(value: F) -> Result> { + // Ok(From::from(value)) + // } + // } impl From for i64 { type From = bool; diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr index e1410d2e652c1..a32a9b9157d74 100644 --- a/src/tools/clippy/tests/ui/use_self.stderr +++ b/src/tools/clippy/tests/ui/use_self.stderr @@ -157,22 +157,10 @@ LL | Foo { value } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:319:21 - | -LL | type From = T::From; - | ^^^^^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/use_self.rs:320:19 - | -LL | type To = T::To; - | ^^^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/use_self.rs:453:13 + --> $DIR/use_self.rs:454:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` -error: aborting due to 29 previous errors +error: aborting due to 27 previous errors diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr index 334d921a9af3f..d924f33797d29 100644 --- a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr +++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr @@ -83,7 +83,7 @@ error: map with zero-sized value type --> $DIR/zero_sized_btreemap_values.rs:64:35 | LL | let _: BTreeMap = BTreeMap::new(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^ | = help: consider using a set instead diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr index 43987b3d01d16..79770bf90d701 100644 --- a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr +++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr @@ -83,7 +83,7 @@ error: map with zero-sized value type --> $DIR/zero_sized_hashmap_values.rs:64:34 | LL | let _: HashMap = HashMap::new(); - | ^^^^^^^^^^^^ + | ^^^^^^^ | = help: consider using a set instead