From 73fc00ff8c497af386cce222fe467371dc335885 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Oct 2024 17:51:08 +0200 Subject: [PATCH 01/24] Delay ambiguous intra-doc link resolution after `Cache` has been populated --- src/librustdoc/clean/types.rs | 13 +- src/librustdoc/core.rs | 24 +- .../passes/calculate_doc_coverage.rs | 2 +- .../passes/check_doc_test_visibility.rs | 2 +- .../passes/collect_intra_doc_links.rs | 260 +++++++++++++++--- src/librustdoc/passes/collect_trait_impls.rs | 2 +- src/librustdoc/passes/lint.rs | 2 +- src/librustdoc/passes/mod.rs | 2 +- src/librustdoc/passes/propagate_doc_cfg.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 2 +- .../passes/strip_aliased_non_local.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- src/librustdoc/passes/strip_priv_imports.rs | 2 +- src/librustdoc/passes/strip_private.rs | 2 +- 14 files changed, 263 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bc5bf4c05838a..44d9a5fdbe8ad 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1228,15 +1228,14 @@ impl Attributes { for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { if let Some(values) = attr.meta_item_list() { for l in values { - match l.lit().unwrap().kind { - ast::LitKind::Str(s, _) => { - aliases.insert(s); - } - _ => unreachable!(), + if let Some(lit) = l.lit() + && let ast::LitKind::Str(s, _) = lit.kind + { + aliases.insert(s); } } - } else { - aliases.insert(attr.value_str().unwrap()); + } else if let Some(value) = attr.value_str() { + aliases.insert(value); } } aliases.into_iter().collect::>().into() diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index aaf4c80f99763..9bebe1fb4c1d7 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -29,8 +29,9 @@ use crate::clean::inline::build_external_trait; use crate::clean::{self, ItemId}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; +use crate::passes; use crate::passes::Condition::*; -use crate::passes::{self}; +use crate::passes::collect_intra_doc_links::LinkCollector; pub(crate) struct DocContext<'tcx> { pub(crate) tcx: TyCtxt<'tcx>, @@ -427,6 +428,9 @@ pub(crate) fn run_global_ctxt( info!("Executing passes"); + let mut visited = FxHashMap::default(); + let mut ambiguous = FxIndexMap::default(); + for p in passes::defaults(show_coverage) { let run = match p.condition { Always => true, @@ -436,18 +440,30 @@ pub(crate) fn run_global_ctxt( }; if run { debug!("running pass {}", p.pass.name); - krate = tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &mut ctxt)); + if let Some(run_fn) = p.pass.run { + krate = tcx.sess.time(p.pass.name, || run_fn(krate, &mut ctxt)); + } else { + let (k, LinkCollector { visited_links, ambiguous_links, .. }) = + passes::collect_intra_doc_links::collect_intra_doc_links(krate, &mut ctxt); + krate = k; + visited = visited_links; + ambiguous = ambiguous_links; + } } } tcx.sess.time("check_lint_expectations", || tcx.check_expectations(Some(sym::rustdoc))); + krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate)); + + let mut collector = + LinkCollector { cx: &mut ctxt, visited_links: visited, ambiguous_links: ambiguous }; + collector.resolve_ambiguities(); + if let Some(guar) = tcx.dcx().has_errors() { return Err(guar); } - krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate)); - Ok((krate, ctxt.render_options, ctxt.cache)) } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index abea5bcbc51ea..d27e737764dcf 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -20,7 +20,7 @@ use crate::visit::DocVisitor; pub(crate) const CALCULATE_DOC_COVERAGE: Pass = Pass { name: "calculate-doc-coverage", - run: calculate_doc_coverage, + run: Some(calculate_doc_coverage), description: "counts the number of items with and without documentation", }; diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 1dc9af7ebe591..f4579d8553150 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -20,7 +20,7 @@ use crate::visit::DocVisitor; pub(crate) const CHECK_DOC_TEST_VISIBILITY: Pass = Pass { name: "check_doc_test_visibility", - run: check_doc_test_visibility, + run: Some(check_doc_test_visibility), description: "run various visibility-related lints on doctests", }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index db235786cf49a..81e7bcbd7d877 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -9,12 +9,12 @@ use std::ops::Range; use pulldown_cmark::LinkType; use rustc_ast::util::comments::may_have_doc_links; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::{Applicability, Diag, DiagMessage}; use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, Namespace, PerNS}; -use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE}; use rustc_hir::{Mutability, Safety}; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; @@ -30,23 +30,27 @@ use smallvec::{SmallVec, smallvec}; use tracing::{debug, info, instrument, trace}; use crate::clean::utils::find_nearest_parent_module; -use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType}; +use crate::clean::{self, Crate, Item, ItemId, ItemLink, PrimitiveType}; use crate::core::DocContext; use crate::html::markdown::{MarkdownLink, MarkdownLinkRange, markdown_links}; use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS}; use crate::passes::Pass; use crate::visit::DocVisitor; -pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = Pass { - name: "collect-intra-doc-links", - run: collect_intra_doc_links, - description: "resolves intra-doc links", -}; +pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = + Pass { name: "collect-intra-doc-links", run: None, description: "resolves intra-doc links" }; -fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate { - let mut collector = LinkCollector { cx, visited_links: FxHashMap::default() }; +pub(crate) fn collect_intra_doc_links<'a, 'tcx>( + krate: Crate, + cx: &'a mut DocContext<'tcx>, +) -> (Crate, LinkCollector<'a, 'tcx>) { + let mut collector = LinkCollector { + cx, + visited_links: FxHashMap::default(), + ambiguous_links: FxIndexMap::default(), + }; collector.visit_crate(&krate); - krate + (krate, collector) } fn filter_assoc_items_by_name_and_namespace<'a>( @@ -61,7 +65,7 @@ fn filter_assoc_items_by_name_and_namespace<'a>( } #[derive(Copy, Clone, Debug, Hash, PartialEq)] -enum Res { +pub(crate) enum Res { Def(DefKind, DefId), Primitive(PrimitiveType), } @@ -234,7 +238,7 @@ impl UrlFragment { } #[derive(Clone, Debug, Hash, PartialEq, Eq)] -struct ResolutionInfo { +pub(crate) struct ResolutionInfo { item_id: DefId, module_id: DefId, dis: Option, @@ -243,18 +247,63 @@ struct ResolutionInfo { } #[derive(Clone)] -struct DiagnosticInfo<'a> { +pub(crate) struct DiagnosticInfo<'a> { item: &'a Item, dox: &'a str, ori_link: &'a str, link_range: MarkdownLinkRange, } -struct LinkCollector<'a, 'tcx> { - cx: &'a mut DocContext<'tcx>, +pub(crate) struct OwnedDiagnosticInfo { + item: Item, + dox: String, + ori_link: String, + link_range: MarkdownLinkRange, +} + +impl From> for OwnedDiagnosticInfo { + fn from(f: DiagnosticInfo<'_>) -> Self { + Self { + item: f.item.clone(), + dox: f.dox.to_string(), + ori_link: f.ori_link.to_string(), + link_range: f.link_range.clone(), + } + } +} + +impl OwnedDiagnosticInfo { + pub(crate) fn into_info(&self) -> DiagnosticInfo<'_> { + DiagnosticInfo { + item: &self.item, + ori_link: &self.ori_link, + dox: &self.dox, + link_range: self.link_range.clone(), + } + } +} + +pub(crate) struct LinkCollector<'a, 'tcx> { + pub(crate) cx: &'a mut DocContext<'tcx>, /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link. /// The link will be `None` if it could not be resolved (i.e. the error was cached). - visited_links: FxHashMap)>>, + pub(crate) visited_links: FxHashMap)>>, + /// These links are ambiguous. We need for the cache to have its paths filled. Unfortunately, + /// if we run the `LinkCollector` pass after `Cache::populate`, a lot of items that we need + /// to go through will be removed, making a lot of intra-doc links to not be inferred. + /// + /// So instead, we store the ambiguous links and we wait for cache paths to be filled before + /// inferring them (if possible). + /// + /// Key is `(item ID, path str)`. + pub(crate) ambiguous_links: FxIndexMap<(ItemId, String), Vec>, +} + +pub(crate) struct AmbiguousLinks { + disambiguator: Option, + link_text: Box, + diag_info: OwnedDiagnosticInfo, + resolved: Vec<(Res, Option)>, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { @@ -1001,6 +1050,10 @@ impl LinkCollector<'_, '_> { } } + pub(crate) fn save_link(&mut self, item_id: ItemId, link: ItemLink) { + self.cx.cache.intra_doc_links.entry(item_id).or_default().insert(link); + } + /// This is the entry point for resolving an intra-doc link. /// /// FIXME(jynelson): this is way too many arguments @@ -1024,7 +1077,7 @@ impl LinkCollector<'_, '_> { pp_link.as_ref().map_err(|err| err.report(self.cx, diag_info.clone())).ok()?; let disambiguator = *disambiguator; - let (mut res, fragment) = self.resolve_with_disambiguator_cached( + let mut resolved = self.resolve_with_disambiguator_cached( ResolutionInfo { item_id, module_id, @@ -1040,6 +1093,142 @@ impl LinkCollector<'_, '_> { false, )?; + if resolved.len() > 1 { + let links = AmbiguousLinks { + disambiguator, + link_text: link_text.clone(), + diag_info: diag_info.into(), + resolved, + }; + + self.ambiguous_links + .entry((item.item_id, path_str.to_string())) + .or_default() + .push(links); + None + } else if let Some((res, fragment)) = resolved.pop() { + self.compute_link(res, fragment, path_str, disambiguator, diag_info, link_text) + } else { + None + } + } + + /// Returns `true` if a link could be generated from the given intra-doc information. + /// + /// This is a very light version of `format::href_with_root_path` since we're only interested + /// about whether we can generate a link to an item or not. + /// + /// * If `original_did` is local, then we check if the item is reexported or public. + /// * If `original_did` is not local, then we check if the crate it comes from is a direct + /// public dependency. + fn validate_link(&self, original_did: DefId) -> bool { + let tcx = self.cx.tcx; + let def_kind = tcx.def_kind(original_did); + let did = match def_kind { + DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => { + // documented on their parent's page + tcx.parent(original_did) + } + // If this a constructor, we get the parent (either a struct or a variant) and then + // generate the link for this item. + DefKind::Ctor(..) => return self.validate_link(tcx.parent(original_did)), + DefKind::ExternCrate => { + // Link to the crate itself, not the `extern crate` item. + if let Some(local_did) = original_did.as_local() { + tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id() + } else { + original_did + } + } + _ => original_did, + }; + + let cache = &self.cx.cache; + if !original_did.is_local() + && !cache.effective_visibilities.is_directly_public(tcx, did) + && !cache.document_private + && !cache.primitive_locations.values().any(|&id| id == did) + { + return false; + } + + cache.paths.get(&did).is_some() + || cache.external_paths.get(&did).is_some() + || !did.is_local() + } + + #[allow(rustc::potential_query_instability)] + pub(crate) fn resolve_ambiguities(&mut self) { + let mut ambiguous_links = mem::take(&mut self.ambiguous_links); + + for ((item_id, path_str), info_items) in ambiguous_links.iter_mut() { + for info in info_items { + info.resolved.retain(|(res, _)| match res { + Res::Def(_, def_id) => self.validate_link(*def_id), + // Primitive types are always valid. + Res::Primitive(_) => true, + }); + let diag_info = info.diag_info.into_info(); + match info.resolved.len() { + 1 => { + let (res, fragment) = info.resolved.pop().unwrap(); + if let Some(link) = self.compute_link( + res, + fragment, + path_str, + info.disambiguator, + diag_info, + &info.link_text, + ) { + self.save_link(*item_id, link); + } + } + 0 => { + report_diagnostic( + self.cx.tcx, + BROKEN_INTRA_DOC_LINKS, + format!( + "all items matching `{path_str}` are either private or doc(hidden)" + ), + &diag_info, + |diag, sp, _| { + if let Some(sp) = sp { + diag.span_label(sp, "unresolved link"); + } else { + diag.note("unresolved link"); + } + }, + ); + } + _ => { + let candidates = info + .resolved + .iter() + .map(|(res, fragment)| { + let def_id = if let Some(UrlFragment::Item(def_id)) = fragment { + Some(*def_id) + } else { + None + }; + (*res, def_id) + }) + .collect::>(); + ambiguity_error(self.cx, &diag_info, path_str, &candidates, true); + } + } + } + } + } + + fn compute_link( + &mut self, + mut res: Res, + fragment: Option, + path_str: &str, + disambiguator: Option, + diag_info: DiagnosticInfo<'_>, + link_text: &Box, + ) -> Option { // Check for a primitive which might conflict with a module // Report the ambiguity and require that the user specify which one they meant. // FIXME: could there ever be a primitive not in the type namespace? @@ -1055,7 +1244,7 @@ impl LinkCollector<'_, '_> { } else { // `[char]` when a `char` module is in scope let candidates = &[(res, res.def_id(self.cx.tcx)), (prim, None)]; - ambiguity_error(self.cx, &diag_info, path_str, candidates); + ambiguity_error(self.cx, &diag_info, path_str, candidates, true); return None; } } @@ -1085,7 +1274,7 @@ impl LinkCollector<'_, '_> { } res.def_id(self.cx.tcx).map(|page_id| ItemLink { - link: Box::::from(&*ori_link.link), + link: Box::::from(&*diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1107,7 +1296,7 @@ impl LinkCollector<'_, '_> { let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); Some(ItemLink { - link: Box::::from(&*ori_link.link), + link: Box::::from(&*diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1220,10 +1409,10 @@ impl LinkCollector<'_, '_> { // If this call is intended to be recoverable, then pass true to silence. // This is only recoverable when path is failed to resolved. recoverable: bool, - ) -> Option<(Res, Option)> { + ) -> Option)>> { if let Some(res) = self.visited_links.get(&key) { if res.is_some() || cache_errors { - return res.clone(); + return res.clone().map(|r| vec![r]); } } @@ -1248,13 +1437,14 @@ impl LinkCollector<'_, '_> { // and after removing duplicated kinds, only one remains, the `ambiguity_error` function // won't emit an error. So at this point, we can just take the first candidate as it was // the first retrieved and use it to generate the link. - if let [candidate, _candidate2, ..] = *candidates - && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates) - { - candidates = vec![candidate]; + if let [candidate, _candidate2, ..] = *candidates { + if !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) { + candidates = vec![candidate]; + } } - if let &[(res, def_id)] = candidates.as_slice() { + let mut out = Vec::with_capacity(candidates.len()); + for (res, def_id) in candidates { let fragment = match (&key.extra_fragment, def_id) { (Some(_), Some(def_id)) => { report_anchor_conflict(self.cx, diag, def_id); @@ -1264,15 +1454,14 @@ impl LinkCollector<'_, '_> { (None, Some(def_id)) => Some(UrlFragment::Item(def_id)), (None, None) => None, }; - let r = Some((res, fragment)); - self.visited_links.insert(key, r.clone()); - return r; + out.push((res, fragment)); } - - if cache_errors { + if let [r] = out.as_slice() { + self.visited_links.insert(key, Some(r.clone())); + } else if cache_errors { self.visited_links.insert(key, None); } - None + Some(out) } /// After parsing the disambiguator, resolve the main part of the link. @@ -2046,6 +2235,7 @@ fn ambiguity_error( diag_info: &DiagnosticInfo<'_>, path_str: &str, candidates: &[(Res, Option)], + emit_error: bool, ) -> bool { let mut descrs = FxHashSet::default(); let kinds = candidates @@ -2061,6 +2251,8 @@ fn ambiguity_error( // There is no way for users to disambiguate at this point, so better return the first // candidate and not show a warning. return false; + } else if !emit_error { + return true; } let mut msg = format!("`{path_str}` is "); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index d1a1f0df3e7ed..f358908032285 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -16,7 +16,7 @@ use crate::visit::DocVisitor; pub(crate) const COLLECT_TRAIT_IMPLS: Pass = Pass { name: "collect-trait-impls", - run: collect_trait_impls, + run: Some(collect_trait_impls), description: "retrieves trait impls for items in the crate", }; diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index 593027ef7d293..35b62370abb29 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -14,7 +14,7 @@ use crate::core::DocContext; use crate::visit::DocVisitor; pub(crate) const RUN_LINTS: Pass = - Pass { name: "run-lints", run: run_lints, description: "runs some of rustdoc's lints" }; + Pass { name: "run-lints", run: Some(run_lints), description: "runs some of rustdoc's lints" }; struct Linter<'a, 'tcx> { cx: &'a mut DocContext<'tcx>, diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index f5b7802372149..9ba63d34144ae 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -47,7 +47,7 @@ pub(crate) use self::lint::RUN_LINTS; #[derive(Copy, Clone)] pub(crate) struct Pass { pub(crate) name: &'static str, - pub(crate) run: fn(clean::Crate, &mut DocContext<'_>) -> clean::Crate, + pub(crate) run: Option) -> clean::Crate>, pub(crate) description: &'static str, } diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 6be51dd156066..350be37f553da 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -13,7 +13,7 @@ use crate::passes::Pass; pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass { name: "propagate-doc-cfg", - run: propagate_doc_cfg, + run: Some(propagate_doc_cfg), description: "propagates `#[doc(cfg(...))]` to child items", }; diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index f51e993bfa5d0..f55479687f8e7 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -16,7 +16,7 @@ use crate::passes::Pass; pub(crate) const PROPAGATE_STABILITY: Pass = Pass { name: "propagate-stability", - run: propagate_stability, + run: Some(propagate_stability), description: "propagates stability to child items", }; diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index 155ad5438314e..a078eec048ece 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -8,7 +8,7 @@ use crate::passes::Pass; pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { name: "strip-aliased-non-local", - run: strip_aliased_non_local, + run: Some(strip_aliased_non_local), description: "strips all non-local private aliased items from the output", }; diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 430f3d8a574c3..aba04283e59dc 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -16,7 +16,7 @@ use crate::passes::{ImplStripper, Pass}; pub(crate) const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", - run: strip_hidden, + run: Some(strip_hidden), description: "strips all `#[doc(hidden)]` items from the output", }; diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 7b05756ae215e..2e9f06bd0a30c 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -8,7 +8,7 @@ use crate::passes::{ImportStripper, Pass}; pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass { name: "strip-priv-imports", - run: strip_priv_imports, + run: Some(strip_priv_imports), description: "strips all private import statements (`use`, `extern crate`) from a crate", }; diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 1bafa450be904..78f0ad277408b 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -8,7 +8,7 @@ use crate::passes::{ImplStripper, ImportStripper, Pass, Stripper}; pub(crate) const STRIP_PRIVATE: Pass = Pass { name: "strip-private", - run: strip_private, + run: Some(strip_private), description: "strips all private items from a crate which cannot be seen externally, \ implies strip-priv-imports", }; From d540e7285ca14393d2b51f486ecc0f26d2f986c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Oct 2024 17:51:37 +0200 Subject: [PATCH 02/24] Add regression tests for #130233 --- .../intra-doc/filter-out-private-2.rs | 15 +++++++++++ .../intra-doc/filter-out-private-2.stderr | 14 ++++++++++ .../intra-doc/filter-out-private.rs | 13 ++++++++++ .../intra-doc/filter-out-private.stderr | 22 ++++++++++++++++ tests/rustdoc/intra-doc/filter-out-private.rs | 26 +++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private-2.rs create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private.rs create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private.stderr create mode 100644 tests/rustdoc/intra-doc/filter-out-private.rs diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs new file mode 100644 index 0000000000000..9209203c99ee5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs @@ -0,0 +1,15 @@ +// This test ensures that ambiguities (not) resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +#[doc(hidden)] +pub struct Thing {} + +#[allow(non_snake_case)] +#[doc(hidden)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR all items matching `Thing` are either private or doc(hidden) +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr new file mode 100644 index 0000000000000..394f919de943e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr @@ -0,0 +1,14 @@ +error: all items matching `Thing` are either private or doc(hidden) + --> $DIR/filter-out-private-2.rs:13:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ unresolved link + | +note: the lint level is defined here + --> $DIR/filter-out-private-2.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.rs b/tests/rustdoc-ui/intra-doc/filter-out-private.rs new file mode 100644 index 0000000000000..f481b51dad066 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.rs @@ -0,0 +1,13 @@ +// This test ensures that ambiguities resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Thing {} + +#[allow(non_snake_case)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR `Thing` is both a function and a struct +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr new file mode 100644 index 0000000000000..1d1830b1f1c37 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr @@ -0,0 +1,22 @@ +error: `Thing` is both a function and a struct + --> $DIR/filter-out-private.rs:11:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/filter-out-private.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the function, add parentheses + | +LL | /// Do stuff with [`Thing()`]. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// Do stuff with [`struct@Thing`]. + | +++++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc/intra-doc/filter-out-private.rs b/tests/rustdoc/intra-doc/filter-out-private.rs new file mode 100644 index 0000000000000..70591b120d823 --- /dev/null +++ b/tests/rustdoc/intra-doc/filter-out-private.rs @@ -0,0 +1,26 @@ +// This test ensures that private/hidden items don't create ambiguity. +// This is a regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Thing {} + +#[doc(hidden)] +#[allow(non_snake_case)] +pub fn Thing() {} + +pub struct Bar {} + +#[allow(non_snake_case)] +fn Bar() {} + +//@ has 'foo/fn.repro.html' +//@ has - '//*[@class="toggle top-doc"]/*[@class="docblock"]//a/@href' 'struct.Thing.html' +/// Do stuff with [`Thing`]. +pub fn repro(_: Thing) {} + +//@ has 'foo/fn.repro2.html' +//@ has - '//*[@class="toggle top-doc"]/*[@class="docblock"]//a/@href' 'struct.Bar.html' +/// Do stuff with [`Bar`]. +pub fn repro2(_: Bar) {} From f708d6de79a3e17074d03a641633e2f12972dc1a Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Mon, 14 Oct 2024 15:37:59 +0200 Subject: [PATCH 03/24] Fix match_same_arms in stable_mir --- compiler/stable_mir/src/mir/pretty.rs | 10 +++----- compiler/stable_mir/src/mir/visit.rs | 36 ++++++++++----------------- compiler/stable_mir/src/visitor.rs | 16 ++++++------ 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 74081af1d86d0..d71d96804f3ea 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -189,7 +189,9 @@ fn pretty_terminator_head(writer: &mut W, terminator: &TerminatorKind) fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec { use self::TerminatorKind::*; match terminator { - Resume | Abort | Return | Unreachable => vec![], + Call { target: None, unwind: UnwindAction::Cleanup(_), .. } + | InlineAsm { destination: None, .. } => vec!["unwind".into()], + Resume | Abort | Return | Unreachable | Call { target: None, unwind: _, .. } => vec![], Goto { .. } => vec!["".to_string()], SwitchInt { targets, .. } => targets .branches() @@ -197,19 +199,15 @@ fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec { .chain(iter::once("otherwise".into())) .collect(), Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()], - Drop { unwind: _, .. } => vec!["return".into()], Call { target: Some(_), unwind: UnwindAction::Cleanup(_), .. } => { vec!["return".into(), "unwind".into()] } - Call { target: Some(_), unwind: _, .. } => vec!["return".into()], - Call { target: None, unwind: UnwindAction::Cleanup(_), .. } => vec!["unwind".into()], - Call { target: None, unwind: _, .. } => vec![], + Drop { unwind: _, .. } | Call { target: Some(_), unwind: _, .. } => vec!["return".into()], Assert { unwind: UnwindAction::Cleanup(_), .. } => { vec!["success".into(), "unwind".into()] } Assert { unwind: _, .. } => vec!["success".into()], InlineAsm { destination: Some(_), .. } => vec!["goto".into(), "unwind".into()], - InlineAsm { destination: None, .. } => vec!["unwind".into()], } } diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index e2d1ff7fdd3a4..08fcfa01a06c1 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -194,27 +194,17 @@ pub trait MirVisitor { self.visit_place(place, PlaceContext::MUTATING, location); self.visit_rvalue(rvalue, location); } - StatementKind::FakeRead(_, place) => { + StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => { self.visit_place(place, PlaceContext::NON_MUTATING, location); } - StatementKind::SetDiscriminant { place, .. } => { + StatementKind::SetDiscriminant { place, .. } + | StatementKind::Deinit(place) + | StatementKind::Retag(_, place) => { self.visit_place(place, PlaceContext::MUTATING, location); } - StatementKind::Deinit(place) => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - StatementKind::StorageLive(local) => { - self.visit_local(local, PlaceContext::NON_USE, location); - } - StatementKind::StorageDead(local) => { + StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { self.visit_local(local, PlaceContext::NON_USE, location); } - StatementKind::Retag(_, place) => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - StatementKind::PlaceMention(place) => { - self.visit_place(place, PlaceContext::NON_MUTATING, location); - } StatementKind::AscribeUserType { place, projections, variance: _ } => { self.visit_place(place, PlaceContext::NON_USE, location); self.visit_user_type_projection(projections); @@ -234,8 +224,7 @@ pub trait MirVisitor { self.visit_operand(count, location); } }, - StatementKind::ConstEvalCounter => {} - StatementKind::Nop => {} + StatementKind::ConstEvalCounter | StatementKind::Nop => {} } } @@ -304,14 +293,15 @@ pub trait MirVisitor { location: Location, ) { match elem { - ProjectionElem::Deref => {} + ProjectionElem::Downcast(_idx) => {} + ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } + | ProjectionElem::Deref + | ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), ProjectionElem::Index(local) => self.visit_local(local, ptx, location), - ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {} - ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} - ProjectionElem::Downcast(_idx) => {} - ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), - ProjectionElem::Subtype(ty) => self.visit_ty(ty, location), + ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => { + self.visit_ty(ty, location) + } } } diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 3c769b2d37cfc..48260285408c7 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -35,8 +35,7 @@ impl Visitable for Ty { match self.kind() { super::ty::TyKind::RigidTy(ty) => ty.visit(visitor)?, super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor)?, - super::ty::TyKind::Param(_) => {} - super::ty::TyKind::Bound(_, _) => {} + super::ty::TyKind::Param(_) | super::ty::TyKind::Bound(_, _) => {} } ControlFlow::Continue(()) } @@ -48,8 +47,7 @@ impl Visitable for TyConst { } fn super_visit(&self, visitor: &mut V) -> ControlFlow { match &self.kind { - crate::ty::TyConstKind::Param(_) => {} - crate::ty::TyConstKind::Bound(_, _) => {} + crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {} crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?, crate::ty::TyConstKind::Value(ty, alloc) => { alloc.visit(visitor)?; @@ -166,17 +164,17 @@ impl Visitable for RigidTy { reg.visit(visitor); ty.visit(visitor) } - RigidTy::FnDef(_, args) => args.visit(visitor), + RigidTy::Adt(_, args) + | RigidTy::Closure(_, args) + | RigidTy::Coroutine(_, args, _) + | RigidTy::CoroutineWitness(_, args) + | RigidTy::FnDef(_, args) => args.visit(visitor), RigidTy::FnPtr(sig) => sig.visit(visitor), - RigidTy::Closure(_, args) => args.visit(visitor), - RigidTy::Coroutine(_, args, _) => args.visit(visitor), - RigidTy::CoroutineWitness(_, args) => args.visit(visitor), RigidTy::Dynamic(pred, r, _) => { pred.visit(visitor)?; r.visit(visitor) } RigidTy::Tuple(fields) => fields.visit(visitor), - RigidTy::Adt(_, args) => args.visit(visitor), } } } From 918dc38733985770d1cdcea76169340c620c1f32 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:23:39 +0900 Subject: [PATCH 04/24] Combine impl_int and impl_uint Two macros are exactly the same. --- library/core/src/fmt/num.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index aecd725eca561..cc94c392de581 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -31,22 +31,11 @@ macro_rules! impl_int { })* ) } -macro_rules! impl_uint { - ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* - ) -} -impl_int! { i8 i16 i32 i64 i128 isize } -impl_uint! { u8 u16 u32 u64 u128 usize } +impl_int! { + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize +} /// A type that represents a specific radix /// From 0637517da6802bcdc8df9a73a75edb8c41033f11 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:32:21 +0900 Subject: [PATCH 05/24] Rename debug! macro to impl_Debug! --- library/core/src/fmt/num.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index cc94c392de581..0f33d730a68e6 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -167,7 +167,8 @@ integer! { i16, u16 } integer! { i32, u32 } integer! { i64, u64 } integer! { i128, u128 } -macro_rules! debug { + +macro_rules! impl_Debug { ($($T:ident)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for $T { @@ -184,10 +185,6 @@ macro_rules! debug { } )*}; } -debug! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize -} // 2 digit decimal look up table static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\ @@ -510,6 +507,11 @@ macro_rules! impl_Exp { }; } +impl_Debug! { + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize +} + // Include wasm32 in here since it doesn't reflect the native pointer size, and // often cares strongly about getting a smaller code size. #[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] From 99af761632420b2778e2b44465a396e28adf6103 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:39:30 +0900 Subject: [PATCH 06/24] Refactor `floating` macro and nofloat panic message --- library/core/src/fmt/float.rs | 47 ++++++++++++++++--------------- library/core/src/fmt/nofloat.rs | 21 +++++++------- library/core/src/fmt/num.rs | 50 +++++++++++++++++---------------- 3 files changed, 60 insertions(+), 58 deletions(-) diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 20ea0352c2dce..c70dbf54304de 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -196,39 +196,40 @@ where } macro_rules! floating { - ($ty:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl Debug for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_general_debug(fmt, self) + ($($ty:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Debug for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_general_debug(fmt, self) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl Display for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_display(fmt, self) + #[stable(feature = "rust1", since = "1.0.0")] + impl Display for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_decimal_display(fmt, self) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl LowerExp for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_exponential_common(fmt, self, false) + #[stable(feature = "rust1", since = "1.0.0")] + impl LowerExp for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_exponential_common(fmt, self, false) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl UpperExp for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_exponential_common(fmt, self, true) + #[stable(feature = "rust1", since = "1.0.0")] + impl UpperExp for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_exponential_common(fmt, self, true) + } } - } + )* }; } -floating! { f32 } -floating! { f64 } +floating! { f32 f64 } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for f16 { diff --git a/library/core/src/fmt/nofloat.rs b/library/core/src/fmt/nofloat.rs index 6b07236f1da12..29aaee75d22bc 100644 --- a/library/core/src/fmt/nofloat.rs +++ b/library/core/src/fmt/nofloat.rs @@ -1,18 +1,17 @@ use crate::fmt::{Debug, Formatter, Result}; macro_rules! floating { - ($ty:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl Debug for $ty { - #[inline] - fn fmt(&self, _fmt: &mut Formatter<'_>) -> Result { - panic!("floating point support is turned off"); + ($($ty:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Debug for $ty { + #[inline] + fn fmt(&self, _fmt: &mut Formatter<'_>) -> Result { + panic!("floating point fmt support is turned off"); + } } - } + )* }; } -floating! { f16 } -floating! { f32 } -floating! { f64 } -floating! { f128 } +floating! { f16 f32 f64 f128 } diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 0f33d730a68e6..f1540803f978d 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -20,15 +20,15 @@ trait DisplayInt: macro_rules! impl_int { ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* + $(impl DisplayInt for $t { + fn zero() -> Self { 0 } + fn from_u8(u: u8) -> Self { u as Self } + fn to_u8(&self) -> u8 { *self as u8 } + #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] + fn to_u32(&self) -> u32 { *self as u32 } + fn to_u64(&self) -> u64 { *self as u64 } + fn to_u128(&self) -> u128 { *self as u128 } + })* ) } @@ -169,21 +169,23 @@ integer! { i64, u64 } integer! { i128, u128 } macro_rules! impl_Debug { - ($($T:ident)*) => {$( - #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Debug for $T { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.debug_lower_hex() { - fmt::LowerHex::fmt(self, f) - } else if f.debug_upper_hex() { - fmt::UpperHex::fmt(self, f) - } else { - fmt::Display::fmt(self, f) + ($($T:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Debug for $T { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.debug_lower_hex() { + fmt::LowerHex::fmt(self, f) + } else if f.debug_upper_hex() { + fmt::UpperHex::fmt(self, f) + } else { + fmt::Display::fmt(self, f) + } } } - } - )*}; + )* + }; } // 2 digit decimal look up table @@ -508,8 +510,8 @@ macro_rules! impl_Exp { } impl_Debug! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize } // Include wasm32 in here since it doesn't reflect the native pointer size, and From 2b9e41c1288a5e9f015be4f5da4c90d5a4d9c158 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Oct 2024 01:58:27 +0200 Subject: [PATCH 07/24] Improve documentation for intra-doc links computation --- .../passes/collect_intra_doc_links.rs | 18 +++++++++--------- .../intra-doc/filter-out-private-2.rs | 2 +- .../intra-doc/filter-out-private-2.stderr | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 81e7bcbd7d877..10026e9f05d26 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -288,14 +288,16 @@ pub(crate) struct LinkCollector<'a, 'tcx> { /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link. /// The link will be `None` if it could not be resolved (i.e. the error was cached). pub(crate) visited_links: FxHashMap)>>, - /// These links are ambiguous. We need for the cache to have its paths filled. Unfortunately, - /// if we run the `LinkCollector` pass after `Cache::populate`, a lot of items that we need - /// to go through will be removed, making a lot of intra-doc links to not be inferred. + /// According to `rustc_resolve`, these links are ambiguous. /// - /// So instead, we store the ambiguous links and we wait for cache paths to be filled before - /// inferring them (if possible). + /// However, we cannot link to an item that has been stripped from the documentation. If all + /// but one of the "possibilities" are stripped, then there is no real ambiguity. To determine + /// if an ambiguity is real, we delay resolving them until after `Cache::populate`, then filter + /// every item that doesn't have a cached path. /// - /// Key is `(item ID, path str)`. + /// We could get correct results by simply delaying everything. This would have fewer happy + /// codepaths, but we want to distinguish different kinds of error conditions, and this is easy + /// to do by resolving links as soon as possible. pub(crate) ambiguous_links: FxIndexMap<(ItemId, String), Vec>, } @@ -1187,9 +1189,7 @@ impl LinkCollector<'_, '_> { report_diagnostic( self.cx.tcx, BROKEN_INTRA_DOC_LINKS, - format!( - "all items matching `{path_str}` are either private or doc(hidden)" - ), + format!("all items matching `{path_str}` are private or doc(hidden)"), &diag_info, |diag, sp, _| { if let Some(sp) = sp { diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs index 9209203c99ee5..9d8edbf6b5dd2 100644 --- a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs @@ -11,5 +11,5 @@ pub struct Thing {} pub fn Thing() {} /// Do stuff with [`Thing`]. -//~^ ERROR all items matching `Thing` are either private or doc(hidden) +//~^ ERROR all items matching `Thing` are private or doc(hidden) pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr index 394f919de943e..1a49c90a17286 100644 --- a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr @@ -1,4 +1,4 @@ -error: all items matching `Thing` are either private or doc(hidden) +error: all items matching `Thing` are private or doc(hidden) --> $DIR/filter-out-private-2.rs:13:21 | LL | /// Do stuff with [`Thing`]. From 10f2395c9ee5849e3a769ce21d3e704191ec8085 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Oct 2024 15:42:47 +0200 Subject: [PATCH 08/24] Remove `AmbiguousLinks::disambiguator` --- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 10026e9f05d26..cbc6e351fac53 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -302,7 +302,6 @@ pub(crate) struct LinkCollector<'a, 'tcx> { } pub(crate) struct AmbiguousLinks { - disambiguator: Option, link_text: Box, diag_info: OwnedDiagnosticInfo, resolved: Vec<(Res, Option)>, @@ -1097,7 +1096,6 @@ impl LinkCollector<'_, '_> { if resolved.len() > 1 { let links = AmbiguousLinks { - disambiguator, link_text: link_text.clone(), diag_info: diag_info.into(), resolved, @@ -1178,7 +1176,7 @@ impl LinkCollector<'_, '_> { res, fragment, path_str, - info.disambiguator, + None, diag_info, &info.link_text, ) { From 05dec8fbae6873bdcf237b006e7b019c9088b933 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 15 Oct 2024 18:03:25 +0200 Subject: [PATCH 09/24] `ImpliedOutlivesBounds` to `rustc_middle` --- .../src/type_check/free_region_relations.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 12 ++++++------ compiler/rustc_middle/src/traits/query.rs | 8 ++++++++ .../src/traits/outlives_bounds.rs | 8 +++++--- .../query/type_op/implied_outlives_bounds.rs | 15 +-------------- .../rustc_traits/src/implied_outlives_bounds.rs | 11 ++++++----- 6 files changed, 27 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index cded9935f971a..43abc0128fe52 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -373,7 +373,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { ) -> Option<&'tcx QueryRegionConstraints<'tcx>> { let TypeOpOutput { output: bounds, constraints, .. } = self .param_env - .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) + .and(type_op::ImpliedOutlivesBounds { ty }) .fully_perform(self.infcx, span) .map_err(|_: ErrorGuaranteed| debug!("failed to compute implied bounds {:?}", ty)) .ok()?; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f0be70e00dfca..dffb16f398c2b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -65,8 +65,8 @@ use crate::query::plumbing::{ CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at, }; use crate::traits::query::{ - CanonicalAliasGoal, CanonicalPredicateGoal, CanonicalTyGoal, - CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, + CanonicalAliasGoal, CanonicalImpliedOutlivesBoundsGoal, CanonicalPredicateGoal, + CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult, OutlivesBound, }; @@ -2049,21 +2049,21 @@ rustc_queries! { } query implied_outlives_bounds_compat( - goal: CanonicalTyGoal<'tcx> + goal: CanonicalImpliedOutlivesBoundsGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - desc { "computing implied outlives bounds for `{}`", goal.value.value } + desc { "computing implied outlives bounds for `{}`", goal.value.value.ty } } query implied_outlives_bounds( - goal: CanonicalTyGoal<'tcx> + goal: CanonicalImpliedOutlivesBoundsGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - desc { "computing implied outlives bounds v2 for `{}`", goal.value.value } + desc { "computing implied outlives bounds v2 for `{}`", goal.value.value.ty } } /// Do not call this query directly: diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 81a543e647a7e..706848ae6de7c 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -70,6 +70,11 @@ pub mod type_op { Self { value } } } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] + pub struct ImpliedOutlivesBounds<'tcx> { + pub ty: Ty<'tcx>, + } } pub type CanonicalAliasGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; @@ -92,6 +97,9 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; +pub type CanonicalImpliedOutlivesBoundsGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>; + #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)] pub struct DropckOutlivesResult<'tcx> { pub kinds: Vec>, diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index f1faff2c036f7..91cf52b152ded 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_macros::extension; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; use rustc_middle::span_bug; @@ -54,11 +55,12 @@ fn implied_outlives_bounds<'a, 'tcx>( assert!(!ty.has_non_region_infer()); let mut canonical_var_values = OriginalQueryValues::default(); - let canonical_ty = infcx.canonicalize_query(param_env.and(ty), &mut canonical_var_values); + let input = ImpliedOutlivesBounds { ty }; + let canonical = infcx.canonicalize_query(param_env.and(input), &mut canonical_var_values); let implied_bounds_result = if compat { - infcx.tcx.implied_outlives_bounds_compat(canonical_ty) + infcx.tcx.implied_outlives_bounds_compat(canonical) } else { - infcx.tcx.implied_outlives_bounds(canonical_ty) + infcx.tcx.implied_outlives_bounds(canonical) }; let Ok(canonical_result) = implied_bounds_result else { return vec![]; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index bab038af9ed2a..f0824eb2a4612 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -1,7 +1,7 @@ use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::OutlivesBound; -use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; +use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; @@ -14,11 +14,6 @@ use tracing::debug; use crate::traits::query::NoSolution; use crate::traits::{ObligationCtxt, wf}; -#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable)] -pub struct ImpliedOutlivesBounds<'tcx> { - pub ty: Ty<'tcx>, -} - impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { type QueryResponse = Vec>; @@ -40,14 +35,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { - // FIXME this `unchecked_map` is only necessary because the - // query is defined as taking a `ParamEnvAnd`; it should - // take an `ImpliedOutlivesBounds` instead - let canonicalized = canonicalized.unchecked_map(|ParamEnvAnd { param_env, value }| { - let ImpliedOutlivesBounds { ty } = value; - param_env.and(ty) - }); - if tcx.sess.opts.unstable_opts.no_implied_bounds_compat { tcx.implied_outlives_bounds(canonicalized) } else { diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index f9e1db567c2ba..a51eefd908cc7 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -5,13 +5,14 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::{self, Canonical}; use rustc_infer::traits::query::OutlivesBound; +use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{ compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner, }; -use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; +use rustc_trait_selection::traits::query::{CanonicalImpliedOutlivesBoundsGoal, NoSolution}; pub(crate) fn provide(p: &mut Providers) { *p = Providers { implied_outlives_bounds_compat, ..*p }; @@ -20,26 +21,26 @@ pub(crate) fn provide(p: &mut Providers) { fn implied_outlives_bounds_compat<'tcx>( tcx: TyCtxt<'tcx>, - goal: CanonicalTyGoal<'tcx>, + goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>, ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { - let (param_env, ty) = key.into_parts(); + let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty) }) } fn implied_outlives_bounds<'tcx>( tcx: TyCtxt<'tcx>, - goal: CanonicalTyGoal<'tcx>, + goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>, ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { - let (param_env, ty) = key.into_parts(); + let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); compute_implied_outlives_bounds_inner(ocx, param_env, ty) }) } From 044ce0c63682db23db6bd1e56af3145c7f691c21 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 15 Oct 2024 18:11:37 +0200 Subject: [PATCH 10/24] remove type_op constructors --- .../src/type_check/canonical.rs | 6 ++--- .../src/type_check/free_region_relations.rs | 4 +-- compiler/rustc_middle/src/traits/query.rs | 26 +------------------ 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 0c6f8cd7b5bfe..fde68615cc089 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -137,7 +137,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( locations, category, - param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)), + param_env.and(type_op::prove_predicate::ProvePredicate { predicate }), ); } @@ -162,7 +162,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( location.to_locations(), category, - param_env.and(type_op::normalize::Normalize::new(value)), + param_env.and(type_op::normalize::Normalize { value }), ); result.unwrap_or(value) } @@ -223,7 +223,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( Locations::All(span), ConstraintCategory::Boring, - self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(mir_ty, user_ty)), + self.param_env.and(type_op::ascribe_user_type::AscribeUserType { mir_ty, user_ty }), ); } diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 43abc0128fe52..8e1faf025e25c 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -280,7 +280,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { } let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self .param_env - .and(type_op::normalize::Normalize::new(ty)) + .and(type_op::normalize::Normalize { value: ty }) .fully_perform(self.infcx, span) .unwrap_or_else(|guar| TypeOpOutput { output: Ty::new_error(self.infcx.tcx, guar), @@ -318,7 +318,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) { let result: Result<_, ErrorGuaranteed> = self .param_env - .and(type_op::normalize::Normalize::new(ty)) + .and(type_op::normalize::Normalize { value: ty }) .fully_perform(self.infcx, span); let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else { continue; diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 706848ae6de7c..a7990b820e8c9 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -15,12 +15,9 @@ use crate::infer::canonical::{Canonical, QueryResponse}; use crate::ty::{self, GenericArg, Ty, TyCtxt}; pub mod type_op { - use std::fmt; - use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; - use crate::ty::fold::TypeFoldable; - use crate::ty::{Predicate, Ty, TyCtxt, UserType}; + use crate::ty::{Predicate, Ty, UserType}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] pub struct AscribeUserType<'tcx> { @@ -28,12 +25,6 @@ pub mod type_op { pub user_ty: UserType<'tcx>, } - impl<'tcx> AscribeUserType<'tcx> { - pub fn new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self { - Self { mir_ty, user_ty } - } - } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] pub struct Eq<'tcx> { pub a: Ty<'tcx>, @@ -51,26 +42,11 @@ pub mod type_op { pub predicate: Predicate<'tcx>, } - impl<'tcx> ProvePredicate<'tcx> { - pub fn new(predicate: Predicate<'tcx>) -> Self { - ProvePredicate { predicate } - } - } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] pub struct Normalize { pub value: T, } - impl<'tcx, T> Normalize - where - T: fmt::Debug + TypeFoldable>, - { - pub fn new(value: T) -> Self { - Self { value } - } - } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] pub struct ImpliedOutlivesBounds<'tcx> { pub ty: Ty<'tcx>, From e457466e98a10870409910cf307e54a8bbbda240 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 15 Oct 2024 18:23:32 +0200 Subject: [PATCH 11/24] `DropckOutlives` to `rustc_middle` --- .../src/type_check/liveness/trace.rs | 5 ++-- compiler/rustc_middle/src/query/mod.rs | 13 +++++----- compiler/rustc_middle/src/traits/query.rs | 8 ++++++ .../src/traits/query/dropck_outlives.rs | 9 ++++--- .../src/traits/query/type_op/outlives.rs | 25 +++---------------- compiler/rustc_traits/src/dropck_outlives.rs | 4 +-- 6 files changed, 27 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index a5175e653d8fe..35963228181f7 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -11,8 +11,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; use rustc_span::DUMMY_SP; -use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives; -use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; +use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; use tracing::debug; use crate::location::RichLocation; @@ -632,7 +631,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { match typeck .param_env - .and(DropckOutlives::new(dropped_ty)) + .and(DropckOutlives { dropped_ty }) .fully_perform(typeck.infcx, DUMMY_SP) { Ok(TypeOpOutput { output, constraints, .. }) => { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index dffb16f398c2b..2f5e47f6f359e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -65,10 +65,11 @@ use crate::query::plumbing::{ CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at, }; use crate::traits::query::{ - CanonicalAliasGoal, CanonicalImpliedOutlivesBoundsGoal, CanonicalPredicateGoal, - CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, - CanonicalTypeOpProvePredicateGoal, DropckConstraint, DropckOutlivesResult, - MethodAutoderefStepsResult, NoSolution, NormalizationResult, OutlivesBound, + CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal, + CanonicalPredicateGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, + CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint, + DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult, + OutlivesBound, }; use crate::traits::{ CodegenObligationError, DynCompatibilityViolation, EvaluationResult, ImplSource, @@ -2069,12 +2070,12 @@ rustc_queries! { /// Do not call this query directly: /// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead. query dropck_outlives( - goal: CanonicalTyGoal<'tcx> + goal: CanonicalDropckOutlivesGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution, > { - desc { "computing dropck types for `{}`", goal.value.value } + desc { "computing dropck types for `{}`", goal.value.value.dropped_ty } } /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index a7990b820e8c9..6439ab8691568 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -51,6 +51,11 @@ pub mod type_op { pub struct ImpliedOutlivesBounds<'tcx> { pub ty: Ty<'tcx>, } + + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] + pub struct DropckOutlives<'tcx> { + pub dropped_ty: Ty<'tcx>, + } } pub type CanonicalAliasGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; @@ -76,6 +81,9 @@ pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = pub type CanonicalImpliedOutlivesBoundsGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>; +pub type CanonicalDropckOutlivesGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::DropckOutlives<'tcx>>>; + #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)] pub struct DropckOutlivesResult<'tcx> { pub kinds: Vec>, diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index c70fe13fc69a2..4ff0910c9b969 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::FxHashSet; +use rustc_infer::traits::query::type_op::DropckOutlives; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt}; use rustc_span::{DUMMY_SP, Span}; @@ -88,10 +89,10 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { pub fn compute_dropck_outlives_inner<'tcx>( ocx: &ObligationCtxt<'_, 'tcx>, - goal: ParamEnvAnd<'tcx, Ty<'tcx>>, + goal: ParamEnvAnd<'tcx, DropckOutlives<'tcx>>, ) -> Result, NoSolution> { let tcx = ocx.infcx.tcx; - let ParamEnvAnd { param_env, value: for_ty } = goal; + let ParamEnvAnd { param_env, value: DropckOutlives { dropped_ty } } = goal; let mut result = DropckOutlivesResult { kinds: vec![], overflows: vec![] }; @@ -99,7 +100,7 @@ pub fn compute_dropck_outlives_inner<'tcx>( // something from the stack and invoke // `dtorck_constraint_for_ty_inner`. This may produce new types that // have to be pushed on the stack. This continues until we have explored - // all the reachable types from the type `for_ty`. + // all the reachable types from the type `dropped_ty`. // // Example: Imagine that we have the following code: // @@ -129,7 +130,7 @@ pub fn compute_dropck_outlives_inner<'tcx>( // lead to us trying to push `A` a second time -- to prevent // infinite recursion, we notice that `A` was already pushed // once and stop. - let mut ty_stack = vec![(for_ty, 0)]; + let mut ty_stack = vec![(dropped_ty, 0)]; // Set used to detect infinite recursion. let mut ty_set = FxHashSet::default(); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index d891d4ca06f9d..eb17703e03118 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -1,23 +1,12 @@ -use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution}; -use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; use crate::traits::ObligationCtxt; use crate::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, trivial_dropck_outlives, }; - -#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable)] -pub struct DropckOutlives<'tcx> { - dropped_ty: Ty<'tcx>, -} - -impl<'tcx> DropckOutlives<'tcx> { - pub fn new(dropped_ty: Ty<'tcx>) -> Self { - DropckOutlives { dropped_ty } - } -} +use crate::traits::query::type_op::DropckOutlives; impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { type QueryResponse = DropckOutlivesResult<'tcx>; @@ -33,14 +22,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { - // FIXME convert to the type expected by the `dropck_outlives` - // query. This should eventually be fixed by changing the - // *underlying query*. - let canonicalized = canonicalized.unchecked_map(|ParamEnvAnd { param_env, value }| { - let DropckOutlives { dropped_ty } = value; - param_env.and(dropped_ty) - }); - tcx.dropck_outlives(canonicalized) } @@ -48,6 +29,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result { - compute_dropck_outlives_inner(ocx, key.param_env.and(key.value.dropped_ty)) + compute_dropck_outlives_inner(ocx, key.param_env.and(key.value)) } } diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 0d052ecf0dfd2..4e5309eea287b 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -10,7 +10,7 @@ use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner, }; -use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; +use rustc_trait_selection::traits::query::{CanonicalDropckOutlivesGoal, NoSolution}; use tracing::debug; pub(crate) fn provide(p: &mut Providers) { @@ -19,7 +19,7 @@ pub(crate) fn provide(p: &mut Providers) { fn dropck_outlives<'tcx>( tcx: TyCtxt<'tcx>, - canonical_goal: CanonicalTyGoal<'tcx>, + canonical_goal: CanonicalDropckOutlivesGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", canonical_goal); From a5e280e8bc0690a43b8882f3b366547c0592d5cd Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 15 Oct 2024 18:24:05 +0200 Subject: [PATCH 12/24] remove Canonical::unchecked_rebind, it's unused --- compiler/rustc_type_ir/src/canonical.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index d609e5add14b9..351179df9d74a 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -57,16 +57,6 @@ impl Canonical { let Canonical { defining_opaque_types, max_universe, variables, value } = self; Canonical { defining_opaque_types, max_universe, variables, value: map_op(value) } } - - /// Allows you to map the `value` of a canonical while keeping the same set of - /// bound variables. - /// - /// **WARNING:** This function is very easy to mis-use, hence the name! See - /// the comment of [Canonical::unchecked_map] for more details. - pub fn unchecked_rebind(self, value: W) -> Canonical { - let Canonical { defining_opaque_types, max_universe, variables, value: _ } = self; - Canonical { defining_opaque_types, max_universe, variables, value } - } } impl fmt::Display for Canonical { From 0630c5dbf2205698dcfdf1937a063d035443d368 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 15 Oct 2024 18:43:41 +0200 Subject: [PATCH 13/24] move `defining_opaque_types` out of `Canonical` --- .../src/diagnostics/bound_region_errors.rs | 29 +++++++++---------- compiler/rustc_hir_typeck/src/method/probe.rs | 11 +++---- .../src/infer/canonical/canonicalizer.rs | 25 +++++----------- compiler/rustc_infer/src/infer/mod.rs | 8 ++--- compiler/rustc_middle/src/infer/canonical.rs | 2 +- compiler/rustc_middle/src/query/keys.rs | 4 +-- compiler/rustc_middle/src/query/mod.rs | 28 +++++++++--------- compiler/rustc_middle/src/traits/query.rs | 25 +++++++++------- .../src/canonicalizer.rs | 3 +- .../rustc_next_trait_solver/src/delegate.rs | 2 +- .../src/solve/eval_ctxt/canonical.rs | 8 +++-- .../src/solve/eval_ctxt/mod.rs | 4 +-- .../rustc_next_trait_solver/src/solve/mod.rs | 1 - .../src/solve/search_graph.rs | 11 +++++-- compiler/rustc_trait_selection/src/infer.rs | 6 ++-- .../src/solve/delegate.rs | 4 +-- .../traits/query/type_op/ascribe_user_type.rs | 4 +-- .../query/type_op/implied_outlives_bounds.rs | 4 +-- .../src/traits/query/type_op/mod.rs | 10 +++---- .../src/traits/query/type_op/normalize.rs | 14 ++++----- .../src/traits/query/type_op/outlives.rs | 4 +-- .../traits/query/type_op/prove_predicate.rs | 4 +-- compiler/rustc_traits/src/type_op.rs | 14 ++++----- compiler/rustc_type_ir/src/canonical.rs | 22 ++++++++++---- compiler/rustc_type_ir/src/solve/mod.rs | 3 +- 25 files changed, 130 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 40a6d506ffa63..2437a43bd5a36 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -3,12 +3,16 @@ use std::rc::Rc; use rustc_errors::Diag; use rustc_hir::def_id::LocalDefId; -use rustc_infer::infer::canonical::Canonical; +use rustc_infer::infer::canonical::CanonicalQueryInput; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_infer::infer::{ InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt as _, }; use rustc_infer::traits::ObligationCause; +use rustc_infer::traits::query::{ + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, + CanonicalTypeOpProvePredicateGoal, +}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, @@ -95,9 +99,7 @@ impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tc } } -impl<'tcx> ToUniverseInfo<'tcx> - for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>> -{ +impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpProvePredicateGoal<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(PredicateQuery { canonical_query: self, @@ -107,7 +109,7 @@ impl<'tcx> ToUniverseInfo<'tcx> } impl<'tcx, T: Copy + fmt::Display + TypeFoldable> + 'tcx> ToUniverseInfo<'tcx> - for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>> + for CanonicalTypeOpNormalizeGoal<'tcx, T> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(NormalizeQuery { @@ -117,9 +119,7 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable> + 'tcx> ToUnivers } } -impl<'tcx> ToUniverseInfo<'tcx> - for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>> -{ +impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpAscribeUserTypeGoal<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(AscribeUserTypeQuery { canonical_query: self, @@ -128,7 +128,7 @@ impl<'tcx> ToUniverseInfo<'tcx> } } -impl<'tcx, F> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp> { +impl<'tcx, F> ToUniverseInfo<'tcx> for CanonicalQueryInput<'tcx, type_op::custom::CustomTypeOp> { fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { // We can't rerun custom type ops. UniverseInfo::other() @@ -211,8 +211,7 @@ trait TypeOpInfo<'tcx> { } struct PredicateQuery<'tcx> { - canonical_query: - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>, + canonical_query: CanonicalTypeOpProvePredicateGoal<'tcx>, base_universe: ty::UniverseIndex, } @@ -220,7 +219,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> { tcx.dcx().create_err(HigherRankedLifetimeError { cause: Some(HigherRankedErrorCause::CouldNotProve { - predicate: self.canonical_query.value.value.predicate.to_string(), + predicate: self.canonical_query.canonical.value.value.predicate.to_string(), }), span, }) @@ -253,7 +252,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { } struct NormalizeQuery<'tcx, T> { - canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>, + canonical_query: CanonicalTypeOpNormalizeGoal<'tcx, T>, base_universe: ty::UniverseIndex, } @@ -264,7 +263,7 @@ where fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> { tcx.dcx().create_err(HigherRankedLifetimeError { cause: Some(HigherRankedErrorCause::CouldNotNormalize { - value: self.canonical_query.value.value.value.to_string(), + value: self.canonical_query.canonical.value.value.value.to_string(), }), span, }) @@ -306,7 +305,7 @@ where } struct AscribeUserTypeQuery<'tcx> { - canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>, + canonical_query: CanonicalTypeOpAscribeUserTypeGoal<'tcx>, base_universe: ty::UniverseIndex, } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ba6bfd3a5e940..1be711887d9fa 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -340,13 +340,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { OP: FnOnce(ProbeContext<'_, 'tcx>) -> Result>, { let mut orig_values = OriginalQueryValues::default(); - let param_env_and_self_ty = self.canonicalize_query( + let query_input = self.canonicalize_query( ParamEnvAnd { param_env: self.param_env, value: self_ty }, &mut orig_values, ); let steps = match mode { - Mode::MethodCall => self.tcx.method_autoderef_steps(param_env_and_self_ty), + Mode::MethodCall => self.tcx.method_autoderef_steps(query_input), Mode::Path => self.probe(|_| { // Mode::Path - the deref steps is "trivial". This turns // our CanonicalQuery into a "trivial" QueryResponse. This @@ -355,11 +355,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let infcx = &self.infcx; let (ParamEnvAnd { param_env: _, value: self_ty }, canonical_inference_vars) = - infcx.instantiate_canonical(span, ¶m_env_and_self_ty); - debug!( - "probe_op: Mode::Path, param_env_and_self_ty={:?} self_ty={:?}", - param_env_and_self_ty, self_ty - ); + infcx.instantiate_canonical(span, &query_input.canonical); + debug!(?self_ty, ?query_input, "probe_op: Mode::Path"); MethodAutoderefStepsResult { steps: infcx.tcx.arena.alloc_from_iter([CandidateStep { self_ty: self.make_query_response_ignoring_pending_obligations( diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 35ea42338250d..e3519dfb02852 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -17,7 +17,8 @@ use tracing::debug; use crate::infer::InferCtxt; use crate::infer::canonical::{ - Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, OriginalQueryValues, + Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, + OriginalQueryValues, }; impl<'tcx> InferCtxt<'tcx> { @@ -40,12 +41,12 @@ impl<'tcx> InferCtxt<'tcx> { &self, value: ty::ParamEnvAnd<'tcx, V>, query_state: &mut OriginalQueryValues<'tcx>, - ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>> + ) -> CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, V>> where V: TypeFoldable>, { let (param_env, value) = value.into_parts(); - let mut param_env = self.tcx.canonical_param_env_cache.get_or_insert( + let param_env = self.tcx.canonical_param_env_cache.get_or_insert( self.tcx, param_env, query_state, @@ -62,9 +63,7 @@ impl<'tcx> InferCtxt<'tcx> { }, ); - param_env.defining_opaque_types = self.defining_opaque_types; - - Canonicalizer::canonicalize_with_base( + let canonical = Canonicalizer::canonicalize_with_base( param_env, value, Some(self), @@ -72,7 +71,8 @@ impl<'tcx> InferCtxt<'tcx> { &CanonicalizeAllFreeRegions, query_state, ) - .unchecked_map(|(param_env, value)| param_env.and(value)) + .unchecked_map(|(param_env, value)| param_env.and(value)); + CanonicalQueryInput { canonical, defining_opaque_types: self.defining_opaque_types() } } /// Canonicalizes a query *response* `V`. When we canonicalize a @@ -544,7 +544,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { max_universe: ty::UniverseIndex::ROOT, variables: List::empty(), value: (), - defining_opaque_types: infcx.map(|i| i.defining_opaque_types).unwrap_or_default(), }; Canonicalizer::canonicalize_with_base( base, @@ -614,15 +613,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .max() .unwrap_or(ty::UniverseIndex::ROOT); - assert!( - !infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types) - ); - Canonical { - max_universe, - variables: canonical_variables, - value: (base.value, out_value), - defining_opaque_types: base.defining_opaque_types, - } + Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) } } /// Creates a canonical variable replacing `kind` from the input, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bc813305ba480..509b1c8cd517a 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -25,7 +25,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::extension; pub use rustc_macros::{TypeFoldable, TypeVisitable}; -use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; +use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ ConstVariableOrigin, ConstVariableValue, ConstVidKey, EffectVarValue, EffectVidKey, }; @@ -604,14 +604,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> { pub fn build_with_canonical( mut self, span: Span, - canonical: &Canonical<'tcx, T>, + input: &CanonicalQueryInput<'tcx, T>, ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) where T: TypeFoldable>, { - self.defining_opaque_types = canonical.defining_opaque_types; + self.defining_opaque_types = input.defining_opaque_types; let infcx = self.build(); - let (value, args) = infcx.instantiate_canonical(span, canonical); + let (value, args) = infcx.instantiate_canonical(span, &input.canonical); (infcx, value, args) } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index d431497881919..ac55497f8b3d4 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -34,6 +34,7 @@ use crate::infer::MemberConstraint; use crate::mir::ConstraintCategory; use crate::ty::{self, GenericArg, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; +pub type CanonicalQueryInput<'tcx, V> = ir::CanonicalQueryInput, V>; pub type Canonical<'tcx, V> = ir::Canonical, V>; pub type CanonicalVarInfo<'tcx> = ir::CanonicalVarInfo>; pub type CanonicalVarValues<'tcx> = ir::CanonicalVarValues>; @@ -182,7 +183,6 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> { max_universe: ty::UniverseIndex::ROOT, variables: List::empty(), value: key, - defining_opaque_types: ty::List::empty(), }; } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 80adbe74fe702..ba7b57c891c52 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -7,7 +7,7 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{DUMMY_SP, Span}; use rustc_target::abi; -use crate::infer::canonical::Canonical; +use crate::infer::canonical::CanonicalQueryInput; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::{TyAndLayout, ValidityRequirement}; use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; @@ -485,7 +485,7 @@ impl Key for Option { /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. -impl<'tcx, T: Clone> Key for Canonical<'tcx, T> { +impl<'tcx, T: Clone> Key for CanonicalQueryInput<'tcx, T> { type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2f5e47f6f359e..33128bdbf1e06 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2011,7 +2011,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { - desc { "normalizing `{}`", goal.value.value } + desc { "normalizing `{}`", goal.canonical.value.value } } ///
@@ -2025,7 +2025,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { - desc { "normalizing `{}`", goal.value.value } + desc { "normalizing `{}`", goal.canonical.value.value } } ///
@@ -2039,7 +2039,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { - desc { "normalizing `{}`", goal.value.value } + desc { "normalizing `{}`", goal.canonical.value.value } } /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. @@ -2055,7 +2055,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - desc { "computing implied outlives bounds for `{}`", goal.value.value.ty } + desc { "computing implied outlives bounds for `{}`", goal.canonical.value.value.ty } } query implied_outlives_bounds( @@ -2064,7 +2064,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - desc { "computing implied outlives bounds v2 for `{}`", goal.value.value.ty } + desc { "computing implied outlives bounds v2 for `{}`", goal.canonical.value.value.ty } } /// Do not call this query directly: @@ -2075,7 +2075,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution, > { - desc { "computing dropck types for `{}`", goal.value.value.dropped_ty } + desc { "computing dropck types for `{}`", goal.canonical.value.value.dropped_ty } } /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or @@ -2083,7 +2083,7 @@ rustc_queries! { query evaluate_obligation( goal: CanonicalPredicateGoal<'tcx> ) -> Result { - desc { "evaluating trait selection obligation `{}`", goal.value.value } + desc { "evaluating trait selection obligation `{}`", goal.canonical.value.value } } /// Do not call this query directly: part of the `Eq` type-op @@ -2093,7 +2093,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value } + desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.canonical.value.value } } /// Do not call this query directly: part of the `ProvePredicate` type-op @@ -2103,7 +2103,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.value.value } + desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.canonical.value.value } } /// Do not call this query directly: part of the `Normalize` type-op @@ -2113,7 +2113,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, NoSolution, > { - desc { "normalizing `{}`", goal.value.value.value } + desc { "normalizing `{}`", goal.canonical.value.value.value } } /// Do not call this query directly: part of the `Normalize` type-op @@ -2123,7 +2123,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Clause<'tcx>>>, NoSolution, > { - desc { "normalizing `{:?}`", goal.value.value.value } + desc { "normalizing `{:?}`", goal.canonical.value.value.value } } /// Do not call this query directly: part of the `Normalize` type-op @@ -2133,7 +2133,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, NoSolution, > { - desc { "normalizing `{:?}`", goal.value.value.value } + desc { "normalizing `{:?}`", goal.canonical.value.value.value } } /// Do not call this query directly: part of the `Normalize` type-op @@ -2143,7 +2143,7 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, NoSolution, > { - desc { "normalizing `{:?}`", goal.value.value.value } + desc { "normalizing `{:?}`", goal.canonical.value.value.value } } query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { @@ -2164,7 +2164,7 @@ rustc_queries! { query method_autoderef_steps( goal: CanonicalTyGoal<'tcx> ) -> MethodAutoderefStepsResult<'tcx> { - desc { "computing autoderef types for `{}`", goal.value.value } + desc { "computing autoderef types for `{}`", goal.canonical.value.value } } query supported_target_features(_: CrateNum) -> &'tcx UnordMap> { diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 6439ab8691568..eeed5118592bc 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -11,7 +11,7 @@ use rustc_span::Span; pub use rustc_type_ir::solve::NoSolution; use crate::error::DropCheckOverflow; -use crate::infer::canonical::{Canonical, QueryResponse}; +use crate::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse}; use crate::ty::{self, GenericArg, Ty, TyCtxt}; pub mod type_op { @@ -58,31 +58,34 @@ pub mod type_op { } } -pub type CanonicalAliasGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; +pub type CanonicalAliasGoal<'tcx> = + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; -pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; +pub type CanonicalTyGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; -pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; +pub type CanonicalPredicateGoal<'tcx> = + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>; -pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>; +pub type CanonicalTypeOpEqGoal<'tcx> = + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>; pub type CanonicalTypeOpSubtypeGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>; pub type CanonicalTypeOpProvePredicateGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>; pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; pub type CanonicalImpliedOutlivesBoundsGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>; pub type CanonicalDropckOutlivesGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::DropckOutlives<'tcx>>>; + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::DropckOutlives<'tcx>>>; #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)] pub struct DropckOutlivesResult<'tcx> { diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 0bf9d7b924952..23634d35c07fe 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -83,8 +83,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let (max_universe, variables) = canonicalizer.finalize(); - let defining_opaque_types = delegate.defining_opaque_types(); - Canonical { defining_opaque_types, max_universe, variables, value } + Canonical { max_universe, variables, value } } fn get_or_insert_bound_var( diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 6a3d58b59066b..76d5f0ea07b45 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -17,7 +17,7 @@ pub trait SolverDelegate: fn build_with_canonical( cx: Self::Interner, solver_mode: SolverMode, - canonical: &ty::Canonical, + canonical: &ty::CanonicalQueryInput, ) -> (Self, V, ty::CanonicalVarValues) where V: TypeFoldable; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index fdefec33eeb5d..f49f3a1a3bf04 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -60,7 +60,7 @@ where (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate)); let mut orig_values = Default::default(); - let canonical_goal = Canonicalizer::canonicalize( + let canonical = Canonicalizer::canonicalize( self.delegate, CanonicalizeMode::Input, &mut orig_values, @@ -71,7 +71,11 @@ where .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), }, ); - (orig_values, canonical_goal) + let query_input = ty::CanonicalQueryInput { + canonical, + defining_opaque_types: self.delegate.defining_opaque_types(), + }; + (orig_values, query_input) } /// To return the constraints of a canonical query to the caller, we canonicalize: diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index daacc6691182d..10e15735fd8d1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -283,11 +283,11 @@ where let mut ecx = EvalCtxt { delegate, - variables: canonical_input.variables, + variables: canonical_input.canonical.variables, var_values, is_normalizes_to_goal: false, predefined_opaques_in_body: input.predefined_opaques_in_body, - max_input_universe: canonical_input.max_universe, + max_input_universe: canonical_input.canonical.max_universe, search_graph, nested_goals: NestedGoals::new(), tainted: Ok(()), diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 8fe39bb4ee163..ff91fa13fd068 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -313,6 +313,5 @@ fn response_no_constraints_raw( external_constraints: cx.mk_external_constraints(ExternalConstraintsData::default()), certainty, }, - defining_opaque_types: Default::default(), } } diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 0e3f179b0c846..843200ca184ea 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -96,14 +96,19 @@ where } fn step_is_coinductive(cx: I, input: CanonicalInput) -> bool { - input.value.goal.predicate.is_coinductive(cx) + input.canonical.value.goal.predicate.is_coinductive(cx) } } fn response_no_constraints( cx: I, - goal: CanonicalInput, + input: CanonicalInput, certainty: Certainty, ) -> QueryResult { - Ok(super::response_no_constraints_raw(cx, goal.max_universe, goal.variables, certainty)) + Ok(super::response_no_constraints_raw( + cx, + input.canonical.max_universe, + input.canonical.variables, + certainty, + )) } diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index f232a896f9698..bacb3b1b1b861 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -5,7 +5,9 @@ use rustc_hir::lang_items::LangItem; pub use rustc_infer::infer::*; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; -use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; +use rustc_middle::infer::canonical::{ + Canonical, CanonicalQueryInput, CanonicalQueryResponse, QueryResponse, +}; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast}; use rustc_span::DUMMY_SP; @@ -132,7 +134,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { /// `K: TypeFoldable>`.) fn enter_canonical_trait_query( self, - canonical_key: &Canonical<'tcx, K>, + canonical_key: &CanonicalQueryInput<'tcx, K>, operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, ) -> Result, NoSolution> where diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index df9ac2b80fded..62f56beb34b19 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::{ - Canonical, CanonicalExt as _, CanonicalVarInfo, CanonicalVarValues, + Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarInfo, CanonicalVarValues, }; use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::solve::Goal; @@ -47,7 +47,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< fn build_with_canonical( interner: TyCtxt<'tcx>, solver_mode: SolverMode, - canonical: &Canonical<'tcx, V>, + canonical: &CanonicalQueryInput<'tcx, V>, ) -> (Self, V, CanonicalVarValues<'tcx>) where V: TypeFoldable>, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index c84c3147a3842..dc3f5544613ad 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, User use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; -use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::traits::ObligationCtxt; impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { @@ -22,7 +22,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { tcx.type_op_ascribe_user_type(canonicalized) } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index f0824eb2a4612..dfd0cab69058b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::canonical::Canonical; +use rustc_infer::infer::canonical::CanonicalQueryInput; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; @@ -33,7 +33,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { if tcx.sess.opts.unstable_opts.no_implied_bounds_compat { tcx.implied_outlives_bounds(canonicalized) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a765de92afd55..ba554e23f9a36 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -1,7 +1,6 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; -use rustc_infer::infer::canonical::Certainty; use rustc_infer::traits::PredicateObligation; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; @@ -9,7 +8,8 @@ use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::Span; use crate::infer::canonical::{ - Canonical, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints, + CanonicalQueryInput, CanonicalQueryResponse, Certainty, OriginalQueryValues, + QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; use crate::traits::{ObligationCause, ObligationCtxt}; @@ -80,7 +80,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't /// not captured in the return value. fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution>; /// In the new trait solver, we already do caching in the solver itself, @@ -102,7 +102,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't ) -> Result< ( Self::QueryResponse, - Option>>, + Option>>, Vec>, Certainty, ), @@ -135,7 +135,7 @@ where Q: QueryTypeOp<'tcx>, { type Output = Q::QueryResponse; - type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>; + type ErrorInfo = CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Q>>; fn fully_perform( self, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 62d5655922b09..94df222932efe 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -6,7 +6,7 @@ pub use rustc_middle::traits::query::type_op::Normalize; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; -use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::traits::ObligationCtxt; impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize @@ -21,7 +21,7 @@ where fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { T::type_op_method(tcx, canonicalized) } @@ -40,14 +40,14 @@ pub trait Normalizable<'tcx>: { fn type_op_method( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Result, NoSolution>; } impl<'tcx> Normalizable<'tcx> for Ty<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Result, NoSolution> { tcx.type_op_normalize_ty(canonicalized) } @@ -56,7 +56,7 @@ impl<'tcx> Normalizable<'tcx> for Ty<'tcx> { impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Result, NoSolution> { tcx.type_op_normalize_clause(canonicalized) } @@ -65,7 +65,7 @@ impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> { impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Result, NoSolution> { tcx.type_op_normalize_poly_fn_sig(canonicalized) } @@ -74,7 +74,7 @@ impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> { impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Result, NoSolution> { tcx.type_op_normalize_fn_sig(canonicalized) } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index eb17703e03118..fa05f901f663d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -1,7 +1,7 @@ use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution}; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; -use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::traits::ObligationCtxt; use crate::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, trivial_dropck_outlives, @@ -20,7 +20,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { tcx.dropck_outlives(canonicalized) } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 7cdb9ee691e4b..b2dab379262f5 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -5,7 +5,7 @@ use rustc_middle::traits::query::NoSolution; pub use rustc_middle::traits::query::type_op::ProvePredicate; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; -use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::traits::ObligationCtxt; impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { @@ -49,7 +49,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { tcx.type_op_prove_predicate(canonicalized) } diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index c982cd66bca12..71088a598bb93 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::canonical::{Canonical, QueryResponse}; +use rustc_infer::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse}; use rustc_middle::query::Providers; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{Clause, FnSig, ParamEnvAnd, PolyFnSig, Ty, TyCtxt, TypeFoldable}; @@ -28,7 +28,7 @@ pub(crate) fn provide(p: &mut Providers) { fn type_op_ascribe_user_type<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { type_op_ascribe_user_type_with_span(ocx, key, None) @@ -51,35 +51,35 @@ where fn type_op_normalize_ty<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize) } fn type_op_normalize_clause<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Clause<'tcx>>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize) } fn type_op_normalize_fn_sig<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, FnSig<'tcx>>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize) } fn type_op_normalize_poly_fn_sig<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, PolyFnSig<'tcx>>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize) } fn type_op_prove_predicate<'tcx>( tcx: TyCtxt<'tcx>, - canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, + canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { type_op_prove_predicate_with_cause(ocx, key, ObligationCause::dummy()); diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 351179df9d74a..07cb8b037ecf7 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -10,6 +10,18 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use crate::inherent::*; use crate::{self as ty, Interner, UniverseIndex}; +#[derive_where(Clone; I: Interner, V: Clone)] +#[derive_where(Hash; I: Interner, V: Hash)] +#[derive_where(PartialEq; I: Interner, V: PartialEq)] +#[derive_where(Eq; I: Interner, V: Eq)] +#[derive_where(Debug; I: Interner, V: fmt::Debug)] +#[derive_where(Copy; I: Interner, V: Copy)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub struct CanonicalQueryInput { + pub canonical: Canonical, + pub defining_opaque_types: I::DefiningOpaqueTypes, +} + /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are /// numbered starting from 0 in order of first appearance. @@ -24,8 +36,6 @@ use crate::{self as ty, Interner, UniverseIndex}; pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, - // FIXME(lcnr, oli-obk): try moving this into the query inputs instead - pub defining_opaque_types: I::DefiningOpaqueTypes, pub variables: I::CanonicalVars, } @@ -54,17 +64,17 @@ impl Canonical { /// let b: Canonical)> = a.unchecked_map(|v| (v, ty)); /// ``` pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical { - let Canonical { defining_opaque_types, max_universe, variables, value } = self; - Canonical { defining_opaque_types, max_universe, variables, value: map_op(value) } + let Canonical { max_universe, variables, value } = self; + Canonical { max_universe, variables, value: map_op(value) } } } impl fmt::Display for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; + let Self { value, max_universe, variables } = self; write!( f, - "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, defining_opaque_types: {defining_opaque_types:?} }}", + "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?} }}", ) } } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a0f7658212f4b..85e50947a8789 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -71,7 +71,8 @@ pub enum SolverMode { Coherence, } -pub type CanonicalInput::Predicate> = Canonical>; +pub type CanonicalInput::Predicate> = + ty::CanonicalQueryInput>; pub type CanonicalResponse = Canonical>; /// The result of evaluating a canonical query. /// From 68885216b63f6e75e50b4c0f3c7250ca4ac7afda Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 14:58:41 -0400 Subject: [PATCH 14/24] Don't report bivariance error when nesting a struct with field errors into another struct --- .../rustc_hir_analysis/src/check/wfcheck.rs | 60 +++++++++++++++---- .../type-resolve-error-two-structs-deep.rs | 13 ++++ ...type-resolve-error-two-structs-deep.stderr | 9 +++ 3 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 tests/ui/variance/type-resolve-error-two-structs-deep.rs create mode 100644 tests/ui/variance/type-resolve-error-two-structs-deep.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 607068f162aa3..f788456d4e9eb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1875,24 +1875,15 @@ fn check_variances_for_type_defn<'tcx>( item: &'tcx hir::Item<'tcx>, hir_generics: &hir::Generics<'tcx>, ) { - let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id); - match item.kind { ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { - for field in tcx.adt_def(item.owner_id).all_fields() { - if field.ty(tcx, identity_args).references_error() { - return; - } - } + // Ok } ItemKind::TyAlias(..) => { assert!( tcx.type_alias_is_lazy(item.owner_id), "should not be computing variance of non-weak type alias" ); - if tcx.type_of(item.owner_id).skip_binder().references_error() { - return; - } } kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), } @@ -1955,6 +1946,15 @@ fn check_variances_for_type_defn<'tcx>( continue; } + // Look for `ErrorGuaranteed` deeply within this type. + if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx + .type_of(item.owner_id) + .instantiate_identity() + .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) + { + continue; + } + match hir_param.name { hir::ParamName::Error => {} _ => { @@ -1965,6 +1965,46 @@ fn check_variances_for_type_defn<'tcx>( } } +/// Look for `ErrorGuaranteed` deeply within structs' (unsubstituted) fields. +struct HasErrorDeep<'tcx> { + tcx: TyCtxt<'tcx>, + seen: FxHashSet, +} +impl<'tcx> TypeVisitor> for HasErrorDeep<'tcx> { + type Result = ControlFlow; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + match *ty.kind() { + ty::Adt(def, _) => { + if self.seen.insert(def.did()) { + for field in def.all_fields() { + self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?; + } + } + } + ty::Error(guar) => return ControlFlow::Break(guar), + _ => {} + } + ty.super_visit_with(self) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { + if let Err(guar) = r.error_reported() { + ControlFlow::Break(guar) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result { + if let Err(guar) = c.error_reported() { + ControlFlow::Break(guar) + } else { + ControlFlow::Continue(()) + } + } +} + fn report_bivariance<'tcx>( tcx: TyCtxt<'tcx>, param: &'tcx hir::GenericParam<'tcx>, diff --git a/tests/ui/variance/type-resolve-error-two-structs-deep.rs b/tests/ui/variance/type-resolve-error-two-structs-deep.rs new file mode 100644 index 0000000000000..47ec532ab9681 --- /dev/null +++ b/tests/ui/variance/type-resolve-error-two-structs-deep.rs @@ -0,0 +1,13 @@ +// Make sure we don't report bivariance errors when nesting structs w/ unresolved +// fields into *other* structs. + +struct Hello<'a> { + missing: Missing<'a>, + //~^ ERROR cannot find type `Missing` in this scope +} + +struct Other<'a> { + hello: Hello<'a>, +} + +fn main() {} diff --git a/tests/ui/variance/type-resolve-error-two-structs-deep.stderr b/tests/ui/variance/type-resolve-error-two-structs-deep.stderr new file mode 100644 index 0000000000000..3458d924bb153 --- /dev/null +++ b/tests/ui/variance/type-resolve-error-two-structs-deep.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/type-resolve-error-two-structs-deep.rs:5:14 + | +LL | missing: Missing<'a>, + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. From e744e229f7e280ec4ac984bb1d2d66095a63422f Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 16 Oct 2024 00:35:21 +0200 Subject: [PATCH 15/24] bless mir-opt tests --- ..._of_reborrow.SimplifyCfg-initial.after.mir | 60 +++++++++---------- ...ignment.main.SimplifyCfg-initial.after.mir | 4 +- .../issue_101867.main.built.after.mir | 4 +- ...ceiver_ptr_mutability.main.built.after.mir | 8 +-- .../issue_72181_1.main.built.after.mir | 4 +- .../issue_99325.main.built.after.32bit.mir | 4 +- .../issue_99325.main.built.after.64bit.mir | 4 +- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index ae445ad9b915b..5fc77f95eaf72 100644 --- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -1,36 +1,36 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] -| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send -| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] -| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] -| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] -| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] -| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send -| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send -| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] -| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send -| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] -| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] -| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] -| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] -| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send -| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send -| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] -| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send -| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] -| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] -| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] -| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] -| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send -| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send -| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] -| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] +| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send +| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] +| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] +| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send +| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send +| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] +| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] +| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send +| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] +| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] +| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send +| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send +| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] +| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] +| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send +| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] +| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] +| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send +| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send +| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] +| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] | fn address_of_reborrow() -> () { let mut _0: (); diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index d4f0363e44314..b9d26c67538e7 100644 --- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> -| 1: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> +| 0: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> +| 1: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 34e5bedf4ce9c..dd1d093c4dba3 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option -| 1: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option +| 0: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option +| 1: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index be972b62cbd31..6e349a2a24ff6 100644 --- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -1,10 +1,10 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test -| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test -| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test -| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test +| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test +| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test +| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test +| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir index 293aa37944dd2..79eaf96683306 100644 --- a/tests/mir-opt/issue_72181_1.main.built.after.mir +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void -| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void +| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void +| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index 161c73529f53c..48a399eb39ce5 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index 161c73529f53c..48a399eb39ce5 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); From 50b8029ce143aa5ed67aab9d3c05533330df97d6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 12:40:08 -0400 Subject: [PATCH 16/24] Always recurse on predicates in BestObligation --- compiler/rustc_trait_selection/src/solve/fulfill.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 081d7a6a769a1..0e2b081448e58 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -465,13 +465,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { polarity: ty::PredicatePolarity::Positive, })) } - ty::PredicateKind::Clause( - ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..), - ) - | ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough, - _ => { - return ControlFlow::Break(self.obligation.clone()); - } + _ => ChildMode::PassThrough, }; let mut impl_where_bound_count = 0; From fd2038d344c3abb34a0a7812c49f1730c3cee3b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 10:52:34 -0400 Subject: [PATCH 17/24] Make sure the alias is actually rigid --- .../src/solve/normalizes_to/mod.rs | 53 ++++++++++++++- .../defaults-unsound-62211-1.next.stderr | 21 ++++-- .../defaults-unsound-62211-2.next.stderr | 21 ++++-- .../associated-types/issue-54108.next.stderr | 21 ++++-- tests/ui/for/issue-20605.next.stderr | 11 +-- ...mbig-hr-projection-issue-93340.next.stderr | 12 +++- .../in-trait/alias-bounds-when-not-wf.stderr | 28 ++++++-- .../impl-trait/method-resolution4.next.stderr | 50 +++++++++++--- .../recursive-coroutine-boxed.next.stderr | 68 +++++++++++++++---- .../impl-trait/unsized_coercion.next.stderr | 35 +++++++--- .../impl-trait/unsized_coercion3.next.stderr | 43 ++++++------ .../opaque-type-unsatisfied-bound.stderr | 62 +++++++++++++++-- .../opaque-type-unsatisfied-fn-bound.stderr | 28 +++++++- .../traits/next-solver/coroutine.fail.stderr | 41 ++++++++++- .../diagnostics/projection-trait-ref.stderr | 33 ++++++++- .../next-solver/dyn-incompatibility.stderr | 15 +++- tests/ui/traits/next-solver/fn-trait.stderr | 61 ++++++++++++++++- .../issue-118950-root-region.stderr | 18 ++--- ...ution_trait_method_from_opaque.next.stderr | 19 +++++- ...hod_resolution_trait_method_from_opaque.rs | 2 + 20 files changed, 530 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 005b293621afc..bf1d2bf08b788 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate}; use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - NoSolution, QueryResult, + NoSolution, QueryResult, Reveal, }; impl EvalCtxt<'_, D> @@ -39,11 +39,58 @@ where Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; + self.add_rigid_constraints(param_env, alias)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } } + /// Register any obligations that are used to validate that an alias should be + /// treated as rigid. + /// + /// An alias may be considered rigid if it fails normalization, but we also don't + /// want to consider aliases that are not well-formed to be rigid simply because + /// they fail normalization. + /// + /// For example, some `::Assoc` where `T: Trait` does not hold, or an + /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds. + fn add_rigid_constraints( + &mut self, + param_env: I::ParamEnv, + rigid_alias: ty::AliasTerm, + ) -> Result<(), NoSolution> { + match rigid_alias.kind(self.cx()) { + // Projections are rigid only if their trait ref holds. + ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { + let trait_ref = rigid_alias.trait_ref(self.cx()); + self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref)); + Ok(()) + } + ty::AliasTermKind::OpaqueTy => { + match param_env.reveal() { + // In user-facing mode, paques are only rigid if we may not define it. + Reveal::UserFacing => { + if rigid_alias + .def_id + .as_local() + .is_some_and(|def_id| self.can_define_opaque_ty(def_id)) + { + Err(NoSolution) + } else { + Ok(()) + } + } + // Opaques are never rigid in reveal-all mode. + Reveal::All => Err(NoSolution), + } + } + // FIXME(generic_const_exprs): we would need to support generic consts here + ty::AliasTermKind::UnevaluatedConst => Err(NoSolution), + // Inherent and weak types are never rigid. This type must not be well-formed. + ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution), + } + } + /// Normalize the given alias by at least one step. If the alias is rigid, this /// returns `NoSolution`. #[instrument(level = "trace", skip(self), ret)] @@ -124,6 +171,7 @@ where ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); // Add GAT where clauses from the trait's definition + // FIXME: We don't need these, since these are the type's own WF obligations. ecx.add_goals( GoalSource::Misc, cx.own_predicates_of(goal.predicate.def_id()) @@ -179,7 +227,8 @@ where .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); - // Add GAT where clauses from the trait's definition + // Add GAT where clauses from the trait's definition. + // FIXME: We don't need these, since these are the type's own WF obligations. ecx.add_goals( GoalSource::Misc, cx.own_predicates_of(goal.predicate.def_id()) diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index 010f51df15ad3..4523fc3e037e8 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -31,17 +31,29 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0277]: the trait bound `Self: Deref` is not satisfied +error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` --> $DIR/defaults-unsound-62211-1.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ the trait `Deref` is not implemented for `Self` + | ^^^^ types differ | note: required by a bound in `UncheckedCopy::Output` --> $DIR/defaults-unsound-62211-1.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + +error[E0277]: the trait bound `Self: Deref` is not satisfied + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Deref` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:25 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -63,6 +75,7 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index 9347894657078..7a68f1ac8cc47 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -31,17 +31,29 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0277]: the trait bound `Self: Deref` is not satisfied +error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` --> $DIR/defaults-unsound-62211-2.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ the trait `Deref` is not implemented for `Self` + | ^^^^ types differ | note: required by a bound in `UncheckedCopy::Output` --> $DIR/defaults-unsound-62211-2.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + +error[E0277]: the trait bound `Self: Deref` is not satisfied + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Deref` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:25 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -63,6 +75,7 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr index 5e2fa551afe30..0866ed054514b 100644 --- a/tests/ui/associated-types/issue-54108.next.stderr +++ b/tests/ui/associated-types/issue-54108.next.stderr @@ -1,3 +1,15 @@ +error[E0271]: type mismatch resolving `<::ActualSize as Add>::Output normalizes-to <::ActualSize as Add>::Output` + --> $DIR/issue-54108.rs:23:17 + | +LL | type Size = ::ActualSize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | +note: required by a bound in `Encoder::Size` + --> $DIR/issue-54108.rs:8:20 + | +LL | type Size: Add; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + error[E0277]: cannot add `::ActualSize` to `::ActualSize` --> $DIR/issue-54108.rs:23:17 | @@ -6,15 +18,16 @@ LL | type Size = ::ActualSize; | = help: the trait `Add` is not implemented for `::ActualSize` note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:20 + --> $DIR/issue-54108.rs:8:16 | LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` help: consider further restricting the associated type | LL | T: SubEncoder, ::ActualSize: Add | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 98609211865c4..1a66cb4146495 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -11,13 +11,6 @@ help: consider mutably borrowing here LL | for item in &mut *things { *item = 0 } | ++++ -error[E0614]: type ` as IntoIterator>::Item` cannot be dereferenced - --> $DIR/issue-20605.rs:6:27 - | -LL | for item in *things { *item = 0 } - | ^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0614. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr index d913b2e91ca0e..bc57874bf850a 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr @@ -15,6 +15,14 @@ help: consider specifying the generic arguments LL | cmp_eq:: | +++++++++++ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `build_expression::{opaque#0} normalizes-to _` + --> $DIR/ambig-hr-projection-issue-93340.rs:14:1 + | +LL | / fn build_expression( +LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + | |_________________________________________________^ types differ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0271, E0283. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index 9663fab3d8c39..cab6163803a4e 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -7,14 +7,32 @@ LL | #![feature(lazy_type_alias)] = note: see issue #112792 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the size for values of type `A` cannot be known at compilation time +error[E0271]: type mismatch resolving `A normalizes-to _` --> $DIR/alias-bounds-when-not-wf.rs:16:13 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:10 | - = help: the trait `Sized` is not implemented for `A` +LL | fn hello(_: W>) {} + | ^ types differ + +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:10 + | +LL | fn hello(_: W>) {} + | ^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:1 + | +LL | fn hello(_: W>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index b48de0af3579d..5aa6931d371e2 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -4,19 +4,51 @@ error[E0282]: type annotations needed LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:16:5 +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:13:9 + | +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time + --> $DIR/method-resolution4.rs:11:20 | LL | fn foo(b: bool) -> impl Iterator { - | ------------------------ the expected opaque type -... + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Iterator` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:16:5 + | LL | std::iter::empty() | ^^^^^^^^^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time + --> $DIR/method-resolution4.rs:13:9 | - = note: expected opaque type `impl Iterator` - found struct `std::iter::Empty<_>` +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Iterator` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:13:9 + | +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:11:1 + | +LL | fn foo(b: bool) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 2 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0271, E0277, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index 96db2030a405c..5feef0b44b53b 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -12,15 +12,9 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` --> $DIR/recursive-coroutine-boxed.rs:14:18 | -LL | fn foo() -> impl Coroutine { - | --------------------------------------- - | | - | the expected opaque type - | expected `impl Coroutine` because of return type -... LL | #[coroutine] || { | __________________^ LL | | let mut gen = Box::pin(foo()); @@ -30,11 +24,61 @@ LL | | let mut r = gen.as_mut().resume(()); LL | | } LL | | } | |_____^ types differ + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ types differ + +error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time + --> $DIR/recursive-coroutine-boxed.rs:9:13 + | +LL | fn foo() -> impl Coroutine { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Coroutine` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:14:18 + | +LL | #[coroutine] || { + | __________________^ +LL | | let mut gen = Box::pin(foo()); +LL | | +LL | | let mut r = gen.as_mut().resume(()); +... | +LL | | } +LL | | } + | |_____^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Coroutine` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:9:1 | - = note: expected opaque type `impl Coroutine` - found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}` +LL | fn foo() -> impl Coroutine { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 2 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0271, E0277, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr index 49ac3f1845fb3..f31a2a806674b 100644 --- a/tests/ui/impl-trait/unsized_coercion.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -1,26 +1,39 @@ -error[E0271]: type mismatch resolving `impl Trait <: dyn Trait` +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` --> $DIR/unsized_coercion.rs:14:17 | LL | let x = hello(); | ^^^^^^^ types differ error[E0308]: mismatched types - --> $DIR/unsized_coercion.rs:18:14 + --> $DIR/unsized_coercion.rs:18:5 | LL | fn hello() -> Box { - | ---------- the expected opaque type + | --------------- + | | | + | | the expected opaque type + | expected `Box` because of return type ... LL | Box::new(1u32) - | -------- ^^^^ types differ - | | - | arguments to this function are incorrect + | ^^^^^^^^^^^^^^ types differ | - = note: expected opaque type `impl Trait` - found type `u32` -note: associated function defined here - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: expected struct `Box` + found struct `Box` -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion.rs:14:17 + | +LL | let x = hello(); + | ^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion.rs:12:1 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index 586ae07602821..f5187a6256efa 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -1,38 +1,39 @@ -error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send` +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` --> $DIR/unsized_coercion3.rs:13:17 | LL | let x = hello(); | ^^^^^^^ types differ error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:18:14 + --> $DIR/unsized_coercion3.rs:18:5 | LL | fn hello() -> Box { - | ------------------- the expected opaque type + | ------------------------ + | | | + | | the expected opaque type + | expected `Box` because of return type ... LL | Box::new(1u32) - | -------- ^^^^ types differ - | | - | arguments to this function are incorrect + | ^^^^^^^^^^^^^^ types differ | - = note: expected opaque type `impl Trait + ?Sized` - found type `u32` -note: associated function defined here - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: expected struct `Box` + found struct `Box` -error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:18:14 +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion3.rs:13:17 | -LL | Box::new(1u32) - | -------- ^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call +LL | let x = hello(); + | ^^^^^^^ types differ | - = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` -note: required by a bound in `Box::::new` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion3.rs:11:1 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277, E0308. +Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 3dd2b27b55b67..561bf8eee2283 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,21 +1,69 @@ -error[E0271]: type mismatch resolving `impl !Sized + Sized == ()` +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} | ^^^^^^^^^^^^^^^^^^^ types differ -error[E0271]: type mismatch resolving `impl !Sized + Sized == ()` +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^ types differ + +error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Sized + Sized` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ types differ -error[E0271]: type mismatch resolving `impl !Sized == ()` +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:17:36 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^ types differ + +error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Sized + Sized` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:17:1 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ types differ +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:19:28 + | +LL | fn weird2() -> impl !Sized {} + | ^^ types differ + error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | @@ -25,6 +73,12 @@ LL | fn weird2() -> impl !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized` = note: the return type of a function must have a statically known size +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 + | +LL | fn weird2() -> impl !Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 | @@ -39,7 +93,7 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 5 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0271, E0277. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index e1b84e0df7a54..a7a83cf1d69cc 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,9 +1,31 @@ -error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()` +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} | ^^^^^^^^^^^^^^^^ types differ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^ types differ + +error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index 8c263e8644bd0..b37dbc0e579eb 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -16,6 +16,43 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine` -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield` + --> $DIR/coroutine.rs:20:9 + | +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { +LL | | +LL | | yield (); +LL | | }, + | |_________^ types differ + | +note: required by a bound in `needs_coroutine` + --> $DIR/coroutine.rs:14:41 + | +LL | fn needs_coroutine(_: impl Coroutine) {} + | ^^^^^^^^^ required by this bound in `needs_coroutine` + +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return` + --> $DIR/coroutine.rs:20:9 + | +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { +LL | | +LL | | yield (); +LL | | }, + | |_________^ types differ + | +note: required by a bound in `needs_coroutine` + --> $DIR/coroutine.rs:14:52 + | +LL | fn needs_coroutine(_: impl Coroutine) {} + | ^^^^^^^^^^ required by this bound in `needs_coroutine` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr index cd8d8b3ffcd38..dbd2880943c97 100644 --- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr @@ -9,6 +9,20 @@ help: consider restricting type parameter `T` LL | fn test_poly() { | +++++++ +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:8:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:8:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0277]: the trait bound `i32: Trait` is not satisfied --> $DIR/projection-trait-ref.rs:13:12 | @@ -21,6 +35,21 @@ help: this trait has no implementations, consider adding one LL | trait Trait { | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:13:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:13:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr index 7f2c0646ef501..adf46686e081a 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr +++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr @@ -43,7 +43,20 @@ help: consider restricting type parameter `T` LL | pub fn copy_any(t: &T) -> T { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error[E0277]: the size for values of type ` as Setup>::From` cannot be known at compilation time + --> $DIR/dyn-incompatibility.rs:12:5 + | +LL | copy::>(t) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for ` as Setup>::From` + = note: the return type of a function must have a statically known size +help: consider further restricting the associated type + | +LL | pub fn copy_any(t: &T) -> T where as Setup>::From: Sized { + | +++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index 00243fd905950..0dee26d467271 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -15,6 +15,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:20:16 + | +LL | require_fn(f as unsafe fn() -> i32); + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}` --> $DIR/fn-trait.rs:22:16 | @@ -31,6 +45,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 {g} as FnOnce<()>>::Output normalizes-to i32 {g} as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:22:16 + | +LL | require_fn(g); + | ---------- ^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32` --> $DIR/fn-trait.rs:24:16 | @@ -47,6 +75,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:24:16 + | +LL | require_fn(g as extern "C" fn() -> i32); + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}` --> $DIR/fn-trait.rs:26:16 | @@ -64,6 +106,21 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error: aborting due to 4 previous errors +error[E0271]: type mismatch resolving ` i32 {h} as FnOnce<()>>::Output normalizes-to i32 {h} as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:26:16 + | +LL | require_fn(h); + | ---------- ^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 7c3e22fb4014a..82ec9e3a22f75 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,21 +26,13 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error[E0119]: conflicting implementations of trait `Overlap` for type `fn(_)` - --> $DIR/issue-118950-root-region.rs:19:1 +error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _` + --> $DIR/issue-118950-root-region.rs:19:17 | -LL | impl Overlap for T {} - | ------------------------ first implementation here -LL | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0119, E0277, E0412. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0271, E0277, E0412. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index 2617ce124c105..f953111aef025 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -4,6 +4,21 @@ error[E0282]: type annotations needed LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `Tait normalizes-to _` + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + | +LL | self.bar.next().unwrap(); + | ^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `Tait normalizes-to _` + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + | +LL | self.bar.next().unwrap(); + | ^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0271, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index b6adf08853f2f..5c9a3b7c2d296 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -25,6 +25,8 @@ impl Foo { //[current]~^ ERROR: item does not constrain self.bar.next().unwrap(); //[next]~^ ERROR: type annotations needed + //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` + //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` } } From 8528387743709360f1cb2d3b5538342ec71bd03a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 13:04:10 -0400 Subject: [PATCH 18/24] Be better at reporting alias errors --- .../src/solve/eval_ctxt/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 20 +++-- .../src/solve/fulfill.rs | 17 ++++- .../src/solve/inspect/analyse.rs | 6 +- .../rustc_trait_selection/src/solve/select.rs | 3 +- compiler/rustc_type_ir/src/solve/inspect.rs | 2 + compiler/rustc_type_ir/src/solve/mod.rs | 4 + .../defaults-unsound-62211-1.next.stderr | 21 +----- .../defaults-unsound-62211-2.next.stderr | 21 +----- .../associated-types/issue-54108.next.stderr | 21 +----- tests/ui/for/issue-20605.rs | 7 +- ...mbig-hr-projection-issue-93340.next.stderr | 12 +-- ...ambig-hr-projection-issue-93340.old.stderr | 2 +- .../ambig-hr-projection-issue-93340.rs | 1 + .../in-trait/alias-bounds-when-not-wf.rs | 4 +- .../in-trait/alias-bounds-when-not-wf.stderr | 38 ++++++---- .../impl-trait/method-resolution4.next.stderr | 36 ++------- tests/ui/impl-trait/method-resolution4.rs | 3 +- .../recursive-coroutine-boxed.next.stderr | 60 ++------------- .../impl-trait/recursive-coroutine-boxed.rs | 6 +- .../impl-trait/unsized_coercion.next.stderr | 30 ++++---- tests/ui/impl-trait/unsized_coercion.rs | 3 +- .../impl-trait/unsized_coercion3.next.stderr | 30 ++++---- .../impl-trait/unsized_coercion3.old.stderr | 2 +- tests/ui/impl-trait/unsized_coercion3.rs | 4 +- .../opaque-type-unsatisfied-bound.rs | 16 +++- .../opaque-type-unsatisfied-bound.stderr | 73 ++++++++++++------- .../opaque-type-unsatisfied-fn-bound.rs | 5 +- .../opaque-type-unsatisfied-fn-bound.stderr | 21 ++++-- .../traits/next-solver/coroutine.fail.stderr | 41 +---------- .../diagnostics/projection-trait-ref.stderr | 33 +-------- .../traits/next-solver/dyn-incompatibility.rs | 1 + tests/ui/traits/next-solver/fn-trait.stderr | 61 +--------------- .../next-solver/issue-118950-root-region.rs | 4 +- .../issue-118950-root-region.stderr | 14 +++- .../normalize/normalize-region-obligations.rs | 2 +- ...ution_trait_method_from_opaque.next.stderr | 19 +---- ...hod_resolution_trait_method_from_opaque.rs | 2 - tests/ui/typeck/issue-103899.rs | 10 +-- 39 files changed, 237 insertions(+), 420 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index daacc6691182d..0f8b796d602a7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -983,7 +983,7 @@ where hidden_ty, &mut goals, ); - self.add_goals(GoalSource::Misc, goals); + self.add_goals(GoalSource::AliasWellFormed, goals); } // Do something for each opaque/hidden pair defined with `def_id` in the diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index bf1d2bf08b788..4d8b193ee4911 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -37,10 +37,12 @@ where match normalize_result { Ok(res) => Ok(res), Err(NoSolution) => { - let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; - self.add_rigid_constraints(param_env, alias)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| { + let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; + this.add_rigid_constraints(param_env, alias)?; + this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } } } @@ -59,11 +61,13 @@ where param_env: I::ParamEnv, rigid_alias: ty::AliasTerm, ) -> Result<(), NoSolution> { - match rigid_alias.kind(self.cx()) { - // Projections are rigid only if their trait ref holds. + let cx = self.cx(); + match rigid_alias.kind(cx) { + // Projections are rigid only if their trait ref holds, + // and the GAT where-clauses hold. ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { - let trait_ref = rigid_alias.trait_ref(self.cx()); - self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref)); + let trait_ref = rigid_alias.trait_ref(cx); + self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref)); Ok(()) } ty::AliasTermKind::OpaqueTy => { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 0e2b081448e58..0f977beb85a91 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -13,7 +13,7 @@ use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _}; -use tracing::instrument; +use tracing::{instrument, trace}; use super::Certainty; use super::delegate::SolverDelegate; @@ -402,6 +402,7 @@ impl<'tcx> BestObligation<'tcx> { nested_goal.source(), GoalSource::ImplWhereBound | GoalSource::InstantiateHigherRanked + | GoalSource::AliasWellFormed ) && match self.consider_ambiguities { true => { matches!( @@ -416,6 +417,13 @@ impl<'tcx> BestObligation<'tcx> { }) }); } + + // Prefer a non-rigid candidate if there is one. + if candidates.len() > 1 { + candidates.retain(|candidate| { + !matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. }) + }); + } } } @@ -430,8 +438,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { self.obligation.cause.span } + #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))] fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result { let candidates = self.non_trivial_candidates(goal); + trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::>()); + let [candidate] = candidates.as_slice() else { return ControlFlow::Break(self.obligation.clone()); }; @@ -470,6 +481,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { let mut impl_where_bound_count = 0; for nested_goal in candidate.instantiate_nested_goals(self.span()) { + trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result())); + let make_obligation = |cause| Obligation { cause, param_env: nested_goal.goal().param_env, @@ -496,7 +509,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { (_, GoalSource::InstantiateHigherRanked) => { obligation = self.obligation.clone(); } - (ChildMode::PassThrough, _) => { + (ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => { obligation = make_obligation(self.obligation.cause.clone()); } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 254620e0b597f..4975a9ce0c757 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { | inspect::ProbeKind::Root { .. } | inspect::ProbeKind::TryNormalizeNonRigid { .. } | inspect::ProbeKind::TraitCandidate { .. } - | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => { + | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } + | inspect::ProbeKind::RigidAlias { .. } => { // Nested probes have to prove goals added in their parent // but do not leak them, so we truncate the added goals // afterwards. @@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeKind::Root { result } | inspect::ProbeKind::TryNormalizeNonRigid { result } | inspect::ProbeKind::TraitCandidate { source: _, result } - | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => { + | inspect::ProbeKind::OpaqueTypeStorageLookup { result } + | inspect::ProbeKind::RigidAlias { result } => { // We only add a candidate if `shallow_certainty` was set, which means // that we ended up calling `evaluate_added_goals_and_make_canonical_response`. if let Some(shallow_certainty) = shallow_certainty { diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index 257fd263b9447..1661852903c48 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -177,7 +177,8 @@ fn to_selection<'tcx>( | ProbeKind::UpcastProjectionCompatibility | ProbeKind::OpaqueTypeStorageLookup { result: _ } | ProbeKind::Root { result: _ } - | ProbeKind::ShadowedEnvProbing => { + | ProbeKind::ShadowedEnvProbing + | ProbeKind::RigidAlias { result: _ } => { span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind()) } }) diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index 099c66f6bdc81..138ba8bac8871 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -135,4 +135,6 @@ pub enum ProbeKind { ShadowedEnvProbing, /// Try to unify an opaque type with an existing key in the storage. OpaqueTypeStorageLookup { result: QueryResult }, + /// Checking that a rigid alias is well-formed. + RigidAlias { result: QueryResult }, } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a0f7658212f4b..f02c7a3207193 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -130,6 +130,10 @@ pub enum GoalSource { ImplWhereBound, /// Instantiating a higher-ranked goal and re-proving it. InstantiateHigherRanked, + /// Predicate required for an alias projection to be well-formed. + /// This is used in two places: projecting to an opaque whose hidden type + /// is already registered in the opaque type storage, and for rigid projections. + AliasWellFormed, } #[derive_where(Clone; I: Interner, Goal: Clone)] diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index 4523fc3e037e8..010f51df15ad3 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -31,18 +31,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` - --> $DIR/defaults-unsound-62211-1.rs:24:96 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ types differ - | -note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:24:31 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` - error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:24:96 | @@ -50,10 +38,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:24:25 + --> $DIR/defaults-unsound-62211-1.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -75,7 +63,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index 7a68f1ac8cc47..9347894657078 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -31,18 +31,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` - --> $DIR/defaults-unsound-62211-2.rs:24:96 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ types differ - | -note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:24:31 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` - error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:24:96 | @@ -50,10 +38,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:24:25 + --> $DIR/defaults-unsound-62211-2.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -75,7 +63,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr index 0866ed054514b..5e2fa551afe30 100644 --- a/tests/ui/associated-types/issue-54108.next.stderr +++ b/tests/ui/associated-types/issue-54108.next.stderr @@ -1,15 +1,3 @@ -error[E0271]: type mismatch resolving `<::ActualSize as Add>::Output normalizes-to <::ActualSize as Add>::Output` - --> $DIR/issue-54108.rs:23:17 - | -LL | type Size = ::ActualSize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - | -note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:20 - | -LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` - error[E0277]: cannot add `::ActualSize` to `::ActualSize` --> $DIR/issue-54108.rs:23:17 | @@ -18,16 +6,15 @@ LL | type Size = ::ActualSize; | = help: the trait `Add` is not implemented for `::ActualSize` note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:16 + --> $DIR/issue-54108.rs:8:20 | LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` help: consider further restricting the associated type | LL | T: SubEncoder, ::ActualSize: Add | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 647dc84028c33..5c56e64a01727 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -4,12 +4,7 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } - //[current]~^ ERROR `dyn Iterator` is not an iterator - //[next]~^^ ERROR `dyn Iterator` is not an iterator - //[next]~| ERROR type ` as IntoIterator>::Item` cannot be dereferenced - - // FIXME(-Znext-solver): these error messages are horrible and have to be - // improved before we stabilize the new solver. + //~^ ERROR `dyn Iterator` is not an iterator } fn main() {} diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr index bc57874bf850a..d624fb1e42b6f 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + --> $DIR/ambig-hr-projection-issue-93340.rs:17:5 | LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` @@ -15,14 +15,16 @@ help: consider specifying the generic arguments LL | cmp_eq:: | +++++++++++ -error[E0271]: type mismatch resolving `build_expression::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(::RefType<'_>, ::RefType<'_>)` closure, found `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` --> $DIR/ambig-hr-projection-issue-93340.rs:14:1 | LL | / fn build_expression( LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { - | |_________________________________________________^ types differ + | |_________________________________________________^ expected an `Fn(::RefType<'_>, ::RefType<'_>)` closure, found `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` + | + = help: the trait `for<'a, 'b> Fn(::RefType<'a>, ::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0283. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0283. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr index d913b2e91ca0e..4a293d44e0e3d 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + --> $DIR/ambig-hr-projection-issue-93340.rs:17:5 | LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs index acfebad38db0c..5f2e134109e22 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs @@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT fn build_expression( ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + //[next]~^^ expected a `Fn(::RefType<'_>, ::RefType<'_>)` closure cmp_eq //~^ ERROR type annotations needed } diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs index 5a6bf9bfaef24..351cdad4ee115 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs @@ -14,6 +14,8 @@ struct W(T); // `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still // encounter weak types in `assemble_alias_bound_candidates_recur`. fn hello(_: W>) {} -//~^ ERROR the size for values of type `A` cannot be known at compilation time +//~^ ERROR the trait bound `usize: Foo` is not satisfied +//~| ERROR the trait bound `usize: Foo` is not satisfied +//~| ERROR the trait bound `usize: Foo` is not satisfied fn main() {} diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index cab6163803a4e..79581066a3a32 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -7,32 +7,42 @@ LL | #![feature(lazy_type_alias)] = note: see issue #112792 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:13 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^ types differ - -error[E0271]: type mismatch resolving `A normalizes-to _` - --> $DIR/alias-bounds-when-not-wf.rs:16:10 + | ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` | -LL | fn hello(_: W>) {} - | ^ types differ +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:10 | LL | fn hello(_: W>) {} - | ^ types differ + | ^ the trait `Foo` is not implemented for `usize` | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:1 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` + | +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 5aa6931d371e2..8eacfd3e44d40 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,15 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:13:9 + --> $DIR/method-resolution4.rs:14:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:13:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ types differ - error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time --> $DIR/method-resolution4.rs:11:20 | @@ -19,14 +13,8 @@ LL | fn foo(b: bool) -> impl Iterator { = help: the trait `Sized` is not implemented for `impl Iterator` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:16:5 - | -LL | std::iter::empty() - | ^^^^^^^^^^^^^^^^^^ types differ - error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:13:9 + --> $DIR/method-resolution4.rs:14:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -34,21 +22,7 @@ LL | foo(false).next().unwrap(); = help: the trait `Sized` is not implemented for `impl Iterator` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:13:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:11:1 - | -LL | fn foo(b: bool) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - -error: aborting due to 7 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0277, E0282. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0282. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 91884eb59fd63..8eeedf04cbeb1 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -9,12 +9,13 @@ //@[current] check-pass fn foo(b: bool) -> impl Iterator { + //[next]~^ ERROR the size for values of type `impl Iterator` cannot be known at compilation time if b { foo(false).next().unwrap(); //[next]~^ type annotations needed + //[next]~| ERROR the size for values of type `impl Iterator` cannot be known at compilation time } std::iter::empty() - //[next]~^ mismatched types } fn main() {} diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index 5feef0b44b53b..b38850c9214e4 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,9 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:15:23 + --> $DIR/recursive-coroutine-boxed.rs:16:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` -LL | +... LL | let mut r = gen.as_mut().resume(()); | ------ type must be known at this point | @@ -12,25 +12,6 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:14:18 - | -LL | #[coroutine] || { - | __________________^ -LL | | let mut gen = Box::pin(foo()); -LL | | -LL | | let mut r = gen.as_mut().resume(()); -... | -LL | | } -LL | | } - | |_____^ types differ - -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:15:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ types differ - error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time --> $DIR/recursive-coroutine-boxed.rs:9:13 | @@ -40,23 +21,8 @@ LL | fn foo() -> impl Coroutine { = help: the trait `Sized` is not implemented for `impl Coroutine` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:14:18 - | -LL | #[coroutine] || { - | __________________^ -LL | | let mut gen = Box::pin(foo()); -LL | | -LL | | let mut r = gen.as_mut().resume(()); -... | -LL | | } -LL | | } - | |_____^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:15:32 + --> $DIR/recursive-coroutine-boxed.rs:16:32 | LL | let mut gen = Box::pin(foo()); | ^^^^^ doesn't have a size known at compile-time @@ -64,21 +30,7 @@ LL | let mut gen = Box::pin(foo()); = help: the trait `Sized` is not implemented for `impl Coroutine` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:15:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:9:1 - | -LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - -error: aborting due to 8 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0277, E0282. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0282. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 24a77d7311419..8e670dd78ecb5 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -7,13 +7,15 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { + //[next]~^ ERROR the size for values of type `impl Coroutine` cannot be known at compilation time + // FIXME(-Znext-solver): this fails with a mismatched types as the // hidden type of the opaque ends up as {type error}. We should not // emit errors for such goals. - - #[coroutine] || { //[next]~ ERROR mismatched types + #[coroutine] || { let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed + //[next]~| ERROR the size for values of type `impl Coroutine` cannot be known at compilation time let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr index f31a2a806674b..4cebd26a5bee6 100644 --- a/tests/ui/impl-trait/unsized_coercion.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion.rs:14:17 +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/unsized_coercion.rs:15:17 | LL | let x = hello(); - | ^^^^^^^ types differ + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` error[E0308]: mismatched types - --> $DIR/unsized_coercion.rs:18:5 + --> $DIR/unsized_coercion.rs:19:5 | LL | fn hello() -> Box { | --------------- @@ -19,21 +21,15 @@ LL | Box::new(1u32) = note: expected struct `Box` found struct `Box` -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion.rs:14:17 - | -LL | let x = hello(); - | ^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time --> $DIR/unsized_coercion.rs:12:1 | LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0308. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs index 46e040c1428a4..b3791b38abc2d 100644 --- a/tests/ui/impl-trait/unsized_coercion.rs +++ b/tests/ui/impl-trait/unsized_coercion.rs @@ -10,9 +10,10 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { + //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time if true { let x = hello(); - //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait` + //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time let y: Box = x; } Box::new(1u32) //[next]~ ERROR: mismatched types diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index f5187a6256efa..d1e1809cf1656 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion3.rs:13:17 +error[E0277]: the trait bound `dyn Send: Trait` is not satisfied + --> $DIR/unsized_coercion3.rs:14:17 | LL | let x = hello(); - | ^^^^^^^ types differ + | ^^^^^^^ the trait `Trait` is not implemented for `dyn Send` + | + = help: the trait `Trait` is implemented for `u32` error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:18:5 + --> $DIR/unsized_coercion3.rs:19:5 | LL | fn hello() -> Box { | ------------------------ @@ -19,21 +21,15 @@ LL | Box::new(1u32) = note: expected struct `Box` found struct `Box` -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion3.rs:13:17 - | -LL | let x = hello(); - | ^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` +error[E0277]: the trait bound `dyn Send: Trait` is not satisfied --> $DIR/unsized_coercion3.rs:11:1 | LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send` + | + = help: the trait `Trait` is implemented for `u32` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0308. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr index 52a72b84a8dd6..3bb9f9c209510 100644 --- a/tests/ui/impl-trait/unsized_coercion3.old.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:15:32 + --> $DIR/unsized_coercion3.rs:16:32 | LL | let y: Box = x; | ^ doesn't have a size known at compile-time diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs index 7e862de2157d9..c1dd5350e229a 100644 --- a/tests/ui/impl-trait/unsized_coercion3.rs +++ b/tests/ui/impl-trait/unsized_coercion3.rs @@ -9,15 +9,15 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { + //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied if true { let x = hello(); - //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send` + //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied let y: Box = x; //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } Box::new(1u32) //[next]~^ ERROR: mismatched types - //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 35757f2339dbf..70cc47bb0225f 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -13,9 +13,17 @@ fn main() { } fn weird0() -> impl Sized + !Sized {} -//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()` +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird1() -> impl !Sized + Sized {} -//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()` +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird2() -> impl !Sized {} -//~^ ERROR type mismatch resolving `impl !Sized == ()` -//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 561bf8eee2283..366baf26dea94 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,14 +1,18 @@ -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 @@ -19,26 +23,32 @@ LL | fn weird0() -> impl Sized + !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized + Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:36 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:36 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -46,26 +56,32 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait `Sized` is not implemented for `impl !Sized + Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:1 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:1 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ types differ + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:28 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:28 | LL | fn weird2() -> impl !Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -73,11 +89,13 @@ LL | fn weird2() -> impl !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:1 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 @@ -95,5 +113,4 @@ LL | fn consume(_: impl Trait) {} error: aborting due to 13 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 9951826a8466d..3633e9f3f481c 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -3,6 +3,9 @@ #![feature(negative_bounds, unboxed_closures)] fn produce() -> impl !Fn<(u32,)> {} -//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()` +//~^ ERROR expected a `Fn(u32)` closure, found `()` +//~| ERROR expected a `Fn(u32)` closure, found `()` +//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time +//~| ERROR expected a `Fn(u32)` closure, found `()` fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index a7a83cf1d69cc..cdd89de0d888e 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,14 +1,18 @@ -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^ types differ + | ^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 @@ -19,13 +23,14 @@ LL | fn produce() -> impl !Fn<(u32,)> {} = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index b37dbc0e579eb..8c263e8644bd0 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -16,43 +16,6 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine` -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield` - --> $DIR/coroutine.rs:20:9 - | -LL | needs_coroutine( - | --------------- required by a bound introduced by this call -LL | #[coroutine] -LL | / || { -LL | | -LL | | yield (); -LL | | }, - | |_________^ types differ - | -note: required by a bound in `needs_coroutine` - --> $DIR/coroutine.rs:14:41 - | -LL | fn needs_coroutine(_: impl Coroutine) {} - | ^^^^^^^^^ required by this bound in `needs_coroutine` - -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return` - --> $DIR/coroutine.rs:20:9 - | -LL | needs_coroutine( - | --------------- required by a bound introduced by this call -LL | #[coroutine] -LL | / || { -LL | | -LL | | yield (); -LL | | }, - | |_________^ types differ - | -note: required by a bound in `needs_coroutine` - --> $DIR/coroutine.rs:14:52 - | -LL | fn needs_coroutine(_: impl Coroutine) {} - | ^^^^^^^^^^ required by this bound in `needs_coroutine` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr index dbd2880943c97..cd8d8b3ffcd38 100644 --- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr @@ -9,20 +9,6 @@ help: consider restricting type parameter `T` LL | fn test_poly() { | +++++++ -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:8:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^ types differ - -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:8:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0277]: the trait bound `i32: Trait` is not satisfied --> $DIR/projection-trait-ref.rs:13:12 | @@ -35,21 +21,6 @@ help: this trait has no implementations, consider adding one LL | trait Trait { | ^^^^^^^^^^^ -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:13:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^^^ types differ - -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:13:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs index a347984daf6a6..b53a6543c90a4 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.rs +++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs @@ -13,6 +13,7 @@ pub fn copy_any(t: &T) -> T { //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup` //~| ERROR mismatched types //~| ERROR the trait bound `T: Copy` is not satisfied + //~| ERROR the size for values of type ` as Setup>::From` cannot be known at compilation time // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index 0dee26d467271..00243fd905950 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -15,20 +15,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:20:16 - | -LL | require_fn(f as unsafe fn() -> i32); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}` --> $DIR/fn-trait.rs:22:16 | @@ -45,20 +31,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 {g} as FnOnce<()>>::Output normalizes-to i32 {g} as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:22:16 - | -LL | require_fn(g); - | ---------- ^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32` --> $DIR/fn-trait.rs:24:16 | @@ -75,20 +47,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:24:16 - | -LL | require_fn(g as extern "C" fn() -> i32); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}` --> $DIR/fn-trait.rs:26:16 | @@ -106,21 +64,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 {h} as FnOnce<()>>::Output normalizes-to i32 {h} as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:26:16 - | -LL | require_fn(h); - | ---------- ^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 9f6dea5d5bf86..e1bd234a275a6 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -17,7 +17,7 @@ type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} -//~^ ERROR conflicting implementations of trait `Overlap` for type `fn(_)` -//~| ERROR cannot find type `Missing` in this scope +//~^ ERROR cannot find type `Missing` in this scope +//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 82ec9e3a22f75..f6545c6ebf9de 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,13 +26,19 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _` +error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied --> $DIR/issue-118950-root-region.rs:19:17 | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-118950-root-region.rs:8:1 + | +LL | trait ToUnit<'a> { + | ^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0271, E0277, E0412. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0412. +For more information about an error, try `rustc --explain E0277`. 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 7bf3274f9c634..c4c2e695a1df5 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs @@ -15,7 +15,7 @@ trait Mirror { type Assoc: ?Sized; } impl Mirror for T { type Assoc = T; } trait MirrorRegion<'a> { type Assoc: ?Sized; } -impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; } +impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; } impl Foo for T { #[cfg(normalize_param_env)] diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index f953111aef025..2617ce124c105 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -4,21 +4,6 @@ error[E0282]: type annotations needed LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type -error[E0271]: type mismatch resolving `Tait normalizes-to _` - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 - | -LL | self.bar.next().unwrap(); - | ^^^^^^^^ types differ - -error[E0271]: type mismatch resolving `Tait normalizes-to _` - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 - | -LL | self.bar.next().unwrap(); - | ^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0271, E0282. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index 5c9a3b7c2d296..b6adf08853f2f 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -25,8 +25,6 @@ impl Foo { //[current]~^ ERROR: item does not constrain self.bar.next().unwrap(); //[next]~^ ERROR: type annotations needed - //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` - //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` } } diff --git a/tests/ui/typeck/issue-103899.rs b/tests/ui/typeck/issue-103899.rs index 38882e9dc54da..81ab92a8994c4 100644 --- a/tests/ui/typeck/issue-103899.rs +++ b/tests/ui/typeck/issue-103899.rs @@ -1,11 +1,9 @@ //@ revisions: current next -//@[next] compile-flags: -Znext-solver -//@[next] check-pass //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-fail -//@[current] failure-status: 101 -//@[current] dont-check-compiler-stderr -//@[current] known-bug: #103899 +//@ check-fail +//@ failure-status: 101 +//@ dont-check-compiler-stderr +//@ known-bug: #103899 trait BaseWithAssoc { type Assoc; From 0ead25c4a99242a526ef1076c52fa420c65b667a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 13:49:31 -0400 Subject: [PATCH 19/24] Register a dummy candidate for failed structural normalization during candiate assembly --- .../src/solve/assembly/mod.rs | 20 +++++++++ .../impl-trait/method-resolution4.next.stderr | 25 ++--------- tests/ui/impl-trait/method-resolution4.rs | 2 - .../recursive-coroutine-boxed.next.stderr | 27 ++---------- .../impl-trait/recursive-coroutine-boxed.rs | 3 -- .../opaque-type-unsatisfied-bound.rs | 3 -- .../opaque-type-unsatisfied-bound.stderr | 41 ++++--------------- .../opaque-type-unsatisfied-fn-bound.rs | 1 - .../opaque-type-unsatisfied-fn-bound.stderr | 11 +---- .../traits/next-solver/dyn-incompatibility.rs | 1 - .../next-solver/dyn-incompatibility.stderr | 15 +------ 11 files changed, 36 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index cebeef76bfc03..c9c0d6391fc81 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -6,6 +6,7 @@ use derive_where::derive_where; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::inspect; use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate}; use tracing::{debug, instrument}; @@ -288,6 +289,25 @@ where let Ok(normalized_self_ty) = self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty()) else { + // FIXME: We register a fake candidate when normalization fails so that + // we can point at the reason for *why*. I'm tempted to say that this + // is the wrong way to do this, though. + let result = + self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| { + let normalized_ty = this.next_ty_infer(); + let alias_relate_goal = Goal::new( + this.cx(), + goal.param_env, + ty::PredicateKind::AliasRelate( + goal.predicate.self_ty().into(), + normalized_ty.into(), + ty::AliasRelationDirection::Equate, + ), + ); + this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal); + this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + }); + assert_eq!(result, Err(NoSolution)); return vec![]; }; diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 8eacfd3e44d40..0524f49f98e58 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,28 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:14:9 + --> $DIR/method-resolution4.rs:13:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:11:20 - | -LL | fn foo(b: bool) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Iterator` - = note: the return type of a function must have a statically known size - -error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:14:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Iterator` - = note: the return type of a function must have a statically known size - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0282. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 8eeedf04cbeb1..5c8813ed79224 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -9,11 +9,9 @@ //@[current] check-pass fn foo(b: bool) -> impl Iterator { - //[next]~^ ERROR the size for values of type `impl Iterator` cannot be known at compilation time if b { foo(false).next().unwrap(); //[next]~^ type annotations needed - //[next]~| ERROR the size for values of type `impl Iterator` cannot be known at compilation time } std::iter::empty() } diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index b38850c9214e4..132f7de4ef230 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,9 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:16:23 + --> $DIR/recursive-coroutine-boxed.rs:14:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` -... +LL | LL | let mut r = gen.as_mut().resume(()); | ------ type must be known at this point | @@ -12,25 +12,6 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:9:13 - | -LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Coroutine` - = note: the return type of a function must have a statically known size - -error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:16:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Coroutine` - = note: the return type of a function must have a statically known size - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0282. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 8e670dd78ecb5..8d38e6aed1246 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -7,15 +7,12 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { - //[next]~^ ERROR the size for values of type `impl Coroutine` cannot be known at compilation time - // FIXME(-Znext-solver): this fails with a mismatched types as the // hidden type of the opaque ends up as {type error}. We should not // emit errors for such goals. #[coroutine] || { let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed - //[next]~| ERROR the size for values of type `impl Coroutine` cannot be known at compilation time let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 70cc47bb0225f..25034b67e35b8 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -15,15 +15,12 @@ fn main() { fn weird0() -> impl Sized + !Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird1() -> impl !Sized + Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird2() -> impl !Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 366baf26dea94..3e803a1c24fa3 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -14,15 +14,6 @@ LL | fn weird0() -> impl Sized + !Sized {} | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 - | -LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized + Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | @@ -32,7 +23,7 @@ LL | fn weird0() -> impl Sized + !Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -40,24 +31,15 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:36 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:36 | LL | fn weird1() -> impl !Sized + Sized {} | ^^ doesn't have a size known at compile-time | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 - | -LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized + Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:1 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -65,7 +47,7 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -73,24 +55,15 @@ LL | fn weird2() -> impl !Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:28 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:28 | LL | fn weird2() -> impl !Sized {} | ^^ doesn't have a size known at compile-time | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 - | -LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:1 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:1 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -111,6 +84,6 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 13 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 3633e9f3f481c..7538e3c0d2bba 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -5,7 +5,6 @@ fn produce() -> impl !Fn<(u32,)> {} //~^ ERROR expected a `Fn(u32)` closure, found `()` //~| ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time //~| ERROR expected a `Fn(u32)` closure, found `()` fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index cdd89de0d888e..57a423741b394 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -14,15 +14,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {} | = help: the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 - | -LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` - = note: the return type of a function must have a statically known size - error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | @@ -31,6 +22,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {} | = help: the trait bound `(): !Fn(u32)` is not satisfied -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs index b53a6543c90a4..a347984daf6a6 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.rs +++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs @@ -13,7 +13,6 @@ pub fn copy_any(t: &T) -> T { //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup` //~| ERROR mismatched types //~| ERROR the trait bound `T: Copy` is not satisfied - //~| ERROR the size for values of type ` as Setup>::From` cannot be known at compilation time // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr index adf46686e081a..7f2c0646ef501 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr +++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr @@ -43,20 +43,7 @@ help: consider restricting type parameter `T` LL | pub fn copy_any(t: &T) -> T { | +++++++++++++++++++ -error[E0277]: the size for values of type ` as Setup>::From` cannot be known at compilation time - --> $DIR/dyn-incompatibility.rs:12:5 - | -LL | copy::>(t) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for ` as Setup>::From` - = note: the return type of a function must have a statically known size -help: consider further restricting the associated type - | -LL | pub fn copy_any(t: &T) -> T where as Setup>::From: Sized { - | +++++++++++++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. From f956dc2e779ae5ca14c882998d308609648025e9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 20:38:43 -0400 Subject: [PATCH 20/24] Bless tests --- .../structually-relate-aliases.rs | 3 +- .../structually-relate-aliases.stderr | 32 ++++++----- .../opaque-type-unsatisfied-bound.rs | 18 +++---- .../opaque-type-unsatisfied-bound.stderr | 54 +++++++------------ .../opaque-type-unsatisfied-fn-bound.rs | 6 +-- .../opaque-type-unsatisfied-fn-bound.stderr | 18 +++---- 6 files changed, 58 insertions(+), 73 deletions(-) diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs index 6988245096136..73c2cd23d86e3 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.rs +++ b/tests/ui/higher-ranked/structually-relate-aliases.rs @@ -11,6 +11,7 @@ type Assoc<'a, T> = >::Unit; impl Overlap for T {} impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} -//~^ ERROR conflicting implementations of trait `Overlap fn(&'a (), _)>` +//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied +//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 4ecd5829bc352..e9d91e45e217b 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,18 +1,26 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. } -error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` - --> $DIR/structually-relate-aliases.rs:13:1 +error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied + --> $DIR/structually-relate-aliases.rs:13:36 | -LL | impl Overlap for T {} - | ------------------------ first implementation here -LL | LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)` + | ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ++++++++++++++++++++ + +error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied + --> $DIR/structually-relate-aliases.rs:13:17 + | +LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` + | +help: consider restricting type parameter `T` | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details +LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ++++++++++++++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 25034b67e35b8..1260cca510680 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -13,14 +13,14 @@ fn main() { } fn weird0() -> impl Sized + !Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird1() -> impl !Sized + Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird2() -> impl !Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 3e803a1c24fa3..4ec578a3b7bc2 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,74 +1,56 @@ -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:36 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:16 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:28 | LL | fn weird2() -> impl !Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:1 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 7538e3c0d2bba..c6826578658fd 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -3,8 +3,8 @@ #![feature(negative_bounds, unboxed_closures)] fn produce() -> impl !Fn<(u32,)> {} -//~^ ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR expected a `Fn(u32)` closure, found `()` +//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied +//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied +//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index 57a423741b394..f81f0a23ac315 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,26 +1,20 @@ -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^ the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied error: aborting due to 3 previous errors From b4e9aad137800936b4fbc3c36da6ff2819b385b5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:20:41 -0400 Subject: [PATCH 21/24] Rename can_coerce to may_coerce --- compiler/rustc_hir_typeck/src/_match.rs | 4 +-- compiler/rustc_hir_typeck/src/cast.rs | 8 ++--- compiler/rustc_hir_typeck/src/coercion.rs | 17 ++++++---- compiler/rustc_hir_typeck/src/expr.rs | 10 +++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 10 +++--- .../src/fn_ctxt/suggestions.rs | 34 +++++++++---------- .../rustc_hir_typeck/src/method/suggest.rs | 4 +-- compiler/rustc_hir_typeck/src/pat.rs | 2 +- 8 files changed, 46 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 0d9d1910ae0c1..e68caa3e2e35e 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -235,8 +235,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ret_coercion) => { let ret_ty = ret_coercion.borrow().expected_ty(); let ret_ty = self.infcx.shallow_resolve(ret_ty); - self.can_coerce(arm_ty, ret_ty) - && prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty)) + self.may_coerce(arm_ty, ret_ty) + && prior_arm.is_none_or(|(_, ty, _)| self.may_coerce(ty, ret_ty)) // The match arms need to unify for the case of `impl Trait`. && !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..)) } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 407191661a4b3..8fa6ab8503d08 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let mut sugg_mutref = false; if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() { if let ty::RawPtr(expr_ty, _) = *self.expr_ty.kind() - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, expr_ty, mutbl), self.cast_ty, ) @@ -418,14 +418,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() && expr_mutbl == Mutability::Not && mutbl == Mutability::Mut - && fcx.can_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty) + && fcx.may_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty) { sugg_mutref = true; } if !sugg_mutref && sugg == None - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, reg, self.expr_ty, mutbl), self.cast_ty, ) @@ -433,7 +433,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } } else if let ty::RawPtr(_, mutbl) = *self.cast_ty.kind() - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, self.expr_ty, mutbl), self.cast_ty, ) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bd0b98702983a..a6df9e45db506 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1083,21 +1083,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - /// Same as `coerce()`, but without side-effects. + /// Probe whether `expr_ty` can be coerced to `target_ty`. This has no side-effects, + /// and may return false positives if types are not yet fully constrained by inference. /// - /// Returns false if the coercion creates any obligations that result in - /// errors. - pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool { + /// Returns false if the coercion is not possible, or if the coercion creates any + /// sub-obligations that result in errors. + /// + /// This should only be used for diagnostics. + pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool { // FIXME(-Znext-solver): We need to structurally resolve both types here. let source = self.resolve_vars_with_obligations(expr_ty); - debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); + debug!("coercion::can_with_predicates({:?} -> {:?})", source, target_ty); let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); self.probe(|_| { - let Ok(ok) = coerce.coerce(source, target) else { + let Ok(ok) = coerce.coerce(source, target_ty) else { return false; }; let ocx = ObligationCtxt::new(self); @@ -1369,7 +1372,7 @@ pub fn can_coerce<'tcx>( ) -> bool { let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id); let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id); - fn_ctxt.can_coerce(ty, output_ty) + fn_ctxt.may_coerce(ty, output_ty) } /// CoerceMany encapsulates the pattern you should use when you have diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b310398a0f1ba..7bdd3c95ad181 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1330,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| { let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs()); let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs()); - self.can_coerce(rhs, lhs) + self.may_coerce(rhs, lhs) }; - let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) { + let (applicability, eq) = if self.may_coerce(rhs_ty, lhs_ty) { (Applicability::MachineApplicable, true) } else if refs_can_coerce(rhs_ty, lhs_ty) { // The lhs and rhs are likely missing some references in either side. Subsequent @@ -1349,7 +1349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let actual_lhs_ty = self.check_expr(rhs_expr); ( Applicability::MaybeIncorrect, - self.can_coerce(rhs_ty, actual_lhs_ty) + self.may_coerce(rhs_ty, actual_lhs_ty) || refs_can_coerce(rhs_ty, actual_lhs_ty), ) } else if let ExprKind::Binary( @@ -1363,7 +1363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let actual_rhs_ty = self.check_expr(lhs_expr); ( Applicability::MaybeIncorrect, - self.can_coerce(actual_rhs_ty, lhs_ty) + self.may_coerce(actual_rhs_ty, lhs_ty) || refs_can_coerce(actual_rhs_ty, lhs_ty), ) } else { @@ -1414,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ) .may_apply(); - if lhs_deref_ty_is_sized && self.can_coerce(rhs_ty, lhs_deref_ty) { + if lhs_deref_ty_is_sized && self.may_coerce(rhs_ty, lhs_deref_ty) { err.span_suggestion_verbose( lhs.span.shrink_to_lo(), "consider dereferencing here to assign to the mutably borrowed value", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index fa471647d02d0..660cbc29d4cd6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -658,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && fn_sig.inputs()[1..] .iter() .zip(input_types.iter()) - .all(|(expected, found)| self.can_coerce(*expected, *found)) + .all(|(expected, found)| self.may_coerce(*expected, *found)) && fn_sig.inputs()[1..].len() == input_types.len() { err.span_suggestion_verbose( @@ -722,7 +722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expectation = Expectation::rvalue_hint(self, expected_input_ty); let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty); - let can_coerce = self.can_coerce(arg_ty, coerced_ty); + let can_coerce = self.may_coerce(arg_ty, coerced_ty); if !can_coerce { return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts( ty::error::ExpectedFound::new(true, coerced_ty, arg_ty), @@ -802,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx + tys.len()), ), ) { - if !self.can_coerce(provided_ty, *expected_ty) { + if !self.may_coerce(provided_ty, *expected_ty) { satisfied = false; break; } @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all( |((expected_ty, _), (provided_ty, _))| { !provided_ty.references_error() - && self.can_coerce(*provided_ty, *expected_ty) + && self.may_coerce(*provided_ty, *expected_ty) }, ) }; @@ -2124,7 +2124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_ty = self.typeck_results.borrow().expr_ty(expr); let return_ty = fn_sig.output(); if !matches!(expr.kind, hir::ExprKind::Ret(..)) - && self.can_coerce(expr_ty, return_ty) + && self.may_coerce(expr_ty, return_ty) { found_semi = true; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3e9e53261562c..3f703c2fcf692 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -261,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind && let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) - && self.can_coerce(recv_ty, expected) + && self.may_coerce(recv_ty, expected) && let name = method.name.as_str() && (name.starts_with("to_") || name.starts_with("as_") || name == "into") { @@ -349,7 +349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return true; } - if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected)) + if self.suggest_fn_call(err, expr, found, |output| self.may_coerce(output, expected)) && let ty::FnDef(def_id, ..) = *found.kind() && let Some(sp) = self.tcx.hir().span_if_local(def_id) { @@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() { return false; } - if self.can_coerce(Ty::new_box(self.tcx, found), expected) { + if self.may_coerce(Ty::new_box(self.tcx, found), expected) { let suggest_boxing = match found.kind() { ty::Tuple(tuple) if tuple.is_empty() => { errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span } @@ -663,7 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; match expected.kind() { ty::Adt(def, _) if Some(def.did()) == pin_did => { - if self.can_coerce(pin_box_found, expected) { + if self.may_coerce(pin_box_found, expected) { debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected); match found.kind() { ty::Adt(def, _) if def.is_box() => { @@ -689,7 +689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } true - } else if self.can_coerce(pin_found, expected) { + } else if self.may_coerce(pin_found, expected) { match found.kind() { ty::Adt(def, _) if def.is_box() => { err.help("use `Box::pin`"); @@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } } - ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => { + ty::Adt(def, _) if def.is_box() && self.may_coerce(box_found, expected) => { // Check if the parent expression is a call to Pin::new. If it // is and we were expecting a Box, ergo Pin>, we // can suggest Box::pin. @@ -884,7 +884,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = Binder::bind_with_vars(ty, bound_vars); let ty = self.normalize(hir_ty.span, ty); let ty = self.tcx.instantiate_bound_regions_with_erased(ty); - if self.can_coerce(expected, ty) { + if self.may_coerce(expected, ty) { err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected, @@ -1141,12 +1141,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Asyncness::No => ty, }; let ty = self.normalize(expr.span, ty); - self.can_coerce(found, ty) + self.may_coerce(found, ty) } hir::FnRetTy::DefaultReturn(_) if in_closure => { self.ret_coercion.as_ref().map_or(false, |ret| { let ret_ty = ret.borrow().expected_ty(); - self.can_coerce(found, ret_ty) + self.may_coerce(found, ret_ty) }) } _ => false, @@ -1510,7 +1510,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { provided_ty }; - if !self.can_coerce(expected_ty, dummy_ty) { + if !self.may_coerce(expected_ty, dummy_ty) { return; } let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`"); @@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, ) { if let ty::Slice(elem_ty) | ty::Array(elem_ty, _) = expected_ty.kind() { - if self.can_coerce(blk_ty, *elem_ty) + if self.may_coerce(blk_ty, *elem_ty) && blk.stmts.is_empty() && blk.rules == hir::BlockCheckMode::DefaultBlock { @@ -1744,7 +1744,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if item_ty.has_param() { return false; } - if self.can_coerce(item_ty, expected_ty) { + if self.may_coerce(item_ty, expected_ty) { err.span_suggestion_verbose( segment.ident.span, format!("try referring to the associated const `{capitalized_name}` instead",), @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // diagnostic in cases where we have `(&&T).clone()` and we expect `T`). && !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..))) // Check that we're in fact trying to clone into the expected type - && self.can_coerce(*pointee_ty, expected_ty) + && self.may_coerce(*pointee_ty, expected_ty) && let trait_ref = ty::TraitRef::new(self.tcx, clone_trait_did, [expected_ty]) // And the expected type doesn't implement `Clone` && !self.predicate_must_hold_considering_regions(&traits::Obligation::new( @@ -2022,7 +2022,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { return false; }; - if is_ctor || !self.can_coerce(args.type_at(0), expected) { + if is_ctor || !self.may_coerce(args.type_at(0), expected) { return false; } @@ -2293,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .then(|| " (its field is private, but it's local to this crate and its privacy can be changed)".to_string()); let sole_field_ty = sole_field.ty(self.tcx, args); - if self.can_coerce(expr_ty, sole_field_ty) { + if self.may_coerce(expr_ty, sole_field_ty) { let variant_path = with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); // FIXME #56861: DRYer prelude filtering @@ -2401,7 +2401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let int_type = args.type_at(0); - if !self.can_coerce(expr_ty, int_type) { + if !self.may_coerce(expr_ty, int_type) { return false; } @@ -2585,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, checked_ty) } }; - if self.can_coerce(ref_ty, expected) { + if self.may_coerce(ref_ty, expected) { let mut sugg_sp = sp; if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind { let clone_trait = diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7f68e19a31392..9dd5954114860 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1934,7 +1934,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && fn_sig.inputs()[1..] .iter() .zip(args.into_iter()) - .all(|(expected, found)| self.can_coerce(*expected, *found)) + .all(|(expected, found)| self.may_coerce(*expected, *found)) && fn_sig.inputs()[1..].len() == args.len() { err.span_suggestion_verbose( @@ -4148,7 +4148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; }; - if !self.can_coerce(output, expected) { + if !self.may_coerce(output, expected) { return false; } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index fb78da0a86c66..5ce9bae81c1c9 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1767,7 +1767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if inexistent_fields.len() == 1 { match pat_field.pat.kind { PatKind::Lit(expr) - if !self.can_coerce( + if !self.may_coerce( self.typeck_results.borrow().expr_ty(expr), self.field_ty(field.span, field_def, args), ) => {} From e3eba2d9204e9af2ac7a089f61996b25cfecf2d8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:26:56 -0400 Subject: [PATCH 22/24] Don't structurally resolve in may_coerce --- compiler/rustc_hir_typeck/src/coercion.rs | 6 +---- .../lazy_subtyping_of_opaques.stderr | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index a6df9e45db506..bb2f1f0493a7e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1091,16 +1091,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// This should only be used for diagnostics. pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool { - // FIXME(-Znext-solver): We need to structurally resolve both types here. - let source = self.resolve_vars_with_obligations(expr_ty); - debug!("coercion::can_with_predicates({:?} -> {:?})", source, target_ty); - let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); self.probe(|_| { - let Ok(ok) = coerce.coerce(source, target_ty) else { + let Ok(ok) = coerce.coerce(expr_ty, target_ty) else { return false; }; let ocx = ObligationCtxt::new(self); diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr index 7bc2fa1b09ea6..921667f577b4e 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr @@ -1,3 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/lazy_subtyping_of_opaques.rs:11:5 + | +LL | fn reify_as_tait() -> Thunk { + | ----------- expected `Thunk<_>` because of return type +LL | +LL | Thunk::new(|cont| cont) + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` + | + = note: expected struct `Thunk<_>` + found unit type `()` + error[E0277]: expected a `FnOnce()` closure, found `()` --> $DIR/lazy_subtyping_of_opaques.rs:11:23 | @@ -12,19 +24,13 @@ error[E0277]: expected a `FnOnce()` closure, found `()` | LL | fn reify_as_tait() -> Thunk { | ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()` +LL | +LL | Thunk::new(|cont| cont) + | ----------------------- return type was inferred to be `{type error}` here | = help: the trait `FnOnce()` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` -error[E0308]: mismatched types - --> $DIR/lazy_subtyping_of_opaques.rs:11:5 - | -LL | Thunk::new(|cont| cont) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` - | - = note: expected struct `Thunk<_>` - found unit type `()` - error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. From 9070abab4b6862e42a8ce25eeb4a810301b76dd7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:47:43 -0400 Subject: [PATCH 23/24] Structurally resolve in may_coerce --- compiler/rustc_hir_typeck/src/coercion.rs | 23 +++++++++++++++++-- .../diagnostics/coerce-in-may-coerce.rs | 19 +++++++++++++++ .../diagnostics/coerce-in-may-coerce.stderr | 21 +++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs create mode 100644 tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bb2f1f0493a7e..fb9262a59b9c9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1094,12 +1094,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. - let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); + let coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No, true); self.probe(|_| { + // Make sure to structurally resolve the types, since we use + // the `TyKind`s heavily in coercion. + let ocx = ObligationCtxt::new(self); + let structurally_resolve = |ty| { + let ty = self.shallow_resolve(ty); + if self.next_trait_solver() + && let ty::Alias(..) = ty.kind() + { + ocx.structurally_normalize(&cause, self.param_env, ty) + } else { + Ok(ty) + } + }; + let Ok(expr_ty) = structurally_resolve(expr_ty) else { + return false; + }; + let Ok(target_ty) = structurally_resolve(target_ty) else { + return false; + }; + let Ok(ok) = coerce.coerce(expr_ty, target_ty) else { return false; }; - let ocx = ObligationCtxt::new(self); ocx.register_obligations(ok.obligations); ocx.select_where_possible().is_empty() }) diff --git a/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs new file mode 100644 index 0000000000000..bd3dccad15280 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Znext-solver + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +fn arg() -> &'static [i32; 1] { todo!() } + +fn arg_error(x: ::Assoc, y: ()) { todo!() } + +fn main() { + // Should suggest to reverse the args... + // but if we don't normalize the expected, then we don't. + arg_error((), || ()); + //~^ ERROR arguments to this function are incorrect +} diff --git a/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr new file mode 100644 index 0000000000000..1938b3375a51a --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr @@ -0,0 +1,21 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/coerce-in-may-coerce.rs:17:5 + | +LL | arg_error((), || ()); + | ^^^^^^^^^ -- ----- expected `()`, found `{closure@$DIR/coerce-in-may-coerce.rs:17:19: 17:21}` + | | + | expected `::Assoc`, found `()` + | +note: function defined here + --> $DIR/coerce-in-may-coerce.rs:12:4 + | +LL | fn arg_error(x: ::Assoc, y: ()) { todo!() } + | ^^^^^^^^^ -------------------------- ----- +help: swap these arguments + | +LL | arg_error(|| (), ()); + | ~~~~~~~~~~~ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From c7730989de17b0cbdc1d48481062745d31d5c5a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 28 Sep 2024 13:21:39 -0400 Subject: [PATCH 24/24] Don't check unsize goal in MIR validation when opaques remain --- compiler/rustc_mir_transform/src/validate.rs | 11 +++++++++++ tests/crashes/130921.rs | 10 ---------- tests/ui/impl-trait/unsize-cast-validation-rpit.rs | 12 ++++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/130921.rs create mode 100644 tests/ui/impl-trait/unsize-cast-validation-rpit.rs diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index e353be6a105f0..25e68f44456b8 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -595,6 +595,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &self, pred: impl Upcast, ty::Predicate<'tcx>>, ) -> bool { + let pred: ty::Predicate<'tcx> = pred.upcast(self.tcx); + + // We sometimes have to use `defining_opaque_types` for predicates + // to succeed here and figuring out how exactly that should work + // is annoying. It is harmless enough to just not validate anything + // in that case. We still check this after analysis as all opaque + // types have been revealed at this point. + if pred.has_opaque_types() { + return true; + } + let infcx = self.tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( diff --git a/tests/crashes/130921.rs b/tests/crashes/130921.rs deleted file mode 100644 index b7cb1303937e6..0000000000000 --- a/tests/crashes/130921.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #130921 -//@ compile-flags: -Zvalidate-mir -Copt-level=0 --crate-type lib - -pub fn hello() -> [impl Sized; 2] { - if false { - let x = hello(); - let _: &[i32] = &x; - } - todo!() -} diff --git a/tests/ui/impl-trait/unsize-cast-validation-rpit.rs b/tests/ui/impl-trait/unsize-cast-validation-rpit.rs new file mode 100644 index 0000000000000..cace30aca8a6d --- /dev/null +++ b/tests/ui/impl-trait/unsize-cast-validation-rpit.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: -Zvalidate-mir + +fn hello() -> &'static [impl Sized; 0] { + if false { + let x = hello(); + let _: &[i32] = x; + } + &[] +} + +fn main() {}