diff --git a/.mailmap b/.mailmap index 17232083679c5..c29f6a66f5d7d 100644 --- a/.mailmap +++ b/.mailmap @@ -258,11 +258,11 @@ Greg V Gregor Peach Grzegorz Bartoszek Guanqun Lu -Guillaume Gomez -Guillaume Gomez ggomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez Guillaume Gomez +Guillaume Gomez +Guillaume Gomez Guillaume Gomez +Guillaume Gomez ggomez +Guillaume Gomez Guillaume Gomez +Guillaume Gomez Guillaume Gomez gnzlbg hamidreza kalbasi Hanna Kruppe diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 239daecd3d1fb..07593a361ef86 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,13 +1,16 @@ use std::mem; +use std::sync::Arc; use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::steal::Steal; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; +use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId, LocalDefIdMap}; +use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::{ self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, }; @@ -48,11 +51,21 @@ impl<'hir> Owners<'_, 'hir> { } } +/// Default disambiguators are used during default lowering, when we lower +/// AST owners in a loop we can use the whole map, in contrast delayed lowering +/// lowers each AST owner separately, so we use readonly disambiguators map +/// with `Steal`s to get disambiguators. +pub(super) enum Disambiguators { + Default(LocalDefIdMap), + Delayed(Arc>>), +} + pub(super) struct ItemLowerer<'a, 'hir, R> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'a mut R, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: Owners<'a, 'hir>, + pub(super) disambiguators: &'a mut Disambiguators, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -80,7 +93,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> ItemLowerer<'_, 'hir, R> { owner: NodeId, f: impl FnOnce(&mut LoweringContext<'_, 'hir, R>) -> hir::OwnerNode<'hir>, ) { - let mut lctx = LoweringContext::new(self.tcx, self.resolver); + let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.disambiguators); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); for (def_id, info) in lctx.children { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2ffb9c123b5f8..bf773301ed4b5 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -70,7 +70,7 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; -use crate::item::Owners; +use crate::item::{Disambiguators, Owners}; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -94,7 +94,8 @@ pub mod stability; struct LoweringContext<'a, 'hir, R> { tcx: TyCtxt<'hir>, resolver: &'a mut R, - disambiguator: PerParentDisambiguatorState, + disambiguators: &'a mut Disambiguators, + current_disambiguator: PerParentDisambiguatorState, /// Used to allocate HIR nodes. arena: &'hir hir::Arena<'hir>, @@ -154,12 +155,13 @@ struct LoweringContext<'a, 'hir, R> { } impl<'a, 'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'a, 'hir, R> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a mut R) -> Self { + fn new(tcx: TyCtxt<'hir>, resolver: &'a mut R, disambiguators: &'a mut Disambiguators) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { tcx, resolver, - disambiguator: Default::default(), + disambiguators, + current_disambiguator: Default::default(), arena: tcx.hir_arena, // HirId handling. @@ -302,10 +304,6 @@ impl<'a, 'tcx> ResolverAstLoweringExt<'tcx> for ResolverDelayedAstLowering<'a, ' fn next_node_id(&mut self) -> NodeId { next_node_id(&mut self.next_node_id) } - - fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState { - self.base.steal_or_create_disambiguator(parent) - } } fn next_node_id(current_id: &mut NodeId) -> NodeId { @@ -408,10 +406,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { fn next_node_id(&mut self) -> NodeId { next_node_id(&mut self.next_node_id) } - - fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState { - self.per_parent_disambiguators.get(&parent).map(|s| s.steal()).unwrap_or_default() - } } /// How relaxed bounds `?Trait` should be treated. @@ -632,11 +626,13 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { tcx.definitions_untracked().def_index_count(), ); + let mut disambiguators = Disambiguators::Default(resolver.disambiguators.steal()); let mut lowerer = item::ItemLowerer { tcx, resolver: &mut resolver, ast_index: &ast_index, owners: Owners::IndexVec(&mut owners), + disambiguators: &mut disambiguators, }; let mut delayed_ids: FxIndexSet = Default::default(); @@ -655,7 +651,11 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let opt_hir_hash = if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; - let delayed_resolver = Steal::new((resolver, krate)); + let Disambiguators::Default(disambiguators) = disambiguators else { unreachable!() }; + let delayed_disambigs = + Arc::new(disambiguators.into_items().map(|(id, d)| (id, Steal::new(d))).collect()); + + let delayed_resolver = Steal::new((resolver, krate, delayed_disambigs)); mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) } @@ -663,7 +663,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { let krate = tcx.hir_crate(()); - let (resolver, krate) = &*krate.delayed_resolver.borrow(); + let (resolver, krate, delayed_disambigs) = &*krate.delayed_resolver.borrow(); // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, // as it is too bad to reindex whole crate on each delegation lowering. @@ -677,12 +677,12 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { }; let mut map = Default::default(); - let mut lowerer = item::ItemLowerer { tcx, resolver: &mut resolver, ast_index: &ast_index, owners: Owners::Map(&mut map), + disambiguators: &mut Disambiguators::Delayed(Arc::clone(delayed_disambigs)), }; lowerer.lower_node(def_id); @@ -740,7 +740,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let def_id = self .tcx .at(span) - .create_def(parent, name, def_kind, None, &mut self.disambiguator) + .create_def(parent, name, def_kind, None, &mut self.current_disambiguator) .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); @@ -780,9 +780,16 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>, ) { let owner_id = self.owner_id(owner); + let def_id = owner_id.def_id; + + let new_disambig = match &mut self.disambiguators { + Disambiguators::Default(map) => map.remove(&def_id), + Disambiguators::Delayed(map) => map.get(&def_id).map(Steal::steal), + }; + + let new_disambig = new_disambig.unwrap_or_else(|| PerParentDisambiguatorState::new(def_id)); - let new_disambig = self.resolver.steal_or_create_disambiguator(owner_id.def_id); - let disambiguator = std::mem::replace(&mut self.disambiguator, new_disambig); + let disambiguator = std::mem::replace(&mut self.current_disambiguator, new_disambig); let current_attrs = std::mem::take(&mut self.attrs); let current_bodies = std::mem::take(&mut self.bodies); let current_define_opaque = std::mem::take(&mut self.define_opaque); @@ -817,7 +824,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { assert!(self.impl_trait_bounds.is_empty()); let info = self.make_owner_info(item); - self.disambiguator = disambiguator; + self.current_disambiguator = disambiguator; self.attrs = current_attrs; self.bodies = current_bodies; self.define_opaque = current_define_opaque; diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index fed4ca7e76ab5..3739461c2004d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,10 +1,11 @@ +use rustc_errors::Diagnostic; use rustc_hir::attrs::{CrateType, WindowsSubsystemKind}; -use rustc_hir::lints::AttributeLintKind; use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES; use rustc_span::Symbol; use rustc_span::edit_distance::find_best_match_for_name; use super::prelude::*; +use crate::errors::{UnknownCrateTypes, UnknownCrateTypesSuggestion}; pub(crate) struct CrateNameParser; @@ -65,13 +66,17 @@ impl CombineAttributeParser for CrateTypeParser { crate_type, None, ); - cx.emit_lint( + let span = n.value_span; + cx.emit_dyn_lint( UNKNOWN_CRATE_TYPES, - AttributeLintKind::CrateTypeUnknown { - span: n.value_span, - suggested: candidate, + move |dcx, level| { + UnknownCrateTypes { + sugg: candidate + .map(|s| UnknownCrateTypesSuggestion { span, snippet: s }), + } + .into_diag(dcx, level) }, - n.value_span, + span, ); } return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs index 8cf6be088a7a5..bf811438db93f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs @@ -2,7 +2,6 @@ use rustc_errors::Diagnostic; use rustc_feature::{AttributeTemplate, template}; use rustc_hir::Target; use rustc_hir::attrs::AttributeKind; -use rustc_hir::lints::AttributeLintKind; use rustc_session::lint::builtin::{ MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, }; @@ -25,9 +24,9 @@ impl SingleAttributeParser for DoNotRecommendParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let attr_span = cx.attr_span; if !matches!(args, ArgParser::NoArgs) { - cx.emit_lint( + cx.emit_dyn_lint( MALFORMED_DIAGNOSTIC_ATTRIBUTES, - AttributeLintKind::DoNotRecommendDoesNotExpectArgs, + |dcx, level| crate::errors::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level), attr_span, ); } diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 09d474a227fb7..2b6d56c411939 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -14,8 +14,9 @@ use super::prelude::{ALL_TARGETS, AllowedTargets}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::errors::{ - DocAliasDuplicated, DocAutoCfgExpectsHideOrShow, DocAutoCfgHideShowExpectsList, - DocAutoCfgHideShowUnexpectedItem, DocAutoCfgWrongLiteral, DocUnknownAny, DocUnknownInclude, + AttrCrateLevelOnly, DocAliasDuplicated, DocAutoCfgExpectsHideOrShow, + DocAutoCfgHideShowExpectsList, DocAutoCfgHideShowUnexpectedItem, DocAutoCfgWrongLiteral, + DocTestLiteral, DocTestTakesList, DocTestUnknown, DocUnknownAny, DocUnknownInclude, DocUnknownPasses, DocUnknownPlugins, DocUnknownSpotlight, IllFormedAttributeInput, }; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser}; @@ -67,9 +68,9 @@ fn check_attr_not_crate_level( /// Checks that an attribute is used at the crate level. Returns `true` if valid. fn check_attr_crate_level(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool { if cx.shared.target != Target::Crate { - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::AttrCrateLevelOnly, + |dcx, level| AttrCrateLevelOnly.into_diag(dcx, level), span, ); return false; @@ -216,16 +217,16 @@ impl DocParser { } } Some(name) => { - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::DocTestUnknown { name }, + move |dcx, level| DocTestUnknown { name }.into_diag(dcx, level), path.span(), ); } None => { - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::DocTestLiteral, + |dcx, level| DocTestLiteral.into_diag(dcx, level), path.span(), ); } @@ -587,9 +588,9 @@ impl DocParser { Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args), Some(sym::test) => { let Some(list) = args.list() else { - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::DocTestTakesList, + |dcx, level| DocTestTakesList.into_diag(dcx, level), args.span().unwrap_or(path.span()), ); return; diff --git a/compiler/rustc_attr_parsing/src/errors.rs b/compiler/rustc_attr_parsing/src/errors.rs index 8e4dfb40ad868..96a4c473c3ae2 100644 --- a/compiler/rustc_attr_parsing/src/errors.rs +++ b/compiler/rustc_attr_parsing/src/errors.rs @@ -253,6 +253,46 @@ pub(crate) struct DocUnknownAny { #[diag("expected boolean for `#[doc(auto_cfg = ...)]`")] pub(crate) struct DocAutoCfgWrongLiteral; +#[derive(Diagnostic)] +#[diag("`#[doc(test(...)]` takes a list of attributes")] +pub(crate) struct DocTestTakesList; + +#[derive(Diagnostic)] +#[diag("unknown `doc(test)` attribute `{$name}`")] +pub(crate) struct DocTestUnknown { + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag("`#![doc(test(...)]` does not take a literal")] +pub(crate) struct DocTestLiteral; + +#[derive(Diagnostic)] +#[diag("this attribute can only be applied at the crate level")] +#[note( + "read for more information" +)] +pub(crate) struct AttrCrateLevelOnly; + +#[derive(Diagnostic)] +#[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] +pub(crate) struct DoNotRecommendDoesNotExpectArgs; + +#[derive(Diagnostic)] +#[diag("invalid `crate_type` value")] +pub(crate) struct UnknownCrateTypes { + #[subdiagnostic] + pub sugg: Option, +} + +#[derive(Subdiagnostic)] +#[suggestion("did you mean", code = r#""{snippet}""#, applicability = "maybe-incorrect")] +pub(crate) struct UnknownCrateTypesSuggestion { + #[primary_span] + pub span: Span, + pub snippet: Symbol, +} + #[derive(Diagnostic)] #[diag("`#[diagnostic::on_const]` can only be applied to non-const trait implementations")] pub(crate) struct DiagnosticOnConstOnlyForTraitImpls { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs index d331ef6a6df51..abe3980031a44 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::ty::{ - self, GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + self, Flags, GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use tracing::{debug, instrument}; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 49b3e75b25e39..58511d35f91d2 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -10,7 +10,7 @@ use rustc_infer::traits::ObligationCause; use rustc_macros::extension; use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ - self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, + self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, Flags, GenericArg, GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions, }; diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 5d510a9835264..57139d077d493 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -16,8 +16,11 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; -use rustc_hir as hir; -use rustc_hir::definitions::{DefPathData, DisambiguatorState}; +use rustc_hir::def_id::LocalDefIdMap; +use rustc_hir::definitions::{ + DefPathData, PerParentDisambiguatorState, PerParentDisambiguatorsMap, +}; +use rustc_hir::{self as hir}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::interpret::{ AllocBytes, ConstAllocation, CtfeProvenance, InterpResult, Provenance, @@ -105,7 +108,7 @@ fn intern_shallow<'tcx, M: CompileTimeMachine<'tcx>>( ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, - disambiguator: Option<&mut DisambiguatorState>, + disambiguators: Option<&mut LocalDefIdMap>, ) -> Result + 'tcx, InternError> { trace!("intern_shallow {:?}", alloc_id); // remove allocation @@ -129,7 +132,7 @@ fn intern_shallow<'tcx, M: CompileTimeMachine<'tcx>>( static_id, alloc_id, alloc, - disambiguator.expect("disambiguator needed"), + disambiguators.expect("disambiguators needed"), ); } else { ecx.tcx.set_alloc_id_memory(alloc_id, alloc); @@ -144,7 +147,7 @@ fn intern_as_new_static<'tcx>( static_id: LocalDefId, alloc_id: AllocId, alloc: ConstAllocation<'tcx>, - disambiguator: &mut DisambiguatorState, + disambiguators: &mut LocalDefIdMap, ) { // `intern_const_alloc_recursive` is called once per static and it contains the `DisambiguatorState`. // The `::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the @@ -155,7 +158,8 @@ fn intern_as_new_static<'tcx>( None, DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, Some(DefPathData::NestedStatic), - disambiguator, + //FIXME(oli-obk): cleanup (https://github.com/rust-lang/rust/pull/155547#discussion_r3110792640) + disambiguators.get_or_create(static_id), ); tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); @@ -205,7 +209,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( intern_kind: InternKind, ret: &MPlaceTy<'tcx>, ) -> Result<(), InternError> { - let mut disambiguator = DisambiguatorState::new(); + let mut disambiguators = Default::default(); // We are interning recursively, and for mutability we are distinguishing the "root" allocation // that we are starting in, and all other allocations that we are encountering recursively. @@ -250,7 +254,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( prepare_alloc(*ecx.tcx, *kind, alloc, base_mutability)?; alloc.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() } else { - intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguator))?.collect() + intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguators))?.collect() }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. @@ -332,7 +336,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx>>( // okay with losing some potential for immutability here. This can anyway only affect // `static mut`. just_interned.insert(alloc_id); - let next = intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator))?; + let next = intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguators))?; todo.extend(next); } if found_bad_mutable_ptr { diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d18653f6267ad..e9801a8a5231b 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,11 +7,12 @@ use std::fmt::{self, Write}; use std::hash::Hash; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; use rustc_index::IndexVec; -use rustc_macros::{BlobDecodable, Decodable, Encodable}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, extension}; +use rustc_span::def_id::LocalDefIdMap; use rustc_span::{Symbol, kw, sym}; use tracing::{debug, instrument}; @@ -97,45 +98,28 @@ impl DefPathTable { } } -pub trait Disambiguator { - fn entry(&mut self, parent: LocalDefId, data: DefPathData) -> &mut u32; -} - #[derive(Debug, Default, Clone)] pub struct PerParentDisambiguatorState { - next: UnordMap, -} - -impl Disambiguator for PerParentDisambiguatorState { - #[inline] - fn entry(&mut self, _: LocalDefId, data: DefPathData) -> &mut u32 { - self.next.entry(data).or_insert(0) - } -} - -#[derive(Debug, Default, Clone)] -pub struct DisambiguatorState { - next: UnordMap<(LocalDefId, DefPathData), u32>, + #[cfg(debug_assertions)] + parent: Option, + next: FxHashMap, } -impl Disambiguator for DisambiguatorState { - #[inline] - fn entry(&mut self, parent: LocalDefId, data: DefPathData) -> &mut u32 { - self.next.entry((parent, data)).or_insert(0) +impl PerParentDisambiguatorState { + #[inline(always)] + pub fn new(_parent: LocalDefId) -> PerParentDisambiguatorState { + PerParentDisambiguatorState { + #[cfg(debug_assertions)] + parent: Some(_parent), + next: Default::default(), + } } } -impl DisambiguatorState { - pub const fn new() -> Self { - Self { next: Default::default() } - } - - /// Creates a `DisambiguatorState` where the next allocated `(LocalDefId, DefPathData)` pair - /// will have `index` as the disambiguator. - pub fn with(def_id: LocalDefId, data: DefPathData, index: u32) -> Self { - let mut this = Self::new(); - this.next.insert((def_id, data), index); - this +#[extension(pub trait PerParentDisambiguatorsMap)] +impl LocalDefIdMap { + fn get_or_create(&mut self, parent: LocalDefId) -> &mut PerParentDisambiguatorState { + self.entry(parent).or_insert_with(|| PerParentDisambiguatorState::new(parent)) } } @@ -408,7 +392,7 @@ impl Definitions { &mut self, parent: LocalDefId, data: DefPathData, - disambiguator: &mut impl Disambiguator, + disambiguator: &mut PerParentDisambiguatorState, ) -> LocalDefId { // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a // reference to `Definitions` and we're already holding a mutable reference. @@ -422,7 +406,14 @@ impl Definitions { // Find the next free disambiguator for this key. let disambiguator = { - let next_disamb = disambiguator.entry(parent, data); + #[cfg(debug_assertions)] + debug_assert_eq!( + parent, + disambiguator.parent.expect("must be set"), + "provided parent and parent in disambiguator must be the same" + ); + + let next_disamb = disambiguator.next.entry(data).or_insert(0); let disambiguator = *next_disamb; *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); disambiguator diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 782eda0e00a39..2aebe267dc4bc 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -14,7 +14,8 @@ use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::definitions::{DefPathData, DisambiguatorState}; +use rustc_hir::def_id::LocalDefIdMap; +use rustc_hir::definitions::{DefPathData, PerParentDisambiguatorsMap}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node, @@ -30,6 +31,7 @@ use rustc_span::{Ident, Span, sym}; use tracing::{debug, debug_span, instrument}; use crate::errors; +use crate::hir::definitions::PerParentDisambiguatorState; #[extension(trait RegionExt)] impl ResolvedArg { @@ -64,7 +66,7 @@ impl ResolvedArg { struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, rbv: &'a mut ResolveBoundVars<'tcx>, - disambiguator: &'a mut DisambiguatorState, + disambiguators: &'a mut LocalDefIdMap, scope: ScopeRef<'a, 'tcx>, opaque_capture_errors: RefCell>, } @@ -259,7 +261,7 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None }, - disambiguator: &mut DisambiguatorState::new(), + disambiguators: &mut Default::default(), opaque_capture_errors: RefCell::new(None), }; match tcx.hir_owner_node(local_def_id) { @@ -1104,12 +1106,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, rbv, disambiguator, .. } = self; + let BoundVarContext { tcx, rbv, disambiguators, .. } = self; let nested_errors = RefCell::new(self.opaque_capture_errors.borrow_mut().take()); let mut this = BoundVarContext { tcx: *tcx, rbv, - disambiguator, + disambiguators, scope: &wrap_scope, opaque_capture_errors: nested_errors, }; @@ -1523,7 +1525,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { None, DefKind::LifetimeParam, Some(DefPathData::OpaqueLifetime(ident.name)), - self.disambiguator, + self.disambiguators.get_or_create(opaque_def_id), ); feed.def_span(ident.span); feed.def_ident_span(Some(ident.span)); diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index b55e7933cc1e9..3f8ac61eed084 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -173,6 +173,12 @@ pub(crate) enum ExpectedReturnTypeLabel<'tcx> { span: Span, expected: Ty<'tcx>, }, + #[label("expected a single type implementing `{$trait_name}` because of return type")] + ImplTrait { + #[primary_span] + span: Span, + trait_name: String, + }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 4a5d609586f0e..d9c63c41a67c1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_hir_analysis::hir_ty_lowering::{ }; use rustc_infer::infer::{self, RegionVariableOrigin}; use rustc_infer::traits::{DynCompatibilityViolation, Obligation}; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; +use rustc_middle::ty::{self, Const, Flags, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_session::Session; use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span}; use rustc_trait_selection::error_reporting::TypeErrCtxt; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index eea5edd922de2..1f08dff18f3ed 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -931,6 +931,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } hir::FnRetTy::Return(hir_ty) => { if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind + && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds + && !trait_ref + .trait_ref + .path + .segments + .last() + .and_then(|seg| seg.args) + .map_or(false, |args| !args.constraints.is_empty()) + { + // Use the path to get the trait name string + let trait_name = trait_ref + .trait_ref + .path + .segments + .iter() + .map(|seg| seg.ident.as_str()) + .collect::>() + .join("::"); + + err.subdiagnostic(errors::ExpectedReturnTypeLabel::ImplTrait { + span: hir_ty.span, + trait_name, + }); + + if let Some(ret_coercion_span) = self.ret_coercion_span.get() { + let expected_name = expected.to_string(); + err.span_label( + ret_coercion_span, + format!("return type resolved to be `{expected_name}`"), + ); + } + + self.try_suggest_return_impl_trait(err, expected, found, fn_id); + self.try_note_caller_chooses_ty_for_ty_param(err, expected, found); + return true; + } else if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind // FIXME: account for RPITIT. && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds && let Some(hir::PathSegment { args: Some(generic_args), .. }) = diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index e0d9970a5a16d..ba5b55b43049f 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -21,7 +21,7 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ - self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, + self, DefiningScopeKind, DefinitionSiteHiddenType, Flags, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, fold_regions, }; @@ -933,7 +933,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { fn handle_term( &mut self, value: T, - outer_exclusive_binder: impl FnOnce(T) -> ty::DebruijnIndex, + outer_exclusive_binder: impl FnOnce(&T) -> ty::DebruijnIndex, new_err: impl Fn(TyCtxt<'tcx>, ErrorGuaranteed) -> T, ) -> T where @@ -946,7 +946,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { let body_id = tcx.hir_body_owner_def_id(self.body.id()); let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); let at = self.fcx.at(&cause, self.fcx.param_env); - let universes = vec![None; outer_exclusive_binder(value).as_usize()]; + let universes = vec![None; outer_exclusive_binder(&value).as_usize()]; match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( at, Unnormalized::new_wip(value), diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index c889381586753..a575ba79df45c 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -10,10 +10,9 @@ use rustc_data_structures::sso::SsoHashMap; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::ty::{ - self, BoundVar, GenericArg, InferConst, List, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitableExt, + self, BoundVar, Flags, GenericArg, InferConst, List, Ty, TyCtxt, TypeFlags, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypingModeEqWrapper, }; -use rustc_type_ir::TypingModeEqWrapper; use smallvec::SmallVec; use tracing::debug; diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index 66a7bd2fc636c..9df7b35211df0 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -8,10 +8,9 @@ use rustc_macros::extension; use rustc_middle::ty::{ - self, DelayedMap, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitableExt, TypeVisitor, + self, DelayedMap, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_type_ir::{TypeFlags, TypeVisitable}; use crate::infer::canonical::{Canonical, CanonicalVarValues}; diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index a550621a82d60..0a56b42c502e2 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -1,5 +1,5 @@ use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + self, Flags, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, }; diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 4a0320cbaf80d..60bfdd689609d 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -43,27 +43,6 @@ impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { .into_diag(dcx, level) } - &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.into_diag(dcx, level), - - &AttributeLintKind::DocTestUnknown { name } => { - lints::DocTestUnknown { name }.into_diag(dcx, level) - } - - &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.into_diag(dcx, level), - - &AttributeLintKind::AttrCrateLevelOnly => { - lints::AttrCrateLevelOnly.into_diag(dcx, level) - } - - &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => { - lints::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level) - } - - &AttributeLintKind::CrateTypeUnknown { span, suggested } => lints::UnknownCrateTypes { - sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), - } - .into_diag(dcx, level), - &AttributeLintKind::MalformedDoc => lints::MalformedDoc.into_diag(dcx, level), &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.into_diag(dcx, level), diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 19fabc51ae536..ccbc325648e38 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3303,46 +3303,6 @@ pub(crate) struct ExpectedNoArgs; )] pub(crate) struct ExpectedNameValue; -#[derive(Diagnostic)] -#[diag("`#[doc(test(...)]` takes a list of attributes")] -pub(crate) struct DocTestTakesList; - -#[derive(Diagnostic)] -#[diag("unknown `doc(test)` attribute `{$name}`")] -pub(crate) struct DocTestUnknown { - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag("`#![doc(test(...)]` does not take a literal")] -pub(crate) struct DocTestLiteral; - -#[derive(Diagnostic)] -#[diag("this attribute can only be applied at the crate level")] -#[note( - "read for more information" -)] -pub(crate) struct AttrCrateLevelOnly; - -#[derive(Diagnostic)] -#[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] -pub(crate) struct DoNotRecommendDoesNotExpectArgs; - -#[derive(Diagnostic)] -#[diag("invalid `crate_type` value")] -pub(crate) struct UnknownCrateTypes { - #[subdiagnostic] - pub sugg: Option, -} - -#[derive(Subdiagnostic)] -#[suggestion("did you mean", code = r#""{snippet}""#, applicability = "maybe-incorrect")] -pub(crate) struct UnknownCrateTypesSuggestion { - #[primary_span] - pub span: Span, - pub snippet: Symbol, -} - #[derive(Diagnostic)] #[diag("positional format arguments are not allowed here")] #[help( diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 96c7dec3d8188..45ac2c59b04e9 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -656,12 +656,6 @@ pub enum DeprecatedSinceKind { pub enum AttributeLintKind { UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), - DocTestTakesList, - DocTestUnknown { name: Symbol }, - DocTestLiteral, - AttrCrateLevelOnly, - DoNotRecommendDoesNotExpectArgs, - CrateTypeUnknown { span: Span, suggested: Option }, MalformedDoc, ExpectedNoArgs, ExpectedNameValue, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 68357212bebe8..6a78509998313 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1251,7 +1251,7 @@ fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { tcx.ensure_done().lower_delayed_owner(id); } - let (_, krate) = krate.delayed_resolver.steal(); + let (_, krate, _) = krate.delayed_resolver.steal(); let prof = tcx.sess.prof.clone(); // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 7f82b9161fe61..c81b0a7182558 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -16,7 +16,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; +use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModDefId}; +use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::*; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable}; @@ -39,7 +40,11 @@ pub struct Crate<'hir> { pub delayed_ids: FxIndexSet, // The resolver and AST crate which are set in the end of the `hir_crate` query // and then stolen and dropped in `force_delayed_owners_lowering`. - pub delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, + pub delayed_resolver: Steal<( + ResolverAstLowering<'hir>, + Arc, + Arc>>, + )>, // Only present when incr. comp. is enabled. pub opt_hir_hash: Option, } @@ -48,7 +53,11 @@ impl<'hir> Crate<'hir> { pub fn new( owners: IndexVec>, delayed_ids: FxIndexSet, - delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, + delayed_resolver: Steal<( + ResolverAstLowering<'hir>, + Arc, + Arc>>, + )>, opt_hir_hash: Option, ) -> Crate<'hir> { Crate { owners, delayed_ids, delayed_resolver, opt_hir_hash } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d342e4ba5efae..c31d6ac41b7c6 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -55,18 +55,6 @@ impl<'tcx> Const<'tcx> { *a } - // FIXME(compiler-errors): Think about removing this. - #[inline] - pub fn flags(self) -> TypeFlags { - self.0.flags - } - - // FIXME(compiler-errors): Think about removing this. - #[inline] - pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { - self.0.outer_exclusive_binder - } - #[inline] pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>) -> Const<'tcx> { tcx.mk_ct_from_kind(kind) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 71b0077b62131..a65a5fcc6bffe 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -32,7 +32,7 @@ use rustc_data_structures::sync::{ use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::definitions::{DefPathData, Definitions, Disambiguator}; +use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; @@ -1399,7 +1399,7 @@ impl<'tcx> TyCtxtAt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut impl Disambiguator, + disambiguator: &mut PerParentDisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { let feed = self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator); @@ -1417,7 +1417,7 @@ impl<'tcx> TyCtxt<'tcx> { name: Option, def_kind: DefKind, override_def_path_data: Option, - disambiguator: &mut impl Disambiguator, + disambiguator: &mut PerParentDisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name)); // The following call has the side effect of modifying the tables inside `definitions`. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 56a7abfac6635..5561781ab47cb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -227,7 +227,7 @@ pub struct ResolverAstLowering<'tcx> { // Information about delegations which is used when handling recursive delegations pub delegation_infos: LocalDefIdMap, - pub per_parent_disambiguators: LocalDefIdMap>, + pub disambiguators: Steal>, } #[derive(Debug)] diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 47175f404cf34..cb3b9fd1efacb 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -5,9 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, extension}; use rustc_type_ir as ir; -use crate::ty::{ - self, DebruijnIndex, EarlyBinder, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, WithCachedTypeInfo, -}; +use crate::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, WithCachedTypeInfo}; pub type TraitRef<'tcx> = ir::TraitRef>; pub type AliasTerm<'tcx> = ir::AliasTerm>; @@ -78,18 +76,6 @@ impl<'tcx> Predicate<'tcx> { self.0.internee } - // FIXME(compiler-errors): Think about removing this. - #[inline(always)] - pub fn flags(self) -> TypeFlags { - self.0.flags - } - - // FIXME(compiler-errors): Think about removing this. - #[inline(always)] - pub fn outer_exclusive_binder(self) -> DebruijnIndex { - self.0.outer_exclusive_binder - } - /// Flips the polarity of a Predicate. /// /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 295acc5350831..f8e1dc334f1f6 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -27,7 +27,7 @@ use crate::traits::ObligationCause; use crate::ty::InferTy::*; use crate::ty::{ self, AdtDef, Const, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv, Region, - Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, ValTree, + Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, ValTree, }; // Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here @@ -1125,12 +1125,6 @@ impl<'tcx> Ty<'tcx> { self.0.0 } - // FIXME(compiler-errors): Think about removing this. - #[inline(always)] - pub fn flags(self) -> TypeFlags { - self.0.0.flags - } - #[inline] pub fn is_unit(self) -> bool { match self.kind() { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 07baf5b49d659..48d85689b188c 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1495,12 +1495,6 @@ impl<'tcx> Ty<'tcx> { } ty } - - // FIXME(compiler-errors): Think about removing this. - #[inline] - pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { - self.0.outer_exclusive_binder - } } /// Returns a list of types such that the given type needs drop if and only if diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 519a9eb484e0d..af270988abc9c 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_type_ir::TypeFoldable; use crate::ty::{ - self, Binder, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, Binder, Flags, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index d17d188850412..cfe07081ee219 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -70,10 +70,10 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::steal::Steal; use rustc_data_structures::unord::UnordMap; -use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::definitions::DisambiguatorState; +use rustc_hir::definitions::PerParentDisambiguatorState; +use rustc_hir::{self as hir}; use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; @@ -221,7 +221,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( None, DefKind::SyntheticCoroutineBody, None, - &mut DisambiguatorState::new(), + &mut PerParentDisambiguatorState::new(parent_def_id), ); by_move_body.source = mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index bf260d823b765..a92ed9cd3ae83 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -979,23 +979,47 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .source_map() .span_extend_to_prev_str(ident.span, current, true, false); - let ((with, with_label), without) = match sp { + let (with, with_label, without) = match sp { Some(sp) if !self.tcx.sess.source_map().is_multiline(sp) => { let sp = sp .with_lo(BytePos(sp.lo().0 - (current.len() as u32))) .until(ident.span); - ( - (Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion { - span: sp, - suggestion, - current, - type_span, - }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})), - None, - ) + + // Only suggest replacing the binding keyword if this is a simple + // binding. + // + // Note: this approach still incorrectly suggests for irrefutable + // patterns like `if let x = 1 { const { x } }`, since the text + // between `let` and the identifier is just whitespace. + // See tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.rs + let is_simple_binding = + self.tcx.sess.source_map().span_to_snippet(sp).is_ok_and(|snippet| { + let after_keyword = snippet[current.len()..].trim(); + after_keyword.is_empty() || after_keyword == "mut" + }); + + if is_simple_binding { + ( + Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion { + span: sp, + suggestion, + current, + type_span, + }), + Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion { span }), + None, + ) + } else { + ( + None, + Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion { span }), + None, + ) + } } _ => ( - (None, None), + None, + None, Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion { ident_span: ident.span, suggestion, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a44a7b30b4e60..5d4367ea045cf 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -57,7 +57,7 @@ use rustc_hir::def::{ PerNS, }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::PerParentDisambiguatorState; +use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguatorsMap}; use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; @@ -1417,7 +1417,7 @@ pub struct Resolver<'ra, 'tcx> { node_id_to_def_id: NodeMap>, - per_parent_disambiguators: LocalDefIdMap, + disambiguators: LocalDefIdMap, /// Indices of unnamed struct or variant fields with unresolved attributes. placeholder_field_indices: FxHashMap = default::fx_hash_map(), @@ -1620,14 +1620,10 @@ impl<'tcx> Resolver<'_, 'tcx> { self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id].key()), ); + let disambiguator = self.disambiguators.get_or_create(parent); + // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()` - let feed = self.tcx.create_def( - parent, - name, - def_kind, - None, - self.per_parent_disambiguators.entry(parent).or_default(), - ); + let feed = self.tcx.create_def(parent, name, def_kind, None, disambiguator); let def_id = feed.def_id(); // Create the definition. @@ -1811,7 +1807,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), current_crate_outer_attr_insert_span, - per_parent_disambiguators: Default::default(), + disambiguators: Default::default(), .. }; @@ -1951,11 +1947,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), delegation_infos: self.delegation_infos, - per_parent_disambiguators: self - .per_parent_disambiguators - .into_items() - .map(|(k, d)| (k, Steal::new(d))) - .collect(), + disambiguators: Steal::new(self.disambiguators), }; ResolverOutputs { global_ctxt, ast_lowering } } diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 7d4bf731454e2..21c29721037f2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{FromSolverError, Obligation, TraitEngine}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ - self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + self, FallibleTypeFolder, Flags, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, Unnormalized, }; use tracing::instrument; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 2aef690e61035..a3e4eb4537cac 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -9,8 +9,8 @@ use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::{ - self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, + self, FallibleTypeFolder, Flags, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, }; use rustc_span::DUMMY_SP; use tracing::{debug, info, instrument}; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 497f9205eb19d..1d24a207103c8 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,6 +1,8 @@ use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; -use rustc_hir::definitions::{DefPathData, DisambiguatorState}; +use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdMap}; +use rustc_hir::definitions::{ + DefPathData, PerParentDisambiguatorState, PerParentDisambiguatorsMap, +}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, ConstItemRhs, ImplItemImplKind, ItemKind}; use rustc_middle::query::Providers; @@ -129,7 +131,7 @@ struct RPITVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, synthetics: Vec, data: DefPathData, - disambiguator: &'a mut DisambiguatorState, + disambiguators: &'a mut LocalDefIdMap, } impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> { @@ -138,7 +140,7 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> { self.tcx, opaque.def_id, self.data, - &mut self.disambiguator, + &mut self.disambiguators, )); intravisit::walk_opaque_ty(self, opaque) } @@ -149,7 +151,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( def_id: LocalDefId, ) -> DefIdMap> { let item = tcx.hir_expect_item(def_id); - let disambiguator = &mut DisambiguatorState::new(); + let disambiguators = &mut Default::default(); match item.kind { ItemKind::Trait(.., trait_item_refs) => trait_item_refs .iter() @@ -163,7 +165,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( }; let def_name = tcx.item_name(fn_def_id.to_def_id()); let data = DefPathData::AnonAssocTy(def_name); - let mut visitor = RPITVisitor { tcx, synthetics: vec![], data, disambiguator }; + let mut visitor = RPITVisitor { tcx, synthetics: vec![], data, disambiguators }; visitor.visit_fn_ret_ty(output); let defs = visitor .synthetics @@ -197,7 +199,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( return Some((did, vec![])); }; let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| { - associated_type_for_impl_trait_in_impl(tcx, id, item, disambiguator) + associated_type_for_impl_trait_in_impl(tcx, id, item, disambiguators) .to_def_id() }); Some((did, iter.collect())) @@ -221,7 +223,7 @@ fn associated_type_for_impl_trait_in_trait( tcx: TyCtxt<'_>, opaque_ty_def_id: LocalDefId, data: DefPathData, - disambiguator: &mut DisambiguatorState, + disambiguators: &mut LocalDefIdMap, ) -> LocalDefId { let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) = @@ -240,7 +242,7 @@ fn associated_type_for_impl_trait_in_trait( None, DefKind::AssocTy, Some(data), - disambiguator, + disambiguators.get_or_create(trait_def_id), ); let local_def_id = trait_assoc_ty.def_id(); @@ -283,7 +285,7 @@ fn associated_type_for_impl_trait_in_impl( tcx: TyCtxt<'_>, trait_assoc_def_id: DefId, impl_fn: &hir::ImplItem<'_>, - disambiguator: &mut DisambiguatorState, + disambiguators: &mut LocalDefIdMap, ) -> LocalDefId { let impl_local_def_id = tcx.local_parent(impl_fn.owner_id.def_id); @@ -306,7 +308,7 @@ fn associated_type_for_impl_trait_in_impl( None, DefKind::AssocTy, Some(data), - disambiguator, + disambiguators.get_or_create(impl_local_def_id), ); let local_def_id = impl_assoc_ty.def_id(); diff --git a/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.rs b/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.rs new file mode 100644 index 0000000000000..de5a573354082 --- /dev/null +++ b/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.rs @@ -0,0 +1,13 @@ +// Irrefutable `if let` pattern bindings still produce an incorrect suggestion +// to replace `let` with `const`. +// See https://github.com/rust-lang/rust/pull/152834#discussion_r3068766148 + +//@ known-bug: #152831 + +fn irrefutable_if_let_binding() { + if let x = 1 { + const { x } + } +} + +fn main() {} diff --git a/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.stderr b/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.stderr new file mode 100644 index 0000000000000..1a2fa226e633c --- /dev/null +++ b/tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.stderr @@ -0,0 +1,15 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/non-const-value-in-const-irrefutable-pat-binding.rs:9:17 + | +LL | const { x } + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - if let x = 1 { +LL + if const x: /* Type */ = 1 { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/consts/non-const-value-in-const-pat-binding.rs b/tests/ui/consts/non-const-value-in-const-pat-binding.rs new file mode 100644 index 0000000000000..8c6edfdf363c5 --- /dev/null +++ b/tests/ui/consts/non-const-value-in-const-pat-binding.rs @@ -0,0 +1,24 @@ +// Regression test for https://github.com/rust-lang/rust/issues/152831 + +fn if_let_binding() { + if let Some(v) = Some(1) { + const { v } + //~^ ERROR: attempt to use a non-constant value in a constant + } +} + +fn while_let_binding() { + while let Some(v) = Some(1) { + const { v } + //~^ ERROR: attempt to use a non-constant value in a constant + break; + } +} + +fn let_else_binding() { + let Some(v) = Some(1) else { return }; + const { v } + //~^ ERROR: attempt to use a non-constant value in a constant +} + +fn main() {} diff --git a/tests/ui/consts/non-const-value-in-const-pat-binding.stderr b/tests/ui/consts/non-const-value-in-const-pat-binding.stderr new file mode 100644 index 0000000000000..d303189eb3051 --- /dev/null +++ b/tests/ui/consts/non-const-value-in-const-pat-binding.stderr @@ -0,0 +1,21 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/non-const-value-in-const-pat-binding.rs:5:17 + | +LL | const { v } + | ^ non-constant value + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/non-const-value-in-const-pat-binding.rs:12:17 + | +LL | const { v } + | ^ non-constant value + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/non-const-value-in-const-pat-binding.rs:20:13 + | +LL | const { v } + | ^ non-constant value + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-impl-trait.stderr b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-impl-trait.stderr index 6a485881bfccb..2447a5d8d4b80 100644 --- a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-impl-trait.stderr +++ b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-impl-trait.stderr @@ -2,8 +2,11 @@ error[E0308]: mismatched types --> $DIR/dyn-incompatible-trait-in-return-position-impl-trait.rs:36:5 | LL | fn can() -> impl DynIncompatible { - | -------------------- expected `A` because of return type -... + | -------------------- expected a single type implementing `DynIncompatible` because of return type +LL | if true { +LL | return A; + | - return type resolved to be `A` +LL | } LL | B | ^ expected `A`, found `B` @@ -11,8 +14,11 @@ error[E0308]: mismatched types --> $DIR/dyn-incompatible-trait-in-return-position-impl-trait.rs:43:5 | LL | fn cat() -> impl DynCompatible { - | ------------------ expected `A` because of return type -... + | ------------------ expected a single type implementing `DynCompatible` because of return type +LL | if true { +LL | return A; + | - return type resolved to be `A` +LL | } LL | B | ^ expected `A`, found `B` diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 3c765da66bdcf..a44be96052512 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -2,8 +2,11 @@ error[E0308]: mismatched types --> $DIR/equality.rs:17:5 | LL | fn two(x: bool) -> impl Foo { - | -------- expected `i32` because of return type -... + | -------- expected a single type implementing `Foo` because of return type +LL | if x { +LL | return 1_i32; + | ----- return type resolved to be `i32` +LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index b2aa0e592df7a..2a4c5ff4a5bed 100644 --- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -64,8 +64,11 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 | LL | fn foo() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type -... + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type +LL | if false { +LL | return 0i32; + | ---- return type resolved to be `i32` +LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` | @@ -79,8 +82,11 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16 | LL | fn bar() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type -... + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type +LL | if false { +LL | return 0i32; + | ---- return type resolved to be `i32` +LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` | @@ -94,8 +100,11 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9 | LL | fn baz() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type -... + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type +LL | if false { +LL | return 0i32; + | ---- return type resolved to be `i32` +LL | } else { LL | 1u32 | ^^^^ expected `i32`, found `u32` | @@ -137,8 +146,10 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14 | LL | fn bat() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type -... + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type +LL | match 13 { +LL | 0 => return 0i32, + | ---- return type resolved to be `i32` LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` | @@ -151,9 +162,10 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5 | LL | fn can() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type LL | / match 13 { LL | | 0 => return 0i32, + | | ---- return type resolved to be `i32` LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } @@ -168,7 +180,10 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 | LL | fn cat() -> impl std::fmt::Display { - | ---------------------- expected `i32` because of return type + | ---------------------- expected a single type implementing `std::fmt::Display` because of return type +... +LL | return 0i32; + | ---- return type resolved to be `i32` ... LL | 1u32 | ^^^^ expected `i32`, found `u32`