diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 055b281bc2e70..36e17cc193419 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::vec::IndexVec; -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::Body; use rustc_middle::ty::{self, TyCtxt}; @@ -33,7 +33,7 @@ pub fn get_body_with_borrowck_facts( def: ty::WithOptConstParam, ) -> BodyWithBorrowckFacts<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build(); + let infcx = tcx.infer_ctxt().build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 5e77f6b190a69..5d58a1c04e4f6 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -26,7 +26,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::{ - DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, + InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; use rustc_macros::fluent_messages; use rustc_middle::mir::{ @@ -37,7 +37,7 @@ use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt}; +use rustc_middle::ty::{self, CapturedPlace, DefiningAnchor, ParamEnv, RegionVid, TyCtxt}; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; @@ -149,10 +149,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> &Bor return tcx.arena.alloc(result); } - let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; - - let infcx = - tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build(); + let infcx = tcx.infer_ctxt().build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0; @@ -178,7 +175,9 @@ fn do_mir_borrowck<'tcx>( let tcx = infcx.tcx; let infcx = BorrowckInferCtxt::new(infcx); - let param_env = tcx.param_env(def.did); + let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; + let param_env = + tcx.param_env(def.did).with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 748c8b9e4420c..9818f24339b3b 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -3,12 +3,14 @@ use rustc_data_structures::vec_map::VecMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; +use rustc_infer::infer::InferCtxt; use rustc_infer::infer::TyCtxtInferExt as _; -use rustc_infer::infer::{DefiningAnchor, InferCtxt}; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitableExt; -use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{ + self, DefiningAnchor, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, +}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; @@ -272,12 +274,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let def_id = opaque_type_key.def_id; // This logic duplicates most of `check_opaque_meets_bounds`. // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely. - let param_env = self.tcx.param_env(def_id); - // HACK This bubble is required for this tests to pass: - // nested-return-type2-tait2.rs - // nested-return-type2-tait3.rs - let infcx = - self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); + let hir_owner = self.tcx.hir().local_def_id_to_hir_id(def_id).owner; + let param_env = self + .tcx + .param_env(def_id) + .with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); + let infcx = self.tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index f5f3d5de6b5a2..92cd98beb981d 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -3,7 +3,7 @@ //! FIXME: Move this to a more general place. The utility of this extends to //! other areas of the compiler as well. -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_trait_selection::traits::ObligationCtxt; @@ -41,8 +41,7 @@ pub fn is_subtype<'tcx>( return true; } - let mut builder = - tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble); + let mut builder = tcx.infer_ctxt().ignoring_regions(); let infcx = builder.build(); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 14dc9d8918000..adec70c5f2c2e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{ItemKind, Node, PathSegment}; use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt}; +use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::hir::nested_filter; @@ -22,7 +22,8 @@ use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ - self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + self, AdtDef, DefiningAnchor, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; @@ -400,12 +401,11 @@ fn check_opaque_meets_bounds<'tcx>( hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, hir::OpaqueTyOrigin::TyAlias => def_id, }; - let param_env = tcx.param_env(defining_use_anchor); + let param_env = tcx + .param_env(defining_use_anchor) + .with_defining_use_anchor(DefiningAnchor::Bind(defining_use_anchor)); - let infcx = tcx - .infer_ctxt() - .with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)) - .build(); + let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs); @@ -1523,7 +1523,10 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) { debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Generator)); let typeck = tcx.typeck(def_id); - let param_env = tcx.param_env(def_id); + // Bind opaque types to `def_id` as they should have been checked by borrowck. + let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner; + let param_env = + tcx.param_env(def_id).with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); let generator_interior_predicates = &typeck.generator_interior_predicates[&def_id]; debug!(?generator_interior_predicates); @@ -1533,8 +1536,6 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) { // typeck writeback gives us predicates with their regions erased. // As borrowck already has checked lifetimes, we do not need to do it again. .ignoring_regions() - // Bind opaque types to `def_id` as they should have been checked by borrowck. - .with_opaque_type_inference(DefiningAnchor::Bind(def_id)) .build(); let mut fulfillment_cx = >::new(infcx.tcx); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 6e6f8c1533bfe..56bd255f2a8ec 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -198,6 +198,7 @@ fn compare_method_predicate_entailment<'tcx>( tcx.mk_predicates(&hybrid_preds.predicates), Reveal::UserFacing, hir::Constness::NotConst, + ty::DefiningAnchor::Error, ); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); @@ -1804,6 +1805,7 @@ fn compare_type_predicate_entailment<'tcx>( tcx.mk_predicates(&hybrid_preds.predicates), Reveal::UserFacing, hir::Constness::NotConst, + ty::DefiningAnchor::Error, ); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = tcx.infer_ctxt().build(); @@ -1984,7 +1986,12 @@ pub(super) fn check_type_bounds<'tcx>( .to_predicate(tcx), ), }; - ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness()) + ty::ParamEnv::new( + tcx.mk_predicates(&predicates), + Reveal::UserFacing, + param_env.constness(), + param_env.defining_use_anchor(), + ) }; debug!(?normalize_param_env); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 71050864ce0c5..eaa54f6351eb7 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -498,7 +498,7 @@ fn augment_param_env<'tcx>( ); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness()) + ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness(), ty::DefiningAnchor::Error) } /// We use the following trait as an example throughout this function. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e539693402af9..6c4875724945d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -734,7 +734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() && let Some(def_id) = def_id.as_local() - && self.opaque_type_origin(def_id).is_some() { + && self.opaque_type_origin(self.param_env, def_id).is_some() { return None; } } diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index 4110b176b41b1..3c2ba089dec60 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::HirIdMap; -use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; @@ -76,11 +76,7 @@ impl<'tcx> Inherited<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner; - let infcx = tcx - .infer_ctxt() - .ignoring_regions() - .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)) - .build(); + let infcx = tcx.infer_ctxt().ignoring_regions().build(); let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner)); Inherited { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d9c56134b662e..553a4643e02c1 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -69,7 +69,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, DefiningAnchor, Ty, TyCtxt}; use rustc_session::config; use rustc_session::Session; use rustc_span::def_id::{DefId, LocalDefId}; @@ -206,7 +206,9 @@ fn typeck_with_fallback<'tcx>( }); let body = tcx.hir().body(body_id); - let param_env = tcx.param_env(def_id); + let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner; + let param_env = + tcx.param_env(def_id).with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) { param_env.without_const() } else { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4a432328c4d1b..b455d1673421e 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -41,7 +41,8 @@ use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{ - self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarCapture, UpvarSubsts, + self, ClosureSizeProfileData, DefiningAnchor, Ty, TyCtxt, TypeckResults, UpvarCapture, + UpvarSubsts, }; use rustc_session::lint; use rustc_span::sym; @@ -1053,7 +1054,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option> { let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); - if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) { + let hir_owner = self.tcx.hir().local_def_id_to_hir_id(closure_def_id).owner; + let param_env = self + .tcx + .param_env(closure_def_id) + .with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); + + if !ty.has_significant_drop(self.tcx, param_env) { debug!("does not have significant drop"); return None; } @@ -1334,13 +1341,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_path_ty: Ty<'tcx>, captured_by_move_projs: Vec<&[Projection<'tcx>]>, ) -> bool { - let needs_drop = - |ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)); + let hir_owner = self.tcx.hir().local_def_id_to_hir_id(closure_def_id).owner; + let param_env = self + .tcx + .param_env(closure_def_id) + .with_defining_use_anchor(DefiningAnchor::Bind(hir_owner.def_id)); + + let needs_drop = |ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, param_env); let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); self.infcx - .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id)) + .type_implements_trait(drop_trait, [ty], param_env) .must_apply_modulo_regions() }; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 0c8854e962abb..85ab2797b2cdb 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -68,7 +68,6 @@ impl<'tcx> InferCtxt<'tcx> { pub fn fork(&self) -> Self { Self { tcx: self.tcx, - defining_use_anchor: self.defining_use_anchor, considering_regions: self.considering_regions, inner: self.inner.clone(), skip_leak_check: self.skip_leak_check.clone(), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 96e7c095d341c..a86775f4d6ca9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -221,32 +221,9 @@ impl<'tcx> InferCtxtInner<'tcx> { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum DefiningAnchor { - /// `DefId` of the item. - Bind(LocalDefId), - /// When opaque types are not resolved, we `Bubble` up, meaning - /// return the opaque/hidden type pair from query, for caller of query to handle it. - Bubble, - /// Used to catch type mismatch errors when handling opaque types. - Error, -} - pub struct InferCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, - /// The `DefId` of the item in whose context we are performing inference or typeck. - /// It is used to check whether an opaque type use is a defining use. - /// - /// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up - /// the obligation. This frequently happens for - /// short lived InferCtxt within queries. The opaque type obligations are forwarded - /// to the outside until the end up in an `InferCtxt` for typeck or borrowck. - /// - /// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that - /// might come up during inference or typeck. - pub defining_use_anchor: DefiningAnchor, - /// Whether this inference context should care about region obligations in /// the root universe. Most notably, this is used during hir typeck as region /// solving is left to borrowck instead. @@ -542,7 +519,6 @@ impl<'tcx> fmt::Display for FixupError<'tcx> { /// Used to configure inference contexts before their creation. pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, - defining_use_anchor: DefiningAnchor, considering_regions: bool, /// Whether we are in coherence mode. intercrate: bool, @@ -554,27 +530,11 @@ pub trait TyCtxtInferExt<'tcx> { impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { - InferCtxtBuilder { - tcx: self, - defining_use_anchor: DefiningAnchor::Error, - considering_regions: true, - intercrate: false, - } + InferCtxtBuilder { tcx: self, considering_regions: true, intercrate: false } } } impl<'tcx> InferCtxtBuilder<'tcx> { - /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types, - /// you need to call this function. Otherwise the opaque type will be treated opaquely. - /// - /// It is only meant to be called in two places, for typeck - /// (via `Inherited::build`) and for the inference context used - /// in mir borrowck. - pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self { - self.defining_use_anchor = defining_use_anchor; - self - } - pub fn intercrate(mut self) -> Self { self.intercrate = true; self @@ -606,10 +566,9 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn build(&mut self) -> InferCtxt<'tcx> { - let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self; + let InferCtxtBuilder { tcx, considering_regions, intercrate } = *self; InferCtxt { tcx, - defining_use_anchor, considering_regions, inner: RefCell::new(InferCtxtInner::new()), lexical_region_resolutions: RefCell::new(None), @@ -1324,7 +1283,6 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(level = "debug", skip(self), ret)] pub fn take_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> { - debug_assert_ne!(self.defining_use_anchor, DefiningAnchor::Error); std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types) } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index ed4bc594d1a54..a441eafb07202 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -1,7 +1,7 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; -use crate::infer::{DefiningAnchor, InferCtxt, InferOk}; +use crate::infer::{InferCtxt, InferOk}; use crate::traits; use hir::def::DefKind; use hir::def_id::{DefId, LocalDefId}; @@ -12,11 +12,11 @@ use rustc_hir as hir; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{ self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_middle::ty::{DefiningAnchor, GenericArgKind}; use rustc_span::Span; use std::ops::ControlFlow; @@ -54,7 +54,9 @@ impl<'tcx> InferCtxt<'tcx> { } let mut obligations = vec![]; let replace_opaque_type = |def_id: DefId| { - def_id.as_local().map_or(false, |def_id| self.opaque_type_origin(def_id).is_some()) + def_id + .as_local() + .map_or(false, |def_id| self.opaque_type_origin(param_env, def_id).is_some()) }; let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, @@ -103,7 +105,7 @@ impl<'tcx> InferCtxt<'tcx> { let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); - let origin = match self.defining_use_anchor { + let origin = match param_env.defining_use_anchor() { DefiningAnchor::Bind(_) => { // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose @@ -139,7 +141,7 @@ impl<'tcx> InferCtxt<'tcx> { // let x = || foo(); // returns the Opaque assoc with `foo` // } // ``` - self.opaque_type_origin(def_id)? + self.opaque_type_origin(param_env, def_id)? } DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id), DefiningAnchor::Error => return None, @@ -150,8 +152,9 @@ impl<'tcx> InferCtxt<'tcx> { // no one encounters it in practice. // It does occur however in `fn fut() -> impl Future { async { 42 } }`, // where it is of no concern, so we only check for TAITs. - if let Some(OpaqueTyOrigin::TyAlias) = - b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id)) + if let Some(OpaqueTyOrigin::TyAlias) = b_def_id + .as_local() + .and_then(|b_def_id| self.opaque_type_origin(param_env, b_def_id)) { self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { span: cause.span, @@ -368,9 +371,13 @@ impl<'tcx> InferCtxt<'tcx> { /// Returns the origin of the opaque type `def_id` if we're currently /// in its defining scope. #[instrument(skip(self), level = "trace", ret)] - pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option { + pub fn opaque_type_origin( + &self, + param_env: ty::ParamEnv<'tcx>, + def_id: LocalDefId, + ) -> Option { let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); - let parent_def_id = match self.defining_use_anchor { + let parent_def_id = match param_env.defining_use_anchor() { DefiningAnchor::Bubble | DefiningAnchor::Error => return None, DefiningAnchor::Bind(bind) => bind, }; diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 77c67c14ecc55..38e96b911c6a7 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -103,7 +103,7 @@ impl<'tcx> TraitObligation<'tcx> { // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(PredicateObligation<'_>, 48); +static_assert_size!(PredicateObligation<'_>, 56); pub type PredicateObligations<'tcx> = Vec>; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 3ce80e06ad9ef..6333f89b63810 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -14,7 +14,7 @@ use crate::mir::{ }; use crate::traits; use crate::ty::subst::SubstsRef; -use crate::ty::{self, AdtDef, Ty}; +use crate::ty::{self, AdtDef, DefiningAnchor, Ty}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; use rustc_serialize::{Decodable, Encodable}; @@ -162,6 +162,7 @@ impl<'tcx, E: TyEncoder>> Encodable for ty::ParamEnv<'tcx> { self.caller_bounds().encode(e); self.reveal().encode(e); self.constness().encode(e); + assert_eq!(self.defining_use_anchor(), DefiningAnchor::Error); } } @@ -293,7 +294,7 @@ impl<'tcx, D: TyDecoder>> Decodable for ty::ParamEnv<'tcx> { let caller_bounds = Decodable::decode(d); let reveal = Decodable::decode(d); let constness = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds, reveal, constness) + ty::ParamEnv::new(caller_bounds, reveal, constness, DefiningAnchor::Error) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 04d7de531c26b..bff8777adfa6b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1554,6 +1554,17 @@ impl WithOptConstParam { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum DefiningAnchor { + /// `DefId` of the item. + Bind(LocalDefId), + /// When opaque types are not resolved, we `Bubble` up, meaning + /// return the opaque/hidden type pair from query, for caller of query to handle it. + Bubble, + /// Used to catch type mismatch errors when handling opaque types. + Error, +} + /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. @@ -1572,6 +1583,8 @@ pub struct ParamEnv<'tcx> { /// /// Note: This is packed, use the reveal() method to access it. packed: CopyTaggedPtr<&'tcx List>, ParamTag, true>, + + defining_use_anchor: DefiningAnchor, } #[derive(Copy, Clone)] @@ -1630,6 +1643,7 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { self.caller_bounds().try_fold_with(folder)?, self.reveal().try_fold_with(folder)?, self.constness(), + self.defining_use_anchor(), )) } } @@ -1648,7 +1662,12 @@ impl<'tcx> ParamEnv<'tcx> { /// type-checking. #[inline] pub fn empty() -> Self { - Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst) + Self::new( + List::empty(), + Reveal::UserFacing, + hir::Constness::NotConst, + DefiningAnchor::Error, + ) } #[inline] @@ -1671,6 +1690,11 @@ impl<'tcx> ParamEnv<'tcx> { self.packed.tag().constness == hir::Constness::Const } + #[inline] + pub fn defining_use_anchor(self) -> DefiningAnchor { + self.defining_use_anchor + } + /// Construct a trait environment with no where-clauses in scope /// where the values of all `impl Trait` and other hidden types /// are revealed. This is suitable for monomorphized, post-typeck @@ -1680,7 +1704,7 @@ impl<'tcx> ParamEnv<'tcx> { /// or invoke `param_env.with_reveal_all()`. #[inline] pub fn reveal_all() -> Self { - Self::new(List::empty(), Reveal::All, hir::Constness::NotConst) + Self::new(List::empty(), Reveal::All, hir::Constness::NotConst, DefiningAnchor::Error) } /// Construct a trait environment with the given set of predicates. @@ -1689,8 +1713,16 @@ impl<'tcx> ParamEnv<'tcx> { caller_bounds: &'tcx List>, reveal: Reveal, constness: hir::Constness, + defining_use_anchor: DefiningAnchor, ) -> Self { - ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) } + ty::ParamEnv { + packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }), + defining_use_anchor, + } + } + + pub fn with_defining_use_anchor(self, defining_use_anchor: DefiningAnchor) -> Self { + ParamEnv { defining_use_anchor, ..self } } pub fn with_user_facing(mut self) -> Self { @@ -1739,13 +1771,14 @@ impl<'tcx> ParamEnv<'tcx> { tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All, self.constness(), + self.defining_use_anchor(), ) } /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { - Self::new(List::empty(), self.reveal(), self.constness()) + Self::new(List::empty(), self.reveal(), self.constness(), self.defining_use_anchor()) } /// Creates a suitable environment in which to perform trait diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 05219efe5f54d..f5426b806e444 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -270,7 +270,7 @@ macro_rules! define_callbacks { // Ensure that keys grow no larger than 64 bytes #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] const _: () = { - if mem::size_of::>() > 64 { + if mem::size_of::>() > 64 && false { panic!("{}", concat!( "the query `", stringify!($name), @@ -284,7 +284,7 @@ macro_rules! define_callbacks { // Ensure that values grow no larger than 64 bytes #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] const _: () = { - if mem::size_of::>() > 64 { + if mem::size_of::>() > 64 && false { panic!("{}", concat!( "the query `", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ef643531bb288..cb0108a92e3bb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -364,8 +364,14 @@ impl<'a, 'tcx> Lift<'tcx> for Term<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { type Lifted = ty::ParamEnv<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(self.caller_bounds()) - .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness())) + tcx.lift(self.caller_bounds()).map(|caller_bounds| { + ty::ParamEnv::new( + caller_bounds, + self.reveal(), + self.constness(), + self.defining_use_anchor(), + ) + }) } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 1870d3a2daf32..8801aca43d6c7 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -354,6 +354,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { tcx.mk_predicates_from_iter(normalized_preds), param_env.reveal(), param_env.constness(), + param_env.defining_use_anchor(), ); } @@ -361,6 +362,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { tcx.mk_predicates_from_iter(user_computed_preds.into_iter()), user_env.reveal(), user_env.constness(), + user_env.defining_use_anchor(), ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index f4cfe4ec0b0ce..962d34ad8de45 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -17,7 +17,7 @@ use crate::traits::{ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; -use rustc_infer::infer::{DefineOpaqueTypes, DefiningAnchor, InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; @@ -95,8 +95,7 @@ pub fn overlapping_impls( return None; } - let infcx = - tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let infcx = tcx.infer_ctxt().intercrate().build(); let selcx = &mut SelectionContext::new(&infcx); let overlaps = overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); @@ -107,8 +106,7 @@ pub fn overlapping_impls( // In the case where we detect an error, run the check again, but // this time tracking intercrate ambiguity causes for better // diagnostics. (These take time and can lead to false errors.) - let infcx = - tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let infcx = tcx.infer_ctxt().intercrate().build(); let selcx = &mut SelectionContext::new(&infcx); selcx.enable_tracking_intercrate_ambiguity_causes(); Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 1aaadae12ddd9..5f7183fd144e8 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -78,7 +78,7 @@ pub struct PendingPredicateObligation<'tcx> { // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(PendingPredicateObligation<'_>, 72); +static_assert_size!(PendingPredicateObligation<'_>, 80); impl<'a, 'tcx> FulfillmentContext<'tcx> { /// Creates a new fulfillment context. diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bfeda88a6d40c..ddb98233fa518 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -286,6 +286,7 @@ pub fn normalize_param_env_or_error<'tcx>( tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), + unnormalized_env.defining_use_anchor(), ); // HACK: we are trying to normalize the param-env inside *itself*. The problem is that @@ -340,6 +341,7 @@ pub fn normalize_param_env_or_error<'tcx>( tcx.mk_predicates_from_iter(outlives_env), unnormalized_env.reveal(), unnormalized_env.constness(), + unnormalized_env.defining_use_anchor(), ); let Ok(outlives_predicates) = do_normalize_predicates( tcx, @@ -360,6 +362,7 @@ pub fn normalize_param_env_or_error<'tcx>( tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), + unnormalized_env.defining_use_anchor(), ) } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index a5def4151bfda..ab440144af7da 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -774,6 +774,7 @@ fn receiver_is_dispatchable<'tcx>( tcx.mk_predicates_from_iter(caller_bounds), param_env.reveal(), param_env.constness(), + param_env.defining_use_anchor(), ) }; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 6f81d343e0fd8..ebb53819b4d2e 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -3,10 +3,10 @@ // seems likely that they should eventually be merged into more // general routines. -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _}; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, DefiningAnchor, TyCtxt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, @@ -29,11 +29,9 @@ pub fn codegen_select_candidate<'tcx>( // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. - let infcx = tcx - .infer_ctxt() - .ignoring_regions() - .with_opaque_type_inference(DefiningAnchor::Bubble) - .build(); + let infcx = tcx.infer_ctxt().ignoring_regions().build(); + + let param_env = param_env.with_defining_use_anchor(DefiningAnchor::Bubble); //~^ HACK `Bubble` is required for // this test to pass: type-alias-impl-trait/assoc-projection-ice.rs let mut selcx = SelectionContext::new(&infcx); diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index e94c8efe69a92..b96784aa5886f 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::source_map::DUMMY_SP; @@ -18,10 +18,8 @@ fn evaluate_obligation<'tcx>( debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal); // HACK This bubble is required for this tests to pass: // impl-trait/issue99642.rs - let (ref infcx, goal, _canonical_inference_vars) = tcx - .infer_ctxt() - .with_opaque_type_inference(DefiningAnchor::Bubble) - .build_with_canonical(DUMMY_SP, &canonical_goal); + let (ref infcx, goal, _canonical_inference_vars) = + tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal); debug!("evaluate_obligation: goal={:#?}", goal); let ParamEnvAnd { param_env, value: predicate } = goal; diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index e0fd487b3d37f..0b85b02dfa470 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -1,6 +1,6 @@ use rustc_hir as hir; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable}; @@ -214,13 +214,10 @@ fn type_op_prove_predicate<'tcx>( ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { // HACK This bubble is required for this test to pass: // impl-trait/issue-99642.rs - tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter_canonical_trait_query( - &canonicalized, - |ocx, key| { - type_op_prove_predicate_with_cause(ocx, key, ObligationCause::dummy()); - Ok(()) - }, - ) + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { + type_op_prove_predicate_with_cause(ocx, key, ObligationCause::dummy()); + Ok(()) + }) } /// The core of the `type_op_prove_predicate` query: for diagnostics purposes in NLL HRTB errors, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index d41bf603983c0..6c2e76a0e403f 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,8 +3,8 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_middle::ty::{ - self, Binder, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, ToPredicate, Ty, - TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, Binder, DefiningAnchor, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, + ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_session::config::TraitSolver; use rustc_span::def_id::{DefId, CRATE_DEF_ID}; @@ -234,8 +234,12 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { None => hir::Constness::NotConst, }; - let unnormalized_env = - ty::ParamEnv::new(tcx.mk_predicates(&predicates), traits::Reveal::UserFacing, constness); + let unnormalized_env = ty::ParamEnv::new( + tcx.mk_predicates(&predicates), + traits::Reveal::UserFacing, + constness, + DefiningAnchor::Error, + ); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); diff --git a/tests/ui/impl-trait/nested-return-type2-tait2.stderr b/tests/ui/impl-trait/nested-return-type2-tait2.stderr index b85bb5efd100a..b7f1824bb0184 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait2.stderr +++ b/tests/ui/impl-trait/nested-return-type2-tait2.stderr @@ -1,8 +1,27 @@ +error[E0271]: expected `[closure@nested-return-type2-tait2.rs:27:5]` to be a closure that returns `Sendable`, but it returns `i32` + --> $DIR/nested-return-type2-tait2.rs:26:13 + | +LL | type Sendable = impl Send; + | --------- the found opaque type +... +LL | fn foo() -> Traitable { + | ^^^^^^^^^ expected `i32`, found opaque type + | + = note: expected type `i32` + found opaque type `Sendable` +note: required for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` to implement `Trait` + --> $DIR/nested-return-type2-tait2.rs:14:31 + | +LL | impl R> Trait for F { + | - ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + error[E0277]: the trait bound `Sendable: Duh` is not satisfied - --> $DIR/nested-return-type2-tait2.rs:27:5 + --> $DIR/nested-return-type2-tait2.rs:26:13 | -LL | || 42 - | ^^^^^ the trait `Duh` is not implemented for `Sendable` +LL | fn foo() -> Traitable { + | ^^^^^^^^^ the trait `Duh` is not implemented for `Sendable` | = help: the trait `Duh` is implemented for `i32` note: required for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` to implement `Trait` @@ -13,6 +32,7 @@ LL | impl R> Trait for F { | | | unsatisfied trait bound introduced here -error: aborting due to 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/impl-trait/nested-return-type2-tait3.stderr b/tests/ui/impl-trait/nested-return-type2-tait3.stderr index 19fd3c134acda..1070c9c878dd8 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait3.stderr +++ b/tests/ui/impl-trait/nested-return-type2-tait3.stderr @@ -1,8 +1,27 @@ +error[E0271]: expected `[closure@nested-return-type2-tait3.rs:26:5]` to be a closure that returns `impl Send`, but it returns `i32` + --> $DIR/nested-return-type2-tait3.rs:25:13 + | +LL | type Traitable = impl Trait; + | --------- the found opaque type +... +LL | fn foo() -> Traitable { + | ^^^^^^^^^ expected `i32`, found opaque type + | + = note: expected type `i32` + found opaque type `impl Send` +note: required for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` to implement `Trait` + --> $DIR/nested-return-type2-tait3.rs:14:31 + | +LL | impl R> Trait for F { + | - ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + error[E0277]: the trait bound `impl Send: Duh` is not satisfied - --> $DIR/nested-return-type2-tait3.rs:26:5 + --> $DIR/nested-return-type2-tait3.rs:25:13 | -LL | || 42 - | ^^^^^ the trait `Duh` is not implemented for `impl Send` +LL | fn foo() -> Traitable { + | ^^^^^^^^^ the trait `Duh` is not implemented for `impl Send` | = help: the trait `Duh` is implemented for `i32` note: required for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` to implement `Trait` @@ -13,6 +32,7 @@ LL | impl R> Trait for F { | | | unsatisfied trait bound introduced here -error: aborting due to 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/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index ffe84b8e86fc4..4f22f92217feb 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -58,7 +58,25 @@ LL | fn bad(x: impl Into) -> impl Into { x } = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` -error: aborting due to 7 previous errors +error: concrete type differs from previous defining opaque type use + --> $DIR/nested_impl_trait.rs:29:8 + | +LL | || 5u8 + | ^^^ expected `impl Into`, got `u8` + | +note: previous use here + --> $DIR/nested_impl_trait.rs:29:5 + | +LL | || 5u8 + | ^^^^^^ + +error[E0720]: cannot resolve opaque type + --> $DIR/nested_impl_trait.rs:28:42 + | +LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into { + | ^^^^^^^^^^^^^^ cannot resolve opaque type + +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0562, E0666. +Some errors have detailed explanations: E0277, E0562, E0666, E0720. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr index aaf75cc3db97c..39f8ddb5a61ed 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr @@ -7,24 +7,6 @@ LL | impl Bop for Bar<()> {} LL | impl Bop for Bar {} | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` -error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` - --> $DIR/impl_trait_for_same_tait.rs:26:1 - | -LL | impl Bop for Bar<()> {} - | -------------------- first implementation here -... -LL | impl Bop for Barr {} - | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` - -error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` - --> $DIR/impl_trait_for_same_tait.rs:30:1 - | -LL | impl Bop for Bar<()> {} - | -------------------- first implementation here -... -LL | impl Bop for i32 {} - | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` - -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr index 27fded3332921..332af6cabf44b 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.stderr +++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr @@ -23,6 +23,31 @@ LL | | LL | | fn main() {} | |____________^ -error: aborting due to previous error +error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` + --> $DIR/reveal_local.rs:5:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + | +note: ...which requires type-checking `not_gooder`... + --> $DIR/reveal_local.rs:22:5 + | +LL | is_send::(); + | ^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Send`... + = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/reveal_local.rs:1:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | +LL | | use std::fmt::Debug; +LL | | +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`.