From b93020257e4b6c88cd7947257984b1da2158a757 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 18 Jun 2025 12:23:35 +0000 Subject: [PATCH 01/15] hir_analysis: add `#![rustc_no_implicit_bounds]` Adds a new `rustc_attrs` attribute that stops rustc from adding any default bounds. Useful for tests where default bounds just add noise and make debugging harder. --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++++ .../src/hir_ty_lowering/bounds.rs | 20 ++++++++++--------- compiler/rustc_span/src/symbol.rs | 1 + 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7d6e471e7e951..705836b4fa3c4 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1108,6 +1108,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes ), + rustc_attr!( + TEST, rustc_no_implicit_bounds, CrateLevel, template!(Word), + WarnFollowing, EncodeCrossCrate::No + ), rustc_attr!( TEST, rustc_strict_coherence, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index ea1dfdfd80619..e06df5e4679f4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -5,14 +5,14 @@ use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::{AmbigArg, LangItem, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, }; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::traits; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -188,6 +188,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) { let tcx = self.tcx(); + // Skip adding any default bounds if `#![rustc_no_implicit_bounds]` + if tcx.has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) { + return; + } + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span); let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span); @@ -408,24 +413,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let trait_id = tcx.lang_items().get(trait_); if let Some(trait_id) = trait_id - && self.do_not_provide_default_trait_bound( - trait_id, - hir_bounds, - self_ty_where_predicates, - ) + && self.should_add_default_traits(trait_id, hir_bounds, self_ty_where_predicates) { add_trait_bound(tcx, bounds, self_ty, trait_id, span); } } - fn do_not_provide_default_trait_bound<'a>( + /// Returns `true` if default trait bound should be added. + fn should_add_default_traits<'a>( &self, trait_def_id: DefId, hir_bounds: &'a [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, ) -> bool { let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id); - !collected.any() + !self.tcx().has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) && !collected.any() } /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index baadff16120f3..6102a73bcdae7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1866,6 +1866,7 @@ symbols! { rustc_never_returns_null_ptr, rustc_never_type_options, rustc_no_implicit_autorefs, + rustc_no_implicit_bounds, rustc_no_mir_inline, rustc_nonnull_optimization_guaranteed, rustc_nounwind, From 625f8ee5dc9341320cbb221cc6a9c133bd0c6ea4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 26 Jun 2025 11:15:55 +0200 Subject: [PATCH 02/15] Fix documentation of validate_operand The name of the parameter changed from `op` to `val` in cbdcbf0d6a586792c5e0a0b8965a3179bac56120 --- compiler/rustc_const_eval/src/interpret/validity.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 7d76d925ef23e..231f8091777b3 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1364,8 +1364,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }) } - /// This function checks the data at `op` to be const-valid. - /// `op` is assumed to cover valid memory if it is an indirect operand. + /// This function checks the data at `val` to be const-valid. + /// `val` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. /// /// `ref_tracking` is used to record references that we encounter so that they @@ -1391,8 +1391,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) } - /// This function checks the data at `op` to be runtime-valid. - /// `op` is assumed to cover valid memory if it is an indirect operand. + /// This function checks the data at `val` to be runtime-valid. + /// `val` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. #[inline(always)] pub fn validate_operand( From d1f313649ce215c9b0442354ec6aa03384d7101c Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 26 Jun 2025 23:06:38 +0800 Subject: [PATCH 03/15] Only args in main diag are saved and restored without removing the newly added ones Signed-off-by: xizheyin --- .../src/diagnostics/subdiagnostic.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 04fdada802494..dcd0116d804d3 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -220,7 +220,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } /// Generates the code for a field with no attributes. - fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> (TokenStream, TokenStream) { + fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream { let diag = &self.parent.diag; let field = binding_info.ast(); @@ -230,16 +230,12 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let ident = field.ident.as_ref().unwrap(); let ident = format_ident!("{}", ident); // strip `r#` prefix, if present - let args = quote! { + quote! { #diag.arg( stringify!(#ident), #field_binding ); - }; - let remove_args = quote! { - #diag.remove_arg(stringify!(#ident)); - }; - (args, remove_args) + } } /// Generates the necessary code for all attributes on a field. @@ -610,7 +606,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let restore_args = quote! { #diag.restore_args(); }; - let (plain_args, remove_args): (TokenStream, TokenStream) = self + let plain_args: TokenStream = self .variant .bindings() .iter() @@ -623,9 +619,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { // For #[derive(Subdiagnostic)] // // - Store args of the main diagnostic for later restore. - // - add args of subdiagnostic. + // - Add args of subdiagnostic. // - Generate the calls, such as note, label, etc. - // - Remove the arguments for allowing Vec to be used. // - Restore the arguments for allowing main and subdiagnostic share the same fields. Ok(quote! { #init @@ -634,7 +629,6 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { #store_args #plain_args #calls - #remove_args #restore_args }) } From 3b259ad33c8257944bf7069d3c6f463393bf7bc4 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 9 Jun 2025 15:33:30 -0500 Subject: [PATCH 04/15] rustdoc js: several typechecking improvments non-exhaustive list of changes: * rustdoc.Results has a max_dist field * improve typechecking around pathDist and addIntoResults * give handleNameSearch a type signature * typecheck sortQ * currentCrate is string and not optional * searchState is referenced as a global, not through window --- src/librustdoc/html/static/js/rustdoc.d.ts | 28 ++++--- src/librustdoc/html/static/js/search.js | 92 +++++++--------------- 2 files changed, 43 insertions(+), 77 deletions(-) diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 6af16441de88b..bbcd96040bec6 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -4,6 +4,8 @@ /* eslint-disable */ declare global { + /** Search engine data used by main.js and search.js */ + declare var searchState: rustdoc.SearchState; /** Defined and documented in `storage.js` */ declare function nonnull(x: T|null, msg: string|undefined); /** Defined and documented in `storage.js` */ @@ -17,8 +19,6 @@ declare global { RUSTDOC_TOOLTIP_HOVER_MS: number; /** Used by the popover tooltip code. */ RUSTDOC_TOOLTIP_HOVER_EXIT_MS: number; - /** Search engine data used by main.js and search.js */ - searchState: rustdoc.SearchState; /** Global option, with a long list of "../"'s */ rootPath: string|null; /** @@ -102,20 +102,22 @@ declare namespace rustdoc { currentTab: number; focusedByTab: [number|null, number|null, number|null]; clearInputTimeout: function; - outputElement: function(): HTMLElement|null; - focus: function(); - defocus: function(); - showResults: function(HTMLElement|null|undefined); - removeQueryParameters: function(); - hideResults: function(); - getQueryStringParams: function(): Object.; + outputElement(): HTMLElement|null; + focus(); + defocus(); + // note: an optional param is not the same as + // a nullable/undef-able param. + showResults(elem?: HTMLElement|null); + removeQueryParameters(); + hideResults(); + getQueryStringParams(): Object.; origPlaceholder: string; setup: function(); - setLoadingSearch: function(); + setLoadingSearch(); descShards: Map; loadDesc: function({descShard: SearchDescShard, descIndex: number}): Promise; - loadedDescShard: function(string, number, string); - isDisplayed: function(): boolean, + loadedDescShard(string, number, string); + isDisplayed(): boolean, } interface SearchDescShard { @@ -237,7 +239,7 @@ declare namespace rustdoc { query: ParsedQuery, } - type Results = Map; + type Results = { max_dist?: number } & Map /** * An annotated `Row`, used in the viewmodel. diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index a2c48708512e8..15cad31f555a6 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2515,13 +2515,17 @@ class DocSearch { * * @param {rustdoc.ParsedQuery} origParsedQuery * - The parsed user query - * @param {Object} [filterCrates] - Crate to search in if defined - * @param {Object} [currentCrate] - Current crate, to rank results from this crate higher + * @param {Object} filterCrates - Crate to search in if defined + * @param {string} currentCrate - Current crate, to rank results from this crate higher * * @return {Promise} */ async execQuery(origParsedQuery, filterCrates, currentCrate) { - const results_others = new Map(), results_in_args = new Map(), + /** @type {rustdoc.Results} */ + const results_others = new Map(), + /** @type {rustdoc.Results} */ + results_in_args = new Map(), + /** @type {rustdoc.Results} */ results_returned = new Map(); /** @type {rustdoc.ParsedQuery} */ @@ -4365,7 +4369,7 @@ class DocSearch { * * The `results` map contains information which will be used to sort the search results: * - * * `fullId` is a `string`` used as the key of the object we use for the `results` map. + * * `fullId` is an `integer`` used as the key of the object we use for the `results` map. * * `id` is the index in the `searchIndex` array for this element. * * `index` is an `integer`` used to sort by the position of the word in the item's name. * * `dist` is the main metric used to sort the search results. @@ -4373,19 +4377,18 @@ class DocSearch { * distance computed for everything other than the last path component. * * @param {rustdoc.Results} results - * @param {string} fullId + * @param {number} fullId * @param {number} id * @param {number} index * @param {number} dist * @param {number} path_dist + * @param {number} maxEditDistance */ - // @ts-expect-error function addIntoResults(results, fullId, id, index, dist, path_dist, maxEditDistance) { if (dist <= maxEditDistance || index !== -1) { if (results.has(fullId)) { const result = results.get(fullId); - // @ts-expect-error - if (result.dontValidate || result.dist <= dist) { + if (result === undefined || result.dontValidate || result.dist <= dist) { return; } } @@ -4452,9 +4455,8 @@ class DocSearch { return; } - // @ts-expect-error results.max_dist = Math.max(results.max_dist || 0, tfpDist); - addIntoResults(results, row.id.toString(), pos, 0, tfpDist, 0, Number.MAX_VALUE); + addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE); } /** @@ -4495,7 +4497,7 @@ class DocSearch { if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) { const elem = parsedQuery.elems[0]; // use arrow functions to preserve `this`. - // @ts-expect-error + /** @type {function(number): void} */ const handleNameSearch = id => { const row = this.searchIndex[id]; if (!typePassesFilter(elem.typeFilter, row.ty) || @@ -4505,22 +4507,21 @@ class DocSearch { let pathDist = 0; if (elem.fullPath.length > 1) { - // @ts-expect-error - pathDist = checkPath(elem.pathWithoutLast, row); - if (pathDist === null) { + + const maybePathDist = checkPath(elem.pathWithoutLast, row); + if (maybePathDist === null) { return; } + pathDist = maybePathDist; } if (parsedQuery.literalSearch) { if (row.word === elem.pathLast) { - // @ts-expect-error - addIntoResults(results_others, row.id, id, 0, 0, pathDist); + addIntoResults(results_others, row.id, id, 0, 0, pathDist, 0); } } else { addIntoResults( results_others, - // @ts-expect-error row.id, id, row.normalizedName.indexOf(elem.normalizedPathLast), @@ -4561,31 +4562,23 @@ class DocSearch { const returned = row.type && row.type.output && checkIfInList(row.type.output, elem, row.type.where_clause, null, 0); if (in_args) { - // @ts-expect-error results_in_args.max_dist = Math.max( - // @ts-expect-error results_in_args.max_dist || 0, tfpDist, ); const maxDist = results_in_args.size < MAX_RESULTS ? (tfpDist + 1) : - // @ts-expect-error results_in_args.max_dist; - // @ts-expect-error addIntoResults(results_in_args, row.id, i, -1, tfpDist, 0, maxDist); } if (returned) { - // @ts-expect-error results_returned.max_dist = Math.max( - // @ts-expect-error results_returned.max_dist || 0, tfpDist, ); const maxDist = results_returned.size < MAX_RESULTS ? (tfpDist + 1) : - // @ts-expect-error results_returned.max_dist; - // @ts-expect-error addIntoResults(results_returned, row.id, i, -1, tfpDist, 0, maxDist); } } @@ -4595,18 +4588,17 @@ class DocSearch { // types with generic parameters go last. // That's because of the way unification is structured: it eats off // the end, and hits a fast path if the last item is a simple atom. - // @ts-expect-error + /** @type {function(rustdoc.QueryElement, rustdoc.QueryElement): number} */ const sortQ = (a, b) => { const ag = a.generics.length === 0 && a.bindings.size === 0; const bg = b.generics.length === 0 && b.bindings.size === 0; if (ag !== bg) { - // @ts-expect-error - return ag - bg; + // unary `+` converts booleans into integers. + return +ag - +bg; } - const ai = a.id > 0; - const bi = b.id > 0; - // @ts-expect-error - return ai - bi; + const ai = a.id !== null && a.id > 0; + const bi = b.id !== null && b.id > 0; + return +ai - +bi; }; parsedQuery.elems.sort(sortQ); parsedQuery.returned.sort(sortQ); @@ -4622,9 +4614,7 @@ class DocSearch { const isType = parsedQuery.foundElems !== 1 || parsedQuery.hasReturnArrow; const [sorted_in_args, sorted_returned, sorted_others] = await Promise.all([ - // @ts-expect-error sortResults(results_in_args, "elems", currentCrate), - // @ts-expect-error sortResults(results_returned, "returned", currentCrate), // @ts-expect-error sortResults(results_others, (isType ? "query" : null), currentCrate), @@ -4724,7 +4714,6 @@ function printTab(nb) { iter += 1; }); if (foundCurrentTab && foundCurrentResultSet) { - // @ts-expect-error searchState.currentTab = nb; // Corrections only kick in on type-based searches. const correctionsElem = document.getElementsByClassName("search-corrections"); @@ -4777,7 +4766,6 @@ function getFilterCrates() { // @ts-expect-error function nextTab(direction) { - // @ts-expect-error const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length; // @ts-expect-error searchState.focusedByTab[searchState.currentTab] = document.activeElement; @@ -4788,14 +4776,12 @@ function nextTab(direction) { // Focus the first search result on the active tab, or the result that // was focused last time this tab was active. function focusSearchResult() { - // @ts-expect-error const target = searchState.focusedByTab[searchState.currentTab] || document.querySelectorAll(".search-results.active a").item(0) || - // @ts-expect-error document.querySelectorAll("#search-tabs button").item(searchState.currentTab); - // @ts-expect-error searchState.focusedByTab[searchState.currentTab] = null; if (target) { + // @ts-expect-error target.focus(); } } @@ -4947,7 +4933,6 @@ function makeTabHeader(tabNb, text, nbElems) { const fmtNbElems = nbElems < 10 ? `\u{2007}(${nbElems})\u{2007}\u{2007}` : nbElems < 100 ? `\u{2007}(${nbElems})\u{2007}` : `\u{2007}(${nbElems})`; - // @ts-expect-error if (searchState.currentTab === tabNb) { return ""; @@ -4961,7 +4946,6 @@ function makeTabHeader(tabNb, text, nbElems) { * @param {string} filterCrates */ async function showResults(results, go_to_first, filterCrates) { - // @ts-expect-error const search = searchState.outputElement(); if (go_to_first || (results.others.length === 1 && getSettingValue("go-to-only-result") === "true") @@ -4979,7 +4963,6 @@ async function showResults(results, go_to_first, filterCrates) { // will be used, starting search again since the search input is not empty, leading you // back to the previous page again. window.onunload = () => { }; - // @ts-expect-error searchState.removeQueryParameters(); const elem = document.createElement("a"); elem.href = results.others[0].href; @@ -4999,7 +4982,6 @@ async function showResults(results, go_to_first, filterCrates) { // Navigate to the relevant tab if the current tab is empty, like in case users search // for "-> String". If they had selected another tab previously, they have to click on // it again. - // @ts-expect-error let currentTab = searchState.currentTab; if ((currentTab === 0 && results.others.length === 0) || (currentTab === 1 && results.in_args.length === 0) || @@ -5087,8 +5069,8 @@ async function showResults(results, go_to_first, filterCrates) { resultsElem.appendChild(ret_in_args); resultsElem.appendChild(ret_returned); - search.innerHTML = output; // @ts-expect-error + search.innerHTML = output; if (searchState.rustdocToolbar) { // @ts-expect-error search.querySelector(".main-heading").appendChild(searchState.rustdocToolbar); @@ -5097,9 +5079,9 @@ async function showResults(results, go_to_first, filterCrates) { if (crateSearch) { crateSearch.addEventListener("input", updateCrate); } + // @ts-expect-error search.appendChild(resultsElem); // Reset focused elements. - // @ts-expect-error searchState.showResults(search); // @ts-expect-error const elems = document.getElementById("search-tabs").childNodes; @@ -5110,7 +5092,6 @@ async function showResults(results, go_to_first, filterCrates) { const j = i; // @ts-expect-error elem.onclick = () => printTab(j); - // @ts-expect-error searchState.focusedByTab.push(null); i += 1; } @@ -5122,7 +5103,6 @@ function updateSearchHistory(url) { if (!browserSupportsHistoryApi()) { return; } - // @ts-expect-error const params = searchState.getQueryStringParams(); if (!history.state && !params.search) { history.pushState(null, "", url); @@ -5149,10 +5129,8 @@ async function search(forced) { return; } - // @ts-expect-error searchState.setLoadingSearch(); - // @ts-expect-error const params = searchState.getQueryStringParams(); // In case we have no information about the saved crate and there is a URL query parameter, @@ -5162,7 +5140,6 @@ async function search(forced) { } // Update document title to maintain a meaningful browser history - // @ts-expect-error searchState.title = "\"" + query.userQuery + "\" Search - Rust"; // Because searching is incremental by character, only the most @@ -5184,33 +5161,28 @@ async function search(forced) { function onSearchSubmit(e) { // @ts-expect-error e.preventDefault(); - // @ts-expect-error searchState.clearInputTimeout(); search(); } function putBackSearch() { - // @ts-expect-error const search_input = searchState.input; - // @ts-expect-error if (!searchState.input) { return; } // @ts-expect-error if (search_input.value !== "" && !searchState.isDisplayed()) { - // @ts-expect-error searchState.showResults(); if (browserSupportsHistoryApi()) { history.replaceState(null, "", + // @ts-expect-error buildUrl(search_input.value, getFilterCrates())); } - // @ts-expect-error document.title = searchState.title; } } function registerSearchEvents() { - // @ts-expect-error const params = searchState.getQueryStringParams(); // Populate search bar with query string search term when provided, @@ -5224,14 +5196,11 @@ function registerSearchEvents() { } const searchAfter500ms = () => { - // @ts-expect-error searchState.clearInputTimeout(); // @ts-expect-error if (searchState.input.value.length === 0) { - // @ts-expect-error searchState.hideResults(); } else { - // @ts-expect-error searchState.timeout = setTimeout(search, 500); } }; @@ -5248,7 +5217,6 @@ function registerSearchEvents() { return; } // Do NOT e.preventDefault() here. It will prevent pasting. - // @ts-expect-error searchState.clearInputTimeout(); // zero-timeout necessary here because at the time of event handler execution the // pasted content is not in the input field yet. Shouldn’t make any difference for @@ -5274,7 +5242,6 @@ function registerSearchEvents() { // @ts-expect-error previous.focus(); } else { - // @ts-expect-error searchState.focus(); } e.preventDefault(); @@ -5327,7 +5294,6 @@ function registerSearchEvents() { const previousTitle = document.title; window.addEventListener("popstate", e => { - // @ts-expect-error const params = searchState.getQueryStringParams(); // Revert to the previous title manually since the History // API ignores the title parameter. @@ -5355,7 +5321,6 @@ function registerSearchEvents() { searchState.input.value = ""; // When browsing back from search results the main page // visibility must be reset. - // @ts-expect-error searchState.hideResults(); } }); @@ -5368,7 +5333,6 @@ function registerSearchEvents() { // that try to sync state between the URL and the search input. To work around it, // do a small amount of re-init on page show. window.onpageshow = () => { - // @ts-expect-error const qSearch = searchState.getQueryStringParams().search; // @ts-expect-error if (searchState.input.value === "" && qSearch) { From 94e9973b92c481d20e5fe1466bbc47f818101d5f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Jun 2025 17:53:01 +0000 Subject: [PATCH 05/15] Add Ident::is_non_reserved_ident --- compiler/rustc_ast/src/token.rs | 6 +++++- compiler/rustc_ast/src/tokenstream.rs | 6 ++---- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 3 +-- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 8 +++----- compiler/rustc_parse/src/parser/stmt.rs | 2 +- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 9b4535dcfbceb..fc816f2cb7922 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -893,7 +893,7 @@ impl Token { || self.is_qpath_start() || matches!(self.is_metavar_seq(), Some(MetaVarKind::Path)) || self.is_path_segment_keyword() - || self.is_ident() && !self.is_reserved_ident() + || self.is_non_reserved_ident() } /// Returns `true` if the token is a given keyword, `kw`. @@ -937,6 +937,10 @@ impl Token { self.is_non_raw_ident_where(Ident::is_reserved) } + pub fn is_non_reserved_ident(&self) -> bool { + self.ident().is_some_and(|(id, raw)| raw == IdentIsRaw::Yes || !Ident::is_reserved(id)) + } + /// Returns `true` if the token is the identifier `true` or `false`. pub fn is_bool_lit(&self) -> bool { self.is_non_raw_ident_where(|id| id.name.is_bool_lit()) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 3c231be20dce5..c60185cdde007 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -634,10 +634,8 @@ impl TokenStream { ( TokenTree::Token(token_left, Spacing::Alone), TokenTree::Token(token_right, _), - ) if ((token_left.is_ident() && !token_left.is_reserved_ident()) - || token_left.is_lit()) - && ((token_right.is_ident() && !token_right.is_reserved_ident()) - || token_right.is_lit()) => + ) if (token_left.is_non_reserved_ident() || token_left.is_lit()) + && (token_right.is_non_reserved_ident() || token_right.is_lit()) => { token_left.span } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a64bb4241173d..1df0ccbd8af76 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2731,7 +2731,7 @@ impl<'a> Parser<'a> { return first_pat; } if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..)) - || !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) + || !self.look_ahead(1, |token| token.is_non_reserved_ident()) { let mut snapshot_type = self.create_snapshot_for_diagnostic(); snapshot_type.bump(); // `:` diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4e312aab4976b..3cedc86dc0dbe 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3875,8 +3875,7 @@ impl<'a> Parser<'a> { // Check if a colon exists one ahead. This means we're parsing a fieldname. let is_shorthand = !this.look_ahead(1, |t| t == &token::Colon || t == &token::Eq); // Proactively check whether parsing the field will be incorrect. - let is_wrong = this.token.is_ident() - && !this.token.is_reserved_ident() + let is_wrong = this.token.is_non_reserved_ident() && !this.look_ahead(1, |t| { t == &token::Colon || t == &token::Eq diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index b2e902513672d..cfc0399b0ca96 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -685,7 +685,7 @@ impl<'a> Parser<'a> { /// Is the given keyword `kw` followed by a non-reserved identifier? fn is_kw_followed_by_ident(&self, kw: Symbol) -> bool { - self.token.is_keyword(kw) && self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()) + self.token.is_keyword(kw) && self.look_ahead(1, |t| t.is_non_reserved_ident()) } #[inline] diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 9bce2fa74caa2..1f4049f197fa8 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -126,7 +126,7 @@ impl<'a> Parser<'a> { /// ``` fn recover_colon_before_qpath_proj(&mut self) -> bool { if !self.check_noexpect(&TokenKind::Colon) - || self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident()) + || self.look_ahead(1, |t| !t.is_non_reserved_ident()) { return false; } @@ -260,7 +260,7 @@ impl<'a> Parser<'a> { if self.may_recover() && style == PathStyle::Expr // (!) && self.token == token::Colon - && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) + && self.look_ahead(1, |token| token.is_non_reserved_ident()) { // Emit a special error message for `a::b:c` to help users // otherwise, `a: c` might have meant to introduce a new binding @@ -334,9 +334,7 @@ impl<'a> Parser<'a> { self.expect_gt().map_err(|mut err| { // Try to recover a `:` into a `::` if self.token == token::Colon - && self.look_ahead(1, |token| { - token.is_ident() && !token.is_reserved_ident() - }) + && self.look_ahead(1, |token| token.is_non_reserved_ident()) { err.cancel(); err = self.dcx().create_err(PathSingleColon { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index c37cb0881c3f1..2fa6520f2a42a 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -798,7 +798,7 @@ impl<'a> Parser<'a> { } if self.prev_token.is_reserved_ident() && self.prev_token.is_ident_named(kw::Await) { // Likely `foo.await bar` - } else if !self.prev_token.is_reserved_ident() && self.prev_token.is_ident() { + } else if self.prev_token.is_non_reserved_ident() { // Likely `foo bar` } else if self.prev_token.kind == token::Question { // `foo? bar` From e63921262ccd2ece7e0861d634f111136da1f7da Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Jun 2025 17:53:39 +0000 Subject: [PATCH 06/15] Make recovery for enum with struct field a bit more accurate --- compiler/rustc_parse/src/parser/item.rs | 3 ++- tests/ui/structs-enums/recover-enum-with-bad-where.rs | 6 ++++++ .../structs-enums/recover-enum-with-bad-where.stderr | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/ui/structs-enums/recover-enum-with-bad-where.rs create mode 100644 tests/ui/structs-enums/recover-enum-with-bad-where.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 5088caa80f88f..9ed7124a11c38 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1552,7 +1552,8 @@ impl<'a> Parser<'a> { }) .map_err(|mut err| { err.span_label(ident.span, "while parsing this enum"); - if self.token == token::Colon { + // Try to recover `enum Foo { ident : Ty }`. + if self.prev_token.is_non_reserved_ident() && self.token == token::Colon { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); match self.parse_ty() { diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.rs b/tests/ui/structs-enums/recover-enum-with-bad-where.rs new file mode 100644 index 0000000000000..850ee6caa1a76 --- /dev/null +++ b/tests/ui/structs-enums/recover-enum-with-bad-where.rs @@ -0,0 +1,6 @@ +pub enum Foo +where: +//~^ ERROR expected one of `#`, `{`, lifetime, or type, found `:` + T: Missing, {} + +fn main() {} diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.stderr b/tests/ui/structs-enums/recover-enum-with-bad-where.stderr new file mode 100644 index 0000000000000..6f28ff56bab7b --- /dev/null +++ b/tests/ui/structs-enums/recover-enum-with-bad-where.stderr @@ -0,0 +1,10 @@ +error: expected one of `#`, `{`, lifetime, or type, found `:` + --> $DIR/recover-enum-with-bad-where.rs:2:6 + | +LL | pub enum Foo + | --- while parsing this enum +LL | where: + | ^ expected one of `#`, `{`, lifetime, or type + +error: aborting due to 1 previous error + From 4e51e67a24d940d3c8069062d07f663ee2034ac3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Jun 2025 18:08:15 +0000 Subject: [PATCH 07/15] Better recovery --- compiler/rustc_parse/src/parser/generics.rs | 14 ++++++++++++++ .../structs-enums/recover-enum-with-bad-where.rs | 4 +++- .../recover-enum-with-bad-where.stderr | 15 ++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index c05479feb611f..af1d1a1ec6697 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -353,6 +353,20 @@ impl<'a> Parser<'a> { if !self.eat_keyword(exp!(Where)) { return Ok((where_clause, None)); } + + if self.eat_noexpect(&token::Colon) { + let colon_span = self.prev_token.span; + self.dcx() + .struct_span_err(colon_span, "unexpected colon after `where`") + .with_span_suggestion_short( + colon_span, + "remove the colon", + "", + Applicability::MachineApplicable, + ) + .emit(); + } + where_clause.has_where_token = true; let where_lo = self.prev_token.span; diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.rs b/tests/ui/structs-enums/recover-enum-with-bad-where.rs index 850ee6caa1a76..cf7747d710b59 100644 --- a/tests/ui/structs-enums/recover-enum-with-bad-where.rs +++ b/tests/ui/structs-enums/recover-enum-with-bad-where.rs @@ -1,6 +1,8 @@ pub enum Foo where: -//~^ ERROR expected one of `#`, `{`, lifetime, or type, found `:` +//~^ ERROR unexpected colon after `where` T: Missing, {} +//~^ ERROR cannot find trait `Missing` in this scope +// (evidence that we continue parsing after the erroneous colon) fn main() {} diff --git a/tests/ui/structs-enums/recover-enum-with-bad-where.stderr b/tests/ui/structs-enums/recover-enum-with-bad-where.stderr index 6f28ff56bab7b..30b73f59e8c01 100644 --- a/tests/ui/structs-enums/recover-enum-with-bad-where.stderr +++ b/tests/ui/structs-enums/recover-enum-with-bad-where.stderr @@ -1,10 +1,15 @@ -error: expected one of `#`, `{`, lifetime, or type, found `:` +error: unexpected colon after `where` --> $DIR/recover-enum-with-bad-where.rs:2:6 | -LL | pub enum Foo - | --- while parsing this enum LL | where: - | ^ expected one of `#`, `{`, lifetime, or type + | ^ help: remove the colon -error: aborting due to 1 previous error +error[E0405]: cannot find trait `Missing` in this scope + --> $DIR/recover-enum-with-bad-where.rs:4:8 + | +LL | T: Missing, {} + | ^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0405`. From 1fd13fddba59ab686d5a01c6ad182a5bc109fe00 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 27 Jun 2025 05:34:08 +0000 Subject: [PATCH 08/15] tests: add #![rustc_no_implicit_bounds] After reviewing all tests with `?Sized` and discussing with lcnr, these tests seem like they could probably benefit from `#![rustc_no_implicit_bounds]`. --- .../coherence/coherence-fulfill-overflow.rs | 10 ++++--- .../coherence-fulfill-overflow.stderr | 10 +++---- .../incompleteness-unstable-result.rs | 29 ++++++++++--------- ...incompleteness-unstable-result.with.stderr | 14 ++++----- ...ompleteness-unstable-result.without.stderr | 14 ++++----- .../cycles/fixpoint-rerun-all-cycle-heads.rs | 21 +++++++------- .../fixpoint-rerun-all-cycle-heads.stderr | 4 +-- .../cycles/inductive-fixpoint-hang.rs | 6 ++-- .../cycles/inductive-fixpoint-hang.stderr | 4 +-- .../provisional-cache-impacts-behavior.rs | 7 +++-- .../next-solver/dont-canonicalize-re-error.rs | 8 +++-- .../dont-canonicalize-re-error.stderr | 14 ++++----- .../normalize/normalize-region-obligations.rs | 10 ++++--- .../overflow/coherence-alias-hang.rs | 16 +++++----- ...cursion-limit-normalizes-to-constraints.rs | 8 +++-- .../traits/next-solver/supertrait-alias-1.rs | 6 ++-- .../ui/traits/overflow-computing-ambiguity.rs | 9 ++++-- .../overflow-computing-ambiguity.stderr | 8 ++--- 18 files changed, 109 insertions(+), 89 deletions(-) diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs index ff577da32c23a..3fd22c7dbf0c1 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs @@ -1,15 +1,17 @@ //@ compile-flags: -Znext-solver=coherence +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] #![recursion_limit = "10"] trait Trait {} -struct W(*const T); +struct W(*const T); trait TwoW {} -impl TwoW for W> {} +impl TwoW for W> {} -impl Trait for W {} -impl Trait for T {} +impl Trait for W {} +impl Trait for T {} //~^ ERROR conflicting implementations of trait `Trait` for type `W fn main() {} diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr index 7d39c82d22f76..1827533a84d90 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr @@ -1,10 +1,10 @@ error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/coherence-fulfill-overflow.rs:12:1 + --> $DIR/coherence-fulfill-overflow.rs:14:1 | -LL | impl Trait for W {} - | ------------------------------------- first implementation here -LL | impl Trait for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>>>` +LL | impl Trait for W {} + | ---------------------------- first implementation here +LL | impl Trait for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>>>` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index 920f8add50795..9da79f7ac8372 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -1,6 +1,7 @@ //@ revisions: with without //@ compile-flags: -Znext-solver #![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // This test is incredibly subtle. At its core the goal is to get a coinductive cycle, // which, depending on its root goal, either holds or errors. We achieve this by getting @@ -17,20 +18,20 @@ // test for that. #[rustc_coinductive] -trait Trait {} -struct A(*const T); -struct B(*const T); +trait Trait {} +struct A(*const T); +struct B(*const T); -trait IncompleteGuidance {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} +trait IncompleteGuidance {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} -trait ImplGuidance {} -impl ImplGuidance for T {} -impl ImplGuidance for T {} +trait ImplGuidance {} +impl ImplGuidance for T {} +impl ImplGuidance for T {} -impl Trait for A +impl Trait for A where T: IncompleteGuidance, A: Trait, @@ -39,17 +40,17 @@ where { } -trait ToU8 {} +trait ToU8 {} impl ToU8 for () {} -impl Trait for B +impl Trait for B where T: ImplGuidance, A: Trait, { } -fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} +fn impls_trait, U, V, D>() {} fn with_bound() where diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr index 9114bcadac0c0..d27104de541b5 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr @@ -1,25 +1,25 @@ error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:66:19 | LL | impls_trait::, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` | = help: the trait `Trait` is implemented for `A` note: required for `A` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:34:18 | -LL | impl Trait for A - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl Trait for A + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A: Trait, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:53:19 | -LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait, U, V, D>() {} + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr index 9114bcadac0c0..d27104de541b5 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr @@ -1,25 +1,25 @@ error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:66:19 | LL | impls_trait::, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` | = help: the trait `Trait` is implemented for `A` note: required for `A` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:34:18 | -LL | impl Trait for A - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl Trait for A + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A: Trait, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:53:19 | -LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait, U, V, D>() {} + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs index f7ed0e100c466..326d888a55f3d 100644 --- a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs +++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs @@ -1,23 +1,24 @@ //@ compile-flags: -Znext-solver #![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // Check that we correctly rerun the trait solver for heads of cycles, // even if they are not the root. -struct A(*const T); -struct B(*const T); -struct C(*const T); +struct A(*const T); +struct B(*const T); +struct C(*const T); #[rustc_coinductive] trait Trait<'a, 'b> {} trait NotImplemented {} -impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A where B: Trait<'a, 'b> {} +impl<'a, 'b, T> Trait<'a, 'b> for A where B: Trait<'a, 'b> {} // With this the root of `B` is `A`, even if the other impl does // not have a cycle with `A`. This candidate never applies because of // the `A: NotImplemented` bound. -impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B +impl<'a, 'b, T> Trait<'a, 'b> for B where A: Trait<'a, 'b>, A: NotImplemented, @@ -31,7 +32,7 @@ where // use the impl itself to prove that adds region constraints as we uniquified the // regions in the `A: Trait<'a, 'b>` where-bound. As both the impl above // and the impl below now apply with some constraints, we failed with ambiguity. -impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B +impl<'a, 'b, T> Trait<'a, 'b> for B where A: NotImplemented, {} @@ -40,7 +41,7 @@ where // // Because of the coinductive cycle through `C` it also requires // 'a to be 'static. -impl<'a, T: ?Sized> Trait<'a, 'static> for B +impl<'a, T> Trait<'a, 'static> for B where C: Trait<'a, 'a>, {} @@ -48,14 +49,14 @@ where // In the first iteration of `B: Trait<'a, 'b>` we don't add any // constraints here, only after setting the provisional result to require // `'b == 'static` do we also add that constraint for `'a`. -impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C +impl<'a, 'b, T> Trait<'a, 'b> for C where B: Trait<'a, 'b>, {} -fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {} +fn impls_trait<'a, 'b, T: Trait<'a, 'b>>() {} -fn check<'a, T: ?Sized>() { +fn check<'a, T>() { impls_trait::<'a, 'static, A>(); //~^ ERROR lifetime may not live long enough } diff --git a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr index 0cbd96540448c..c88081736f3c3 100644 --- a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr +++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr @@ -1,7 +1,7 @@ error: lifetime may not live long enough - --> $DIR/fixpoint-rerun-all-cycle-heads.rs:59:5 + --> $DIR/fixpoint-rerun-all-cycle-heads.rs:60:5 | -LL | fn check<'a, T: ?Sized>() { +LL | fn check<'a, T>() { | -- lifetime `'a` defined here LL | impls_trait::<'a, 'static, A>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs index 9cbcc5a3cdf2f..12feb1e2771ca 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs @@ -1,4 +1,6 @@ //@ compile-flags: -Znext-solver +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // This currently hangs if we do not erase constraints from // overflow. @@ -17,9 +19,9 @@ // the solver to hang without hitting the recursion limit. trait Trait {} -struct W(*const T); +struct W(*const T); -impl Trait for W> +impl Trait for W> where W: Trait, W: Trait, diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr index a2a5c028cf8d5..5ba3c511c1717 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait` - --> $DIR/inductive-fixpoint-hang.rs:31:19 + --> $DIR/inductive-fixpoint-hang.rs:33:19 | LL | impls_trait::>(); | ^^^^ | note: required by a bound in `impls_trait` - --> $DIR/inductive-fixpoint-hang.rs:28:19 + --> $DIR/inductive-fixpoint-hang.rs:30:19 | LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` diff --git a/tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs b/tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs index b005b909aedbe..88a1196b7e5b5 100644 --- a/tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs +++ b/tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass #![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // A test showcasing that using a provisional cache can differ // from only tracking stack entries. @@ -59,9 +60,9 @@ trait B {} #[rustc_coinductive] trait C {} -impl A for T {} -impl B for T {} -impl C for T {} +impl A for T {} +impl B for T {} +impl C for T {} fn impls_a() {} diff --git a/tests/ui/traits/next-solver/dont-canonicalize-re-error.rs b/tests/ui/traits/next-solver/dont-canonicalize-re-error.rs index 57f814bc81ec2..a2ed73b2c8692 100644 --- a/tests/ui/traits/next-solver/dont-canonicalize-re-error.rs +++ b/tests/ui/traits/next-solver/dont-canonicalize-re-error.rs @@ -1,4 +1,6 @@ //@ compile-flags: -Znext-solver +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] trait Tr<'a> {} @@ -16,9 +18,9 @@ trait Tr<'a> {} // Then, when we recompute the goal `W: Constrain<'error>`, when // collecting ambiguities and overflows, we end up assembling a default // error candidate w/o ambiguity, which causes the goal to pass, and ICE. -impl<'a, A: ?Sized> Tr<'a> for W {} -struct W(A); -impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {} +impl<'a, A> Tr<'a> for W {} +struct W(A); +impl<'a, A> Tr<'a> for A where A: Constrain<'a> {} //~^ ERROR conflicting implementations of trait `Tr<'_>` for type `W<_>` trait Constrain<'a> {} diff --git a/tests/ui/traits/next-solver/dont-canonicalize-re-error.stderr b/tests/ui/traits/next-solver/dont-canonicalize-re-error.stderr index cf85c52fb42ee..6d5f1ece0e2e8 100644 --- a/tests/ui/traits/next-solver/dont-canonicalize-re-error.stderr +++ b/tests/ui/traits/next-solver/dont-canonicalize-re-error.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/dont-canonicalize-re-error.rs:25:26 + --> $DIR/dont-canonicalize-re-error.rs:27:26 | LL | impl Constrain<'missing> for W {} | - ^^^^^^^^ undeclared lifetime @@ -7,13 +7,13 @@ LL | impl Constrain<'missing> for W {} | help: consider introducing lifetime `'missing` here: `'missing,` error[E0119]: conflicting implementations of trait `Tr<'_>` for type `W<_>` - --> $DIR/dont-canonicalize-re-error.rs:21:1 + --> $DIR/dont-canonicalize-re-error.rs:23:1 | -LL | impl<'a, A: ?Sized> Tr<'a> for W {} - | ----------------------------------- first implementation here -LL | struct W(A); -LL | impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>` +LL | impl<'a, A> Tr<'a> for W {} + | --------------------------- first implementation here +LL | struct W(A); +LL | impl<'a, A> Tr<'a> for A where A: Constrain<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs index c4c2e695a1df5..e1ffa4e29d699 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs @@ -1,6 +1,8 @@ //@ revisions: normalize_param_env normalize_obligation hrtb //@ check-pass //@ compile-flags: -Znext-solver +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] trait Foo { #[cfg(normalize_param_env)] @@ -11,11 +13,11 @@ trait Foo { type Gat<'b> where for<'a> >::Assoc: 'b; } -trait Mirror { type Assoc: ?Sized; } -impl Mirror for T { type Assoc = T; } +trait Mirror { type Assoc; } +impl Mirror for T { type Assoc = T; } -trait MirrorRegion<'a> { type Assoc: ?Sized; } -impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; } +trait MirrorRegion<'a> { type Assoc; } +impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; } impl Foo for T { #[cfg(normalize_param_env)] diff --git a/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs b/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs index f88f74680b9db..4874e2e1f99c5 100644 --- a/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs +++ b/tests/ui/traits/next-solver/overflow/coherence-alias-hang.rs @@ -4,16 +4,18 @@ // Regression test for nalgebra hang . #![feature(lazy_type_alias)] +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] #![allow(incomplete_features)] -type Id = T; +type Id = T; trait NotImplemented {} -struct W(*const T, *const U); +struct W(*const T, *const U); trait Trait { - type Assoc: ?Sized; + type Assoc; } -impl Trait for W { +impl Trait for W { #[cfg(ai)] type Assoc = W>; #[cfg(ia)] @@ -22,8 +24,8 @@ impl Trait for W { type Assoc = W, Id>; } -trait Overlap {} -impl Overlap for W {} -impl Overlap for T {} +trait Overlap {} +impl Overlap for W {} +impl Overlap for T {} fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs index dee5500aaddbd..e5a57a44d4980 100644 --- a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs @@ -1,5 +1,7 @@ //@ compile-flags: -Znext-solver=coherence //@ check-pass +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // A regression test for trait-system-refactor-initiative#70. @@ -7,8 +9,8 @@ trait Trait { type Assoc; } -struct W(*mut T); -impl Trait for W> +struct W(*mut T); +impl Trait for W> where W: Trait, { @@ -20,6 +22,6 @@ impl> NoOverlap for T {} // `Projection( as Trait>::Assoc, u32)` should result in error even // though applying the impl results in overflow. This is necessary to match // the behavior of the old solver. -impl NoOverlap for W {} +impl NoOverlap for W {} fn main() {} diff --git a/tests/ui/traits/next-solver/supertrait-alias-1.rs b/tests/ui/traits/next-solver/supertrait-alias-1.rs index 579a44677c2ee..2671eed7fcea6 100644 --- a/tests/ui/traits/next-solver/supertrait-alias-1.rs +++ b/tests/ui/traits/next-solver/supertrait-alias-1.rs @@ -1,5 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] // Regression test for . // Tests that we don't try to replace `::Output` when replacing projections in the @@ -13,9 +15,9 @@ pub trait Super { type Output; } -fn bound() {} +fn bound() {} -fn visit_simd_operator() { +fn visit_simd_operator() { bound::::Output>>(); } diff --git a/tests/ui/traits/overflow-computing-ambiguity.rs b/tests/ui/traits/overflow-computing-ambiguity.rs index b8f11efeda283..88eeca56cdd1a 100644 --- a/tests/ui/traits/overflow-computing-ambiguity.rs +++ b/tests/ui/traits/overflow-computing-ambiguity.rs @@ -1,12 +1,15 @@ +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] + trait Hello {} -struct Foo<'a, T: ?Sized>(&'a T); +struct Foo<'a, T>(&'a T); -impl<'a, T: ?Sized> Hello for Foo<'a, &'a T> where Foo<'a, T>: Hello {} +impl<'a, T> Hello for Foo<'a, &'a T> where Foo<'a, T>: Hello {} impl Hello for Foo<'static, i32> {} -fn hello() {} +fn hello() {} fn main() { hello(); diff --git a/tests/ui/traits/overflow-computing-ambiguity.stderr b/tests/ui/traits/overflow-computing-ambiguity.stderr index a2e255865bf48..f3e91a29a9ca7 100644 --- a/tests/ui/traits/overflow-computing-ambiguity.stderr +++ b/tests/ui/traits/overflow-computing-ambiguity.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/overflow-computing-ambiguity.rs:12:5 + --> $DIR/overflow-computing-ambiguity.rs:15:5 | LL | hello(); | ^^^^^ cannot infer type of the type parameter `T` declared on the function `hello` @@ -9,10 +9,10 @@ LL | hello(); Foo<'a, &'a T> Foo<'static, i32> note: required by a bound in `hello` - --> $DIR/overflow-computing-ambiguity.rs:9:22 + --> $DIR/overflow-computing-ambiguity.rs:12:13 | -LL | fn hello() {} - | ^^^^^ required by this bound in `hello` +LL | fn hello() {} + | ^^^^^ required by this bound in `hello` help: consider specifying the generic argument | LL | hello::(); From 1365d3ba1fda7c5be7bb8d13042bee8ae724d748 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Jun 2025 18:33:01 +0200 Subject: [PATCH 09/15] codegen_fn_attrs: make comment more precise --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 94df5e8b361d7..8d1973058b0ae 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -430,7 +430,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } } - // Apply the minimum function alignment here, so that individual backends don't have to. + // Apply the minimum function alignment here. This ensures that a function's alignment is + // determined by the `-C` flags of the crate it is defined in, not the `-C` flags of the crate + // it happens to be codegen'd (or const-eval'd) in. codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment); From 9e3568407234ba4b8fa772cb4acf8d18b12baa7c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 25 Jun 2025 09:36:26 +0200 Subject: [PATCH 10/15] Port `#[used]` to new attribute parsing infrastructure Signed-off-by: Jonathan Brouwer --- .../src/attributes.rs | 14 ++++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/codegen_attrs.rs | 83 ++++++++++++++++++- compiler/rustc_attr_parsing/src/context.rs | 2 + compiler/rustc_codegen_ssa/messages.ftl | 2 - .../rustc_codegen_ssa/src/codegen_attrs.rs | 44 ++-------- compiler/rustc_codegen_ssa/src/errors.rs | 7 -- compiler/rustc_passes/messages.ftl | 3 - compiler/rustc_passes/src/check_attr.rs | 50 +++-------- compiler/rustc_passes/src/errors.rs | 7 -- tests/ui/attributes/used_with_arg.rs | 15 +++- tests/ui/attributes/used_with_arg.stderr | 39 +++++++-- tests/ui/attributes/used_with_multi_args.rs | 2 +- .../ui/attributes/used_with_multi_args.stderr | 16 +++- .../lint/unused/unused-attr-duplicate.stderr | 24 +++--- 15 files changed, 185 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index d755afad59fb8..60a4f28930691 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -131,6 +131,17 @@ impl Deprecation { } } +/// There are three valid forms of the attribute: +/// `#[used]`, which is semantically equivalent to `#[used(linker)]` except that the latter is currently unstable. +/// `#[used(compiler)]` +/// `#[used(linker)]` +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic, PrintAttribute)] +pub enum UsedBy { + Compiler, + Linker, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -285,5 +296,8 @@ pub enum AttributeKind { /// Represents `#[track_caller]` TrackCaller(Span), + + /// Represents `#[used]` + Used { used_by: UsedBy, span: Span }, // tidy-alphabetical-end } diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index d4402f4e2e63d..64bcf1fe6cce7 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -38,6 +38,7 @@ impl AttributeKind { PubTransparent(..) => Yes, SkipDuringMethodDispatch { .. } => No, TrackCaller(..) => Yes, + Used { .. } => No, } } } diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 5a849e79cc32d..7c412d4fa892b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_attr_data_structures::{AttributeKind, OptimizeAttr}; +use rustc_attr_data_structures::{AttributeKind, OptimizeAttr, UsedBy}; use rustc_feature::{AttributeTemplate, template}; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; @@ -228,3 +228,84 @@ impl SingleAttributeParser for NoMangleParser { Some(AttributeKind::NoMangle(cx.attr_span)) } } + +#[derive(Default)] +pub(crate) struct UsedParser { + first_compiler: Option, + first_linker: Option, +} + +// A custom `AttributeParser` is used rather than a Simple attribute parser because +// - Specifying two `#[used]` attributes is a warning (but will be an error in the future) +// - But specifying two conflicting attributes: `#[used(compiler)]` and `#[used(linker)]` is already an error today +// We can change this to a Simple parser once the warning becomes an error +impl AttributeParser for UsedParser { + const ATTRIBUTES: AcceptMapping = &[( + &[sym::used], + template!(Word, List: "compiler|linker"), + |group: &mut Self, cx, args| { + let used_by = match args { + ArgParser::NoArgs => UsedBy::Linker, + ArgParser::List(list) => { + let Some(l) = list.single() else { + cx.expected_single_argument(list.span); + return; + }; + + match l.meta_item().and_then(|i| i.path().word_sym()) { + Some(sym::compiler) => { + if !cx.features().used_with_arg() { + feature_err( + &cx.sess(), + sym::used_with_arg, + cx.attr_span, + "`#[used(compiler)]` is currently unstable", + ) + .emit(); + } + UsedBy::Compiler + } + Some(sym::linker) => { + if !cx.features().used_with_arg() { + feature_err( + &cx.sess(), + sym::used_with_arg, + cx.attr_span, + "`#[used(linker)]` is currently unstable", + ) + .emit(); + } + UsedBy::Linker + } + _ => { + cx.expected_specific_argument(l.span(), vec!["compiler", "linker"]); + return; + } + } + } + ArgParser::NameValue(_) => return, + }; + + let target = match used_by { + UsedBy::Compiler => &mut group.first_compiler, + UsedBy::Linker => &mut group.first_linker, + }; + + let attr_span = cx.attr_span; + if let Some(prev) = *target { + cx.warn_unused_duplicate(prev, attr_span); + } else { + *target = Some(attr_span); + } + }, + )]; + + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { + // Ratcheting behaviour, if both `linker` and `compiler` are specified, use `linker` + Some(match (self.first_compiler, self.first_linker) { + (_, Some(span)) => AttributeKind::Used { used_by: UsedBy::Linker, span }, + (Some(span), _) => AttributeKind::Used { used_by: UsedBy::Compiler, span }, + (None, None) => return None, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 83e3c75dedb4e..71bb86ca3d3b8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -17,6 +17,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; use crate::attributes::codegen_attrs::{ ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TrackCallerParser, + UsedParser, }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; @@ -103,6 +104,7 @@ attribute_parsers!( ConstStabilityParser, NakedParser, StabilityParser, + UsedParser, // tidy-alphabetical-end // tidy-alphabetical-start diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 6362d2edf8554..84d6381934358 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -48,8 +48,6 @@ codegen_ssa_error_writing_def_file = codegen_ssa_expected_name_value_pair = expected name value pair -codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` - codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 94df5e8b361d7..716b2d76c6208 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -4,7 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; use rustc_attr_data_structures::{ - AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, find_attr, + AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, UsedBy, find_attr, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; @@ -160,6 +160,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER } + AttributeKind::Used { used_by, .. } => match used_by { + UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, + UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, + }, _ => {} } } @@ -181,44 +185,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::rustc_std_internal_symbol => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL } - sym::used => { - let inner = attr.meta_item_list(); - match inner.as_deref() { - Some([item]) if item.has_name(sym::linker) => { - if !tcx.features().used_with_arg() { - feature_err( - &tcx.sess, - sym::used_with_arg, - attr.span(), - "`#[used(linker)]` is currently unstable", - ) - .emit(); - } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER; - } - Some([item]) if item.has_name(sym::compiler) => { - if !tcx.features().used_with_arg() { - feature_err( - &tcx.sess, - sym::used_with_arg, - attr.span(), - "`#[used(compiler)]` is currently unstable", - ) - .emit(); - } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER; - } - Some(_) => { - tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() }); - } - None => { - // Unconditionally using `llvm.used` causes issues in handling - // `.init_array` with the gold linker. Luckily gold has been - // deprecated with GCC 15 and rustc now warns about using gold. - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER - } - } - } sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, sym::target_feature => { let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index db536af0162f1..1950a35b364dd 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -726,13 +726,6 @@ pub struct UnknownArchiveKind<'a> { pub kind: &'a str, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_expected_used_symbol)] -pub(crate) struct ExpectedUsedSymbol { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_multiple_main_functions)] #[help] diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index e2995daadfe56..b1c7b0fcd6c62 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -816,9 +816,6 @@ passes_unused_variable_try_prefix = unused variable: `{$name}` .suggestion = if this is intentional, prefix it with an underscore -passes_used_compiler_linker = - `used(compiler)` and `used(linker)` can't be used together - passes_used_static = attribute must be applied to a `static` variable .label = but this is a {$target} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 491b3699f4c32..877bb9be28961 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -200,6 +200,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::NoMangle(attr_span)) => { self.check_no_mangle(hir_id, *attr_span, span, target) } + Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => { + self.check_used(*attr_span, target, span); + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -333,7 +336,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::cfi_encoding // FIXME(cfi_encoding) | sym::pointee // FIXME(derive_coerce_pointee) | sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section) - | sym::used // handled elsewhere to restrict to static items | sym::instruction_set // broken on stable!!! | sym::windows_subsystem // broken on stable!!! | sym::patchable_function_entry // FIXME(patchable_function_entry) @@ -403,7 +405,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } self.check_repr(attrs, span, target, item, hir_id); - self.check_used(attrs, target, span); self.check_rustc_force_inline(hir_id, attrs, span, target); self.check_mix_no_mangle_export(hir_id, attrs); } @@ -2107,44 +2108,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_used(&self, attrs: &[Attribute], target: Target, target_span: Span) { - let mut used_linker_span = None; - let mut used_compiler_span = None; - for attr in attrs.iter().filter(|attr| attr.has_name(sym::used)) { - if target != Target::Static { - self.dcx().emit_err(errors::UsedStatic { - attr_span: attr.span(), - span: target_span, - target: target.name(), - }); - } - let inner = attr.meta_item_list(); - match inner.as_deref() { - Some([item]) if item.has_name(sym::linker) => { - if used_linker_span.is_none() { - used_linker_span = Some(attr.span()); - } - } - Some([item]) if item.has_name(sym::compiler) => { - if used_compiler_span.is_none() { - used_compiler_span = Some(attr.span()); - } - } - Some(_) => { - // This error case is handled in rustc_hir_analysis::collect. - } - None => { - // Default case (compiler) when arg isn't defined. - if used_compiler_span.is_none() { - used_compiler_span = Some(attr.span()); - } - } - } - } - if let (Some(linker_span), Some(compiler_span)) = (used_linker_span, used_compiler_span) { - self.tcx - .dcx() - .emit_err(errors::UsedCompilerLinker { spans: vec![linker_span, compiler_span] }); + fn check_used(&self, attr_span: Span, target: Target, target_span: Span) { + if target != Target::Static { + self.dcx().emit_err(errors::UsedStatic { + attr_span, + span: target_span, + target: target.name(), + }); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3286ccc94f210..f89d925202c26 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -641,13 +641,6 @@ pub(crate) struct UsedStatic { pub target: &'static str, } -#[derive(Diagnostic)] -#[diag(passes_used_compiler_linker)] -pub(crate) struct UsedCompilerLinker { - #[primary_span] - pub spans: Vec, -} - #[derive(Diagnostic)] #[diag(passes_allow_internal_unstable)] pub(crate) struct AllowInternalUnstable { diff --git a/tests/ui/attributes/used_with_arg.rs b/tests/ui/attributes/used_with_arg.rs index ad80ff53f0ef0..bc7a6f07442ba 100644 --- a/tests/ui/attributes/used_with_arg.rs +++ b/tests/ui/attributes/used_with_arg.rs @@ -1,3 +1,4 @@ +#![deny(unused_attributes)] #![feature(used_with_arg)] #[used(linker)] @@ -6,14 +7,22 @@ static mut USED_LINKER: [usize; 1] = [0]; #[used(compiler)] static mut USED_COMPILER: [usize; 1] = [0]; -#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together +#[used(compiler)] #[used(linker)] static mut USED_COMPILER_LINKER2: [usize; 1] = [0]; -#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together -#[used(linker)] #[used(compiler)] #[used(linker)] +#[used(compiler)] //~ ERROR unused attribute +#[used(linker)] //~ ERROR unused attribute static mut USED_COMPILER_LINKER3: [usize; 1] = [0]; +#[used(compiler)] +#[used] +static mut USED_WITHOUT_ATTR1: [usize; 1] = [0]; + +#[used(linker)] +#[used] //~ ERROR unused attribute +static mut USED_WITHOUT_ATTR2: [usize; 1] = [0]; + fn main() {} diff --git a/tests/ui/attributes/used_with_arg.stderr b/tests/ui/attributes/used_with_arg.stderr index 440e5c4a5a020..9ff91a4e03b3e 100644 --- a/tests/ui/attributes/used_with_arg.stderr +++ b/tests/ui/attributes/used_with_arg.stderr @@ -1,18 +1,43 @@ -error: `used(compiler)` and `used(linker)` can't be used together - --> $DIR/used_with_arg.rs:9:1 +error: unused attribute + --> $DIR/used_with_arg.rs:16:1 + | +LL | #[used(compiler)] + | ^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/used_with_arg.rs:14:1 | LL | #[used(compiler)] | ^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/used_with_arg.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/used_with_arg.rs:17:1 + | +LL | #[used(linker)] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/used_with_arg.rs:15:1 + | LL | #[used(linker)] | ^^^^^^^^^^^^^^^ -error: `used(compiler)` and `used(linker)` can't be used together - --> $DIR/used_with_arg.rs:13:1 +error: unused attribute + --> $DIR/used_with_arg.rs:25:1 + | +LL | #[used] + | ^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/used_with_arg.rs:24:1 | -LL | #[used(compiler)] - | ^^^^^^^^^^^^^^^^^ LL | #[used(linker)] | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/used_with_multi_args.rs b/tests/ui/attributes/used_with_multi_args.rs index d3109cc64442e..1c054f792eb99 100644 --- a/tests/ui/attributes/used_with_multi_args.rs +++ b/tests/ui/attributes/used_with_multi_args.rs @@ -1,6 +1,6 @@ #![feature(used_with_arg)] -#[used(compiler, linker)] //~ ERROR expected `used`, `used(compiler)` or `used(linker)` +#[used(compiler, linker)] //~ ERROR malformed `used` attribute input static mut USED_COMPILER_LINKER: [usize; 1] = [0]; fn main() {} diff --git a/tests/ui/attributes/used_with_multi_args.stderr b/tests/ui/attributes/used_with_multi_args.stderr index d4417a202d5fe..e48209cf20424 100644 --- a/tests/ui/attributes/used_with_multi_args.stderr +++ b/tests/ui/attributes/used_with_multi_args.stderr @@ -1,8 +1,20 @@ -error: expected `used`, `used(compiler)` or `used(linker)` +error[E0805]: malformed `used` attribute input --> $DIR/used_with_multi_args.rs:3:1 | LL | #[used(compiler, linker)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^------------------^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[used(compiler, linker)] +LL + #[used(compiler|linker)] + | +LL - #[used(compiler, linker)] +LL + #[used] + | error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0805`. diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 3a520ffcb3df1..a18581192ea66 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -89,18 +89,6 @@ note: attribute also specified here LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:102:1 - | -LL | #[used] - | ^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:101:1 - | -LL | #[used] - | ^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:86:5 | @@ -289,5 +277,17 @@ note: attribute also specified here LL | #[no_mangle] | ^^^^^^^^^^^^ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:102:1 + | +LL | #[used] + | ^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:101:1 + | +LL | #[used] + | ^^^^^^^ + error: aborting due to 23 previous errors From c51f05be3094651711072e43bacac47cf7426be9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Jun 2025 09:28:25 +0000 Subject: [PATCH 11/15] Report infer ty errors during hir ty lowering This centralizes the placeholder type error reporting in one location, but it also exposes the granularity at which we convert things from hir to ty more. E.g. previously infer types in where bounds were errored together with the function signature, but now they are independent. --- compiler/rustc_hir/src/hir.rs | 28 ++ .../rustc_hir_analysis/src/check/wfcheck.rs | 1 - compiler/rustc_hir_analysis/src/collect.rs | 249 +++------- compiler/rustc_middle/src/ty/util.rs | 1 + tests/ui/async-await/issues/issue-95307.rs | 5 +- .../ui/async-await/issues/issue-95307.stderr | 28 +- .../generic_arg_infer/in-signature.rs | 2 + .../generic_arg_infer/in-signature.stderr | 28 +- .../bad-assoc-ty.edition2015.stderr | 86 +--- .../bad-assoc-ty.edition2021.stderr | 86 +--- tests/ui/did_you_mean/bad-assoc-ty.rs | 1 + tests/ui/fn/error-recovery-mismatch.stderr | 6 - ...verlapping-errors-span-issue-123861.stderr | 6 - .../in-trait/not-inferred-generic.stderr | 2 +- tests/ui/macros/issue-118048.rs | 1 + tests/ui/macros/issue-118048.stderr | 20 +- tests/ui/macros/macro-span-issue-116502.rs | 2 + .../ui/macros/macro-span-issue-116502.stderr | 35 +- tests/ui/self/self-infer.stderr | 12 - .../bad-infer-in-trait-impl.stderr | 6 - tests/ui/typeck/issue-74086.rs | 3 +- tests/ui/typeck/issue-74086.stderr | 8 +- tests/ui/typeck/issue-81885.rs | 6 +- tests/ui/typeck/issue-81885.stderr | 16 +- .../ui/typeck/type-placeholder-fn-in-const.rs | 6 +- .../type-placeholder-fn-in-const.stderr | 16 +- .../ui/typeck/typeck_type_placeholder_item.rs | 16 +- .../typeck_type_placeholder_item.stderr | 428 +++++++----------- .../typeck_type_placeholder_item_help.rs | 3 +- .../typeck_type_placeholder_item_help.stderr | 16 +- 30 files changed, 414 insertions(+), 709 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 88e0ee1cc0be2..75dff588669ab 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3141,6 +3141,15 @@ pub enum TraitItemKind<'hir> { /// type. Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>), } +impl TraitItemKind<'_> { + pub fn descr(&self) -> &'static str { + match self { + TraitItemKind::Const(..) => "associated constant", + TraitItemKind::Fn(..) => "function", + TraitItemKind::Type(..) => "associated type", + } + } +} // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item @@ -3202,6 +3211,15 @@ pub enum ImplItemKind<'hir> { /// An associated type. Type(&'hir Ty<'hir>), } +impl ImplItemKind<'_> { + pub fn descr(&self) -> &'static str { + match self { + ImplItemKind::Const(..) => "associated constant", + ImplItemKind::Fn(..) => "function", + ImplItemKind::Type(..) => "associated type", + } + } +} /// A constraint on an associated item. /// @@ -4527,6 +4545,16 @@ pub enum ForeignItemKind<'hir> { Type, } +impl ForeignItemKind<'_> { + pub fn descr(&self) -> &'static str { + match self { + ForeignItemKind::Fn(..) => "function", + ForeignItemKind::Static(..) => "static variable", + ForeignItemKind::Type => "type", + } + } +} + /// A variable captured by a closure. #[derive(Debug, Copy, Clone, HashStable_Generic)] pub struct Upvar { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 00f9347b1cc81..89ce74879d8eb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -231,7 +231,6 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() item.name = ? tcx.def_path_str(def_id) ); crate::collect::lower_item(tcx, item.item_id()); - crate::collect::reject_placeholder_type_signatures_in_item(tcx, item); let res = match item.kind { // Right now we check that every default trait implementation diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c967e87bfd87c..d7568554669e9 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -29,7 +29,7 @@ use rustc_errors::{ }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_generics}; +use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt}; use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause}; @@ -154,26 +154,7 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { } } -/// If there are any placeholder types (`_`), emit an error explaining that this is not allowed -/// and suggest adding type parameters in the appropriate place, taking into consideration any and -/// all already existing generic type parameters to avoid suggesting a name that is already in use. -pub(crate) fn placeholder_type_error<'tcx>( - cx: &dyn HirTyLowerer<'tcx>, - generics: Option<&hir::Generics<'_>>, - placeholder_types: Vec, - suggest: bool, - hir_ty: Option<&hir::Ty<'_>>, - kind: &'static str, -) { - if placeholder_types.is_empty() { - return; - } - - placeholder_type_error_diag(cx, generics, placeholder_types, vec![], suggest, hir_ty, kind) - .emit(); -} - -pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>( +fn placeholder_type_error_diag<'cx, 'tcx>( cx: &'cx dyn HirTyLowerer<'tcx>, generics: Option<&hir::Generics<'_>>, placeholder_types: Vec, @@ -245,37 +226,6 @@ pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>( err } -pub(super) fn reject_placeholder_type_signatures_in_item<'tcx>( - tcx: TyCtxt<'tcx>, - item: &'tcx hir::Item<'tcx>, -) { - let (generics, suggest) = match &item.kind { - hir::ItemKind::Union(_, generics, _) - | hir::ItemKind::Enum(_, generics, _) - | hir::ItemKind::TraitAlias(_, generics, _) - | hir::ItemKind::Trait(_, _, _, generics, ..) - | hir::ItemKind::Impl(hir::Impl { generics, .. }) - | hir::ItemKind::Struct(_, generics, _) => (generics, true), - hir::ItemKind::TyAlias(_, generics, _) => (generics, false), - // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type. - _ => return, - }; - - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_item(item); - - let icx = ItemCtxt::new(tcx, item.owner_id.def_id); - - placeholder_type_error( - icx.lowerer(), - Some(generics), - visitor.spans, - suggest && !visitor.may_contain_const_infer, - None, - item.kind.descr(), - ); -} - /////////////////////////////////////////////////////////////////////////// // Utility types and common code for the above passes. @@ -313,6 +263,54 @@ impl<'tcx> ItemCtxt<'tcx> { None => Ok(()), } } + + fn report_placeholder_type_error( + &self, + placeholder_types: Vec, + infer_replacements: Vec<(Span, String)>, + ) -> ErrorGuaranteed { + let node = self.tcx.hir_node_by_def_id(self.item_def_id); + let generics = node.generics(); + let kind_id = match node { + Node::GenericParam(_) | Node::WherePredicate(_) | Node::Field(_) => { + self.tcx.local_parent(self.item_def_id) + } + _ => self.item_def_id, + }; + // FIXME: just invoke `tcx.def_descr` instead of going through the HIR + // Can also remove most `descr` methods then. + let kind = match self.tcx.hir_node_by_def_id(kind_id) { + Node::Item(it) => it.kind.descr(), + Node::ImplItem(it) => it.kind.descr(), + Node::TraitItem(it) => it.kind.descr(), + Node::ForeignItem(it) => it.kind.descr(), + Node::OpaqueTy(_) => "opaque type", + Node::Synthetic => self.tcx.def_descr(kind_id.into()), + node => todo!("{node:#?}"), + }; + let mut diag = placeholder_type_error_diag( + self, + generics, + placeholder_types, + infer_replacements.iter().map(|&(span, _)| span).collect(), + false, + None, + kind, + ); + if !infer_replacements.is_empty() { + diag.multipart_suggestion( + format!( + "try replacing `_` with the type{} in the corresponding trait method \ + signature", + rustc_errors::pluralize!(infer_replacements.len()), + ), + infer_replacements, + Applicability::MachineApplicable, + ); + } + + diag.emit() + } } impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { @@ -346,10 +344,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { } fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { + if !self.tcx.dcx().has_stashed_diagnostic(span, StashKey::ItemNoType) { + self.report_placeholder_type_error(vec![span], vec![]); + } Ty::new_error_with_message(self.tcx(), span, "bad placeholder type") } fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { + self.report_placeholder_type_error(vec![span], vec![]); ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant") } @@ -524,18 +526,13 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { fn lower_fn_sig( &self, decl: &hir::FnDecl<'tcx>, - generics: Option<&hir::Generics<'_>>, + _generics: Option<&hir::Generics<'_>>, hir_id: rustc_hir::HirId, - hir_ty: Option<&hir::Ty<'_>>, + _hir_ty: Option<&hir::Ty<'_>>, ) -> (Vec>, Ty<'tcx>) { let tcx = self.tcx(); - // We proactively collect all the inferred type params to emit a single error per fn def. - let mut visitor = HirPlaceholderCollector::default(); - let mut infer_replacements = vec![]; - if let Some(generics) = generics { - walk_generics(&mut visitor, generics); - } + let mut infer_replacements = vec![]; let input_tys = decl .inputs @@ -551,8 +548,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { } } - // Only visit the type looking for `_` if we didn't fix the type above - visitor.visit_ty_unambig(a); self.lowerer().lower_ty(a) }) .collect(); @@ -566,42 +561,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { infer_replacements.push((output.span, suggested_ty.to_string())); Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string()) } else { - visitor.visit_ty_unambig(output); self.lower_ty(output) } } hir::FnRetTy::DefaultReturn(..) => tcx.types.unit, }; - if !(visitor.spans.is_empty() && infer_replacements.is_empty()) { - // We check for the presence of - // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`. - - let mut diag = crate::collect::placeholder_type_error_diag( - self, - generics, - visitor.spans, - infer_replacements.iter().map(|(s, _)| *s).collect(), - !visitor.may_contain_const_infer, - hir_ty, - "function", - ); - - if !infer_replacements.is_empty() { - diag.multipart_suggestion( - format!( - "try replacing `_` with the type{} in the corresponding trait method \ - signature", - rustc_errors::pluralize!(infer_replacements.len()), - ), - infer_replacements, - Applicability::MachineApplicable, - ); - } - - diag.emit(); + if !infer_replacements.is_empty() { + self.report_placeholder_type_error(vec![], infer_replacements); } - (input_tys, output_ty) } @@ -652,7 +620,6 @@ pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let it = tcx.hir_item(item_id); debug!(item = ?it.kind.ident(), id = %it.hir_id()); let def_id = item_id.owner_id.def_id; - let icx = ItemCtxt::new(tcx, def_id); match &it.kind { // These don't define types. @@ -678,16 +645,6 @@ pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } hir::ForeignItemKind::Static(..) => { tcx.ensure_ok().codegen_fn_attrs(item.owner_id); - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_foreign_item(item); - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "static variable", - ); } _ => (), } @@ -741,22 +698,10 @@ pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure_ok().predicates_of(def_id); } - hir::ItemKind::Static(_, _, ty, _) | hir::ItemKind::Const(_, _, ty, _) => { + hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); - if !ty.is_suggestable_infer_ty() { - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_item(it); - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - it.kind.descr(), - ); - } } hir::ItemKind::Fn { .. } => { @@ -773,7 +718,6 @@ pub(crate) fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) let trait_item = tcx.hir_trait_item(trait_item_id); let def_id = trait_item_id.owner_id; tcx.ensure_ok().generics_of(def_id); - let icx = ItemCtxt::new(tcx, def_id.def_id); match trait_item.kind { hir::TraitItemKind::Fn(..) => { @@ -782,58 +726,19 @@ pub(crate) fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) tcx.ensure_ok().fn_sig(def_id); } - hir::TraitItemKind::Const(ty, body_id) => { + hir::TraitItemKind::Const(..) => { tcx.ensure_ok().type_of(def_id); - if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) - && !(ty.is_suggestable_infer_ty() && body_id.is_some()) - { - // Account for `const C: _;`. - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_trait_item(trait_item); - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "associated constant", - ); - } } hir::TraitItemKind::Type(_, Some(_)) => { tcx.ensure_ok().item_bounds(def_id); tcx.ensure_ok().item_self_bounds(def_id); tcx.ensure_ok().type_of(def_id); - // Account for `type T = _;`. - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_trait_item(trait_item); - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "associated type", - ); } hir::TraitItemKind::Type(_, None) => { tcx.ensure_ok().item_bounds(def_id); tcx.ensure_ok().item_self_bounds(def_id); - // #74612: Visit and try to find bad placeholders - // even if there is no concrete type. - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_trait_item(trait_item); - - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "associated type", - ); } }; @@ -846,41 +751,13 @@ pub(super) fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); let impl_item = tcx.hir_impl_item(impl_item_id); - let icx = ItemCtxt::new(tcx, def_id.def_id); match impl_item.kind { hir::ImplItemKind::Fn(..) => { tcx.ensure_ok().codegen_fn_attrs(def_id); tcx.ensure_ok().fn_sig(def_id); } - hir::ImplItemKind::Type(_) => { - // Account for `type T = _;` - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_impl_item(impl_item); - - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "associated type", - ); - } - hir::ImplItemKind::Const(ty, _) => { - // Account for `const T: _ = ..;` - if !ty.is_suggestable_infer_ty() { - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_impl_item(impl_item); - placeholder_type_error( - icx.lowerer(), - None, - visitor.spans, - false, - None, - "associated constant", - ); - } - } + hir::ImplItemKind::Type(_) => {} + hir::ImplItemKind::Const(..) => {} } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 51f57e71ce9b8..69b8be3d9cbc3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -768,6 +768,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str { match def_kind { DefKind::AssocFn if self.associated_item(def_id).is_method() => "method", + DefKind::AssocTy if self.opt_rpitit_info(def_id).is_some() => "opaque type", DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => { match coroutine_kind { hir::CoroutineKind::Desugared( diff --git a/tests/ui/async-await/issues/issue-95307.rs b/tests/ui/async-await/issues/issue-95307.rs index 83df65612b486..40905c239c348 100644 --- a/tests/ui/async-await/issues/issue-95307.rs +++ b/tests/ui/async-await/issues/issue-95307.rs @@ -5,7 +5,10 @@ pub trait C { async fn new() -> [u8; _]; - //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for opaque types + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for opaque types + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for opaque types + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for opaque types } fn main() {} diff --git a/tests/ui/async-await/issues/issue-95307.stderr b/tests/ui/async-await/issues/issue-95307.stderr index c670686f7c9d5..0aae7a215cda0 100644 --- a/tests/ui/async-await/issues/issue-95307.stderr +++ b/tests/ui/async-await/issues/issue-95307.stderr @@ -1,9 +1,33 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types --> $DIR/issue-95307.rs:7:28 | LL | async fn new() -> [u8; _]; | ^ not allowed in type signatures -error: aborting due to 1 previous error +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ not allowed in type signatures + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ not allowed in type signatures + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ not allowed in type signatures + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.rs b/tests/ui/const-generics/generic_arg_infer/in-signature.rs index cd0235bf45aa8..1be8b564224e2 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.rs +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.rs @@ -41,6 +41,7 @@ trait TyAssocConst { trait TyAssocConstMixed { const ARR: Bar<_, _>; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants + //~| ERROR the placeholder `_` is not allowed within types on item signatures for associated constants } trait AssocTy { @@ -57,4 +58,5 @@ impl AssocTy for i16 { impl AssocTy for i32 { type Assoc = Bar<_, _>; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types + //~| ERROR the placeholder `_` is not allowed within types on item signatures for associated types } diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr index f964fc8d2f2c5..b6f2662a93932 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -103,24 +103,28 @@ LL + static TY_STATIC_MIXED: Bar = Bar::(0); | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/in-signature.rs:50:23 + --> $DIR/in-signature.rs:51:23 | LL | type Assoc = [u8; _]; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/in-signature.rs:54:27 + --> $DIR/in-signature.rs:55:27 | LL | type Assoc = Bar; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/in-signature.rs:58:22 + --> $DIR/in-signature.rs:59:22 | LL | type Assoc = Bar<_, _>; - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/in-signature.rs:59:25 + | +LL | type Assoc = Bar<_, _>; + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/in-signature.rs:34:21 @@ -138,10 +142,14 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/in-signature.rs:42:20 | LL | const ARR: Bar<_, _>; - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/in-signature.rs:42:23 + | +LL | const ARR: Bar<_, _>; + | ^ not allowed in type signatures -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr b/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr index 0835f766a824d..fe1ce5ad18b14 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr @@ -240,96 +240,52 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:56:13 | LL | fn foo>(x: X) {} - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:59:34 + --> $DIR/bad-assoc-ty.rs:56:16 + | +LL | fn foo>(x: X) {} + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/bad-assoc-ty.rs:60:34 | LL | fn bar(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn bar(_: F) where F: Fn() -> _ {} -LL + fn bar(_: F) where F: Fn() -> T {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:62:19 + --> $DIR/bad-assoc-ty.rs:63:19 | LL | fn baz _>(_: F) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn baz _>(_: F) {} -LL + fn baz T, T>(_: F) {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:65:33 + --> $DIR/bad-assoc-ty.rs:66:33 | LL | struct L(F) where F: Fn() -> _; | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct L(F) where F: Fn() -> _; -LL + struct L(F) where F: Fn() -> T; - | - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:87:38 - | -LL | fn foo(_: F) where F: Fn() -> _ {} - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn foo(_: F) where F: Fn() -> _ {} -LL + fn foo(_: F) where F: Fn() -> T {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:67:30 + --> $DIR/bad-assoc-ty.rs:68:30 | LL | struct M where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct M where F: Fn() -> _ { -LL + struct M where F: Fn() -> T { - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for enums - --> $DIR/bad-assoc-ty.rs:71:28 + --> $DIR/bad-assoc-ty.rs:72:28 | LL | enum N where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - enum N where F: Fn() -> _ { -LL + enum N where F: Fn() -> T { - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for unions - --> $DIR/bad-assoc-ty.rs:76:29 + --> $DIR/bad-assoc-ty.rs:77:29 | LL | union O where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - union O where F: Fn() -> _ { -LL + union O where F: Fn() -> T { - | error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union - --> $DIR/bad-assoc-ty.rs:78:5 + --> $DIR/bad-assoc-ty.rs:79:5 | LL | foo: F, | ^^^^^^ @@ -341,18 +297,18 @@ LL | foo: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + error[E0121]: the placeholder `_` is not allowed within types on item signatures for traits - --> $DIR/bad-assoc-ty.rs:82:29 + --> $DIR/bad-assoc-ty.rs:83:29 | LL | trait P where F: Fn() -> _ { | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/bad-assoc-ty.rs:88:38 | -help: use type parameters instead - | -LL - trait P where F: Fn() -> _ { -LL + trait P where F: Fn() -> T { - | +LL | fn foo(_: F) where F: Fn() -> _ {} + | ^ not allowed in type signatures -error: aborting due to 29 previous errors; 1 warning emitted +error: aborting due to 30 previous errors; 1 warning emitted Some errors have detailed explanations: E0121, E0223, E0740. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/did_you_mean/bad-assoc-ty.edition2021.stderr b/tests/ui/did_you_mean/bad-assoc-ty.edition2021.stderr index 3cc403f9ac429..2cf7a150aa277 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.edition2021.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.edition2021.stderr @@ -222,96 +222,52 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:56:13 | LL | fn foo>(x: X) {} - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:59:34 + --> $DIR/bad-assoc-ty.rs:56:16 + | +LL | fn foo>(x: X) {} + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/bad-assoc-ty.rs:60:34 | LL | fn bar(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn bar(_: F) where F: Fn() -> _ {} -LL + fn bar(_: F) where F: Fn() -> T {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:62:19 + --> $DIR/bad-assoc-ty.rs:63:19 | LL | fn baz _>(_: F) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn baz _>(_: F) {} -LL + fn baz T, T>(_: F) {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:65:33 + --> $DIR/bad-assoc-ty.rs:66:33 | LL | struct L(F) where F: Fn() -> _; | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct L(F) where F: Fn() -> _; -LL + struct L(F) where F: Fn() -> T; - | - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:87:38 - | -LL | fn foo(_: F) where F: Fn() -> _ {} - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn foo(_: F) where F: Fn() -> _ {} -LL + fn foo(_: F) where F: Fn() -> T {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:67:30 + --> $DIR/bad-assoc-ty.rs:68:30 | LL | struct M where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct M where F: Fn() -> _ { -LL + struct M where F: Fn() -> T { - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for enums - --> $DIR/bad-assoc-ty.rs:71:28 + --> $DIR/bad-assoc-ty.rs:72:28 | LL | enum N where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - enum N where F: Fn() -> _ { -LL + enum N where F: Fn() -> T { - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for unions - --> $DIR/bad-assoc-ty.rs:76:29 + --> $DIR/bad-assoc-ty.rs:77:29 | LL | union O where F: Fn() -> _ { | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - union O where F: Fn() -> _ { -LL + union O where F: Fn() -> T { - | error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union - --> $DIR/bad-assoc-ty.rs:78:5 + --> $DIR/bad-assoc-ty.rs:79:5 | LL | foo: F, | ^^^^^^ @@ -323,18 +279,18 @@ LL | foo: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + error[E0121]: the placeholder `_` is not allowed within types on item signatures for traits - --> $DIR/bad-assoc-ty.rs:82:29 + --> $DIR/bad-assoc-ty.rs:83:29 | LL | trait P where F: Fn() -> _ { | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/bad-assoc-ty.rs:88:38 | -help: use type parameters instead - | -LL - trait P where F: Fn() -> _ { -LL + trait P where F: Fn() -> T { - | +LL | fn foo(_: F) where F: Fn() -> _ {} + | ^ not allowed in type signatures -error: aborting due to 29 previous errors +error: aborting due to 30 previous errors Some errors have detailed explanations: E0121, E0223, E0740, E0782. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/did_you_mean/bad-assoc-ty.rs b/tests/ui/did_you_mean/bad-assoc-ty.rs index 6e56cba24e1ba..9abda4fd962b4 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.rs +++ b/tests/ui/did_you_mean/bad-assoc-ty.rs @@ -55,6 +55,7 @@ type I = ty!()::AssocTy; trait K {} fn foo>(x: X) {} //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +//~| ERROR the placeholder `_` is not allowed within types on item signatures for functions fn bar(_: F) where F: Fn() -> _ {} //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr index f281e77f13b9b..c046302cb91cf 100644 --- a/tests/ui/fn/error-recovery-mismatch.stderr +++ b/tests/ui/fn/error-recovery-mismatch.stderr @@ -34,12 +34,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn fold(&self, _: T, &self._) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn fold(&self, _: T, &self._) {} -LL + fn fold(&self, _: T, &self.U) {} - | error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr index 9622dffda9f84..7d08d8fed9f92 100644 --- a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr +++ b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr @@ -30,12 +30,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn mainIterator<_ = _> {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn mainIterator<_ = _> {} -LL + fn mainIterator {} - | error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/in-trait/not-inferred-generic.stderr b/tests/ui/impl-trait/in-trait/not-inferred-generic.stderr index 07f029d3bb7dc..c08fc511500c5 100644 --- a/tests/ui/impl-trait/in-trait/not-inferred-generic.stderr +++ b/tests/ui/impl-trait/in-trait/not-inferred-generic.stderr @@ -5,7 +5,7 @@ LL | ().publish_typed(); | ^^^^^^^^^^^^^ cannot infer type of the type parameter `F` declared on the method `publish_typed` | = note: cannot satisfy `_: Clone` - = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + = note: opaque types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` note: required by a bound in `TypedClient::publish_typed::{anon_assoc#0}` --> $DIR/not-inferred-generic.rs:4:12 | diff --git a/tests/ui/macros/issue-118048.rs b/tests/ui/macros/issue-118048.rs index 15a834fa2df48..3b3ab3b4fc936 100644 --- a/tests/ui/macros/issue-118048.rs +++ b/tests/ui/macros/issue-118048.rs @@ -6,5 +6,6 @@ macro_rules! foo { foo!(_); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +//~| ERROR the placeholder `_` is not allowed within types on item signatures for functions fn main() {} diff --git a/tests/ui/macros/issue-118048.stderr b/tests/ui/macros/issue-118048.stderr index 4dc5ef71fec69..f5468b341bce6 100644 --- a/tests/ui/macros/issue-118048.stderr +++ b/tests/ui/macros/issue-118048.stderr @@ -2,20 +2,16 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/issue-118048.rs:7:6 | LL | foo!(_); - | ^ - | | - | not allowed in type signatures - | not allowed in type signatures - | -help: use type parameters instead + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-118048.rs:7:6 | -LL ~ fn foo(_: $ty, _: $ty) {} -LL | } -LL | } -LL | -LL ~ foo!(T); +LL | foo!(_); + | ^ not allowed in type signatures | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/macros/macro-span-issue-116502.rs b/tests/ui/macros/macro-span-issue-116502.rs index 4c254289ee684..b5ae383efca03 100644 --- a/tests/ui/macros/macro-span-issue-116502.rs +++ b/tests/ui/macros/macro-span-issue-116502.rs @@ -5,6 +5,8 @@ fn bug() { macro_rules! m { () => { _ //~ ERROR the placeholder `_` is not allowed within types on item signatures for structs + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs + //~| ERROR the placeholder `_` is not allowed within types on item signatures for structs }; } struct S(m!(), T) diff --git a/tests/ui/macros/macro-span-issue-116502.stderr b/tests/ui/macros/macro-span-issue-116502.stderr index 2a581f7031b95..68f8874f5d628 100644 --- a/tests/ui/macros/macro-span-issue-116502.stderr +++ b/tests/ui/macros/macro-span-issue-116502.stderr @@ -2,22 +2,35 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/macro-span-issue-116502.rs:7:13 | LL | _ - | ^ - | | - | not allowed in type signatures - | not allowed in type signatures - | not allowed in type signatures + | ^ not allowed in type signatures ... -LL | struct S(m!(), T) - | ---- ---- in this macro invocation - | | - | in this macro invocation -LL | where LL | T: Trait; | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/macro-span-issue-116502.rs:7:13 + | +LL | _ + | ^ not allowed in type signatures +... +LL | struct S(m!(), T) + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/macro-span-issue-116502.rs:7:13 + | +LL | _ + | ^ not allowed in type signatures +... +LL | struct S(m!(), T) + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/self/self-infer.stderr b/tests/ui/self/self-infer.stderr index c6bdff22b6970..f9db559390f51 100644 --- a/tests/ui/self/self-infer.stderr +++ b/tests/ui/self/self-infer.stderr @@ -3,24 +3,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn f(self: _) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn f(self: _) {} -LL + fn f(self: T) {} - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/self-infer.rs:5:17 | LL | fn g(self: &_) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn g(self: &_) {} -LL + fn g(self: &T) {} - | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/bad-infer-in-trait-impl.stderr b/tests/ui/suggestions/bad-infer-in-trait-impl.stderr index 68d8f5402e44c..8b7d67ac0412b 100644 --- a/tests/ui/suggestions/bad-infer-in-trait-impl.stderr +++ b/tests/ui/suggestions/bad-infer-in-trait-impl.stderr @@ -3,12 +3,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn bar(s: _) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn bar(s: _) {} -LL + fn bar(s: T) {} - | error[E0050]: method `bar` has 1 parameter but the declaration in trait `Foo::bar` has 0 --> $DIR/bad-infer-in-trait-impl.rs:6:15 diff --git a/tests/ui/typeck/issue-74086.rs b/tests/ui/typeck/issue-74086.rs index 9b7c0d7cc6e2e..1993cc7db350e 100644 --- a/tests/ui/typeck/issue-74086.rs +++ b/tests/ui/typeck/issue-74086.rs @@ -1,5 +1,4 @@ fn main() { static BUG: fn(_) -> u8 = |_| 8; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions [E0121] - //~| ERROR the placeholder `_` is not allowed within types on item signatures for static items + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static items } diff --git a/tests/ui/typeck/issue-74086.stderr b/tests/ui/typeck/issue-74086.stderr index 95ebf9a906c14..25f454ac0c320 100644 --- a/tests/ui/typeck/issue-74086.stderr +++ b/tests/ui/typeck/issue-74086.stderr @@ -1,15 +1,9 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/issue-74086.rs:2:20 - | -LL | static BUG: fn(_) -> u8 = |_| 8; - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items --> $DIR/issue-74086.rs:2:20 | LL | static BUG: fn(_) -> u8 = |_| 8; | ^ not allowed in type signatures -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/issue-81885.rs b/tests/ui/typeck/issue-81885.rs index fb3949478a4d3..d73c77b8f3a27 100644 --- a/tests/ui/typeck/issue-81885.rs +++ b/tests/ui/typeck/issue-81885.rs @@ -1,9 +1,7 @@ const TEST4: fn() -> _ = 42; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions - //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constant items fn main() { const TEST5: fn() -> _ = 42; - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions - //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constant items } diff --git a/tests/ui/typeck/issue-81885.stderr b/tests/ui/typeck/issue-81885.stderr index 91c08bd823502..25a6bb632ef14 100644 --- a/tests/ui/typeck/issue-81885.stderr +++ b/tests/ui/typeck/issue-81885.stderr @@ -1,27 +1,15 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/issue-81885.rs:1:22 - | -LL | const TEST4: fn() -> _ = 42; - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items --> $DIR/issue-81885.rs:1:22 | LL | const TEST4: fn() -> _ = 42; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/issue-81885.rs:6:26 - | -LL | const TEST5: fn() -> _ = 42; - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items - --> $DIR/issue-81885.rs:6:26 + --> $DIR/issue-81885.rs:5:26 | LL | const TEST5: fn() -> _ = 42; | ^ not allowed in type signatures -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.rs b/tests/ui/typeck/type-placeholder-fn-in-const.rs index bbb95a5798af5..1600534dd4f8f 100644 --- a/tests/ui/typeck/type-placeholder-fn-in-const.rs +++ b/tests/ui/typeck/type-placeholder-fn-in-const.rs @@ -2,14 +2,12 @@ struct MyStruct; trait Test { const TEST: fn() -> _; - //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] - //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] } impl Test for MyStruct { const TEST: fn() -> _ = 42; - //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] - //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121] } fn main() {} diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.stderr b/tests/ui/typeck/type-placeholder-fn-in-const.stderr index 92b47bd4781c5..a29752948fe35 100644 --- a/tests/ui/typeck/type-placeholder-fn-in-const.stderr +++ b/tests/ui/typeck/type-placeholder-fn-in-const.stderr @@ -1,17 +1,5 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/type-placeholder-fn-in-const.rs:10:25 - | -LL | const TEST: fn() -> _ = 42; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/type-placeholder-fn-in-const.rs:4:25 - | -LL | const TEST: fn() -> _; - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/type-placeholder-fn-in-const.rs:10:25 + --> $DIR/type-placeholder-fn-in-const.rs:9:25 | LL | const TEST: fn() -> _ = 42; | ^ not allowed in type signatures @@ -22,6 +10,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | const TEST: fn() -> _; | ^ not allowed in type signatures -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index d7351f2e51a8d..dc7903619193a 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -33,7 +33,6 @@ fn test7(x: _) { let _x: usize = x; } fn test8(_f: fn() -> _) { } //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -//~^^ ERROR the placeholder `_` is not allowed within types on item signatures for functions struct Test9; @@ -67,6 +66,8 @@ struct Test10 { a: _, //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs b: (_, _), + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs + //~| ERROR the placeholder `_` is not allowed within types on item signatures for structs } pub fn main() { @@ -99,7 +100,6 @@ pub fn main() { fn fn_test8(_f: fn() -> _) { } //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions - //~^^ ERROR the placeholder `_` is not allowed within types on item signatures for functions struct FnTest9; @@ -123,6 +123,8 @@ pub fn main() { a: _, //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs b: (_, _), + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs + //~| ERROR the placeholder `_` is not allowed within types on item signatures for structs } fn fn_test11(_: _) -> (_, _) { panic!() } @@ -141,12 +143,14 @@ trait T { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions fn method_test2(&self, x: _) -> _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + //~| ERROR the placeholder `_` is not allowed within types on item signatures for functions fn method_test3(&self) -> _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test1(x: _); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test2(x: _) -> _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + //~| ERROR the placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test3() -> _; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions } @@ -158,9 +162,11 @@ trait BadTrait<_> {} //~^ ERROR expected identifier, found reserved identifier `_` impl BadTrait<_> for BadStruct<_> {} //~^ ERROR the placeholder `_` is not allowed within types on item signatures for implementations +//~| ERROR the placeholder `_` is not allowed within types on item signatures for implementations fn impl_trait() -> impl BadTrait<_> { -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types +//~| ERROR the placeholder `_` is not allowed within types on item signatures for opaque types unimplemented!() } @@ -180,7 +186,8 @@ struct Struct; trait Trait {} impl Trait for Struct {} type Y = impl Trait<_>; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for type aliases +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types +//~| ERROR the placeholder `_` is not allowed within types on item signatures for opaque types #[define_opaque(Y)] fn foo() -> Y { Struct @@ -197,6 +204,7 @@ trait Qux { // type E: _; // FIXME: make the parser propagate the existence of `B` type F: std::ops::Fn(_); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types + //~| ERROR the placeholder `_` is not allowed within types on item signatures for associated types } impl Qux for Struct { //~^ ERROR not all trait items implemented, missing: `F` diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 7184244f5dc9d..53476f6c80749 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:154:18 + --> $DIR/typeck_type_placeholder_item.rs:158:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:157:16 + --> $DIR/typeck_type_placeholder_item.rs:161:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:167:19 + --> $DIR/typeck_type_placeholder_item.rs:173:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:167:22 + --> $DIR/typeck_type_placeholder_item.rs:173:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:172:19 + --> $DIR/typeck_type_placeholder_item.rs:178:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:207:5 + --> $DIR/typeck_type_placeholder_item.rs:215:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,7 +37,7 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:167:22 + --> $DIR/typeck_type_placeholder_item.rs:173:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -106,72 +106,87 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn test6(_: _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn test6(_: _) { } -LL + fn test6(_: T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:25:18 | LL | fn test6_b(_: _, _: T) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn test6_b(_: _, _: T) { } -LL + fn test6_b(_: U, _: T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:28:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn test6_c(_: _, _: (T, K, L, A, B)) { } -LL + fn test6_c(_: U, _: (T, K, L, A, B)) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:31:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn test7(x: _) { let _x: usize = x; } -LL + fn test7(x: T) { let _x: usize = x; } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:34:22 | LL | fn test8(_f: fn() -> _) { } - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` + | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:34:22 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:66:8 | -LL | fn test8(_f: fn() -> _) { } - | ^ not allowed in type signatures +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:68:9 | -help: use type parameters instead +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:68:12 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:123:12 + | +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:125:13 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:125:16 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:158:21 + | +LL | struct BadStruct<_>(_); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:173:25 | -LL - fn test8(_f: fn() -> _) { } -LL + fn test8(_f: fn() -> T) { } +LL | struct BadStruct1<_, _>(_); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:178:25 | +LL | struct BadStruct2<_, T>(_, T); + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:48:26 + --> $DIR/typeck_type_placeholder_item.rs:47:26 | LL | fn test11(x: &usize) -> &_ { | -^ @@ -180,7 +195,7 @@ LL | fn test11(x: &usize) -> &_ { | help: replace with the correct return type: `&&usize` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:53:52 + --> $DIR/typeck_type_placeholder_item.rs:52:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { | --------------^ @@ -189,7 +204,7 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ { | help: replace with the correct return type: `*const *const usize` error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:59:24 + --> $DIR/typeck_type_placeholder_item.rs:58:24 | LL | fn clone(&self) -> _ { Test9 } | ^ not allowed in type signatures @@ -201,7 +216,7 @@ LL + fn clone(&self) -> Test9 { Test9 } | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:62:37 + --> $DIR/typeck_type_placeholder_item.rs:61:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures @@ -212,33 +227,14 @@ LL - fn clone_from(&mut self, other: _) { *self = Test9; } LL + fn clone_from(&mut self, other: &Test9) { *self = Test9; } | -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:67:8 - | -LL | a: _, - | ^ not allowed in type signatures -LL | -LL | b: (_, _), - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures - | -help: use type parameters instead - | -LL ~ struct Test10 { -LL ~ a: T, -LL | -LL ~ b: (T, T), - | - error: missing type for `static` item - --> $DIR/typeck_type_placeholder_item.rs:73:13 + --> $DIR/typeck_type_placeholder_item.rs:74:13 | LL | static A = 42; | ^ help: provide a type for the static variable: `: i32` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:75:15 + --> $DIR/typeck_type_placeholder_item.rs:76:15 | LL | static B: _ = 42; | ^ not allowed in type signatures @@ -250,7 +246,7 @@ LL + static B: i32 = 42; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:77:22 + --> $DIR/typeck_type_placeholder_item.rs:78:22 | LL | static C: Option<_> = Some(42); | ^ not allowed in type signatures @@ -262,7 +258,7 @@ LL + static C: Option = Some(42); | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:79:21 + --> $DIR/typeck_type_placeholder_item.rs:80:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -271,7 +267,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:82:23 + --> $DIR/typeck_type_placeholder_item.rs:83:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -281,7 +277,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:85:22 + --> $DIR/typeck_type_placeholder_item.rs:86:22 | LL | static FN_TEST3: _ = "test"; | ^ not allowed in type signatures @@ -293,7 +289,7 @@ LL + static FN_TEST3: &str = "test"; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:88:22 + --> $DIR/typeck_type_placeholder_item.rs:89:22 | LL | static FN_TEST4: _ = 145; | ^ not allowed in type signatures @@ -305,7 +301,7 @@ LL + static FN_TEST4: i32 = 145; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:91:23 + --> $DIR/typeck_type_placeholder_item.rs:92:23 | LL | static FN_TEST5: (_, _) = (1, 2); | ^ ^ not allowed in type signatures @@ -319,49 +315,22 @@ LL + static FN_TEST5: (i32, i32) = (1, 2); | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:94:20 + --> $DIR/typeck_type_placeholder_item.rs:95:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn fn_test6(_: _) { } -LL + fn fn_test6(_: T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:97:20 + --> $DIR/typeck_type_placeholder_item.rs:98:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn fn_test7(x: _) { let _x: usize = x; } -LL + fn fn_test7(x: T) { let _x: usize = x; } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:100:29 - | -LL | fn fn_test8(_f: fn() -> _) { } - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:100:29 + --> $DIR/typeck_type_placeholder_item.rs:101:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn fn_test8(_f: fn() -> _) { } -LL + fn fn_test8(_f: fn() -> T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:115:28 @@ -387,33 +356,14 @@ LL - fn clone_from(&mut self, other: _) { *self = FnTest9; } LL + fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; } | -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:123:12 - | -LL | a: _, - | ^ not allowed in type signatures -LL | -LL | b: (_, _), - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures - | -help: use type parameters instead - | -LL ~ struct FnTest10 { -LL ~ a: T, -LL | -LL ~ b: (T, T), - | - error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:128:21 + --> $DIR/typeck_type_placeholder_item.rs:130:21 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ cannot infer type error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:128:28 + --> $DIR/typeck_type_placeholder_item.rs:130:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -421,7 +371,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:132:30 + --> $DIR/typeck_type_placeholder_item.rs:134:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -431,7 +381,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:135:33 + --> $DIR/typeck_type_placeholder_item.rs:137:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -439,152 +389,116 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | | not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:154:21 - | -LL | struct BadStruct<_>(_); - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct BadStruct<_>(_); -LL + struct BadStruct(T); - | - error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:140:31 + --> $DIR/typeck_type_placeholder_item.rs:142:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn method_test1(&self, x: _); -LL + fn method_test1(&self, x: T); - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:142:31 + --> $DIR/typeck_type_placeholder_item.rs:144:31 | LL | fn method_test2(&self, x: _) -> _; - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures - | -help: use type parameters instead - | -LL - fn method_test2(&self, x: _) -> _; -LL + fn method_test2(&self, x: T) -> T; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:144:37 | +LL | fn method_test2(&self, x: _) -> _; + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:144:31 + --> $DIR/typeck_type_placeholder_item.rs:147:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn method_test3(&self) -> _; -LL + fn method_test3(&self) -> T; - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:146:26 + --> $DIR/typeck_type_placeholder_item.rs:149:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn assoc_fn_test1(x: _); -LL + fn assoc_fn_test1(x: T); - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:148:26 + --> $DIR/typeck_type_placeholder_item.rs:151:26 | LL | fn assoc_fn_test2(x: _) -> _; - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures - | -help: use type parameters instead - | -LL - fn assoc_fn_test2(x: _) -> _; -LL + fn assoc_fn_test2(x: T) -> T; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:151:32 | +LL | fn assoc_fn_test2(x: _) -> _; + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:150:28 + --> $DIR/typeck_type_placeholder_item.rs:154:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/typeck_type_placeholder_item.rs:163:32 | -help: use type parameters instead - | -LL - fn assoc_fn_test3() -> _; -LL + fn assoc_fn_test3() -> T; - | +LL | impl BadTrait<_> for BadStruct<_> {} + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations - --> $DIR/typeck_type_placeholder_item.rs:159:15 + --> $DIR/typeck_type_placeholder_item.rs:163:15 | LL | impl BadTrait<_> for BadStruct<_> {} - | ^ ^ not allowed in type signatures - | | - | not allowed in type signatures + | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:162:34 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:167:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:167:25 - | -LL | struct BadStruct1<_, _>(_); - | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - struct BadStruct1<_, _>(_); -LL + struct BadStruct1(T); +error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/typeck_type_placeholder_item.rs:182:14 | +LL | type X = Box<_>; + | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:172:25 - | -LL | struct BadStruct2<_, T>(_, T); - | ^ not allowed in type signatures +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:188:21 | -help: use type parameters instead +LL | type Y = impl Trait<_>; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:198:14 | -LL - struct BadStruct2<_, T>(_, T); -LL + struct BadStruct2(U, T); +LL | type B = _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:211:14 | +LL | type A = _; + | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases - --> $DIR/typeck_type_placeholder_item.rs:176:14 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:213:14 | -LL | type X = Box<_>; +LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases - --> $DIR/typeck_type_placeholder_item.rs:182:21 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/typeck_type_placeholder_item.rs:200:14 | -LL | type Y = impl Trait<_>; - | ^ not allowed in type signatures +LL | const C: _; + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:207:14 + --> $DIR/typeck_type_placeholder_item.rs:215:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:195:14 + --> $DIR/typeck_type_placeholder_item.rs:202:14 | LL | const D: _ = 42; | ^ not allowed in type signatures @@ -596,13 +510,13 @@ LL + const D: i32 = 42; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:210:14 + --> $DIR/typeck_type_placeholder_item.rs:218:14 | LL | const D: _ = 42; | ^ not allowed in type signatures error[E0046]: not all trait items implemented, missing: `F` - --> $DIR/typeck_type_placeholder_item.rs:201:1 + --> $DIR/typeck_type_placeholder_item.rs:209:1 | LL | type F: std::ops::Fn(_); | ----------------------- `F` from trait @@ -611,7 +525,7 @@ LL | impl Qux for Struct { | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:218:31 + --> $DIR/typeck_type_placeholder_item.rs:226:31 | LL | fn value() -> Option<&'static _> { | ----------------^- @@ -620,7 +534,7 @@ LL | fn value() -> Option<&'static _> { | help: replace with the correct return type: `Option<&'static u8>` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:223:17 + --> $DIR/typeck_type_placeholder_item.rs:231:17 | LL | const _: Option<_> = map(value); | ^ not allowed in type signatures @@ -632,7 +546,7 @@ LL + const _: Option = map(value); | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:227:31 + --> $DIR/typeck_type_placeholder_item.rs:235:31 | LL | fn evens_squared(n: usize) -> _ { | ^ @@ -641,19 +555,19 @@ LL | fn evens_squared(n: usize) -> _ { | help: replace with an appropriate return type: `impl Iterator` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:232:10 + --> $DIR/typeck_type_placeholder_item.rs:240:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^ not allowed in type signatures | -note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:232:29}>, {closure@typeck_type_placeholder_item.rs:232:49}>` cannot be named - --> $DIR/typeck_type_placeholder_item.rs:232:14 +note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:240:29}>, {closure@typeck_type_placeholder_item.rs:240:49}>` cannot be named + --> $DIR/typeck_type_placeholder_item.rs:240:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:41:24 + --> $DIR/typeck_type_placeholder_item.rs:40:24 | LL | fn test9(&self) -> _ { () } | ^ @@ -662,16 +576,10 @@ LL | fn test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item.rs:44:27 + --> $DIR/typeck_type_placeholder_item.rs:43:27 | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn test10(&self, _x : _) { } -LL + fn test10(&self, _x : T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:107:31 @@ -687,68 +595,62 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL - fn fn_test10(&self, _x : _) { } -LL + fn fn_test10(&self, _x : T) { } - | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:203:14 + --> $DIR/typeck_type_placeholder_item.rs:205:26 | -LL | type A = _; - | ^ not allowed in type signatures +LL | type F: std::ops::Fn(_); + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:205:14 + --> $DIR/typeck_type_placeholder_item.rs:205:26 | -LL | type B = _; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:191:14 +LL | type F: std::ops::Fn(_); + | ^ not allowed in type signatures | -LL | type B = _; - | ^ not allowed in type signatures + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:193:14 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:167:34 | -LL | const C: _; - | ^ not allowed in type signatures +LL | fn impl_trait() -> impl BadTrait<_> { + | ^ not allowed in type signatures + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:198:26 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:188:21 | -LL | type F: std::ops::Fn(_); - | ^ not allowed in type signatures +LL | type Y = impl Trait<_>; + | ^ not allowed in type signatures + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const function `map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:223:22 + --> $DIR/typeck_type_placeholder_item.rs:231:22 | LL | const _: Option<_> = map(value); | ^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}>` in constants - --> $DIR/typeck_type_placeholder_item.rs:232:22 +error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}>` in constants + --> $DIR/typeck_type_placeholder_item.rs:240:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}> as Iterator>::map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:232:45 +error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants + --> $DIR/typeck_type_placeholder_item.rs:240:45 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error: aborting due to 75 previous errors +error: aborting due to 83 previous errors Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.rs b/tests/ui/typeck/typeck_type_placeholder_item_help.rs index ff6182588c720..ab433aaaf1620 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.rs @@ -11,8 +11,7 @@ const TEST3: _ = Some(42); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants const TEST4: fn() -> _ = 42; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -//~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constant items trait Test5 { const TEST5: _ = 42; diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr index afdd58e0a0384..5066e2eaa523b 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -31,12 +31,6 @@ LL - const TEST3: _ = Some(42); LL + const TEST3: Option = Some(42); | -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/typeck_type_placeholder_item_help.rs:13:22 - | -LL | const TEST4: fn() -> _ = 42; - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items --> $DIR/typeck_type_placeholder_item_help.rs:13:22 | @@ -44,7 +38,7 @@ LL | const TEST4: fn() -> _ = 42; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item_help.rs:25:18 + --> $DIR/typeck_type_placeholder_item_help.rs:24:18 | LL | const TEST6: _ = 13; | ^ not allowed in type signatures @@ -56,7 +50,7 @@ LL + const TEST6: i32 = 13; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item_help.rs:18:18 + --> $DIR/typeck_type_placeholder_item_help.rs:17:18 | LL | const TEST5: _ = 42; | ^ not allowed in type signatures @@ -68,7 +62,7 @@ LL + const TEST5: i32 = 42; | error[E0308]: mismatched types - --> $DIR/typeck_type_placeholder_item_help.rs:30:28 + --> $DIR/typeck_type_placeholder_item_help.rs:29:28 | LL | let _: Option = test1(); | ------------- ^^^^^^^ expected `Option`, found `Option` @@ -79,7 +73,7 @@ LL | let _: Option = test1(); found enum `Option` error[E0308]: mismatched types - --> $DIR/typeck_type_placeholder_item_help.rs:31:18 + --> $DIR/typeck_type_placeholder_item_help.rs:30:18 | LL | let _: f64 = test1(); | --- ^^^^^^^ expected `f64`, found `Option` @@ -89,7 +83,7 @@ LL | let _: f64 = test1(); = note: expected type `f64` found enum `Option` -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0121, E0308. For more information about an error, try `rustc --explain E0121`. From 89a636fb12d0125f08847a40f8edfa30d2da9186 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 26 Jun 2025 11:22:36 +0200 Subject: [PATCH 12/15] Add tracing to validate_operand --- compiler/rustc_const_eval/src/interpret/validity.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 231f8091777b3..50139ff191047 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -35,6 +35,7 @@ use super::{ Machine, MemPlaceMeta, PlaceTy, Pointer, Projectable, Scalar, ValueVisitor, err_ub, format_interp_error, }; +use crate::enter_trace_span; // for the validation errors #[rustfmt::skip] @@ -1401,6 +1402,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { recursive: bool, reset_provenance_and_padding: bool, ) -> InterpResult<'tcx> { + let _span = enter_trace_span!( + M, + "validate_operand", + "recursive={recursive}, reset_provenance_and_padding={reset_provenance_and_padding}, val={val:?}" + ); + // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's // still correct to not use `ctfe_mode`: that mode is for validation of the final constant // value, it rules out things like `UnsafeCell` in awkward places. From 5e1082899b06c821f8bf06f3458c76a87c89dcd4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 20 May 2025 17:01:59 +0200 Subject: [PATCH 13/15] Add tracing for instantiate_from_frame_and_normalize_erasing_regions --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index b69bc0918be82..70cd7544368c0 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -21,7 +21,7 @@ use super::{ MemPlaceMeta, Memory, OpTy, Place, PlaceTy, PointerArithmetic, Projectable, Provenance, err_inval, interp_ok, throw_inval, throw_ub, throw_ub_custom, }; -use crate::{ReportErrorExt, fluent_generated as fluent, util}; +use crate::{ReportErrorExt, enter_trace_span, fluent_generated as fluent, util}; pub struct InterpCx<'tcx, M: Machine<'tcx>> { /// Stores the `Machine` instance. @@ -284,6 +284,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { frame: &Frame<'tcx, M::Provenance, M::FrameExtra>, value: T, ) -> Result { + let _span = enter_trace_span!( + M, + "instantiate_from_frame_and_normalize_erasing_regions", + "{}", + frame.instance + ); frame .instance .try_instantiate_mir_and_normalize_erasing_regions( From 708dc15cf1f2fe1e0df4a2485e455337408932da Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 27 Jun 2025 10:54:58 +0200 Subject: [PATCH 14/15] Add InterpCx::layout_of with tracing, shadowing LayoutOf --- .../src/const_eval/eval_queries.rs | 2 +- compiler/rustc_const_eval/src/const_eval/mod.rs | 1 - .../rustc_const_eval/src/const_eval/valtrees.rs | 2 +- compiler/rustc_const_eval/src/interpret/call.rs | 2 +- compiler/rustc_const_eval/src/interpret/cast.rs | 2 +- .../src/interpret/discriminant.rs | 2 +- .../src/interpret/eval_context.rs | 17 ++++++++++++++++- .../src/interpret/intrinsics.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 2 +- .../rustc_const_eval/src/interpret/operator.rs | 2 +- .../rustc_const_eval/src/interpret/place.rs | 2 +- .../src/interpret/projection.rs | 2 +- .../rustc_const_eval/src/interpret/stack.rs | 2 +- .../rustc_const_eval/src/interpret/traits.rs | 1 - .../rustc_const_eval/src/interpret/validity.rs | 2 +- .../rustc_const_eval/src/interpret/visitor.rs | 1 - .../src/util/caller_location.rs | 1 - .../src/dataflow_const_prop.rs | 1 - compiler/rustc_mir_transform/src/gvn.rs | 2 +- .../rustc_mir_transform/src/jump_threading.rs | 1 - src/tools/miri/src/eval.rs | 2 +- src/tools/miri/src/intrinsics/simd.rs | 1 - src/tools/miri/src/shims/backtrace.rs | 1 - src/tools/miri/src/shims/os_str.rs | 1 - src/tools/miri/src/shims/unix/env.rs | 1 - src/tools/miri/src/shims/unix/foreign_items.rs | 1 - src/tools/miri/src/shims/windows/thread.rs | 1 - src/tools/miri/src/shims/x86/aesni.rs | 1 - src/tools/miri/src/shims/x86/avx.rs | 1 - src/tools/miri/src/shims/x86/avx2.rs | 1 - src/tools/miri/src/shims/x86/mod.rs | 1 - src/tools/miri/src/shims/x86/sse42.rs | 1 - 32 files changed, 30 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index be84019154710..569a07c3a011e 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -7,7 +7,7 @@ use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo}; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::query::TyCtxtAt; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, throw_inval}; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 73cb1e774361d..2aaf718c733b4 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -2,7 +2,6 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::query::Key; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use tracing::instrument; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index b3d2e1a0598e2..5ab72c853c4fc 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,7 +1,7 @@ use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError}; -use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutCx, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 37677f9e0483a..79c14b204e367 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -6,7 +6,7 @@ use std::borrow::Cow; use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; use rustc_hir::def_id::DefId; -use rustc_middle::ty::layout::{FnAbiOf, IntegerExt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{FnAbiOf, IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::sym; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 9e15f4572d7b9..1036935bb106a 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -6,7 +6,7 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::CastKind; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_middle::{bug, span_bug}; use tracing::trace; diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 6c4b000e16b5e..b7e7f65c95c78 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -1,7 +1,7 @@ //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines). use rustc_abi::{self as abi, FieldIdx, TagEncoding, VariantIdx, Variants}; -use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; +use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, CoroutineArgsExt, ScalarInt, Ty}; use rustc_middle::{mir, span_bug}; use tracing::{instrument, trace}; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 70cd7544368c0..99ca733df58da 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,8 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ - self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, + self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, + TyAndLayout, }; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance}; use rustc_middle::{mir, span_bug}; @@ -91,6 +92,20 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> { } } +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { + /// This inherent method takes priority over the trait method with the same name in LayoutOf, + /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span. + /// See [LayoutOf::layout_of] for the original documentation. + #[inline] + pub fn layout_of( + &self, + ty: Ty<'tcx>, + ) -> as LayoutOfHelpers<'tcx>>::LayoutOfResult { + let _span = enter_trace_span!(M, "InterpCx::layout_of", "ty = {:?}", ty.kind()); + LayoutOf::layout_of(self, ty) + } +} + impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { type FnAbiOfResult = Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, InterpErrorKind<'tcx>>; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 96c39c7bb32ba..6acc89c8b02ae 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -8,7 +8,7 @@ use rustc_abi::Size; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_hir::def_id::DefId; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; -use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement}; +use rustc_middle::ty::layout::{TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{GenericArgsRef, Ty, TyCtxt}; use rustc_middle::{bug, ty}; use rustc_span::{Symbol, sym}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 337b161767631..62cbbae24a8fb 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -8,7 +8,7 @@ use rustc_abi as abi; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_hir::def::Namespace; use rustc_middle::mir::interpret::ScalarSizeMismatch; -use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug, ty}; diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 899670aeb62da..74f8a0a7b093c 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -3,7 +3,7 @@ use rustc_abi::Size; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::NullOp; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; -use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::sym; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index e4885af7faf48..88f323e0c56a4 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -7,7 +7,7 @@ use std::assert_matches::assert_matches; use either::{Either, Left, Right}; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, mir, span_bug}; use tracing::{instrument, trace}; diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index ad47a19a14d5c..a71affb1be16d 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -12,7 +12,7 @@ use std::ops::Range; use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx}; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, mir, span_bug, ty}; use tracing::{debug, instrument}; diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 2a2d1bb27547e..3361a586b8eef 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -7,7 +7,7 @@ use either::{Either, Left, Right}; use rustc_hir as hir; use rustc_hir::definitions::DefPathData; use rustc_index::IndexVec; -use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_mir_dataflow::impls::always_storage_live_locals; diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 7249ef23bf627..8b634955bb796 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -1,6 +1,5 @@ use rustc_abi::{Align, FieldIdx, Size}; use rustc_middle::mir::interpret::{InterpResult, Pointer}; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, VtblEntry}; use tracing::trace; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 7e26b7f3d9629..fff1b62470c95 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -24,7 +24,7 @@ use rustc_middle::mir::interpret::{ ExpectedKind, InterpErrorKind, InvalidMetaKind, Misalignment, PointerKind, Provenance, UnsupportedOpInfo, ValidationErrorInfo, alloc_range, interp_ok, }; -use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutCx, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_span::{Symbol, sym}; use tracing::trace; diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 5aea91233bda9..d5970b69baf79 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -6,7 +6,6 @@ use std::num::NonZero; use rustc_abi::{FieldIdx, FieldsShape, VariantIdx, Variants}; use rustc_index::IndexVec; use rustc_middle::mir::interpret::InterpResult; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use tracing::trace; diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 671214002a0d8..ab2de279ed8de 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,6 +1,5 @@ use rustc_abi::FieldIdx; use rustc_hir::LangItem; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::Symbol; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 0cf8142a560fb..fe53de31f7583 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -16,7 +16,6 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::fmt::DebugWithContext; use rustc_mir_dataflow::lattice::{FlatSet, HasBottom}; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index bda71ceaa551a..1ead241c3ba0e 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -102,7 +102,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index b45bff2af4478..f9e642e28ebd7 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -45,7 +45,6 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ScalarInt, TyCtxt}; use rustc_mir_dataflow::lattice::HasBottom; use rustc_mir_dataflow::value_analysis::{Map, PlaceIndex, State, TrackElem}; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 7a5f96ec1779d..04fe08b30ee36 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -11,7 +11,7 @@ use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; -use rustc_middle::ty::layout::{LayoutCx, LayoutOf}; +use rustc_middle::ty::layout::LayoutCx; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index dbe193bdbda82..52224f33c7302 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -3,7 +3,6 @@ use rand::Rng; use rustc_abi::{Endian, HasDataLayout}; use rustc_apfloat::{Float, Round}; use rustc_middle::ty::FloatTy; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::{mir, ty}; use rustc_span::{Symbol, sym}; diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index feb83ca8829ab..dd00b270b38fb 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -1,5 +1,4 @@ use rustc_abi::{CanonAbi, FieldIdx, Size}; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{BytePos, Loc, Symbol, hygiene}; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index 7080edb26a5ff..b9391a0ffe077 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -7,7 +7,6 @@ use std::os::windows::ffi::{OsStrExt, OsStringExt}; use std::path::{Path, PathBuf}; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf; use crate::*; diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 62ac7ee380654..604fb0974d29a 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -6,7 +6,6 @@ use rustc_abi::{FieldIdx, Size}; use rustc_data_structures::fx::FxHashMap; use rustc_index::IndexVec; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf; use crate::*; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 9106ef94c435b..14ebb22dc2bc3 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -3,7 +3,6 @@ use std::str; use rustc_abi::{CanonAbi, ExternAbi, Size}; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index d5f9ed4e968ea..56ae88bb1a178 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -1,5 +1,4 @@ use rustc_abi::ExternAbi; -use rustc_middle::ty::layout::LayoutOf; use self::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle}; use crate::*; diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 7191284b5a3f4..058ca24e730f6 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -1,6 +1,5 @@ use rustc_abi::CanonAbi; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 37539fec74858..83d23d6ad3698 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -2,7 +2,6 @@ use rustc_abi::CanonAbi; use rustc_apfloat::ieee::{Double, Single}; use rustc_middle::mir; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 5dfe5cc2c5424..49d5977078b03 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -1,7 +1,6 @@ use rustc_abi::CanonAbi; use rustc_middle::mir; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 1e82f521249fc..fbfe459711e0d 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -2,7 +2,6 @@ use rustc_abi::{CanonAbi, FieldIdx, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::{mir, ty}; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 830513f02911f..7e1e1482ef479 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -1,7 +1,6 @@ use rustc_abi::{CanonAbi, Size}; use rustc_middle::mir; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; From ed4f01ed2e033098f6c5e10a4a0cc740dc04f958 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 27 Jun 2025 12:47:47 +0200 Subject: [PATCH 15/15] const-eval: error when initializing a static writes to that static --- compiler/rustc_const_eval/messages.ftl | 2 +- .../src/const_eval/machine.rs | 22 +++++++++----- .../rustc_const_eval/src/interpret/machine.rs | 6 +++- .../rustc_const_eval/src/interpret/memory.rs | 30 ++++++++++++------- tests/ui/consts/recursive-static-write.rs | 24 +++++++++++++++ tests/ui/consts/recursive-static-write.stderr | 15 ++++++++++ .../recursive-zst-static.default.stderr | 10 +++---- tests/ui/consts/recursive-zst-static.rs | 2 +- .../recursive-zst-static.unleash.stderr | 10 +++---- .../consts/write-to-static-mut-in-static.rs | 3 +- .../write-to-static-mut-in-static.stderr | 12 ++++++-- .../recursion/recursive-static-definition.rs | 4 +-- .../recursive-static-definition.stderr | 4 +-- tests/ui/statics/read_before_init.rs | 10 ++++--- tests/ui/statics/read_before_init.stderr | 28 ++++++++++++----- 15 files changed, 133 insertions(+), 49 deletions(-) create mode 100644 tests/ui/consts/recursive-static-write.rs create mode 100644 tests/ui/consts/recursive-static-write.stderr diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 97b154ad14235..671ae5975a78b 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -352,7 +352,7 @@ const_eval_realloc_or_alloc_with_offset = *[other] {""} } {$ptr} which does not point to the beginning of an object -const_eval_recursive_static = encountered static that tried to initialize itself with itself +const_eval_recursive_static = encountered static that tried to access itself during initialization const_eval_remainder_by_zero = calculating the remainder with a divisor of zero diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index a68dcf2998866..2ec3f8432c771 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -62,7 +62,7 @@ pub struct CompileTimeMachine<'tcx> { /// If `Some`, we are evaluating the initializer of the static with the given `LocalDefId`, /// storing the result in the given `AllocId`. - /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops. + /// Used to prevent accesses to a static's base allocation, as that may allow for self-initialization loops. pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>, /// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes). @@ -705,19 +705,27 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { interp_ok(()) } - fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> { + fn before_alloc_access( + tcx: TyCtxtAt<'tcx>, + machine: &Self, + alloc_id: AllocId, + ) -> InterpResult<'tcx> { + if machine.stack.is_empty() { + // Get out of the way for the final copy. + return interp_ok(()); + } // Check if this is the currently evaluated static. - if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { + if Some(alloc_id) == machine.static_root_ids.map(|(id, _)| id) { return Err(ConstEvalErrKind::RecursiveStatic).into(); } // If this is another static, make sure we fire off the query to detect cycles. // But only do that when checks for static recursion are enabled. - if ecx.machine.static_root_ids.is_some() { - if let Some(GlobalAlloc::Static(def_id)) = ecx.tcx.try_get_global_alloc(alloc_id) { - if ecx.tcx.is_foreign_item(def_id) { + if machine.static_root_ids.is_some() { + if let Some(GlobalAlloc::Static(def_id)) = tcx.try_get_global_alloc(alloc_id) { + if tcx.is_foreign_item(def_id) { throw_unsup!(ExternStatic(def_id)); } - ecx.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?; + tcx.eval_static_initializer(def_id)?; } } interp_ok(()) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index b9e022c96043f..d6d230fbd1776 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -443,7 +443,11 @@ pub trait Machine<'tcx>: Sized { /// /// Used to prevent statics from self-initializing by reading from their own memory /// as it is being initialized. - fn before_alloc_read(_ecx: &InterpCx<'tcx, Self>, _alloc_id: AllocId) -> InterpResult<'tcx> { + fn before_alloc_access( + _tcx: TyCtxtAt<'tcx>, + _machine: &Self, + _alloc_id: AllocId, + ) -> InterpResult<'tcx> { interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 57bf867e389b2..69fceb02ff931 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -720,7 +720,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // do this after `check_and_deref_ptr` to ensure some basic sanity has already been checked. if !self.memory.validation_in_progress.get() { if let Ok((alloc_id, ..)) = self.ptr_try_get_alloc_id(ptr, size_i64) { - M::before_alloc_read(self, alloc_id)?; + M::before_alloc_access(self.tcx, &self.machine, alloc_id)?; } } @@ -821,6 +821,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if let Some((alloc_id, offset, prov, alloc, machine)) = ptr_and_alloc { let range = alloc_range(offset, size); if !validation_in_progress { + // For writes, it's okay to only call those when there actually is a non-zero + // amount of bytes to be written: a zero-sized write doesn't manifest anything. + M::before_alloc_access(tcx, machine, alloc_id)?; M::before_memory_write( tcx, machine, @@ -1396,6 +1399,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src_parts = self.get_ptr_access(src, size)?; let dest_parts = self.get_ptr_access(dest, size * num_copies)?; // `Size` multiplication + // Similar to `get_ptr_alloc`, we need to call `before_alloc_access` even for zero-sized + // reads. However, just like in `get_ptr_alloc_mut`, the write part is okay to skip for + // zero-sized writes. + if let Ok((alloc_id, ..)) = self.ptr_try_get_alloc_id(src, size.bytes().try_into().unwrap()) + { + M::before_alloc_access(tcx, &self.machine, alloc_id)?; + } + // FIXME: we look up both allocations twice here, once before for the `check_ptr_access` // and once below to get the underlying `&[mut] Allocation`. @@ -1408,12 +1419,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src_range = alloc_range(src_offset, size); assert!(!self.memory.validation_in_progress.get(), "we can't be copying during validation"); - // Trigger read hooks. - // For the overlapping case, it is crucial that we trigger the read hooks + // Trigger read hook. + // For the overlapping case, it is crucial that we trigger the read hook // before the write hook -- the aliasing model cares about the order. - if let Ok((alloc_id, ..)) = self.ptr_try_get_alloc_id(src, size.bytes() as i64) { - M::before_alloc_read(self, alloc_id)?; - } M::before_memory_read( tcx, &self.machine, @@ -1438,16 +1446,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let provenance = src_alloc .provenance() .prepare_copy(src_range, dest_offset, num_copies, self) - .map_err(|e| e.to_interp_error(dest_alloc_id))?; + .map_err(|e| e.to_interp_error(src_alloc_id))?; // Prepare a copy of the initialization mask. let init = src_alloc.init_mask().prepare_copy(src_range); - // Destination alloc preparations and access hooks. - let (dest_alloc, extra) = self.get_alloc_raw_mut(dest_alloc_id)?; + // Destination alloc preparations... + let (dest_alloc, machine) = self.get_alloc_raw_mut(dest_alloc_id)?; let dest_range = alloc_range(dest_offset, size * num_copies); + // ...and access hooks. + M::before_alloc_access(tcx, machine, dest_alloc_id)?; M::before_memory_write( tcx, - extra, + machine, &mut dest_alloc.extra, dest, (dest_alloc_id, dest_prov), diff --git a/tests/ui/consts/recursive-static-write.rs b/tests/ui/consts/recursive-static-write.rs new file mode 100644 index 0000000000000..dc5813d8c7834 --- /dev/null +++ b/tests/ui/consts/recursive-static-write.rs @@ -0,0 +1,24 @@ +//! Ensure that writing to `S` while initializing `S` errors. +//! Regression test for . +#![allow(dead_code)] + +struct Foo { + x: i32, + y: (), +} + +static S: Foo = Foo { + x: 0, + y: unsafe { + (&raw const S.x).cast_mut().write(1); //~ERROR access itself during initialization + }, +}; + +static mut S2: Foo = Foo { + x: 0, + y: unsafe { + S2.x = 1; //~ERROR access itself during initialization + }, +}; + +fn main() {} diff --git a/tests/ui/consts/recursive-static-write.stderr b/tests/ui/consts/recursive-static-write.stderr new file mode 100644 index 0000000000000..f5b5c49317cfc --- /dev/null +++ b/tests/ui/consts/recursive-static-write.stderr @@ -0,0 +1,15 @@ +error[E0080]: encountered static that tried to access itself during initialization + --> $DIR/recursive-static-write.rs:13:9 + | +LL | (&raw const S.x).cast_mut().write(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `S` failed here + +error[E0080]: encountered static that tried to access itself during initialization + --> $DIR/recursive-static-write.rs:20:9 + | +LL | S2.x = 1; + | ^^^^^^^^ evaluation of `S2` failed here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr index fee33a892d06e..c814576dfd5b9 100644 --- a/tests/ui/consts/recursive-zst-static.default.stderr +++ b/tests/ui/consts/recursive-zst-static.default.stderr @@ -1,20 +1,20 @@ -error[E0080]: encountered static that tried to initialize itself with itself +error[E0080]: encountered static that tried to access itself during initialization --> $DIR/recursive-zst-static.rs:10:18 | LL | static FOO: () = FOO; | ^^^ evaluation of `FOO` failed here error[E0391]: cycle detected when evaluating initializer of static `A` - --> $DIR/recursive-zst-static.rs:13:16 + --> $DIR/recursive-zst-static.rs:13:1 | LL | static A: () = B; - | ^ + | ^^^^^^^^^^^^ | note: ...which requires evaluating initializer of static `B`... - --> $DIR/recursive-zst-static.rs:14:16 + --> $DIR/recursive-zst-static.rs:14:1 | LL | static B: () = A; - | ^ + | ^^^^^^^^^^^^ = note: ...which again requires evaluating initializer of static `A`, completing the cycle = note: cycle used when running analysis passes on this crate = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/consts/recursive-zst-static.rs b/tests/ui/consts/recursive-zst-static.rs index 852caae949341..853af6d70eb09 100644 --- a/tests/ui/consts/recursive-zst-static.rs +++ b/tests/ui/consts/recursive-zst-static.rs @@ -8,7 +8,7 @@ // See https://github.com/rust-lang/rust/issues/71078 for more details. static FOO: () = FOO; -//~^ ERROR encountered static that tried to initialize itself with itself +//~^ ERROR encountered static that tried to access itself during initialization static A: () = B; //~ ERROR cycle detected when evaluating initializer of static `A` static B: () = A; diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr index fee33a892d06e..c814576dfd5b9 100644 --- a/tests/ui/consts/recursive-zst-static.unleash.stderr +++ b/tests/ui/consts/recursive-zst-static.unleash.stderr @@ -1,20 +1,20 @@ -error[E0080]: encountered static that tried to initialize itself with itself +error[E0080]: encountered static that tried to access itself during initialization --> $DIR/recursive-zst-static.rs:10:18 | LL | static FOO: () = FOO; | ^^^ evaluation of `FOO` failed here error[E0391]: cycle detected when evaluating initializer of static `A` - --> $DIR/recursive-zst-static.rs:13:16 + --> $DIR/recursive-zst-static.rs:13:1 | LL | static A: () = B; - | ^ + | ^^^^^^^^^^^^ | note: ...which requires evaluating initializer of static `B`... - --> $DIR/recursive-zst-static.rs:14:16 + --> $DIR/recursive-zst-static.rs:14:1 | LL | static B: () = A; - | ^ + | ^^^^^^^^^^^^ = note: ...which again requires evaluating initializer of static `A`, completing the cycle = note: cycle used when running analysis passes on this crate = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/consts/write-to-static-mut-in-static.rs b/tests/ui/consts/write-to-static-mut-in-static.rs index ce15d9e912b64..016bfb06ccfc7 100644 --- a/tests/ui/consts/write-to-static-mut-in-static.rs +++ b/tests/ui/consts/write-to-static-mut-in-static.rs @@ -3,8 +3,9 @@ pub static mut B: () = unsafe { A = 1; }; //~^ ERROR modifying a static's initial value pub static mut C: u32 = unsafe { C = 1; 0 }; +//~^ ERROR static that tried to access itself during initialization pub static D: u32 = D; -//~^ ERROR static that tried to initialize itself with itself +//~^ ERROR static that tried to access itself during initialization fn main() {} diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr index bb5e217afb97b..4180bb49339e2 100644 --- a/tests/ui/consts/write-to-static-mut-in-static.stderr +++ b/tests/ui/consts/write-to-static-mut-in-static.stderr @@ -4,12 +4,18 @@ error[E0080]: modifying a static's initial value from another static's initializ LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ evaluation of `B` failed here -error[E0080]: encountered static that tried to initialize itself with itself - --> $DIR/write-to-static-mut-in-static.rs:7:21 +error[E0080]: encountered static that tried to access itself during initialization + --> $DIR/write-to-static-mut-in-static.rs:5:34 + | +LL | pub static mut C: u32 = unsafe { C = 1; 0 }; + | ^^^^^ evaluation of `C` failed here + +error[E0080]: encountered static that tried to access itself during initialization + --> $DIR/write-to-static-mut-in-static.rs:8:21 | LL | pub static D: u32 = D; | ^ evaluation of `D` failed here -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/recursion/recursive-static-definition.rs b/tests/ui/recursion/recursive-static-definition.rs index 55db6a86bf1fc..4f0624eb16235 100644 --- a/tests/ui/recursion/recursive-static-definition.rs +++ b/tests/ui/recursion/recursive-static-definition.rs @@ -1,5 +1,5 @@ pub static FOO: u32 = FOO; -//~^ ERROR encountered static that tried to initialize itself with itself +//~^ ERROR encountered static that tried to access itself during initialization #[derive(Copy, Clone)] pub union Foo { @@ -7,6 +7,6 @@ pub union Foo { } pub static BAR: Foo = BAR; -//~^ ERROR encountered static that tried to initialize itself with itself +//~^ ERROR encountered static that tried to access itself during initialization fn main() {} diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr index ce93c41bc67ce..1e4005832cbba 100644 --- a/tests/ui/recursion/recursive-static-definition.stderr +++ b/tests/ui/recursion/recursive-static-definition.stderr @@ -1,10 +1,10 @@ -error[E0080]: encountered static that tried to initialize itself with itself +error[E0080]: encountered static that tried to access itself during initialization --> $DIR/recursive-static-definition.rs:1:23 | LL | pub static FOO: u32 = FOO; | ^^^ evaluation of `FOO` failed here -error[E0080]: encountered static that tried to initialize itself with itself +error[E0080]: encountered static that tried to access itself during initialization --> $DIR/recursive-static-definition.rs:9:23 | LL | pub static BAR: Foo = BAR; diff --git a/tests/ui/statics/read_before_init.rs b/tests/ui/statics/read_before_init.rs index d779ef6dffab2..32cc2554e1a16 100644 --- a/tests/ui/statics/read_before_init.rs +++ b/tests/ui/statics/read_before_init.rs @@ -8,13 +8,15 @@ use std::mem::MaybeUninit; -pub static X: (i32, MaybeUninit) = (1, foo(&X.0)); -//~^ ERROR: encountered static that tried to initialize itself with itself +pub static X: (i32, MaybeUninit) = (1, foo(&X.0, 1)); +//~^ ERROR: encountered static that tried to access itself during initialization +pub static Y: (i32, MaybeUninit) = (1, foo(&Y.0, 0)); +//~^ ERROR: encountered static that tried to access itself during initialization -const fn foo(x: &i32) -> MaybeUninit { +const fn foo(x: &i32, num: usize) -> MaybeUninit { let mut temp = MaybeUninit::::uninit(); unsafe { - std::ptr::copy(x, temp.as_mut_ptr(), 1); + std::ptr::copy(x, temp.as_mut_ptr(), num); } temp } diff --git a/tests/ui/statics/read_before_init.stderr b/tests/ui/statics/read_before_init.stderr index aeebcf7d9ce5a..239568c12050c 100644 --- a/tests/ui/statics/read_before_init.stderr +++ b/tests/ui/statics/read_before_init.stderr @@ -1,17 +1,31 @@ -error[E0080]: encountered static that tried to initialize itself with itself +error[E0080]: encountered static that tried to access itself during initialization --> $DIR/read_before_init.rs:11:45 | -LL | pub static X: (i32, MaybeUninit) = (1, foo(&X.0)); - | ^^^^^^^^^ evaluation of `X` failed inside this call +LL | pub static X: (i32, MaybeUninit) = (1, foo(&X.0, 1)); + | ^^^^^^^^^^^^ evaluation of `X` failed inside this call | note: inside `foo` - --> $DIR/read_before_init.rs:17:9 + --> $DIR/read_before_init.rs:19:9 | -LL | std::ptr::copy(x, temp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | std::ptr::copy(x, temp.as_mut_ptr(), num); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: inside `std::ptr::copy::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -error: aborting due to 1 previous error +error[E0080]: encountered static that tried to access itself during initialization + --> $DIR/read_before_init.rs:13:45 + | +LL | pub static Y: (i32, MaybeUninit) = (1, foo(&Y.0, 0)); + | ^^^^^^^^^^^^ evaluation of `Y` failed inside this call + | +note: inside `foo` + --> $DIR/read_before_init.rs:19:9 + | +LL | std::ptr::copy(x, temp.as_mut_ptr(), num); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `std::ptr::copy::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`.