diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 07289d68e2de3..96326ef2d5a07 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -2,13 +2,9 @@ use rustc_errors::DiagnosticBuilder; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::region_constraints::Constraint; -use rustc_infer::infer::region_constraints::RegionConstraintData; -use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt}; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::RegionVid; -use rustc_middle::ty::UniverseIndex; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op; @@ -82,15 +78,6 @@ crate trait ToUniverseInfo<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>; } -impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { - fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { - UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(crate::type_check::InstantiateOpaqueType { - base_universe: Some(base_universe), - ..self - }))) - } -} - impl<'tcx> ToUniverseInfo<'tcx> for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>> { @@ -131,12 +118,6 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo } } -impl<'tcx> ToUniverseInfo<'tcx> for ! { - fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { - self - } -} - #[allow(unused_lifetimes)] trait TypeOpInfo<'tcx> { /// Returns an error to be reported if rerunning the type op fails to @@ -147,7 +128,7 @@ trait TypeOpInfo<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -194,7 +175,7 @@ trait TypeOpInfo<'tcx> { debug!(?placeholder_region); let span = cause.span; - let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region); + let nice_error = self.nice_error(tcx, cause, placeholder_region, error_region); if let Some(nice_error) = nice_error { nice_error.buffer(&mut mbcx.errors_buffer); @@ -223,16 +204,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { - mbcx.infcx.tcx.infer_ctxt().enter_with_canonical( + tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, |ref infcx, key, _| { - let mut fulfill_cx = >::new(infcx.tcx); + let mut fulfill_cx = >::new(tcx); type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause); try_extract_error_from_fulfill_cx( fulfill_cx, @@ -266,16 +247,16 @@ where fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { - mbcx.infcx.tcx.infer_ctxt().enter_with_canonical( + tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, |ref infcx, key, _| { - let mut fulfill_cx = >::new(infcx.tcx); + let mut fulfill_cx = >::new(tcx); let mut selcx = SelectionContext::new(infcx); @@ -323,16 +304,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { - mbcx.infcx.tcx.infer_ctxt().enter_with_canonical( + tcx.infer_ctxt().enter_with_canonical( cause.span, &self.canonical_query, |ref infcx, key, _| { - let mut fulfill_cx = >::new(infcx.tcx); + let mut fulfill_cx = >::new(tcx); type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)) .ok()?; try_extract_error_from_fulfill_cx( @@ -346,39 +327,6 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { } } -impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { - fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, - // and is only the fallback when the nice error fails. Consider improving this some more. - tcx.sess.struct_span_err(span, "higher-ranked lifetime error for opaque type!") - } - - fn base_universe(&self) -> ty::UniverseIndex { - self.base_universe.unwrap() - } - - fn nice_error( - &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, - _cause: ObligationCause<'tcx>, - placeholder_region: ty::Region<'tcx>, - error_region: Option>, - ) -> Option> { - try_extract_error_from_region_constraints( - mbcx.infcx, - placeholder_region, - error_region, - self.region_constraints.as_ref().unwrap(), - // We're using the original `InferCtxt` that we - // started MIR borrowchecking with, so the region - // constraints have already been taken. Use the data from - // our `mbcx` instead. - |vid| mbcx.regioncx.var_infos[vid].origin, - |vid| mbcx.regioncx.var_infos[vid].universe, - ) - } -} - #[instrument(skip(fulfill_cx, infcx), level = "debug")] fn try_extract_error_from_fulfill_cx<'tcx>( mut fulfill_cx: Box + 'tcx>, @@ -386,30 +334,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>( placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { + let tcx = infcx.tcx; + // We generally shouldn't have errors here because the query was // already run, but there's no point using `delay_span_bug` // when we're going to emit an error here anyway. let _errors = fulfill_cx.select_all_or_error(infcx); - let region_constraints = infcx.with_region_constraints(|r| r.clone()); - try_extract_error_from_region_constraints( - infcx, - placeholder_region, - error_region, - ®ion_constraints, - |vid| infcx.region_var_origin(vid), - |vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))), - ) -} -fn try_extract_error_from_region_constraints<'tcx>( - infcx: &InferCtxt<'_, 'tcx>, - placeholder_region: ty::Region<'tcx>, - error_region: Option>, - region_constraints: &RegionConstraintData<'tcx>, - mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, - mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, -) -> Option> { - let (sub_region, cause) = + let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| { + debug!("{:#?}", region_constraints); region_constraints.constraints.iter().find_map(|(constraint, cause)| { match *constraint { Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => { @@ -417,11 +350,12 @@ fn try_extract_error_from_region_constraints<'tcx>( } // FIXME: Should this check the universe of the var? Constraint::VarSubReg(vid, sup) if sup == placeholder_region => { - Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone())) + Some((tcx.mk_region(ty::ReVar(vid)), cause.clone())) } _ => None, } - })?; + }) + })?; debug!(?sub_region, "cause = {:#?}", cause); let nice_error = match (error_region, sub_region) { @@ -429,7 +363,7 @@ fn try_extract_error_from_region_constraints<'tcx>( infcx, RegionResolutionError::SubSupConflict( vid, - region_var_origin(vid), + infcx.region_var_origin(vid), cause.clone(), error_region, cause.clone(), @@ -446,8 +380,8 @@ fn try_extract_error_from_region_constraints<'tcx>( infcx, RegionResolutionError::UpperBoundUniverseConflict( vid, - region_var_origin(vid), - universe_of_region(vid), + infcx.region_var_origin(vid), + infcx.universe_of_region(sub_region), cause.clone(), placeholder_region, ), diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index d698131df18dc..5597a8b091554 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -5,7 +5,6 @@ #![feature(crate_visibility_modifier)] #![feature(let_else)] #![feature(min_specialization)] -#![feature(never_type)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] #![feature(try_blocks)] @@ -125,9 +124,8 @@ fn mir_borrowck<'tcx>( ) -> &'tcx BorrowCheckResult<'tcx> { let (input_body, promoted) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); - let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; - let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| { + let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| { let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexVec<_, _> = &promoted.borrow(); do_mir_borrowck(&infcx, input_body, promoted, false).0 @@ -142,7 +140,7 @@ fn mir_borrowck<'tcx>( /// If `return_body_with_facts` is true, then return the body with non-erased /// region ids on which the borrow checking was performed together with Polonius /// facts. -#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")] +#[instrument(skip(infcx, input_body, input_promoted), level = "debug")] fn do_mir_borrowck<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, input_body: &Body<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 1dc9240620b13..d9120ff245735 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -44,7 +44,6 @@ mod reverse_sccs; pub mod values; pub struct RegionInferenceContext<'tcx> { - pub var_infos: VarInfos, /// Contains the definition for every region variable. Region /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came @@ -267,7 +266,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) -> Self { // Create a RegionDefinition for each inference variable. let definitions: IndexVec<_, _> = var_infos - .iter() + .into_iter() .map(|info| RegionDefinition::new(info.universe, info.origin)) .collect(); @@ -292,7 +291,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r))); let mut result = Self { - var_infos, definitions, liveness_constraints, constraints, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index f24d881639920..76b3be7976c61 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::vec_map::VecMap; use rustc_hir::OpaqueTyOrigin; +use rustc_infer::infer::opaque_types::OpaqueTypeDecl; use rustc_infer::infer::InferCtxt; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; @@ -53,44 +54,27 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn infer_opaque_types( &self, infcx: &InferCtxt<'_, 'tcx>, - opaque_ty_decls: VecMap, (Ty<'tcx>, Span, OpaqueTyOrigin)>, + opaque_ty_decls: VecMap, OpaqueTypeDecl<'tcx>>, span: Span, ) -> VecMap, Ty<'tcx>> { opaque_ty_decls .into_iter() - .map(|(opaque_type_key, (concrete_type, decl_span, origin))| { + .filter_map(|(opaque_type_key, decl)| { let substs = opaque_type_key.substs; - // FIXME: why are the spans in decl_span often DUMMY_SP? - let span = decl_span.substitute_dummy(span); + let concrete_type = decl.concrete_ty; debug!(?concrete_type, ?substs); let mut subst_regions = vec![self.universal_regions.fr_static]; let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| { - if let ty::RePlaceholder(..) = region { - // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. - return region; - } - let vid = self.to_region_vid(region); - trace!(?vid); - let scc = self.constraint_sccs.scc(vid); - trace!(?scc); - match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| { - self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?) - }) { - Some(region) => { - let vid = self.universal_regions.to_region_vid(region); - subst_regions.push(vid); - region - } - None => { - subst_regions.push(vid); - infcx.tcx.sess.delay_span_bug( - span, - "opaque type with non-universal region substs", - ); - infcx.tcx.lifetimes.re_static - } - } + let vid = self.universal_regions.to_region_vid(region); + subst_regions.push(vid); + self.definitions[vid].external_name.unwrap_or_else(|| { + infcx + .tcx + .sess + .delay_span_bug(span, "opaque type with non-universal region substs"); + infcx.tcx.lifetimes.re_static + }) }); subst_regions.sort(); @@ -116,14 +100,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { span, ); - ( + check_opaque_type_parameter_valid( + infcx.tcx, opaque_type_key, - if check_opaque_type_parameter_valid(infcx.tcx, opaque_type_key, origin, span) { - remapped_type - } else { - infcx.tcx.ty_error() - }, + OpaqueTypeDecl { concrete_ty: remapped_type, ..decl }, ) + .then_some((opaque_type_key, remapped_type)) }) .collect() } @@ -167,10 +149,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn check_opaque_type_parameter_valid( tcx: TyCtxt<'_>, opaque_type_key: OpaqueTypeKey<'_>, - origin: OpaqueTyOrigin, - span: Span, + decl: OpaqueTypeDecl<'_>, ) -> bool { - match origin { + match decl.origin { // No need to check return position impl trait (RPIT) // because for type and const parameters they are correct // by construction: we convert @@ -196,6 +177,7 @@ fn check_opaque_type_parameter_valid( // Check these OpaqueTyOrigin::TyAlias => {} } + let span = decl.definition_span; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); for (i, arg) in opaque_type_key.substs.iter().enumerate() { diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 3856b7f4a4b82..0fa72ed8241bc 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -33,11 +33,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) -> Fallible where Op: type_op::TypeOp<'tcx, Output = R>, - Op::ErrorInfo: ToUniverseInfo<'tcx>, + Canonical<'tcx, Op>: ToUniverseInfo<'tcx>, { let old_universe = self.infcx.universe(); - let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?; + let TypeOpOutput { output, constraints, canonicalized_query } = + op.fully_perform(self.infcx)?; if let Some(data) = &constraints { self.push_region_constraints(locations, category, data); @@ -46,8 +47,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let universe = self.infcx.universe(); if old_universe != universe { - let universe_info = match error_info { - Some(error_info) => error_info.to_universe_info(old_universe), + let universe_info = match canonicalized_query { + Some(canonicalized_query) => canonicalized_query.to_universe_info(old_universe), None => UniverseInfo::other(), }; for u in old_universe..universe { diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 48d8ae8947ff7..fec6bdf314b1d 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -268,7 +268,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { TypeOpOutput { output: self.infcx.tcx.ty_error(), constraints: None, - error_info: None, + canonicalized_query: None, } }); // Note: we need this in examples like diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 83c8ecba1f17a..bc740de515065 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -147,9 +147,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Return types are a bit more complex. They may contain opaque `impl Trait` types. let mir_output_ty = body.local_decls[RETURN_PLACE].ty; let output_span = body.local_decls[RETURN_PLACE].source_info.span; - if let Err(terr) = self.eq_types( - normalized_output_ty, + if let Err(terr) = self.eq_opaque_type_and_type( mir_output_ty, + normalized_output_ty, Locations::All(output_span), ConstraintCategory::BoringNoLocation, ) { @@ -169,9 +169,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let user_provided_output_ty = user_provided_sig.output(); let user_provided_output_ty = self.normalize(user_provided_output_ty, Locations::All(output_span)); - if let Err(err) = self.eq_types( - user_provided_output_ty, + if let Err(err) = self.eq_opaque_type_and_type( mir_output_ty, + user_provided_output_ty, Locations::All(output_span), ConstraintCategory::BoringNoLocation, ) { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 97021aa228420..73103643e3e16 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -5,7 +5,6 @@ use std::{fmt, iter, mem}; use either::Either; -use hir::OpaqueTyOrigin; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::vec_map::VecMap; @@ -16,8 +15,8 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; +use rustc_infer::infer::opaque_types::OpaqueTypeDecl; use rustc_infer::infer::outlives::env::RegionBoundPairs; -use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ InferCtxt, InferOk, LateBoundRegionConversionTime, NllRegionVariableOrigin, @@ -40,11 +39,9 @@ use rustc_target::abi::VariantIdx; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::query::type_op; -use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; -use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; use rustc_trait_selection::traits::query::Fallible; -use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligation}; +use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations}; use rustc_const_eval::transform::{ check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression, @@ -78,7 +75,7 @@ macro_rules! span_mirbug { $context.last_span, &format!( "broken MIR in {:?} ({:?}): {}", - $context.body().source.def_id(), + $context.body.source.def_id(), $elem, format_args!($($message)*), ), @@ -193,44 +190,59 @@ pub(crate) fn type_check<'mir, 'tcx>( liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table); translate_outlives_facts(&mut cx); - let opaque_type_values = - infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + let opaque_type_values = mem::take(&mut infcx.inner.borrow_mut().opaque_types); opaque_type_values .into_iter() - .map(|(opaque_type_key, decl)| { - cx.fully_perform_op( - Locations::All(body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |infcx| { - infcx.register_member_constraints( - param_env, - opaque_type_key, - decl.hidden_type.ty, - decl.hidden_type.span, - ); - Ok(InferOk { value: (), obligations: vec![] }) - }, - || "opaque_type_map".to_string(), - ), - ) - .unwrap(); - let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type.ty); + .filter_map(|(opaque_type_key, mut decl)| { + decl.concrete_ty = infcx.resolve_vars_if_possible(decl.concrete_ty); trace!( "finalized opaque type {:?} to {:#?}", opaque_type_key, - hidden_type.kind() + decl.concrete_ty.kind() ); - if hidden_type.has_infer_types_or_consts() { + if decl.concrete_ty.has_infer_types_or_consts() { infcx.tcx.sess.delay_span_bug( - decl.hidden_type.span, - &format!("could not resolve {:#?}", hidden_type.kind()), + body.span, + &format!("could not resolve {:#?}", decl.concrete_ty.kind()), ); - hidden_type = infcx.tcx.ty_error(); + decl.concrete_ty = infcx.tcx.ty_error(); } + let concrete_is_opaque = if let ty::Opaque(def_id, _) = decl.concrete_ty.kind() + { + *def_id == opaque_type_key.def_id + } else { + false + }; - (opaque_type_key, (hidden_type, decl.hidden_type.span, decl.origin)) + if concrete_is_opaque { + // We're using an opaque `impl Trait` type without + // 'revealing' it. For example, code like this: + // + // type Foo = impl Debug; + // fn foo1() -> Foo { ... } + // fn foo2() -> Foo { foo1() } + // + // In `foo2`, we're not revealing the type of `Foo` - we're + // just treating it as the opaque type. + // + // When this occurs, we do *not* want to try to equate + // the concrete type with the underlying defining type + // of the opaque type - this will always fail, since + // the defining type of an opaque type is always + // some other type (e.g. not itself) + // Essentially, none of the normal obligations apply here - + // we're just passing around some unknown opaque type, + // without actually looking at the underlying type it + // gets 'revealed' into + debug!( + "eq_opaque_type_and_type: non-defining use of {:?}", + opaque_type_key.def_id, + ); + None + } else { + Some((opaque_type_key, decl)) + } }) .collect() }, @@ -262,7 +274,7 @@ fn type_check_internal<'a, 'tcx, R>( borrowck_context, ); let errors_reported = { - let mut verifier = TypeVerifier::new(&mut checker, promoted); + let mut verifier = TypeVerifier::new(&mut checker, body, promoted); verifier.visit_body(&body); verifier.errors_reported }; @@ -319,6 +331,7 @@ enum FieldAccessError { /// is a problem. struct TypeVerifier<'a, 'b, 'tcx> { cx: &'a mut TypeChecker<'b, 'tcx>, + body: &'b Body<'tcx>, promoted: &'b IndexVec>, last_span: Span, errors_reported: bool, @@ -454,7 +467,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { self.super_rvalue(rvalue, location); - let rval_ty = rvalue.ty(self.body(), self.tcx()); + let rval_ty = rvalue.ty(self.body, self.tcx()); self.sanitize_type(rvalue, rval_ty); } @@ -513,13 +526,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn new( cx: &'a mut TypeChecker<'b, 'tcx>, + body: &'b Body<'tcx>, promoted: &'b IndexVec>, ) -> Self { - TypeVerifier { promoted, last_span: cx.body.span, cx, errors_reported: false } - } - - fn body(&self) -> &Body<'tcx> { - self.cx.body + TypeVerifier { body, promoted, cx, last_span: body.span, errors_reported: false } } fn tcx(&self) -> TyCtxt<'tcx> { @@ -544,7 +554,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { ) -> PlaceTy<'tcx> { debug!("sanitize_place: {:?}", place); - let mut place_ty = PlaceTy::from_ty(self.body().local_decls[place.local].ty); + let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty); for elem in place.projection.iter() { if place_ty.variant_index.is_none() { @@ -589,7 +599,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { // checker on the promoted MIR, then transfer the constraints back to // the main MIR, changing the locations to the provided location. - let parent_body = mem::replace(&mut self.cx.body, promoted_body); + let parent_body = mem::replace(&mut self.body, promoted_body); // Use new sets of constraints and closure bounds so that we can // modify their locations. @@ -625,7 +635,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.cx.typeck_mir(promoted_body); } - self.cx.body = parent_body; + self.body = parent_body; // Merge the outlives constraints back in, at the given location. swap_constraints(self); @@ -687,7 +697,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { })) } ProjectionElem::Index(i) => { - let index_ty = Place::from(i).ty(self.body(), tcx).ty; + let index_ty = Place::from(i).ty(self.body, tcx).ty; if index_ty != tcx.types.usize { PlaceTy::from_ty(span_mirbug_and_err!(self, i, "index by non-usize {:?}", i)) } else { @@ -896,7 +906,7 @@ struct BorrowCheckContext<'a, 'tcx> { crate struct MirTypeckResults<'tcx> { crate constraints: MirTypeckRegionConstraints<'tcx>, crate universal_region_relations: Frozen>, - crate opaque_type_values: VecMap, (Ty<'tcx>, Span, OpaqueTyOrigin)>, + crate opaque_type_values: VecMap, OpaqueTypeDecl<'tcx>>, } /// A collection of region constraints that must be satisfied for the @@ -1046,19 +1056,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { checker } - fn body(&self) -> &Body<'tcx> { - self.body - } - fn unsized_feature_enabled(&self) -> bool { let features = self.tcx().features(); features.unsized_locals || features.unsized_fn_params } /// Equate the inferred type and the annotated type for user type annotations - #[instrument(skip(self), level = "debug")] fn check_user_type_annotations(&mut self) { - debug!(?self.user_type_annotations); + debug!( + "check_user_type_annotations: user_type_annotations={:?}", + self.user_type_annotations + ); for user_annotation in self.user_type_annotations { let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; let inferred_ty = self.normalize(inferred_ty, Locations::All(span)); @@ -1199,6 +1207,131 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Ok(()) } + /// Equates a type `anon_ty` that may contain opaque types whose + /// values are to be inferred by the MIR. + /// + /// The type `revealed_ty` contains the same type as `anon_ty`, but with the + /// hidden types for impl traits revealed. + /// + /// # Example + /// + /// Consider a piece of code like + /// + /// ```rust + /// type Foo = impl Debug; + /// + /// fn foo(t: T) -> Box> { + /// Box::new((t, 22_u32)) + /// } + /// ``` + /// + /// Here, the function signature would be something like + /// `fn(T) -> Box`. The MIR return slot would have + /// the type with the opaque type revealed, so `Box<(T, u32)>`. + /// + /// In terms of our function parameters: + /// + /// * `anon_ty` would be `Box>` where `Foo` is an opaque type + /// scoped to this function (note that it is parameterized by the + /// generics of `foo`). Note that `anon_ty` is not just the opaque type, + /// but the entire return type (which may contain opaque types within it). + /// * `revealed_ty` would be `Box<(T, u32)>` + #[instrument(skip(self), level = "debug")] + fn eq_opaque_type_and_type( + &mut self, + revealed_ty: Ty<'tcx>, + anon_ty: Ty<'tcx>, + locations: Locations, + category: ConstraintCategory, + ) -> Fallible<()> { + // Fast path for the common case. + if !anon_ty.has_opaque_types() { + if let Err(terr) = self.eq_types(anon_ty, revealed_ty, locations, category) { + span_mirbug!( + self, + locations, + "eq_opaque_type_and_type: `{:?}=={:?}` failed with `{:?}`", + revealed_ty, + anon_ty, + terr + ); + } + return Ok(()); + } + + let param_env = self.param_env; + let body = self.body; + let mir_def_id = body.source.def_id().expect_local(); + + debug!(?mir_def_id); + self.fully_perform_op( + locations, + category, + CustomTypeOp::new( + |infcx| { + let mut obligations = ObligationAccumulator::default(); + + let dummy_body_id = hir::CRATE_HIR_ID; + + // Replace the opaque types defined by this function with + // inference variables, creating a map. In our example above, + // this would transform the type `Box>` (where `Foo` is an opaque type) + // to `Box`, returning an `opaque_type_map` mapping `{Foo -> ?T}`. + // (Note that the key of the map is both the def-id of `Foo` along with + // any generic parameters.) + let output_ty = obligations.add(infcx.instantiate_opaque_types( + dummy_body_id, + param_env, + anon_ty, + locations.span(body), + )); + debug!(?output_ty, ?revealed_ty); + + // Make sure that the inferred types are well-formed. I'm + // not entirely sure this is needed (the HIR type check + // didn't do this) but it seems sensible to prevent opaque + // types hiding ill-formed types. + obligations.obligations.push(traits::Obligation::new( + ObligationCause::dummy(), + param_env, + ty::Binder::dummy(ty::PredicateKind::WellFormed(revealed_ty.into())) + .to_predicate(infcx.tcx), + )); + obligations.add( + infcx + .at(&ObligationCause::dummy(), param_env) + .eq(output_ty, revealed_ty)?, + ); + + debug!("equated"); + + Ok(InferOk { value: (), obligations: obligations.into_vec() }) + }, + || "input_output".to_string(), + ), + )?; + + // Finally, if we instantiated the anon types successfully, we + // have to solve any bounds (e.g., `-> impl Iterator` needs to + // prove that `T: Iterator` where `T` is the type we + // instantiated it with). + let opaque_type_map = self.infcx.inner.borrow().opaque_types.clone(); + for (opaque_type_key, opaque_decl) in opaque_type_map { + self.fully_perform_op( + locations, + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |infcx| { + infcx.constrain_opaque_type(opaque_type_key, &opaque_decl); + Ok(InferOk { value: (), obligations: vec![] }) + }, + || "opaque_type_map".to_string(), + ), + )?; + } + Ok(()) + } + fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -2641,31 +2774,19 @@ impl NormalizeLocation for Location { } } -/// Runs `infcx.instantiate_opaque_types`. Unlike other `TypeOp`s, -/// this is not canonicalized - it directly affects the main `InferCtxt` -/// that we use during MIR borrowchecking. -#[derive(Debug)] -pub(super) struct InstantiateOpaqueType<'tcx> { - pub base_universe: Option, - pub region_constraints: Option>, - pub obligation: PredicateObligation<'tcx>, +#[derive(Debug, Default)] +struct ObligationAccumulator<'tcx> { + obligations: PredicateObligations<'tcx>, } -impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { - type Output = (); - /// We use this type itself to store the information used - /// when reporting errors. Since this is not a query, we don't - /// re-run anything during error reporting - we just use the information - /// we saved to help extract an error from the already-existing region - /// constraints in our `InferCtxt` - type ErrorInfo = InstantiateOpaqueType<'tcx>; - - fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible> { - let (mut output, region_constraints) = scrape_region_constraints(infcx, || { - Ok(InferOk { value: (), obligations: vec![self.obligation.clone()] }) - })?; - self.region_constraints = Some(region_constraints); - output.error_info = Some(self); - Ok(output) +impl<'tcx> ObligationAccumulator<'tcx> { + fn add(&mut self, value: InferOk<'tcx, T>) -> T { + let InferOk { value, obligations } = value; + self.obligations.extend(obligations); + value + } + + fn into_vec(self) -> PredicateObligations<'tcx> { + self.obligations } } diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 1d6ad697443aa..cc3fe0a123c55 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,15 +1,13 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::NllRegionVariableOrigin; -use rustc_infer::traits::ObligationCause; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Const, Ty}; -use rustc_span::Span; use rustc_trait_selection::traits::query::Fallible; use crate::constraints::OutlivesConstraint; use crate::diagnostics::UniverseInfo; -use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker}; +use crate::type_check::{Locations, TypeChecker}; impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`: @@ -65,10 +63,6 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { } impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { - fn span(&self) -> Span { - self.locations.span(self.type_checker.body) - } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.type_checker.param_env } @@ -123,9 +117,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> // We don't have to worry about the equality of consts during borrow checking // as consts always have a static lifetime. - // FIXME(oli-obk): is this really true? We can at least have HKL and with - // inline consts we may have further lifetimes that may be unsound to treat as - // 'static. fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {} fn normalization() -> NormalizationStrategy { @@ -135,30 +126,4 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> fn forbid_inference_vars() -> bool { true } - - fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) { - let param_env = self.param_env(); - let span = self.span(); - let def_id = self.type_checker.body.source.def_id().expect_local(); - let body_id = self.type_checker.tcx().hir().local_def_id_to_hir_id(def_id); - let cause = ObligationCause::misc(span, body_id); - self.type_checker - .fully_perform_op( - self.locations, - self.category, - InstantiateOpaqueType { - obligation: self.type_checker.infcx.opaque_ty_obligation( - a, - b, - a_is_expected, - param_env, - cause, - ), - // These fields are filled in during exectuion of the operation - base_universe: None, - region_constraints: None, - }, - ) - .unwrap(); - } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index a944b2d87ac6d..16a903d5e593f 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -728,7 +728,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { self.tcx.fold_regions(value, &mut false, |_region, _depth| self.next_nll_region_var(origin)) } - #[instrument(level = "debug", skip(self, indices))] fn replace_bound_regions_with_nll_infer_vars( &self, origin: NllRegionVariableOrigin, @@ -739,15 +738,22 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { where T: TypeFoldable<'tcx>, { + debug!( + "replace_bound_regions_with_nll_infer_vars(value={:?}, all_outlive_scope={:?})", + value, all_outlive_scope, + ); let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { - debug!(?br); + debug!("replace_bound_regions_with_nll_infer_vars: br={:?}", br); let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: all_outlive_scope.to_def_id(), bound_region: br.kind, })); let region_vid = self.next_nll_region_var(origin); indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); - debug!(?liberated_region, ?region_vid); + debug!( + "replace_bound_regions_with_nll_infer_vars: liberated_region={:?} => {:?}", + liberated_region, region_vid + ); region_vid }); value @@ -762,7 +768,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { /// entries for them and store them in the indices map. This code iterates over the complete /// set of late-bound regions and checks for any that we have not yet seen, adding them to the /// inputs vector. - #[instrument(skip(self, indices))] fn replace_late_bound_regions_with_nll_infer_vars( &self, mir_def_id: LocalDefId, @@ -774,7 +779,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r); if !indices.indices.contains_key(&r) { let region_vid = self.next_nll_region_var(FR); - debug!(?region_vid); indices.insert_late_bound_region(r, region_vid.to_region_vid()); } }); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 49a9b911f3a4b..6799514a4490d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt}; -use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeFoldable}; +use rustc_middle::ty::{Binder, TraitPredicate, TraitRef}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; use rustc_trait_selection::traits::SelectionContext; @@ -46,10 +46,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { location: Location, ) -> bool { let ty = ccx.body.local_decls[local].ty; - // Peeking into opaque types causes cycles if the current function declares said opaque - // type. Thus we avoid short circuiting on the type and instead run the more expensive - // analysis that looks at the actual usage within this function - if !ty.has_opaque_types() && !NeedsDrop::in_any_value_of_ty(ccx, ty) { + if !NeedsDrop::in_any_value_of_ty(ccx, ty) { return false; } @@ -103,10 +100,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { location: Location, ) -> bool { let ty = ccx.body.local_decls[local].ty; - // Peeking into opaque types causes cycles if the current function declares said opaque - // type. Thus we avoid short circuiting on the type and instead run the more expensive - // analysis that looks at the actual usage within this function - if !ty.has_opaque_types() && !HasMutInterior::in_any_value_of_ty(ccx, ty) { + if !HasMutInterior::in_any_value_of_ty(ccx, ty) { return false; } @@ -154,12 +148,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { // If we know that all values of the return type are structurally matchable, there's no // need to run dataflow. - // Opaque types do not participate in const generics or pattern matching, so we can safely count them out. - _ if ccx.body.return_ty().has_opaque_types() - || !CustomEq::in_any_value_of_ty(ccx, ccx.body.return_ty()) => - { - false - } + _ if !CustomEq::in_any_value_of_ty(ccx, ccx.body.return_ty()) => false, hir::ConstContext::Const | hir::ConstContext::Static(_) => { let mut cursor = FlowSensitiveAnalysis::new(CustomEq, ccx) @@ -406,7 +395,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { | ty::PredicateKind::Projection(_) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, ty::PredicateKind::ObjectSafe(_) => { bug!("object safe predicate on function: {:#?}", predicate) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index f8e5764878579..cf15fc4ddc3a5 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -79,6 +79,7 @@ pub fn equal_up_to_regions<'tcx>( } // Normalize lifetimes away on both sides, then compare. + let param_env = param_env.with_reveal_all_normalized(tcx); let normalize = |ty: Ty<'tcx>| { tcx.normalize_erasing_regions( param_env, @@ -170,7 +171,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } // Normalize projections and things like that. - let param_env = self.param_env; + // FIXME: We need to reveal_all, as some optimizations change types in ways + // that require unfolding opaque types. + let param_env = self.param_env.with_reveal_all_normalized(self.tcx); let src = self.tcx.normalize_erasing_regions(param_env, src); let dest = self.tcx.normalize_erasing_regions(param_env, dest); diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 2f4b3844430e3..cc7ec9432faed 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -30,11 +30,6 @@ where } } - /// Removes the entry from the map and returns the removed value - pub fn remove(&mut self, k: &K) -> Option { - self.0.iter().position(|(k2, _)| k2 == k).map(|pos| self.0.remove(pos).1) - } - /// Gets a reference to the value in the entry. pub fn get(&self, k: &Q) -> Option<&V> where @@ -44,15 +39,6 @@ where self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1) } - /// Gets a mutable reference to the value in the entry. - pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where - K: Borrow, - Q: Eq, - { - self.0.iter_mut().find(|(key, _)| k == key.borrow()).map(|elem| &mut elem.1) - } - /// Returns the any value corresponding to the supplied predicate filter. /// /// The supplied predicate will be applied to each (key, value) pair and it will return a @@ -72,7 +58,7 @@ where // This should return just one element, otherwise it's a bug assert!( filter.next().is_none(), - "Collection {:#?} should have just one matching element", + "Collection {:?} should have just one matching element", self ); Some(value) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 6515f948dd3bc..c26ea4c966903 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -34,12 +34,6 @@ pub struct At<'a, 'tcx> { pub infcx: &'a InferCtxt<'a, 'tcx>, pub cause: &'a ObligationCause<'tcx>, pub param_env: ty::ParamEnv<'tcx>, - /// Whether we should define opaque types - /// or just treat them opaquely. - /// Currently only used to prevent predicate - /// matching from matching anything against opaque - /// types. - pub define_opaque_types: bool, } pub struct Trace<'a, 'tcx> { @@ -55,7 +49,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> At<'a, 'tcx> { - At { infcx: self, cause, param_env, define_opaque_types: true } + At { infcx: self, cause, param_env } } } @@ -70,10 +64,6 @@ pub trait ToTrace<'tcx>: Relate<'tcx> + Copy { } impl<'a, 'tcx> At<'a, 'tcx> { - pub fn define_opaque_types(self, define_opaque_types: bool) -> Self { - Self { define_opaque_types, ..self } - } - /// Hacky routine for equating two impl headers in coherence. pub fn eq_impl_headers( self, @@ -204,7 +194,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types); + let mut fields = at.infcx.combine_fields(trace, at.param_env); fields .sub(a_is_expected) .relate(a, b) @@ -221,7 +211,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types); + let mut fields = at.infcx.combine_fields(trace, at.param_env); fields .equate(a_is_expected) .relate(a, b) @@ -236,7 +226,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types); + let mut fields = at.infcx.combine_fields(trace, at.param_env); fields .lub(a_is_expected) .relate(a, b) @@ -251,7 +241,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types); + let mut fields = at.infcx.combine_fields(trace, at.param_env); fields .glb(a_is_expected) .relate(a, b) diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 7d86f8a763c30..5b4a9d9dfad45 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -26,7 +26,6 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt}; -use rustc_span::Span; use std::fmt::Debug; use std::iter; @@ -90,7 +89,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { var_values: inference_vars, region_constraints: QueryRegionConstraints::default(), certainty: Certainty::Proven, // Ambiguities are OK! - opaque_types: vec![], value: answer, }) } @@ -135,27 +133,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let certainty = if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; - let opaque_types = self.take_opaque_types_for_query_response(); - Ok(QueryResponse { var_values: inference_vars, region_constraints, certainty, value: answer, - opaque_types, }) } - fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { - self.inner - .borrow_mut() - .opaque_type_storage - .take_opaque_types() - .into_iter() - .map(|(k, v)| (self.tcx.mk_opaque(k.def_id, k.substs), v.hidden_type.ty)) - .collect() - } - /// Given the (canonicalized) result to a canonical query, /// instantiates the result so it can be used, plugging in the /// values from the canonical query. (Note that the result may @@ -238,12 +223,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { where R: Debug + TypeFoldable<'tcx>, { - let InferOk { value: result_subst, mut obligations } = self - .query_response_substitution_guess(cause, param_env, original_values, query_response)?; + let result_subst = + self.query_response_substitution_guess(cause, original_values, query_response); // Compute `QueryOutlivesConstraint` values that unify each of // the original values `v_o` that was canonicalized into a // variable... + let mut obligations = vec![]; for (index, original_value) in original_values.var_values.iter().enumerate() { // ...with the value `v_r` of that variable from the query. @@ -358,25 +344,20 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { original_values, query_response, ); - let mut value = self.query_response_substitution_guess( - cause, - param_env, - original_values, - query_response, - )?; + let result_subst = + self.query_response_substitution_guess(cause, original_values, query_response); - value.obligations.extend( - self.unify_query_response_substitution_guess( + let obligations = self + .unify_query_response_substitution_guess( cause, param_env, original_values, - &value.value, + &result_subst, query_response, )? - .into_obligations(), - ); + .into_obligations(); - Ok(value) + Ok(InferOk { value: result_subst, obligations }) } /// Given the original values and the (canonicalized) result from @@ -391,10 +372,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { fn query_response_substitution_guess( &self, cause: &ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, - ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> + ) -> CanonicalVarValues<'tcx> where R: Debug + TypeFoldable<'tcx>, { @@ -494,16 +474,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { .collect(), }; - let mut obligations = vec![]; - - // Carry all newly resolved opaque types to the caller's scope - for &(a, b) in &query_response.value.opaque_types { - let a = substitute_value(self.tcx, &result_subst, a); - let b = substitute_value(self.tcx, &result_subst, b); - obligations.extend(self.handle_opaque_type(a, b, cause, param_env)?.obligations); - } - - Ok(InferOk { value: result_subst, obligations }) + result_subst } /// Given a "guess" at the values for the canonical variables in @@ -660,10 +631,6 @@ struct QueryTypeRelatingDelegate<'a, 'tcx> { } impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { - fn span(&self) -> Span { - self.cause.span - } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -719,14 +686,4 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { fn forbid_inference_vars() -> bool { true } - - fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) { - self.obligations.push(self.infcx.opaque_ty_obligation( - a, - b, - a_is_expected, - self.param_env, - self.cause.clone(), - )); - } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 5668b6c10b000..a77fd8fae8d20 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -51,12 +51,6 @@ pub struct CombineFields<'infcx, 'tcx> { pub cause: Option, pub param_env: ty::ParamEnv<'tcx>, pub obligations: PredicateObligations<'tcx>, - /// Whether we should define opaque types - /// or just treat them opaquely. - /// Currently only used to prevent predicate - /// matching from matching anything against opaque - /// types. - pub define_opaque_types: bool, } #[derive(Copy, Clone, Debug)] @@ -328,7 +322,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { /// will first instantiate `b_vid` with a *generalized* version /// of `a_ty`. Generalization introduces other inference /// variables wherever subtyping could occur. - #[instrument(skip(self), level = "debug")] pub fn instantiate( &mut self, a_ty: Ty<'tcx>, @@ -341,6 +334,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { // Get the actual variable that b_vid has been inferred to debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown()); + debug!("instantiate(a_ty={:?} dir={:?} b_vid={:?})", a_ty, dir, b_vid); + // Generalize type of `a_ty` appropriately depending on the // direction. As an example, assume: // @@ -353,7 +348,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { // variables. (Down below, we will relate `a_ty <: b_ty`, // adding constraints like `'x: '?2` and `?1 <: ?3`.) let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?; - debug!(?b_ty); + debug!( + "instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})", + a_ty, dir, b_vid, b_ty + ); self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty); if needs_wf { @@ -394,13 +392,13 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { /// Preconditions: /// /// - `for_vid` is a "root vid" - #[instrument(skip(self), level = "trace")] fn generalize( &self, ty: Ty<'tcx>, for_vid: ty::TyVid, dir: RelationDir, ) -> RelateResult<'tcx, Generalization<'tcx>> { + debug!("generalize(ty={:?}, for_vid={:?}, dir={:?}", ty, for_vid, dir); // Determine the ambient variance within which `ty` appears. // The surrounding equation is: // @@ -414,7 +412,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { RelationDir::SupertypeOf => ty::Contravariant, }; - trace!(?ambient_variance); + debug!("generalize: ambient_variance = {:?}", ambient_variance); let for_universe = match self.infcx.inner.borrow_mut().type_variables().probe(for_vid) { v @ TypeVariableValue::Known { .. } => { @@ -423,8 +421,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { TypeVariableValue::Unknown { universe } => universe, }; - trace!(?for_universe); - trace!(?self.trace); + debug!("generalize: for_universe = {:?}", for_universe); + debug!("generalize: trace = {:?}", self.trace); let mut generalize = Generalizer { infcx: self.infcx, @@ -441,12 +439,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { let ty = match generalize.relate(ty, ty) { Ok(ty) => ty, Err(e) => { - debug!(?e, "failure"); + debug!("generalize: failure {:?}", e); return Err(e); } }; let needs_wf = generalize.needs_wf; - trace!(?ty, ?needs_wf, "success"); + debug!("generalize: success {{ {:?}, {:?} }}", ty, needs_wf); Ok(Generalization { ty, needs_wf }) } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 9f6c6d3184533..90c0ff9226f77 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -66,19 +66,18 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.relate(a, b) } - #[instrument(skip(self), level = "debug")] fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + debug!("{}.tys({:?}, {:?})", self.tag(), a, b); if a == b { return Ok(a); } - trace!(a = ?a.kind(), b = ?b.kind()); - let infcx = self.fields.infcx; - let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a); let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b); + debug!("{}.tys: replacements ({:?}, {:?})", self.tag(), a, b); + match (a.kind(), b.kind()) { (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => { infcx.inner.borrow_mut().type_variables().equate(a_id, b_id); @@ -92,21 +91,6 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?; } - (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { - self.fields.infcx.super_combine_tys(self, a, b)?; - } - (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) - if self.fields.define_opaque_types && did.is_local() => - { - self.fields.obligations.push(infcx.opaque_ty_obligation( - a, - b, - self.a_is_expected(), - self.param_env(), - self.fields.trace.cause.clone(), - )); - } - _ => { self.fields.infcx.super_combine_tys(self, a, b)?; } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index c4c4eab261e86..862f5a5fbb8c1 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -4,7 +4,7 @@ use super::InferCtxt; use super::Subtype; use crate::infer::combine::ConstEquateRelation; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -111,20 +111,12 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, &self.fields.trace.cause } - fn add_obligations(&mut self, obligations: Vec>) { - self.fields.obligations.extend(obligations) - } - fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { let mut sub = self.fields.sub(self.a_is_expected); sub.relate(v, a)?; sub.relate(v, b)?; Ok(()) } - - fn define_opaque_types(&self) -> bool { - self.fields.define_opaque_types - } } impl<'tcx> ConstEquateRelation<'tcx> for Glb<'_, '_, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs index 6bda44f0ef256..c47d476963772 100644 --- a/compiler/rustc_infer/src/infer/lattice.rs +++ b/compiler/rustc_infer/src/infer/lattice.rs @@ -22,7 +22,7 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::InferCtxt; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -32,10 +32,6 @@ pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> { fn cause(&self) -> &ObligationCause<'tcx>; - fn add_obligations(&mut self, obligations: Vec>); - - fn define_opaque_types(&self) -> bool; - // Relates the type `v` to `a` and `b` such that `v` represents // the LUB/GLB of `a` and `b` as appropriate. // @@ -45,7 +41,6 @@ pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> { fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>; } -#[instrument(skip(this), level = "debug")] pub fn super_lattice_tys<'a, 'tcx: 'a, L>( this: &mut L, a: Ty<'tcx>, @@ -54,17 +49,15 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( where L: LatticeDir<'a, 'tcx>, { - debug!("{}", this.tag()); + debug!("{}.lattice_tys({:?}, {:?})", this.tag(), a, b); if a == b { return Ok(a); } let infcx = this.infcx(); - let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a); let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b); - match (a.kind(), b.kind()) { // If one side is known to be a variable and one is not, // create a variable (`v`) to represent the LUB. Make sure to @@ -101,22 +94,6 @@ where Ok(v) } - (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { - infcx.super_combine_tys(this, a, b) - } - (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) - if this.define_opaque_types() && did.is_local() => - { - this.add_obligations(vec![infcx.opaque_ty_obligation( - a, - b, - this.a_is_expected(), - this.param_env(), - this.cause().clone(), - )]); - Ok(a) - } - _ => infcx.super_combine_tys(this, a, b), } } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index bbd8e00146905..5191d1c1cc100 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -4,7 +4,7 @@ use super::InferCtxt; use super::Subtype; use crate::infer::combine::ConstEquateRelation; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -117,18 +117,10 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, &self.fields.trace.cause } - fn add_obligations(&mut self, obligations: Vec>) { - self.fields.obligations.extend(obligations) - } - fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { let mut sub = self.fields.sub(self.a_is_expected); sub.relate(a, v)?; sub.relate(b, v)?; Ok(()) } - - fn define_opaque_types(&self) -> bool { - self.fields.define_opaque_types - } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 08320a0ff1d42..c18d36d1f74a2 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -5,7 +5,7 @@ pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; -use self::opaque_types::OpaqueTypeStorage; +use self::opaque_types::OpaqueTypeMap; pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine}; @@ -192,8 +192,18 @@ pub struct InferCtxtInner<'tcx> { undo_log: InferCtxtUndoLogs<'tcx>, - /// Caches for opaque type inference. - pub opaque_type_storage: OpaqueTypeStorage<'tcx>, + // Opaque types found in explicit return types and their + // associated fresh inference variable. Writeback resolves these + // variables to get the concrete type, which can be used to + // 'de-opaque' OpaqueTypeDecl outside of type inference. + pub opaque_types: OpaqueTypeMap<'tcx>, + + /// A map from inference variables created from opaque + /// type instantiations (`ty::Infer`) to the actual opaque + /// type (`ty::Opaque`). Used during fallback to map unconstrained + /// opaque type inference variables to their corresponding + /// opaque type. + pub opaque_types_vars: FxHashMap, Ty<'tcx>>, } impl<'tcx> InferCtxtInner<'tcx> { @@ -207,7 +217,8 @@ impl<'tcx> InferCtxtInner<'tcx> { float_unification_storage: ut::UnificationTableStorage::new(), region_constraint_storage: Some(RegionConstraintStorage::new()), region_obligations: vec![], - opaque_type_storage: Default::default(), + opaque_types: Default::default(), + opaque_types_vars: Default::default(), } } @@ -226,11 +237,6 @@ impl<'tcx> InferCtxtInner<'tcx> { self.type_variable_storage.with_log(&mut self.undo_log) } - #[inline] - pub fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> { - self.opaque_type_storage.with_log(&mut self.undo_log) - } - #[inline] fn int_unification_table( &mut self, @@ -291,10 +297,6 @@ pub struct InferCtxt<'a, 'tcx> { /// to the outside until the end up in an `InferCtxt` for typeck or borrowck. pub defining_use_anchor: Option, - /// Used by WF-checking to not have to figure out hidden types itself, but - /// to just invoke type_of to get the already computed hidden type from typeck. - pub reveal_defining_opaque_types: bool, - /// During type-checking/inference of a body, `in_progress_typeck_results` /// contains a reference to the typeck results being built up, which are /// used for reading closure kinds/signatures as they are inferred, @@ -563,7 +565,6 @@ pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, fresh_typeck_results: Option>>, defining_use_anchor: Option, - reveal_defining_opaque_types: bool, } pub trait TyCtxtInferExt<'tcx> { @@ -572,12 +573,7 @@ pub trait TyCtxtInferExt<'tcx> { impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { - InferCtxtBuilder { - tcx: self, - defining_use_anchor: None, - fresh_typeck_results: None, - reveal_defining_opaque_types: false, - } + InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None } } } @@ -601,13 +597,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } - /// WF-checking doesn't need to recompute opaque types and can instead use - /// the type_of query to get them from typeck. - pub fn reveal_defining_opaque_types(mut self) -> Self { - self.reveal_defining_opaque_types = true; - self - } - /// Given a canonical value `C` as a starting point, create an /// inference context that contains each of the bound values /// within instantiated as a fresh variable. The `f` closure is @@ -632,17 +621,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn enter(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R { - let InferCtxtBuilder { - tcx, - defining_use_anchor, - reveal_defining_opaque_types, - ref fresh_typeck_results, - } = *self; + let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self; let in_progress_typeck_results = fresh_typeck_results.as_ref(); f(InferCtxt { tcx, defining_use_anchor, - reveal_defining_opaque_types, in_progress_typeck_results, inner: RefCell::new(InferCtxtInner::new()), lexical_region_resolutions: RefCell::new(None), @@ -764,7 +747,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>, - define_opaque_types: bool, ) -> CombineFields<'a, 'tcx> { CombineFields { infcx: self, @@ -772,7 +754,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { cause: None, param_env, obligations: PredicateObligations::new(), - define_opaque_types, } } @@ -1088,20 +1069,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.mk_ty_var(self.next_ty_var_id(origin)) } - pub fn next_ty_var_id_in_universe( - &self, - origin: TypeVariableOrigin, - universe: ty::UniverseIndex, - ) -> TyVid { - self.inner.borrow_mut().type_variables().new_var(universe, origin) - } - pub fn next_ty_var_in_universe( &self, origin: TypeVariableOrigin, universe: ty::UniverseIndex, ) -> Ty<'tcx> { - let vid = self.next_ty_var_id_in_universe(origin, universe); + let vid = self.inner.borrow_mut().type_variables().new_var(universe, origin); self.tcx.mk_ty_var(vid) } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 3a288516664e3..0a210ed053ce4 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -24,13 +24,11 @@ use crate::infer::combine::ConstEquateRelation; use crate::infer::InferCtxt; use crate::infer::{ConstVarValue, ConstVariableValue}; -use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; -use rustc_span::Span; use std::fmt::Debug; use std::ops::ControlFlow; @@ -77,7 +75,6 @@ where pub trait TypeRelatingDelegate<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx>; - fn span(&self) -> Span; /// Push a constraint `sup: sub` -- this constraint must be /// satisfied for the two types to be related. `sub` and `sup` may @@ -90,8 +87,6 @@ pub trait TypeRelatingDelegate<'tcx> { info: ty::VarianceDiagInfo<'tcx>, ); - fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool); - fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>); /// Creates a new universe index. Used when instantiating placeholders. @@ -282,6 +277,7 @@ where projection_ty: ty::ProjectionTy<'tcx>, value_ty: Ty<'tcx>, ) -> Ty<'tcx> { + use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_span::DUMMY_SP; match *value_ty.kind() { @@ -290,8 +286,6 @@ where kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }); - // FIXME(lazy-normalization): This will always ICE, because the recursive - // call will end up in the _ arm below. self.relate_projection_ty(projection_ty, var); self.relate_projection_ty(other_projection_ty, var); var @@ -537,8 +531,6 @@ where #[instrument(skip(self), level = "debug")] fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - let infcx = self.infcx; - let a = self.infcx.shallow_resolve(a); if !D::forbid_inference_vars() { @@ -567,35 +559,6 @@ where (&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)), - (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { - self.infcx.super_combine_tys(self, a, b) - } - (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => { - let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; - let mut generalize = |ty, ty_is_expected| { - let var = infcx.next_ty_var_id_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.delegate.span(), - }, - ty::UniverseIndex::ROOT, - ); - if ty_is_expected { - self.relate_ty_var((ty, var)) - } else { - self.relate_ty_var((var, ty)) - } - }; - let (a, b) = match (a.kind(), b.kind()) { - (&ty::Opaque(..), _) => (a, generalize(b, false)?), - (_, &ty::Opaque(..)) => (generalize(a, true)?, b), - _ => unreachable!(), - }; - self.delegate.register_opaque_type(a, b, true); - trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated"); - Ok(a) - } - (&ty::Projection(projection_ty), _) if D::normalization() == NormalizationStrategy::Lazy => { diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 46420fbe0c305..e7dca94806cb7 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -1,11 +1,10 @@ +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::{self, PredicateObligation}; -use hir::def_id::{DefId, LocalDefId}; -use hir::OpaqueTyOrigin; +use crate::traits; use rustc_data_structures::sync::Lrc; use rustc_data_structures::vec_map::VecMap; use rustc_hir as hir; -use rustc_middle::traits::ObligationCause; +use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor}; @@ -15,28 +14,14 @@ use std::ops::ControlFlow; pub type OpaqueTypeMap<'tcx> = VecMap, OpaqueTypeDecl<'tcx>>; -mod table; - -pub use table::{OpaqueTypeStorage, OpaqueTypeTable}; - -use super::InferResult; - /// Information about the opaque types whose values we /// are inferring in this function (these are the `impl Trait` that /// appear in the return type). -#[derive(Clone, Debug)] +#[derive(Copy, Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { - /// The hidden types that have been inferred for this opaque type. - /// There can be multiple, but they are all `lub`ed together at the end - /// to obtain the canonical hidden type. - pub hidden_type: OpaqueHiddenType<'tcx>, - - /// The origin of the opaque type. - pub origin: hir::OpaqueTyOrigin, -} + /// The opaque type (`ty::Opaque`) for this declaration. + pub opaque_type: Ty<'tcx>, -#[derive(Copy, Clone, Debug, TypeFoldable)] -pub struct OpaqueHiddenType<'tcx> { /// The span of this particular definition of the opaque type. So /// for example: /// @@ -50,7 +35,7 @@ pub struct OpaqueHiddenType<'tcx> { /// In cases where the fn returns `(impl Trait, impl Trait)` or /// other such combinations, the result is currently /// over-approximated, but better than nothing. - pub span: Span, + pub definition_span: Span, /// The type variable that represents the value of the opaque type /// that we require. In other words, after we compile this function, @@ -64,132 +49,54 @@ pub struct OpaqueHiddenType<'tcx> { /// those that are arguments to `Foo` in the constraint above. (In /// other words, `?C` should not include `'b`, even though it's a /// lifetime parameter on `foo`.) - pub ty: Ty<'tcx>, + pub concrete_ty: Ty<'tcx>, + + /// The origin of the opaque type. + pub origin: hir::OpaqueTyOrigin, } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub fn handle_opaque_type( + /// Replaces all opaque types in `value` with fresh inference variables + /// and creates appropriate obligations. For example, given the input: + /// + /// impl Iterator + /// + /// this method would create two type variables, `?0` and `?1`. It would + /// return the type `?0` but also the obligations: + /// + /// ?0: Iterator + /// ?1: Debug + /// + /// Moreover, it returns an `OpaqueTypeMap` that would map `?0` to + /// info about the `impl Iterator<..>` type and `?1` to info about + /// the `impl Debug` type. + /// + /// # Parameters + /// + /// - `parent_def_id` -- the `DefId` of the function in which the opaque type + /// is defined + /// - `body_id` -- the body-id with which the resulting obligations should + /// be associated + /// - `param_env` -- the in-scope parameter environment to be used for + /// obligations + /// - `value` -- the value within which we are instantiating opaque types + /// - `value_span` -- the span where the value came from, used in error reporting + pub fn instantiate_opaque_types>( &self, - a: Ty<'tcx>, - b: Ty<'tcx>, - cause: &ObligationCause<'tcx>, + body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - ) -> InferResult<'tcx, ()> { - if a.references_error() || b.references_error() { - return Ok(InferOk { value: (), obligations: vec![] }); - } - if self.defining_use_anchor.is_some() { - let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { - ty::Opaque(def_id, substs) => { - if let ty::Opaque(did2, _) = *b.kind() { - // We could accept this, but there are various ways to handle this situation, and we don't - // want to make a decision on it right now. Likely this case is so super rare anyway, that - // 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) = - self.opaque_type_origin(did2, cause.span) - { - self.tcx - .sess - .struct_span_err( - cause.span, - "opaque type's hidden type cannot be another opaque type from the same scope", - ) - .span_label(cause.span, "one of the two opaque types used here has to be outside its defining scope") - .span_note( - self.tcx.def_span(def_id), - "opaque type whose hidden type is being assigned", - ) - .span_note( - self.tcx.def_span(did2), - "opaque type being used as hidden type", - ) - .emit(); - } - } - Some(self.register_hidden_type( - OpaqueTypeKey { def_id, substs }, - cause.clone(), - param_env, - b, - // Check that this is `impl Trait` type is - // declared by `parent_def_id` -- i.e., one whose - // value we are inferring. At present, this is - // always true during the first phase of - // type-check, but not always true later on during - // NLL. Once we support named opaque types more fully, - // this same scenario will be able to arise during all phases. - // - // Here is an example using type alias `impl Trait` - // that indicates the distinction we are checking for: - // - // ```rust - // mod a { - // pub type Foo = impl Iterator; - // pub fn make_foo() -> Foo { .. } - // } - // - // mod b { - // fn foo() -> a::Foo { a::make_foo() } - // } - // ``` - // - // Here, the return type of `foo` references an - // `Opaque` indeed, but not one whose value is - // presently being inferred. You can get into a - // similar situation with closure return types - // today: - // - // ```rust - // fn foo() -> impl Iterator { .. } - // fn bar() { - // let x = || foo(); // returns the Opaque assoc with `foo` - // } - // ``` - self.opaque_type_origin(def_id, cause.span)?, - )) - } - _ => None, - }; - if let Some(res) = process(a, b) { - res - } else if let Some(res) = process(b, a) { - res - } else { - // Rerun equality check, but this time error out due to - // different types. - match self.at(cause, param_env).define_opaque_types(false).eq(a, b) { - Ok(_) => span_bug!( - cause.span, - "opaque types are never equal to anything but themselves: {:#?}", - (a, b) - ), - Err(e) => Err(e), - } - } - } else { - let (opaque_type, hidden_ty) = match (a.kind(), b.kind()) { - (ty::Opaque(..), _) => (a, b), - (_, ty::Opaque(..)) => (b, a), - types => span_bug!( - cause.span, - "opaque type obligations only work for opaque types: {:#?}", - types - ), - }; - let key = opaque_type.expect_opaque_type(); - let origin = self.opaque_ty_origin_unchecked(key.def_id, cause.span); - let prev = self.inner.borrow_mut().opaque_types().register( - key, - OpaqueHiddenType { ty: hidden_ty, span: cause.span }, - origin, - ); - match prev { - Some(prev) => self.at(cause, param_env).eq(prev, hidden_ty), - None => Ok(InferOk { value: (), obligations: vec![] }), - } - } + value: T, + value_span: Span, + ) -> InferOk<'tcx, T> { + debug!( + "instantiate_opaque_types(value={:?}, body_id={:?}, \ + param_env={:?}, value_span={:?})", + value, body_id, param_env, value_span, + ); + let mut instantiator = + Instantiator { infcx: self, body_id, param_env, value_span, obligations: vec![] }; + let value = instantiator.instantiate_opaque_types_in_map(value); + InferOk { value, obligations: instantiator.obligations } } /// Given the map `opaque_types` containing the opaque @@ -324,23 +231,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// but this is not necessary, because the opaque type we /// create will be allowed to reference `T`. So we only generate a /// constraint that `'0: 'a`. + /// + /// # The `free_region_relations` parameter + /// + /// The `free_region_relations` argument is used to find the + /// "minimum" of the regions supplied to a given opaque type. + /// It must be a relation that can answer whether `'a <= 'b`, + /// where `'a` and `'b` are regions that appear in the "substs" + /// for the opaque type references (the `<'a>` in `Foo1<'a>`). + /// + /// Note that we do not impose the constraints based on the + /// generic regions from the `Foo1` definition (e.g., `'x`). This + /// is because the constraints we are imposing here is basically + /// the concern of the one generating the constraining type C1, + /// which is the current function. It also means that we can + /// take "implied bounds" into account in some cases: + /// + /// ```text + /// trait SomeTrait<'a, 'b> { } + /// fn foo<'a, 'b>(_: &'a &'b u32) -> impl SomeTrait<'a, 'b> { .. } + /// ``` + /// + /// Here, the fact that `'b: 'a` is known only because of the + /// implied bounds from the `&'a &'b u32` parameter, and is not + /// "inherent" to the opaque type definition. + /// + /// # Parameters + /// + /// - `opaque_types` -- the map produced by `instantiate_opaque_types` + /// - `free_region_relations` -- something that can be used to relate + /// the free regions (`'a`) that appear in the impl trait. #[instrument(level = "debug", skip(self))] - pub fn register_member_constraints( + pub fn constrain_opaque_type( &self, - param_env: ty::ParamEnv<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, - concrete_ty: Ty<'tcx>, - span: Span, + opaque_defn: &OpaqueTypeDecl<'tcx>, ) { let def_id = opaque_type_key.def_id; let tcx = self.tcx; - let concrete_ty = self.resolve_vars_if_possible(concrete_ty); + let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty); debug!(?concrete_ty); - let first_own_region = match self.opaque_ty_origin_unchecked(def_id, span) { + let first_own_region = match opaque_defn.origin { hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => { // We lower // @@ -384,7 +319,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { op: |r| { self.member_constraint( opaque_type_key.def_id, - span, + opaque_defn.definition_span, concrete_ty, r, &choice_regions, @@ -393,34 +328,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }); } - pub fn opaque_ty_obligation( - &self, - a: Ty<'tcx>, - b: Ty<'tcx>, - a_is_expected: bool, - param_env: ty::ParamEnv<'tcx>, - cause: ObligationCause<'tcx>, - ) -> PredicateObligation<'tcx> { - let (a, b) = if a_is_expected { (a, b) } else { (b, a) }; - PredicateObligation::new( - cause, - param_env, - self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::OpaqueType(a, b))), - ) - } - - #[instrument(skip(self), level = "trace")] - pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option { - let def_id = opaque_def_id.as_local()?; - let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + fn opaque_type_origin(&self, def_id: LocalDefId) -> Option { + let tcx = self.tcx; + let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let parent_def_id = self.defining_use_anchor?; - let item_kind = &self.tcx.hir().expect_item(def_id).kind; - + let item_kind = &tcx.hir().expect_item(def_id).kind; let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else { span_bug!( - span, - "weird opaque type: {:#?}, {:#?}", - opaque_def_id, + tcx.def_span(def_id), + "weird opaque type: {:#?}", item_kind ) }; @@ -431,29 +347,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id, // Named `type Foo = impl Bar;` hir::OpaqueTyOrigin::TyAlias => { - may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) + may_define_opaque_type(tcx, parent_def_id, opaque_hir_id) } }; - trace!(?origin); in_definition_scope.then_some(*origin) } - - #[instrument(skip(self), level = "trace")] - fn opaque_ty_origin_unchecked(&self, opaque_def_id: DefId, span: Span) -> OpaqueTyOrigin { - let def_id = opaque_def_id.as_local().unwrap(); - let origin = match self.tcx.hir().expect_item(def_id).kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin, - ref itemkind => { - span_bug!(span, "weird opaque type: {:?}, {:#?}", opaque_def_id, itemkind) - } - }; - trace!(?origin); - origin - } - - pub fn opaque_types(&self) -> OpaqueTypeMap<'tcx> { - self.inner.borrow().opaque_type_storage.opaque_types() - } } // Visitor that requires that (almost) all regions in the type visited outlive @@ -528,93 +426,180 @@ where } } -pub enum UseKind { - DefiningUse, - OpaqueUse, +struct Instantiator<'a, 'tcx> { + infcx: &'a InferCtxt<'a, 'tcx>, + body_id: hir::HirId, + param_env: ty::ParamEnv<'tcx>, + value_span: Span, + obligations: Vec>, } -impl UseKind { - pub fn is_defining(self) -> bool { - match self { - UseKind::DefiningUse => true, - UseKind::OpaqueUse => false, - } +impl<'a, 'tcx> Instantiator<'a, 'tcx> { + fn instantiate_opaque_types_in_map>(&mut self, value: T) -> T { + let tcx = self.infcx.tcx; + value.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| { + if ty.references_error() { + return tcx.ty_error(); + } else if let ty::Opaque(def_id, substs) = ty.kind() { + // Check that this is `impl Trait` type is + // declared by `parent_def_id` -- i.e., one whose + // value we are inferring. At present, this is + // always true during the first phase of + // type-check, but not always true later on during + // NLL. Once we support named opaque types more fully, + // this same scenario will be able to arise during all phases. + // + // Here is an example using type alias `impl Trait` + // that indicates the distinction we are checking for: + // + // ```rust + // mod a { + // pub type Foo = impl Iterator; + // pub fn make_foo() -> Foo { .. } + // } + // + // mod b { + // fn foo() -> a::Foo { a::make_foo() } + // } + // ``` + // + // Here, the return type of `foo` references an + // `Opaque` indeed, but not one whose value is + // presently being inferred. You can get into a + // similar situation with closure return types + // today: + // + // ```rust + // fn foo() -> impl Iterator { .. } + // fn bar() { + // let x = || foo(); // returns the Opaque assoc with `foo` + // } + // ``` + if let Some(def_id) = def_id.as_local() { + if let Some(origin) = self.infcx.opaque_type_origin(def_id) { + let opaque_type_key = + OpaqueTypeKey { def_id: def_id.to_def_id(), substs }; + return self.fold_opaque_ty(ty, opaque_type_key, origin); + } + + debug!( + "instantiate_opaque_types_in_map: \ + encountered opaque outside its definition scope \ + def_id={:?}", + def_id, + ); + } + } + + ty + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }) } -} -impl<'a, 'tcx> InferCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] - fn register_hidden_type( - &self, + fn fold_opaque_ty( + &mut self, + ty: Ty<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - hidden_ty: Ty<'tcx>, origin: hir::OpaqueTyOrigin, - ) -> InferResult<'tcx, ()> { - let tcx = self.tcx; + ) -> Ty<'tcx> { + let infcx = self.infcx; + let tcx = infcx.tcx; let OpaqueTypeKey { def_id, substs } = opaque_type_key; + // Use the same type variable if the exact same opaque type appears more + // than once in the return type (e.g., if it's passed to a type alias). + if let Some(opaque_defn) = infcx.inner.borrow().opaque_types.get(&opaque_type_key) { + debug!("re-using cached concrete type {:?}", opaque_defn.concrete_ty.kind()); + return opaque_defn.concrete_ty; + } + + let ty_var = infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: self.value_span, + }); + // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall // value being folded. In simple cases like `-> impl Foo`, // these are the same span, but not in cases like `-> (impl // Foo, impl Bar)`. - let span = cause.span; + let definition_span = self.value_span; - let mut obligations = vec![]; - let prev = self.inner.borrow_mut().opaque_types().register( - OpaqueTypeKey { def_id, substs }, - OpaqueHiddenType { ty: hidden_ty, span }, - origin, - ); - if let Some(prev) = prev { - obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations; + { + let mut infcx = self.infcx.inner.borrow_mut(); + infcx.opaque_types.insert( + OpaqueTypeKey { def_id, substs }, + OpaqueTypeDecl { opaque_type: ty, definition_span, concrete_ty: ty_var, origin }, + ); + infcx.opaque_types_vars.insert(ty_var, ty); } + debug!("generated new type inference var {:?}", ty_var.kind()); + let item_bounds = tcx.explicit_item_bounds(def_id); + self.obligations.reserve(item_bounds.len()); for (predicate, _) in item_bounds { debug!(?predicate); let predicate = predicate.subst(tcx, substs); + debug!(?predicate); let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| match *ty.kind() { - // We can't normalize associated types from `rustc_infer`, - // but we can eagerly register inference variables for them. - ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => { - self.infer_projection( - param_env, - projection_ty, - cause.clone(), - 0, - &mut obligations, - ) - } // Replace all other mentions of the same opaque type with the hidden type, // as the bounds must hold on the hidden type after all. ty::Opaque(def_id2, substs2) if def_id == def_id2 && substs == substs2 => { - hidden_ty + ty_var + } + // Instantiate nested instances of `impl Trait`. + ty::Opaque(..) => self.instantiate_opaque_types_in_map(ty), + _ => ty, + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }); + + // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them. + let predicate = predicate.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| match ty.kind() { + ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => { + infcx.infer_projection( + self.param_env, + *projection_ty, + traits::ObligationCause::misc(self.value_span, self.body_id), + 0, + &mut self.obligations, + ) } _ => ty, }, lt_op: |lt| lt, ct_op: |ct| ct, }); + debug!(?predicate); if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() { if projection.term.references_error() { - // No point on adding these obligations since there's a type error involved. - return Ok(InferOk { value: (), obligations: vec![] }); + return tcx.ty_error(); } - trace!("{:#?}", projection.term); } + + let cause = + traits::ObligationCause::new(self.value_span, self.body_id, traits::OpaqueType); + // Require that the predicate holds for the concrete type. debug!(?predicate); - obligations.push(traits::Obligation::new(cause.clone(), param_env, predicate)); + self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate)); } - Ok(InferOk { value: (), obligations }) + + ty_var } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs deleted file mode 100644 index 9b8f225ce367b..0000000000000 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ /dev/null @@ -1,88 +0,0 @@ -use rustc_data_structures::undo_log::UndoLogs; -use rustc_hir::OpaqueTyOrigin; -use rustc_middle::ty::{self, OpaqueTypeKey, Ty}; -use rustc_span::DUMMY_SP; - -use crate::infer::{InferCtxtUndoLogs, UndoLog}; - -use super::{OpaqueHiddenType, OpaqueTypeDecl, OpaqueTypeMap}; - -#[derive(Default, Debug)] -pub struct OpaqueTypeStorage<'tcx> { - // Opaque types found in explicit return types and their - // associated fresh inference variable. Writeback resolves these - // variables to get the concrete type, which can be used to - // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions. - pub opaque_types: OpaqueTypeMap<'tcx>, -} - -impl<'tcx> OpaqueTypeStorage<'tcx> { - #[instrument(level = "debug")] - pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option>) { - if let Some(idx) = idx { - self.opaque_types.get_mut(&key).unwrap().hidden_type = idx; - } else { - match self.opaque_types.remove(&key) { - None => bug!("reverted opaque type inference that was never registered: {:?}", key), - Some(_) => {} - } - } - } - - pub fn get_decl(&self, key: &OpaqueTypeKey<'tcx>) -> Option<&OpaqueTypeDecl<'tcx>> { - self.opaque_types.get(key) - } - - pub fn opaque_types(&self) -> OpaqueTypeMap<'tcx> { - self.opaque_types.clone() - } - - #[instrument(level = "debug")] - pub fn take_opaque_types(&mut self) -> OpaqueTypeMap<'tcx> { - std::mem::take(&mut self.opaque_types) - } - - #[inline] - pub(crate) fn with_log<'a>( - &'a mut self, - undo_log: &'a mut InferCtxtUndoLogs<'tcx>, - ) -> OpaqueTypeTable<'a, 'tcx> { - OpaqueTypeTable { storage: self, undo_log } - } -} - -impl<'tcx> Drop for OpaqueTypeStorage<'tcx> { - fn drop(&mut self) { - if !self.opaque_types.is_empty() { - ty::tls::with(|tcx| { - tcx.sess.delay_span_bug(DUMMY_SP, &format!("{:?}", self.opaque_types)) - }); - } - } -} - -pub struct OpaqueTypeTable<'a, 'tcx> { - storage: &'a mut OpaqueTypeStorage<'tcx>, - - undo_log: &'a mut InferCtxtUndoLogs<'tcx>, -} - -impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { - #[instrument(skip(self), level = "debug")] - pub fn register( - &mut self, - key: OpaqueTypeKey<'tcx>, - hidden_type: OpaqueHiddenType<'tcx>, - origin: OpaqueTyOrigin, - ) -> Option> { - if let Some(decl) = self.storage.opaque_types.get_mut(&key) { - let prev = std::mem::replace(&mut decl.hidden_type, hidden_type); - self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev))); - return Some(prev.ty); - } - let decl = OpaqueTypeDecl { hidden_type, origin }; - self.storage.opaque_types.insert(key, decl); - self.undo_log.push(UndoLog::OpaqueTypes(key, None)); - None - } -} diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index b60ffc1878be4..03d6c45a65345 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -28,7 +28,6 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { Some(OutlivesBound::RegionSubRegion(r_b, r_a)) diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index d554d7d935c52..a5276afc5bfa7 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -153,7 +153,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// This function may have to perform normalizations, and hence it /// returns an `InferOk` with subobligations that must be /// processed. - #[instrument(level = "debug", skip(self, region_bound_pairs_map))] pub fn process_registered_region_obligations( &self, region_bound_pairs_map: &FxHashMap>, @@ -165,6 +164,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { "cannot process registered region obligations in a snapshot" ); + debug!(?param_env, "process_registered_region_obligations()"); + let my_region_obligations = self.take_registered_region_obligations(); for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations { diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index e0a8219beede1..ccac0efd6c9ee 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -2,7 +2,6 @@ use super::combine::{CombineFields, RelationDir}; use super::SubregionOrigin; use crate::infer::combine::ConstEquateRelation; -use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::traits::Obligation; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; @@ -75,8 +74,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { } } - #[instrument(skip(self), level = "debug")] fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + debug!("{}.tys({:?}, {:?})", self.tag(), a, b); + if a == b { return Ok(a); } @@ -84,7 +84,6 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { let infcx = self.fields.infcx; let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a); let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b); - match (a.kind(), b.kind()) { (&ty::Infer(TyVar(_)), &ty::Infer(TyVar(_))) => { // Shouldn't have any LBR here, so we can safely put @@ -122,40 +121,6 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { Ok(self.tcx().ty_error()) } - (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { - self.fields.infcx.super_combine_tys(self, a, b)?; - Ok(a) - } - (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) - if self.fields.define_opaque_types && did.is_local() => - { - let mut generalize = |ty, ty_is_expected| { - let var = infcx.next_ty_var_id_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.fields.trace.cause.span, - }, - ty::UniverseIndex::ROOT, - ); - self.fields.instantiate(ty, RelationDir::SubtypeOf, var, ty_is_expected)?; - Ok(infcx.tcx.mk_ty_var(var)) - }; - let (a, b) = if self.a_is_expected { (a, b) } else { (b, a) }; - let (a, b) = match (a.kind(), b.kind()) { - (&ty::Opaque(..), _) => (a, generalize(b, true)?), - (_, &ty::Opaque(..)) => (generalize(a, false)?, b), - _ => unreachable!(), - }; - self.fields.obligations.push(infcx.opaque_ty_obligation( - a, - b, - true, - self.param_env(), - self.fields.trace.cause.clone(), - )); - Ok(a) - } - _ => { self.fields.infcx.super_combine_tys(self, a, b)?; Ok(a) diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 02b15baf8fb2d..89db8f464b4e7 100644 --- a/compiler/rustc_infer/src/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs @@ -4,15 +4,13 @@ use rustc_data_structures::snapshot_vec as sv; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; use rustc_data_structures::unify as ut; use rustc_middle::infer::unify_key::RegionVidKey; -use rustc_middle::ty::{self, OpaqueTypeKey}; +use rustc_middle::ty; use crate::{ infer::{region_constraints, type_variable, InferCtxtInner}, traits, }; -use super::opaque_types::OpaqueHiddenType; - pub struct Snapshot<'tcx> { pub(crate) undo_len: usize, _marker: PhantomData<&'tcx ()>, @@ -20,7 +18,6 @@ pub struct Snapshot<'tcx> { /// Records the "undo" data for a single operation that affects some form of inference variable. pub(crate) enum UndoLog<'tcx> { - OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), TypeVariables(type_variable::UndoLog<'tcx>), ConstUnificationTable(sv::UndoLog>>), IntUnificationTable(sv::UndoLog>), @@ -67,7 +64,6 @@ impl_from! { impl<'tcx> Rollback> for InferCtxtInner<'tcx> { fn reverse(&mut self, undo: UndoLog<'tcx>) { match undo { - UndoLog::OpaqueTypes(key, idx) => self.opaque_type_storage.remove(key, idx), UndoLog::TypeVariables(undo) => self.type_variable_storage.reverse(undo), UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo), UndoLog::IntUnificationTable(undo) => self.int_unification_storage.reverse(undo), diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index f4df86e2ac7d3..ae79e14db181c 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -22,7 +22,6 @@ #![feature(control_flow_enum)] #![feature(min_specialization)] #![feature(label_break_value)] -#![feature(backtrace)] #![recursion_limit = "512"] // For rustdoc #![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))] diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 6600d5e4d0279..674c75fdee561 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -167,9 +167,6 @@ impl<'tcx> Elaborator<'tcx> { // Currently, we do not elaborate WF predicates, // although we easily could. } - ty::PredicateKind::OpaqueType(..) => { - todo!("{:#?}", obligation) - } ty::PredicateKind::ObjectSafe(..) => { // Currently, we do not elaborate object-safe // predicates. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 44e3da11826cd..734b32bb92f1e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1654,7 +1654,6 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Coerce(..) | ConstEvaluatable(..) | ConstEquate(..) | - OpaqueType(..) | TypeWellFormedFromEnv(..) => continue, }; if predicate.is_global() { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 2fc901bdbff34..28217aeab13ee 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -178,12 +178,6 @@ pub struct QueryResponse<'tcx, R> { pub var_values: CanonicalVarValues<'tcx>, pub region_constraints: QueryRegionConstraints<'tcx>, pub certainty: Certainty, - /// List of opaque types which we tried to compare to another type. - /// Inside the query we don't know yet whether the opaque type actually - /// should get its hidden type inferred. So we bubble the opaque type - /// and the type it was compared against upwards and let the query caller - /// handle it. - pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, pub value: R, } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 2642bddb9a4d3..e0e3febe6b310 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -53,17 +53,17 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { self.relate(a, b) } - #[instrument(skip(self), level = "debug")] fn regions( &mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?})", self.tag(), a, b); Ok(a) } - #[instrument(skip(self), level = "debug")] fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + debug!("{}.tys({:?}, {:?})", self.tag(), a, b); if a == b { return Ok(a); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b739607c89f99..a119655a90b20 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -30,7 +30,6 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; -use rustc_data_structures::vec_map::VecMap; use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -465,13 +464,9 @@ pub struct TypeckResults<'tcx> { /// this field will be set to `Some(ErrorReported)`. pub tainted_by_errors: Option, - /// All the opaque types that have hidden types set - /// by this function. For return-position-impl-trait we also store the - /// type here, so that mir-borrowck can figure out hidden types, - /// even if they are only set in dead code (which doesn't show up in MIR). - /// For type-alias-impl-trait, this map is only used to prevent query cycles, - /// so the hidden types are all `None`. - pub concrete_opaque_types: VecMap>>, + /// All the opaque types that are restricted to concrete types + /// by this function. + pub concrete_opaque_types: FxHashSet, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 7394bc5b2d8dd..f06a1b09cd82a 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -265,10 +265,6 @@ impl FlagComputation { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { self.add_ty(ty); } - ty::PredicateKind::OpaqueType(opaque, ty) => { - self.add_ty(opaque); - self.add_ty(ty); - } } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 2fd0ca423cc94..3133cdfdd7a72 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -1207,11 +1207,15 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; #[inline] - #[instrument(skip(self), level = "trace")] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - let flags = t.flags(); - trace!(t.flags=?t.flags()); - if flags.intersects(self.flags) { + #[instrument(level = "trace")] + fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow { + debug!( + "HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", + t, + t.flags(), + self.flags + ); + if t.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { ControlFlow::CONTINUE @@ -1231,7 +1235,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } #[inline] - #[instrument(skip(self), level = "trace")] + #[instrument(level = "trace")] fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow { let flags = FlagComputation::for_const(c); trace!(r.flags=?flags); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8bf760179e680..8eb2793cc34e3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -627,11 +627,6 @@ pub enum PredicateKind<'tcx> { /// /// Only used for Chalk. TypeWellFormedFromEnv(Ty<'tcx>), - - /// Represents a hidden type assignment for an opaque type. - /// Such obligations get processed by checking whether the item currently being - /// type-checked may acually define it. - OpaqueType(Ty<'tcx>, Ty<'tcx>), } /// The crate outlives map is computed during typeck and contains the @@ -991,7 +986,6 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::TypeOutlives(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) - | PredicateKind::OpaqueType(..) | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1010,7 +1004,6 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ClosureKind(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) - | PredicateKind::OpaqueType(..) | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1051,18 +1044,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } } -#[derive( - Copy, - Clone, - Debug, - PartialEq, - Eq, - HashStable, - TyEncodable, - TyDecodable, - TypeFoldable, - Lift -)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable, TypeFoldable)] pub struct OpaqueTypeKey<'tcx> { pub def_id: DefId, pub substs: SubstsRef<'tcx>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6521957ec944c..ddcc8680d8352 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -644,23 +644,20 @@ pub trait PrettyPrinter<'tcx>: return Ok(self); } - let parent = self.tcx().parent(def_id).expect("opaque types always have a parent"); - match self.tcx().def_kind(parent) { - DefKind::TyAlias | DefKind::AssocTy => { - if let ty::Opaque(d, _) = *self.tcx().type_of(parent).kind() { - if d == def_id { - // If the type alias directly starts with the `impl` of the - // opaque type we're printing, then skip the `::{opaque#1}`. - p!(print_def_path(parent, substs)); - return Ok(self); - } + return with_no_queries(|| { + let def_key = self.tcx().def_key(def_id); + if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { + p!(write("{}", name)); + // FIXME(eddyb) print this with `print_def_path`. + if !substs.is_empty() { + p!("::"); + p!(generic_delimiters(|cx| cx.comma_sep(substs.iter()))); } - // Complex opaque type, e.g. `type Foo = (i32, impl Debug);` - p!(print_def_path(def_id, substs)); return Ok(self); } - _ => return self.pretty_print_opaque_impl_type(def_id, substs), - } + + self.pretty_print_opaque_impl_type(def_id, substs) + }); } ty::Str => p!("str"), ty::Generator(did, substs, movability) => { @@ -2610,9 +2607,6 @@ define_print_and_forward_display! { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { p!("the type `", print(ty), "` is found in the environment") } - ty::PredicateKind::OpaqueType(a, b) => { - p!("opaque type assigment with `", print(a), "` == `", print(b) ,"`") - } } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ef54832791d41..1c5bc7860db2d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -191,9 +191,6 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { write!(f, "TypeWellFormedFromEnv({:?})", ty) } - ty::PredicateKind::OpaqueType(a, b) => { - write!(f, "OpaqueType({:?}, {:?})", a.kind(), b.kind()) - } } } } @@ -466,9 +463,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv) } - ty::PredicateKind::OpaqueType(opaque, ty) => { - Some(ty::PredicateKind::OpaqueType(tcx.lift(opaque)?, tcx.lift(ty)?)) - } } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 46c6b5eb796d7..786cf4fb25199 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1866,13 +1866,6 @@ impl<'tcx> TyS<'tcx> { } } - pub fn expect_opaque_type(&self) -> ty::OpaqueTypeKey<'tcx> { - match *self.kind() { - Opaque(def_id, substs) => ty::OpaqueTypeKey { def_id, substs }, - _ => bug!("`expect_opaque_type` called on non-opaque type: {}", self), - } - } - pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { match self.kind() { Adt(def, substs) => { diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 8cb19baa29230..df71379c1d886 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,8 +1,8 @@ use crate::build::matches::ArmHasGuard; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; +use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::{mir::*, ty}; use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN; use rustc_session::lint::Level; use rustc_span::Span; @@ -192,9 +192,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // This return type is usually `()`, unless the block is diverging, in which case the // return type is `!`. For the unit type, we need to actually return the unit, but in // the case of `!`, no return value is required, as the block will never return. - // Opaque types of empty bodies also need this unit assignment, in order to infer that their - // type is actually unit. Otherwise there will be no defining use found in the MIR. - if destination_ty.is_unit() || matches!(destination_ty.kind(), ty::Opaque(..)) { + if destination_ty.is_unit() { // We only want to assign an implicit `()` as the return value of the block if the // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.) this.cfg.push_assign_unit(block, source_info, destination, this.tcx); diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 36f2a80773ea3..c95dff13d6615 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -186,6 +186,7 @@ impl EncoderState { } } + #[instrument(level = "debug", skip(self, record_graph))] fn encode_node( &mut self, node: &NodeInfo, @@ -212,6 +213,7 @@ impl EncoderState { stat.edge_counter += edge_count as u64; } + debug!(?index, ?node); let encoder = &mut self.encoder; if self.result.is_ok() { self.result = node.encode(encoder); diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index cd12430a2a249..ea0ac6318bc9a 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -33,7 +33,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// purpose of this function is to do that translation. /// /// (*) C1 and C2 were introduced in the comments on - /// `register_member_constraints`. Read that comment for more context. + /// `constrain_opaque_type`. Read that comment for more context. /// /// # Parameters /// @@ -48,10 +48,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { instantiated_ty: Ty<'tcx>, span: Span, ) -> Ty<'tcx> { - if self.is_tainted_by_errors() { - return self.tcx.ty_error(); - } - let OpaqueTypeKey { def_id, substs } = opaque_type_key; // Use substs to build up a reverse map from regions to their @@ -71,6 +67,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // after producing an error for each of them. let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new( self.tcx, + self.is_tainted_by_errors(), def_id, map, instantiated_ty, @@ -85,6 +82,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { struct ReverseMapper<'tcx> { tcx: TyCtxt<'tcx>, + /// If errors have already been reported in this fn, we suppress + /// our own errors because they are sometimes derivative. + tainted_by_errors: bool, + opaque_type_def_id: DefId, map: FxHashMap, GenericArg<'tcx>>, map_missing_regions_to_empty: bool, @@ -99,6 +100,7 @@ struct ReverseMapper<'tcx> { impl<'tcx> ReverseMapper<'tcx> { fn new( tcx: TyCtxt<'tcx>, + tainted_by_errors: bool, opaque_type_def_id: DefId, map: FxHashMap, GenericArg<'tcx>>, hidden_ty: Ty<'tcx>, @@ -106,6 +108,7 @@ impl<'tcx> ReverseMapper<'tcx> { ) -> Self { Self { tcx, + tainted_by_errors, opaque_type_def_id, map, map_missing_regions_to_empty: false, @@ -164,7 +167,9 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { match self.map.get(&r.into()).map(|k| k.unpack()) { Some(GenericArgKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), - None if self.map_missing_regions_to_empty => self.tcx.lifetimes.re_root_empty, + None if self.map_missing_regions_to_empty || self.tainted_by_errors => { + self.tcx.lifetimes.re_root_empty + } None if generics.parent.is_some() => { if let Some(hidden_ty) = self.hidden_ty.take() { unexpected_hidden_region_diagnostic( @@ -354,7 +359,6 @@ crate fn required_region_bounds<'tcx>( | ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { // Search for a bound of the form `erased_self_ty diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index da04fb2cd2104..f2ed5ae26a3c2 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -853,7 +853,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::Subtype(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => {} }; } diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 138d535a5694d..603ab0622f022 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -90,11 +90,6 @@ pub fn codegen_fulfill_obligation<'tcx>( }); let impl_source = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, impl_source); - // We may constrain the hidden types of opaque types in this query, but this is - // not information our callers need, as all that information is handled by borrowck - // and typeck. - drop(infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types()); - debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source); Ok(&*tcx.arena.alloc(impl_source)) }) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 96671787b3163..f80fad19528da 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -775,10 +775,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span, "TypeWellFormedFromEnv predicate should only exist in the environment" ), - - ty::PredicateKind::OpaqueType(..) => { - todo!("{:#?}", obligation); - } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 65a18897b3915..b594723aa0bd2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1328,7 +1328,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ty::Generator(..) => "generator", _ => "function", }; - let span = self.tcx.sess.source_map().guess_head_span(span); let mut err = struct_span_err!( self.tcx.sess, span, @@ -1681,7 +1680,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { )); let original_span = err.span.primary_span().unwrap(); - let original_span = self.tcx.sess.source_map().guess_head_span(original_span); let mut span = MultiSpan::from_span(original_span); let message = outer_generator diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 274f8a3ef79fa..e7897887df706 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -397,9 +397,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::OpaqueType(..) => { - todo!("{:#?}", obligation); - } }, Some(pred) => match pred { ty::PredicateKind::Trait(data) => { @@ -645,20 +642,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::OpaqueType(a, b) => { - match self.selcx.infcx().handle_opaque_type( - a, - b, - &obligation.cause, - obligation.param_env, - ) { - Ok(value) => ProcessResult::Changed(mk_pending(value.obligations)), - Err(err) => ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( - ExpectedFound::new(true, a, b), - err, - )), - } - } }, } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index cd6f381333ad0..7818053218dec 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -313,7 +313,6 @@ fn predicate_references_self<'tcx>( | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -348,7 +347,6 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, } }) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 605c9ace5ed06..0a85676f4315e 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -3,8 +3,7 @@ use crate::infer::{InferCtxt, InferOk}; use crate::traits::engine::TraitEngineExt as _; use crate::traits::query::type_op::TypeOpOutput; use crate::traits::query::Fallible; -use crate::traits::TraitEngine; -use rustc_infer::infer::region_constraints::RegionConstraintData; +use crate::traits::{ObligationCause, TraitEngine}; use rustc_infer::traits::TraitEngineExt as _; use rustc_span::source_map::DUMMY_SP; @@ -32,9 +31,6 @@ where G: Fn() -> String, { type Output = R; - /// We can't do any custom error reporting for `CustomTypeOp`, so - /// we can use `!` to enforce that the implementation never provides it. - type ErrorInfo = !; /// Processes the operation and all resulting obligations, /// returning the final result along with any region constraints @@ -44,7 +40,7 @@ where info!("fully_perform({:?})", self); } - Ok(scrape_region_constraints(infcx, || (self.closure)(infcx))?.0) + scrape_region_constraints(infcx, || (self.closure)(infcx)) } } @@ -59,11 +55,12 @@ where /// Executes `op` and then scrapes out all the "old style" region /// constraints that result, creating query-region-constraints. -pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( +fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( infcx: &InferCtxt<'_, 'tcx>, op: impl FnOnce() -> Fallible>, -) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> { +) -> Fallible> { let mut fulfill_cx = >::new(infcx.tcx); + let dummy_body_id = ObligationCause::dummy().body_id; // During NLL, we expect that nobody will register region // obligations **except** as part of a custom type op (and, at the @@ -78,6 +75,7 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( ); let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?; + debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id)); fulfill_cx.register_predicate_obligations(infcx, obligations); let errors = fulfill_cx.select_all_or_error(infcx); if !errors.is_empty() { @@ -101,18 +99,12 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( ); if region_constraints.is_empty() { - Ok(( - TypeOpOutput { output: value, constraints: None, error_info: None }, - region_constraint_data, - )) + Ok(TypeOpOutput { output: value, constraints: None, canonicalized_query: None }) } else { - Ok(( - TypeOpOutput { - output: value, - constraints: Some(Rc::new(region_constraints)), - error_info: None, - }, - region_constraint_data, - )) + Ok(TypeOpOutput { + output: value, + constraints: Some(Rc::new(region_constraints)), + canonicalized_query: None, + }) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 1e72dd693396a..d662f61e2cf4d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -28,7 +28,6 @@ pub use rustc_middle::traits::query::type_op::*; /// cannot be completed). pub trait TypeOp<'tcx>: Sized + fmt::Debug { type Output; - type ErrorInfo; /// Processes the operation and all resulting obligations, /// returning the final result along with any region constraints @@ -42,8 +41,9 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> { pub output: Op::Output, /// Any region constraints from performing the type op. pub constraints: Option>>, - /// Used for error reporting to be able to rerun the query - pub error_info: Option, + /// The canonicalized form of the query. + /// This for error reporting to be able to rerun the query. + pub canonicalized_query: Option>, } /// "Query type ops" are type ops that are implemented using a @@ -119,11 +119,10 @@ where Q: QueryTypeOp<'tcx>, { type Output = Q::QueryResponse; - type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>; fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible> { let mut region_constraints = QueryRegionConstraints::default(); - let (output, error_info, mut obligations, _) = + let (output, canonicalized_query, mut obligations, _) = Q::fully_perform_into(self, infcx, &mut region_constraints)?; // Typically, instantiating NLL query results does not @@ -161,6 +160,6 @@ where let region_constraints = if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) }; - Ok(TypeOpOutput { output, constraints: region_constraints, error_info }) + Ok(TypeOpOutput { output, constraints: region_constraints, canonicalized_query }) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 0c5d764e79d0c..db86041f6180b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -254,7 +254,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; if obligation.predicate.skip_binder().self_ty().is_ty_var() { - debug!(ty = ?obligation.predicate.skip_binder().self_ty(), "ambiguous inference var or opaque type"); // Self is a type variable (e.g., `_: AsRef`). // // This is somewhat problematic, as the current scheme can't really diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a183a20a2fed0..47427395b93b3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -37,7 +37,6 @@ use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences}; -use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef}; @@ -698,19 +697,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for chalk") } - ty::PredicateKind::OpaqueType(a, b) => { - match self.infcx().handle_opaque_type( - a, - b, - &obligation.cause, - obligation.param_env, - ) { - Ok(res) => { - self.evaluate_predicates_recursively(previous_stack, res.obligations) - } - Err(_) => Ok(EvaluatedToErr), - } - } } }); @@ -1351,7 +1337,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - #[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")] fn insert_candidate_cache( &mut self, mut param_env: ty::ParamEnv<'tcx>, @@ -1392,7 +1377,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// a projection, look at the bounds of `T::Bar`, see if we can find a /// `Baz` bound. We return indexes into the list returned by /// `tcx.item_bounds` for any applicable bounds. - #[instrument(level = "debug", skip(self))] fn match_projection_obligation_against_definition_bounds( &mut self, obligation: &TraitObligation<'tcx>, @@ -1400,7 +1384,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let poly_trait_predicate = self.infcx().resolve_vars_if_possible(obligation.predicate); let placeholder_trait_predicate = self.infcx().replace_bound_vars_with_placeholders(poly_trait_predicate); - debug!(?placeholder_trait_predicate); + debug!( + ?placeholder_trait_predicate, + "match_projection_obligation_against_definition_bounds" + ); let tcx = self.infcx.tcx; let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() { @@ -1451,7 +1438,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .collect(); - debug!(?matching_bounds); + debug!(?matching_bounds, "match_projection_obligation_against_definition_bounds"); matching_bounds } @@ -1481,7 +1468,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); self.infcx .at(&obligation.cause, obligation.param_env) - .define_opaque_types(false) .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .map(|InferOk { obligations: _, value: () }| { // This method is called within a probe, so we can't have @@ -1537,7 +1523,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx .at(&obligation.cause, obligation.param_env) - .define_opaque_types(false) .sup(obligation.predicate, infer_projection) .map_or(false, |InferOk { obligations, value: () }| { self.evaluate_predicates_recursively( @@ -2096,22 +2081,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.match_impl(impl_def_id, obligation) { Ok(substs) => substs, Err(()) => { - self.infcx.tcx.sess.delay_span_bug( - obligation.cause.span, - &format!( - "Impl {:?} was matchable against {:?} but now is not", - impl_def_id, obligation - ), + bug!( + "Impl {:?} was matchable against {:?} but now is not", + impl_def_id, + obligation ); - let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let err = self.tcx().ty_error(); - let value = value.fold_with(&mut BottomUpFolder { - tcx: self.tcx(), - ty_op: |_| err, - lt_op: |l| l, - ct_op: |c| c, - }); - Normalized { value, obligations: vec![] } } } } @@ -2248,11 +2222,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result>, ()> { self.infcx .at(&obligation.cause, obligation.param_env) - // We don't want predicates for opaque types to just match all other types, - // if there is an obligation on the opaque type, then that obligation must be met - // opaquely. Otherwise we'd match any obligation to the opaque type and then error - // out later. - .define_opaque_types(false) .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 68707fee44f99..493cb199f1144 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -146,10 +146,6 @@ pub fn predicate_obligations<'a, 'tcx>( wf.compute(c1.into()); wf.compute(c2.into()); } - ty::PredicateKind::OpaqueType(opaque, ty) => { - wf.compute(opaque.into()); - wf.compute(ty.into()); - } ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 71ea77dc37910..67d0ba39667d3 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -110,7 +110,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment bug!("unexpected predicate {}", predicate), }; @@ -197,7 +196,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::ConstEquate(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } @@ -612,7 +610,6 @@ impl<'tcx> LowerInto<'tcx, Option { bug!("unexpected predicate {}", &self) } @@ -742,7 +739,6 @@ impl<'tcx> LowerInto<'tcx, Option { bug!("unexpected predicate {}", &self) } diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index 287538e0764d3..09bfdabf47373 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -142,7 +142,6 @@ crate fn evaluate_goal<'tcx>( var_values: CanonicalVarValues { var_values }, region_constraints: QueryRegionConstraints::default(), certainty: Certainty::Proven, - opaque_types: vec![], value: (), }, }; @@ -171,7 +170,6 @@ crate fn evaluate_goal<'tcx>( .make_identity(tcx), region_constraints: QueryRegionConstraints::default(), certainty: Certainty::Ambiguous, - opaque_types: vec![], value: (), }, }; diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 1535a46a01b47..90c698db8fb54 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -105,7 +105,6 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![], ty::PredicateKind::WellFormed(arg) => { wf_args.push(arg); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index c64e97074a6e0..46c2f7e4cf2ed 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -69,7 +69,6 @@ fn not_outlives_predicate<'tcx>(p: &ty::Predicate<'tcx>) -> bool { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => true, } } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 741438b3d29cc..ec6fb622d32aa 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -61,14 +61,6 @@ bitflags! { | TypeFlags::HAS_CT_INFER.bits | TypeFlags::HAS_TY_PLACEHOLDER.bits | TypeFlags::HAS_CT_PLACEHOLDER.bits - // The `evaluate_obligation` query does not return further - // obligations. If it evaluates an obligation with an opaque - // type, that opaque type may get compared to another type, - // constraining it. We would lose this information. - // FIXME: differentiate between crate-local opaque types - // and opaque types from other crates, as only opaque types - // from the local crate can possibly be a local name - | TypeFlags::HAS_TY_OPAQUE.bits // We consider 'freshened' types and constants // to depend on a particular fn. // The freshening process throws away information, diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 195fbd7752065..405e4e8594a3a 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::{self as hir, ExprKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::traits::Obligation; -use rustc_middle::ty::{self, ToPredicate, Ty, TyS, TypeFoldable}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyS}; use rustc_span::{MultiSpan, Span}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ @@ -98,7 +98,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let arm_ty = self.check_expr_with_expectation(&arm.body, expected); all_arms_diverge &= self.diverges.get(); - let opt_suggest_box_span = self.opt_suggest_box_span(arm_ty, orig_expected); + let opt_suggest_box_span = + self.opt_suggest_box_span(arm.body.span, arm_ty, orig_expected); let (arm_span, semi_span) = self.get_appropriate_arm_semicolon_removal_span(&arms, i, prior_arm_ty, arm_ty); @@ -503,15 +504,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // provide a structured suggestion in that case. pub(crate) fn opt_suggest_box_span( &self, + span: Span, outer_ty: &'tcx TyS<'tcx>, orig_expected: Expectation<'tcx>, ) -> Option { - match orig_expected { - Expectation::ExpectHasType(expected) - if self.in_tail_expr - && self.ret_coercion.as_ref()?.borrow().merged_ty().has_opaque_types() - && self.can_coerce(outer_ty, expected) => + match (orig_expected, self.ret_coercion_impl_trait.map(|ty| (self.body_id.owner, ty))) { + (Expectation::ExpectHasType(expected), Some((_id, ty))) + if self.in_tail_expr && self.can_coerce(outer_ty, expected) => { + let impl_trait_ret_ty = + self.infcx.instantiate_opaque_types(self.body_id, self.param_env, ty, span); + assert!( + impl_trait_ret_ty.obligations.is_empty(), + "we should never get new obligations here" + ); let obligations = self.fulfillment_cx.borrow().pending_obligations(); let mut suggest_box = !obligations.is_empty(); for o in obligations { diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 19c3f00ed9357..0fea0afb572c9 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -545,7 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, fn_sig: ty::FnSig<'tcx>, ) -> Ty<'tcx> { - // `fn_sig` is the *signature* of the closure being called. We + // `fn_sig` is the *signature* of the cosure being called. We // don't know the full details yet (`Fn` vs `FnMut` etc), but we // do know the types expected for each argument and the return // type. diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index d10d3e43b5b18..18a0a8767d45b 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::layout::MAX_SIMD_LANES; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, ParamEnv, RegionKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, OpaqueTypeKey, ParamEnv, RegionKind, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, MultiSpan, Span}; @@ -81,6 +81,8 @@ pub(super) fn check_fn<'a, 'tcx>( can_be_generator: Option, return_type_pre_known: bool, ) -> (FnCtxt<'a, 'tcx>, Option>) { + let mut fn_sig = fn_sig; + // Create the function context. This is either derived from scratch or, // in the case of closures, based on the outer context. let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); @@ -93,8 +95,21 @@ pub(super) fn check_fn<'a, 'tcx>( let declared_ret_ty = fn_sig.output(); - fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(declared_ret_ty))); + let revealed_ret_ty = + fcx.instantiate_opaque_types_from_value(declared_ret_ty, decl.output.span()); + debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty); + fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); fcx.ret_type_span = Some(decl.output.span()); + if let ty::Opaque(..) = declared_ret_ty.kind() { + fcx.ret_coercion_impl_trait = Some(declared_ret_ty); + } + fn_sig = tcx.mk_fn_sig( + fn_sig.inputs().iter().cloned(), + revealed_ret_ty, + fn_sig.c_variadic, + fn_sig.unsafety, + fn_sig.abi, + ); let span = body.value.span; @@ -236,7 +251,7 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); debug!("actual_return_ty replaced with {:?}", actual_return_ty); } - fcx.demand_suptype(span, declared_ret_ty, actual_return_ty); + fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty); // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !` if let Some(panic_impl_did) = tcx.lang_items().panic_impl() { @@ -614,8 +629,6 @@ fn check_opaque_meets_bounds<'tcx>( span: Span, origin: &hir::OpaqueTyOrigin, ) { - let hidden_type = tcx.type_of(def_id).subst(tcx, substs); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, @@ -630,12 +643,24 @@ fn check_opaque_meets_bounds<'tcx>( let misc_cause = traits::ObligationCause::misc(span, hir_id); - match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) { - Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok), - Err(ty_err) => tcx.sess.delay_span_bug( - span, - &format!("could not unify `{}` with revealed type:\n{}", hidden_type, ty_err,), - ), + let _ = inh.register_infer_ok_obligations( + infcx.instantiate_opaque_types(hir_id, param_env, opaque_ty, span), + ); + + let opaque_type_map = infcx.inner.borrow().opaque_types.clone(); + for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map { + let hidden_type = tcx.type_of(def_id).subst(tcx, substs); + trace!(?hidden_type); + match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) { + Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok), + Err(ty_err) => tcx.sess.delay_span_bug( + span, + &format!( + "could not check bounds on revealed type `{}`:\n{}", + hidden_type, ty_err, + ), + ), + } } // Check that all obligations are satisfied by the implementation's @@ -647,7 +672,7 @@ fn check_opaque_meets_bounds<'tcx>( match origin { // Checked when type checking the function containing them. - hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {} + hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return, // Can have different predicates to their defining use hir::OpaqueTyOrigin::TyAlias => { // Finally, resolve all regions. This catches wily misuses of @@ -656,9 +681,6 @@ fn check_opaque_meets_bounds<'tcx>( fcx.regionck_item(hir_id, span, FxHashSet::default()); } } - - // Clean up after ourselves - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); }); } diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index c3deab0938d3b..e88099afa0353 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -3,20 +3,16 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use crate::astconv::AstConv; -use crate::rustc_middle::ty::subst::Subst; -use hir::OpaqueTyOrigin; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; -use rustc_infer::traits::ObligationCause; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Span; -use rustc_span::DUMMY_SP; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::ArgKind; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; @@ -176,29 +172,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, ) -> (Option>, Option) { match *expected_ty.kind() { - ty::Opaque(def_id, substs) => { - let bounds = self.tcx.explicit_item_bounds(def_id); - let sig = bounds.iter().find_map(|(pred, span)| match pred.kind().skip_binder() { - ty::PredicateKind::Projection(proj_predicate) => self - .deduce_sig_from_projection( - Some(*span), - pred.kind().rebind(proj_predicate.subst(self.tcx, substs)), - ), - _ => None, - }); - - let kind = bounds - .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Trait(tp) => { - self.tcx.fn_trait_kind_from_lang_item(tp.def_id()) - } - _ => None, - }) - .fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur)))); - trace!(?sig, ?kind); - (sig, kind) - } ty::Dynamic(ref object_type, ..) => { let sig = object_type.projection_bounds().find_map(|pb| { let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self); @@ -224,7 +197,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> (Option>, Option) { let expected_sig = self.obligations_for_self_ty(expected_vid).find_map(|(_, obligation)| { - debug!(?obligation.predicate); + debug!( + "deduce_expectations_from_obligations: obligation.predicate={:?}", + obligation.predicate + ); let bound_predicate = obligation.predicate.kind(); if let ty::PredicateKind::Projection(proj_predicate) = @@ -259,7 +235,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// The `cause_span` should be the span that caused us to /// have this expected signature, or `None` if we can't readily /// know that. - #[instrument(level = "debug", skip(self, cause_span))] fn deduce_sig_from_projection( &self, cause_span: Option, @@ -267,13 +242,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option> { let tcx = self.tcx; + debug!("deduce_sig_from_projection({:?})", projection); + let trait_def_id = projection.trait_def_id(tcx); let is_fn = tcx.fn_trait_kind_from_lang_item(trait_def_id).is_some(); let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span); let is_gen = gen_trait == trait_def_id; if !is_fn && !is_gen { - debug!("not fn or generator"); + debug!("deduce_sig_from_projection: not fn or generator"); return None; } @@ -282,7 +259,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // associated item and not yield. let return_assoc_item = self.tcx.associated_item_def_ids(gen_trait)[1]; if return_assoc_item != projection.projection_def_id() { - debug!("not return assoc item of generator"); + debug!("deduce_sig_from_projection: not return assoc item of generator"); return None; } } @@ -290,7 +267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let input_tys = if is_fn { let arg_param_ty = projection.skip_binder().projection_ty.substs.type_at(1); let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); - debug!(?arg_param_ty); + debug!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty); match arg_param_ty.kind() { ty::Tuple(tys) => tys.into_iter().map(|k| k.expect_ty()).collect::>(), @@ -305,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Since this is a return parameter type it is safe to unwrap. let ret_param_ty = projection.skip_binder().term.ty().unwrap(); let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); - debug!(?ret_param_ty); + debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty); let sig = projection.rebind(self.tcx.mk_fn_sig( input_tys.iter(), @@ -314,7 +291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Unsafety::Normal, Abi::Rust, )); - debug!(?sig); + debug!("deduce_sig_from_projection: sig={:?}", sig); Some(ExpectedSig { cause_span, sig }) } @@ -424,14 +401,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in this binder we are creating. assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST)); let bound_sig = expected_sig.sig.map_bound(|sig| { - let output = self.hide_parent_opaque_types( - sig.output(), - expected_sig.cause_span.unwrap_or(DUMMY_SP), - body.id().hir_id, - ); self.tcx.mk_fn_sig( sig.inputs().iter().cloned(), - output, + sig.output(), sig.c_variadic, hir::Unsafety::Normal, Abi::RustCall, @@ -618,8 +590,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => astconv.ty_infer(None, decl.output.span()), }, }; - let supplied_return = - self.hide_parent_opaque_types(supplied_return, decl.output.span(), body.id().hir_id); let result = ty::Binder::bind_with_vars( self.tcx.mk_fn_sig( @@ -640,57 +610,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { result } - fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> { - ty.fold_with(&mut ty::fold::BottomUpFolder { - tcx: self.infcx.tcx, - lt_op: |lt| lt, - ct_op: |ct| ct, - ty_op: |ty| match *ty.kind() { - // Closures can't create hidden types for opaque types of their parent, as they - // do not have all the outlives information available. Also `type_of` looks for - // hidden types in the owner (so the closure's parent), so it would not find these - // definitions. - ty::Opaque(def_id, _substs) - if matches!( - self.infcx.opaque_type_origin(def_id, DUMMY_SP), - Some(OpaqueTyOrigin::FnReturn(..)) - ) => - { - let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }); - let cause = ObligationCause::misc(span, body_id); - self.register_predicates(vec![self.infcx.opaque_ty_obligation( - ty, - ty_var, - true, - self.param_env, - cause, - )]); - ty_var - } - _ => ty, - }, - }) - } - /// Invoked when we are translating the generator that results /// from desugaring an `async fn`. Returns the "sugared" return /// type of the `async fn` -- that is, the return type that the /// user specified. The "desugared" return type is an `impl /// Future`, so we do this by searching through the /// obligations to extract the `T`. - #[instrument(skip(self), level = "debug")] fn deduce_future_output_from_obligations(&self, expr_def_id: DefId) -> Option> { + debug!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id); + let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| { span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn") }); + // In practice, the return type of the surrounding function is + // always a (not yet resolved) inference variable, because it + // is the hidden type for an `impl Trait` that we are going to + // be inferring. let ret_ty = ret_coercion.borrow().expected_ty(); let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); - let (def_id, substs) = match *ret_ty.kind() { - ty::Opaque(def_id, substs) => (def_id, substs), + let ret_vid = match *ret_ty.kind() { + ty::Infer(ty::TyVar(ret_vid)) => ret_vid, ty::Error(_) => return None, _ => span_bug!( self.tcx.def_span(expr_def_id), @@ -698,19 +638,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), }; - let item_bounds = self.tcx.explicit_item_bounds(def_id); - // Search for a pending obligation like // // `::Output = T` // // where R is the return type we are expecting. This type `T` // will be our output. - let output_ty = item_bounds.iter().find_map(|&(predicate, span)| { - let bound_predicate = predicate.subst(self.tcx, substs).kind(); + let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| { + let bound_predicate = obligation.predicate.kind(); if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() { self.deduce_future_output_from_projection( - span, + obligation.cause.span, bound_predicate.rebind(proj_predicate), ) } else { diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 8204a25e9112b..3668ecd234c64 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1275,7 +1275,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// Returns the current "merged type", representing our best-guess /// at the LUB of the expressions we've seen so far (if any). This - /// isn't *final* until you call `self.complete()`, which will return + /// isn't *final* until you call `self.final()`, which will return /// the merged type. pub fn merged_ty(&self) -> Ty<'tcx> { self.final_ty.unwrap_or(self.expected_ty) diff --git a/compiler/rustc_typeck/src/check/expectation.rs b/compiler/rustc_typeck/src/check/expectation.rs index 9e1a70b7dfb92..e9e810344776b 100644 --- a/compiler/rustc_typeck/src/check/expectation.rs +++ b/compiler/rustc_typeck/src/check/expectation.rs @@ -1,6 +1,5 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::{self, Ty}; -use rustc_span::DUMMY_SP; use rustc_span::{self, Span}; use super::Expectation::*; @@ -44,7 +43,7 @@ impl<'a, 'tcx> Expectation<'tcx> { // when checking the 'then' block which are incompatible with the // 'else' branch. pub(super) fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> { - match self.strip_opaque(fcx) { + match *self { ExpectHasType(ety) => { let ety = fcx.shallow_resolve(ety); if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation } @@ -105,35 +104,14 @@ impl<'a, 'tcx> Expectation<'tcx> { /// for the program to type-check). `only_has_type` will return /// such a constraint, if it exists. pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option> { - match self.strip_opaque(fcx) { - ExpectHasType(ty) => Some(ty), + match self { + ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)), NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) | IsLast(_) => { None } } } - /// We must not treat opaque types as expected types in their defining scope, as that - /// will break `fn foo() -> impl Trait { if cond { a } else { b } }` if `a` and `b` are - /// only "equal" if they coerce to a common target, like two different function items - /// coercing to a function pointer if they have the same signature. - fn strip_opaque(self, fcx: &FnCtxt<'a, 'tcx>) -> Self { - match self { - ExpectHasType(ty) => { - let ty = fcx.resolve_vars_if_possible(ty); - match *ty.kind() { - ty::Opaque(def_id, _) - if fcx.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() => - { - NoExpectation - } - _ => self, - } - } - _ => self, - } - } - /// Like `only_has_type`, but instead of returning `None` if no /// hard constraint exists, creates a fresh type variable. pub(super) fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 74341fef38e27..0347b6a4ab82f 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -956,7 +956,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let else_diverges = self.diverges.get(); - let opt_suggest_box_span = self.opt_suggest_box_span(else_ty, orig_expected); + let opt_suggest_box_span = + self.opt_suggest_box_span(else_expr.span, else_ty, orig_expected); let if_cause = self.if_cause(sp, then_expr, else_expr, then_ty, else_ty, opt_suggest_box_span); diff --git a/compiler/rustc_typeck/src/check/fallback.rs b/compiler/rustc_typeck/src/check/fallback.rs index 8513231782407..e5da33d113e7c 100644 --- a/compiler/rustc_typeck/src/check/fallback.rs +++ b/compiler/rustc_typeck/src/check/fallback.rs @@ -24,7 +24,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.fulfillment_cx.borrow_mut().pending_obligations() ); - // Check if we have any unsolved variables. If not, no need for fallback. + // Check if we have any unsolved varibales. If not, no need for fallback. let unsolved_variables = self.unsolved_variables(); if unsolved_variables.is_empty() { return false; @@ -66,6 +66,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // refer to opaque types. self.select_obligations_where_possible(fallback_has_occurred, |_| {}); + // We now run fallback again, but this time we allow it to replace + // unconstrained opaque type variables, in addition to performing + // other kinds of fallback. + for ty in &self.unsolved_variables() { + fallback_has_occurred |= self.fallback_opaque_type_vars(ty); + } + + // See if we can make any more progress. + self.select_obligations_where_possible(fallback_has_occurred, |_| {}); + fallback_has_occurred } @@ -126,6 +136,59 @@ impl<'tcx> FnCtxt<'_, 'tcx> { true } + /// Second round of fallback: Unconstrained type variables created + /// from the instantiation of an opaque type fall back to the + /// opaque type itself. This is a somewhat incomplete attempt to + /// manage "identity passthrough" for `impl Trait` types. + /// + /// For example, in this code: + /// + ///``` + /// type MyType = impl Copy; + /// fn defining_use() -> MyType { true } + /// fn other_use() -> MyType { defining_use() } + /// ``` + /// + /// `defining_use` will constrain the instantiated inference + /// variable to `bool`, while `other_use` will constrain + /// the instantiated inference variable to `MyType`. + /// + /// When we process opaque types during writeback, we + /// will handle cases like `other_use`, and not count + /// them as defining usages + /// + /// However, we also need to handle cases like this: + /// + /// ```rust + /// pub type Foo = impl Copy; + /// fn produce() -> Option { + /// None + /// } + /// ``` + /// + /// In the above snippet, the inference variable created by + /// instantiating `Option` will be completely unconstrained. + /// We treat this as a non-defining use by making the inference + /// variable fall back to the opaque type itself. + fn fallback_opaque_type_vars(&self, ty: Ty<'tcx>) -> bool { + let span = self + .infcx + .type_var_origin(ty) + .map(|origin| origin.span) + .unwrap_or(rustc_span::DUMMY_SP); + let oty = self.inner.borrow().opaque_types_vars.get(ty).copied(); + if let Some(opaque_ty) = oty { + debug!( + "fallback_opaque_type_vars(ty={:?}): falling back to opaque type {:?}", + ty, opaque_ty + ); + self.demand_eqtype(span, ty, opaque_ty); + true + } else { + return false; + } + } + /// The "diverging fallback" system is rather complicated. This is /// a result of our need to balance 'do the right thing' with /// backwards compatibility. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 52db15b69a375..0f9803b969fb7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -367,6 +367,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (result, spans) } + /// Replaces the opaque types from the given value with type variables, + /// and records the `OpaqueTypeMap` for later use during writeback. See + /// `InferCtxt::instantiate_opaque_types` for more details. + #[instrument(skip(self, value_span), level = "debug")] + pub(in super::super) fn instantiate_opaque_types_from_value>( + &self, + value: T, + value_span: Span, + ) -> T { + self.register_infer_ok_obligations(self.instantiate_opaque_types( + self.body_id, + self.param_env, + value, + value_span, + )) + } + /// Convenience method which tracks extra diagnostic information for normalization /// that occurs as a result of WF checking. The `hir_id` is the `HirId` of the hir item /// whose type is being wf-checked - this is used to construct a more precise span if @@ -703,7 +720,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // inference variable. ty::PredicateKind::ClosureKind(..) => None, ty::PredicateKind::TypeWellFormedFromEnv(..) => None, - ty::PredicateKind::OpaqueType(..) => None, } }) .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root)) @@ -730,32 +746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Vec> { let formal_ret = self.resolve_vars_with_obligations(formal_ret); let ret_ty = match expected_ret.only_has_type(self) { - Some(ret) => { - // HACK(oli-obk): This is a backwards compatibility hack. Without it, the inference - // variable will get instantiated with the opaque type. The inference variable often - // has various helpful obligations registered for it that help closures figure out their - // signature. If we infer the inference var to the opaque type, the closure won't be able - // to find those obligations anymore, and it can't necessarily find them from the opaque - // type itself. We could be more powerful with inference if we *combined* the obligations - // so that we got both the obligations from the opaque type and the ones from the inference - // variable. That will accept more code than we do right now, so we need to carefully consider - // the implications. - // Note: this check is pessimistic, as the inference type could be matched with something other - // than the opaque type, but then we need a new `TypeRelation` just for this specific case and - // can't re-use `sup` below. - if formal_ret.has_infer_types() { - for ty in ret.walk() { - if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() { - if let ty::Opaque(def_id, _) = *ty.kind() { - if self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() { - return Vec::new(); - } - } - } - } - } - ret - } + Some(ret) => ret, None => return Vec::new(), }; let expect_args = self diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 234775ab45269..3a81af0316286 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -57,6 +57,8 @@ pub struct FnCtxt<'a, 'tcx> { /// any). pub(super) ret_coercion: Option>>, + pub(super) ret_coercion_impl_trait: Option>, + pub(super) ret_type_span: Option, /// Used exclusively to reduce cost of advanced evaluation used for @@ -128,6 +130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param_env, err_count_on_creation: inh.tcx.sess.err_count(), ret_coercion: None, + ret_coercion_impl_trait: None, ret_type_span: None, in_tail_expr: false, ret_coercion_span: Cell::new(None), diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs index b775f24f8efd8..beb6b371b2bb8 100644 --- a/compiler/rustc_typeck/src/check/inherited.rs +++ b/compiler/rustc_typeck/src/check/inherited.rs @@ -95,13 +95,6 @@ impl<'tcx> InheritedBuilder<'tcx> { let def_id = self.def_id; self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id))) } - - /// WF-checking doesn't need to recompute opaque types and can instead use - /// the type_of query to get them from typeck. - pub fn reveal_defining_opaque_types(mut self) -> Self { - self.infcx = self.infcx.reveal_defining_opaque_types(); - self - } } impl<'a, 'tcx> Inherited<'a, 'tcx> { @@ -126,8 +119,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] pub(super) fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) { + debug!("register_predicate({:?})", obligation); if obligation.has_escaping_bound_vars() { span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation); } diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 2103c12694f10..cd1c0980a5521 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -856,7 +856,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } }); @@ -1476,7 +1475,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { TraitCandidate(trait_ref) => self.probe(|_| { let _ = self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(candidate.xform_self_ty, self_ty); match self.select_trait_candidate(trait_ref) { Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => { @@ -1506,7 +1504,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // First check that the self type can be related. let sub_obligations = match self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(probe.xform_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => obligations, @@ -1654,7 +1651,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); if self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(return_ty, xform_ret_ty) .is_err() { diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index d4be3889a7ae7..6e0b902a00bda 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -341,7 +341,6 @@ fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::T typeck_with_fallback(tcx, def_id, fallback) } -#[instrument(skip(tcx, fallback))] fn typeck_with_fallback<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 428a866c1fe07..313e305909647 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -335,6 +335,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Returns a list of `Ty`s for each upvar. fn final_upvar_tys(&self, closure_id: DefId) -> Vec> { + // Presently an unboxed closure type cannot "escape" out of a + // function, so we will only encounter ones that originated in the + // local crate or were inlined into it along with some function. + // This may change if abstract return types of some sort are + // implemented. self.typeck_results .borrow() .closure_min_captures_flattened(closure_id) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index c0fa673774ffd..71f45320e4952 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -895,7 +895,7 @@ fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>) -> CheckWfFcxBuilder< fn for_id(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> CheckWfFcxBuilder<'_> { CheckWfFcxBuilder { - inherited: Inherited::build(tcx, def_id).reveal_defining_opaque_types(), + inherited: Inherited::build(tcx, def_id), id: hir::HirId::make_owner(def_id), span, param_env: tcx.param_env(def_id), diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index e04c1423cdac8..ec88bdf4a370f 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -18,6 +18,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; +use rustc_trait_selection::opaque_types::InferCtxtExt; use std::mem; @@ -64,7 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.visit_closures(); wbcx.visit_liberated_fn_sigs(); wbcx.visit_fru_field_types(); - wbcx.visit_opaque_types(); + wbcx.visit_opaque_types(body.value.span); wbcx.visit_coercion_casts(); wbcx.visit_user_provided_tys(); wbcx.visit_user_provided_sigs(); @@ -495,18 +496,64 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fcx_typeck_results.generator_interior_types.clone(); } - #[instrument(skip(self), level = "debug")] - fn visit_opaque_types(&mut self) { - let opaque_types = - self.fcx.infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - for (opaque_type_key, decl) in opaque_types { - let hidden_type = match decl.origin { - hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { - Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span)) + #[instrument(skip(self, span), level = "debug")] + fn visit_opaque_types(&mut self, span: Span) { + let opaque_types = self.fcx.infcx.inner.borrow().opaque_types.clone(); + for (opaque_type_key, opaque_defn) in opaque_types { + let hir_id = + self.tcx().hir().local_def_id_to_hir_id(opaque_type_key.def_id.expect_local()); + let instantiated_ty = self.resolve(opaque_defn.concrete_ty, &hir_id); + + debug_assert!(!instantiated_ty.has_escaping_bound_vars()); + + let opaque_type_key = self.fcx.fully_resolve(opaque_type_key).unwrap(); + + // Prevent: + // * `fn foo() -> Foo` + // * `fn foo() -> Foo` + // from being defining. + + // Also replace all generic params with the ones from the opaque type + // definition so that + // ```rust + // type Foo = impl Baz + 'static; + // fn foo() -> Foo { .. } + // ``` + // figures out the concrete type with `U`, but the stored type is with `T`. + + // FIXME: why are we calling this here? This seems too early, and duplicated. + let definition_ty = self.fcx.infer_opaque_definition_from_instantiation( + opaque_type_key, + instantiated_ty, + span, + ); + + let mut skip_add = false; + + if let ty::Opaque(definition_ty_def_id, _substs) = *definition_ty.kind() { + if opaque_defn.origin == hir::OpaqueTyOrigin::TyAlias { + if opaque_type_key.def_id == definition_ty_def_id { + debug!( + "skipping adding concrete definition for opaque type {:?} {:?}", + opaque_defn, opaque_type_key.def_id + ); + skip_add = true; + } } - hir::OpaqueTyOrigin::TyAlias => None, - }; - self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type); + } + + if opaque_type_key.substs.needs_infer() { + span_bug!(span, "{:#?} has inference variables", opaque_type_key.substs) + } + + // We only want to add an entry into `concrete_opaque_types` + // if we actually found a defining usage of this opaque type. + // Otherwise, we do nothing - we'll either find a defining usage + // in some other location, or we'll end up emitting an error due + // to the lack of defining usage + if !skip_add { + self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id); + } } } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 471cd2e6ccb1c..c911b781f3c9b 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -389,22 +389,28 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .get_value_matching(|(key, _)| key.def_id == def_id.to_def_id()) .copied() .unwrap_or_else(|| { - let table = tcx.typeck(owner); - if let Some(ErrorReported) = table.tainted_by_errors { + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "owner {:?} has no opaque type for {:?} in its typeck results", + owner, def_id, + ), + ); + if let Some(ErrorReported) = + tcx.typeck(owner).tainted_by_errors + { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. tcx.ty_error() } else { - table.concrete_opaque_types.get(&def_id.to_def_id()).copied().unwrap_or_else(|| { - // We failed to resolve the opaque type or it - // resolves to itself. We interpret this as the - // no values of the hidden type ever being constructed, - // so we can just make the hidden type be `!`. - // For backwards compatibility reasons, we fall back to - // `()` until we the diverging default is changed. - Some(tcx.mk_diverging_default()) - }).expect("RPIT always have a hidden type from typeck") + // We failed to resolve the opaque type or it + // resolves to itself. Return the non-revealed + // type, which should result in E0720. + tcx.mk_opaque( + def_id.to_def_id(), + InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), + ) } }); debug!("concrete_ty = {:?}", concrete_ty); @@ -599,21 +605,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } // Calling `mir_borrowck` can lead to cycle errors through // const-checking, avoid calling it if we don't have to. - // ```rust - // type Foo = impl Fn() -> usize; // when computing type for this - // const fn bar() -> Foo { - // || 0usize - // } - // const BAZR: Foo = bar(); // we would mir-borrowck this, causing cycles - // // because we again need to reveal `Foo` so we can check whether the - // // constant does not contain interior mutability. - // ``` - let tables = self.tcx.typeck(def_id); - if let Some(_) = tables.tainted_by_errors { - self.found = Some((DUMMY_SP, self.tcx.ty_error())); - return; - } - if tables.concrete_opaque_types.get(&self.def_id).is_none() { + if !self.tcx.typeck(def_id).concrete_opaque_types.contains(&self.def_id) { debug!("no constraints in typeck results"); return; } @@ -667,7 +659,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { intravisit::walk_expr(self, ex); } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { - trace!(?it.def_id); + debug!("find_existential_constraints: visiting {:?}", it); // The opaque type itself or its children are not within its reveal scope. if it.def_id.to_def_id() != self.def_id { self.check(it.def_id); @@ -675,7 +667,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } } fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) { - trace!(?it.def_id); + debug!("find_existential_constraints: visiting {:?}", it); // The opaque type itself or its children are not within its reveal scope. if it.def_id.to_def_id() != self.def_id { self.check(it.def_id); @@ -683,7 +675,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } } fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) { - trace!(?it.def_id); + debug!("find_existential_constraints: visiting {:?}", it); self.check(it.def_id); intravisit::walk_trait_item(self, it); } @@ -693,12 +685,12 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { let scope = tcx.hir().get_defining_scope(hir_id); let mut locator = ConstraintLocator { def_id: def_id.to_def_id(), tcx, found: None }; - debug!(?scope); + debug!("find_opaque_ty_constraints: scope={:?}", scope); if scope == hir::CRATE_HIR_ID { tcx.hir().walk_toplevel_module(&mut locator); } else { - trace!("scope={:#?}", tcx.hir().get(scope)); + debug!("find_opaque_ty_constraints: scope={:?}", tcx.hir().get(scope)); match tcx.hir().get(scope) { // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods // This allows our visitor to process the defining item itself, causing @@ -725,12 +717,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { Some((_, ty)) => ty, None => { let span = tcx.def_span(def_id); - let name = tcx.item_name(tcx.parent(def_id.to_def_id()).unwrap()); - let label = format!( - "`{}` must be used in combination with a concrete type within the same module", - name - ); - tcx.sess.struct_span_err(span, "unconstrained opaque type").note(&label).emit(); + tcx.sess.span_err(span, "could not find defining uses"); tcx.ty_error() } } diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 4227ed6ab3ad5..d87e670a8fb5a 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -427,7 +427,6 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } diff --git a/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs index 7839ce5e4ff48..bbf31de527eb3 100644 --- a/compiler/rustc_typeck/src/outlives/explicit.rs +++ b/compiler/rustc_typeck/src/outlives/explicit.rs @@ -59,7 +59,6 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => (), } } diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index d9467e8fd6bc1..7105a2457e282 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -147,12 +147,6 @@ fn main() { cmd.arg("-Z").arg("force-unstable-if-unmarked"); } - if let Ok(flags) = env::var("MAGIC_EXTRA_RUSTFLAGS") { - for flag in flags.split(' ') { - cmd.arg(flag); - } - } - let is_test = args.iter().any(|a| a == "--test"); if verbose > 2 { let rust_env_vars = diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 521a88f9beb19..f54fb4af26133 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -297,7 +297,6 @@ impl<'a> Clean> for ty::Predicate<'a> { | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"), } } diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 31564a0cbd5c6..4124eada188e8 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -305,7 +305,7 @@ pub fn return_impl_trait() -> i32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] +#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")] #[rustc_clean(cfg = "cfail3")] #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] #[rustc_clean(cfg = "cfail6")] diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs index 67b97c21805e6..4c36289f47b85 100644 --- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -30,7 +30,7 @@ impl Thing for AssocNoCopy { type Out = Box>; fn func() -> Self::Out { - Box::new(AssocNoCopy) //~^ ERROR the trait bound `String: Copy` is not satisfied + Box::new(AssocNoCopy) } } diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index f1dcd34066dbc..a32ab453152a0 100644 --- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:33:9 + --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:32:18 | -LL | Box::new(AssocNoCopy) - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` - | - = note: required for the cast to the object type `dyn Bar::Out::{opaque#0}>` +LL | fn func() -> Self::Out { + | ^^^^^^^^^ the trait `Copy` is not implemented for `String` error: aborting due to previous error diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs index 30e4c1a3c537b..5f994f26534bd 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs @@ -23,8 +23,8 @@ fn bar() -> impl Bar { } fn baz() -> impl Bar { +//~^ ERROR type mismatch resolving `::Item == i32` bar() - //~^ ERROR type mismatch resolving `::Item == i32` } fn main() { diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr index 9523a54d954df..283ecea735d41 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr @@ -1,16 +1,14 @@ error[E0271]: type mismatch resolving `::Item == i32` - --> $DIR/impl-trait-return-missing-constraint.rs:26:5 + --> $DIR/impl-trait-return-missing-constraint.rs:25:13 | LL | fn bar() -> impl Bar { - | -------- the expected opaque type + | -------- the found opaque type ... -LL | bar() - | ^^^^^ expected associated type, found `i32` +LL | fn baz() -> impl Bar { + | ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type | - = note: expected associated type `::Item` - found type `i32` - = help: consider constraining the associated type `::Item` to `i32` or calling a method that returns `::Item` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: expected type `i32` + found associated type `::Item` help: consider constraining the associated type `::Item` to `i32` | LL | fn bar() -> impl Bar { diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr index f21c811512416..44d60c1d80d88 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -8,10 +8,10 @@ LL | Box::new(async { x } ) | may outlive borrowed value `x` | note: async block is returned here - --> $DIR/async-borrowck-escaping-block-error.rs:6:5 + --> $DIR/async-borrowck-escaping-block-error.rs:4:20 | -LL | Box::new(async { x } ) - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn test_boxed() -> Box> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | Box::new(async move { x } ) diff --git a/src/test/ui/async-await/issue-64130-4-async-move.rs b/src/test/ui/async-await/issue-64130-4-async-move.rs index 7cb02e5cf383d..2538f34351e5a 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.rs +++ b/src/test/ui/async-await/issue-64130-4-async-move.rs @@ -13,9 +13,9 @@ impl Client { async fn get() { } pub fn foo() -> impl Future + Send { + //~^ ERROR future cannot be sent between threads safely let client = Client(Box::new(true)); async move { - //~^ ERROR future cannot be sent between threads safely match client.status() { 200 => { let _x = get().await; diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index 3a84907e0c04b..d631e6dc7f7e9 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-64130-4-async-move.rs:17:5 + --> $DIR/issue-64130-4-async-move.rs:15:17 | -LL | async move { - | ^^^^^^^^^^ future created by async block is not `Send` +LL | pub fn foo() -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-70818.rs b/src/test/ui/async-await/issue-70818.rs index 631389e10f316..0609e4fc08170 100644 --- a/src/test/ui/async-await/issue-70818.rs +++ b/src/test/ui/async-await/issue-70818.rs @@ -2,8 +2,8 @@ use std::future::Future; fn foo(ty: T, ty1: U) -> impl Future + Send { +//~^ Error future cannot be sent between threads safely async { (ty, ty1) } - //~^ Error future cannot be sent between threads safely } fn main() {} diff --git a/src/test/ui/async-await/issue-70818.stderr b/src/test/ui/async-await/issue-70818.stderr index cb50c70f99847..20109d4d1166a 100644 --- a/src/test/ui/async-await/issue-70818.stderr +++ b/src/test/ui/async-await/issue-70818.stderr @@ -1,11 +1,11 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70818.rs:5:5 + --> $DIR/issue-70818.rs:4:38 | -LL | async { (ty, ty1) } - | ^^^^^ future created by async block is not `Send` +LL | fn foo(ty: T, ty1: U) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | note: captured value is not `Send` - --> $DIR/issue-70818.rs:5:18 + --> $DIR/issue-70818.rs:6:18 | LL | async { (ty, ty1) } | ^^^ has type `U` which is not `Send` diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs index 494561229511e..2965a7e0654a4 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.rs +++ b/src/test/ui/async-await/issue-70935-complex-spans.rs @@ -8,8 +8,8 @@ async fn baz(_c: impl FnMut() -> T) where T: Future { } fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { + //~^ ERROR: future cannot be sent between threads safely async move { - //~^ ERROR: future cannot be sent between threads safely baz(|| async{ foo(tx.clone()); }).await; diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.stderr index ad61f21741bb5..db3099381196b 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70935-complex-spans.rs:11:5 + --> $DIR/issue-70935-complex-spans.rs:10:45 | -LL | async move { - | ^^^^^^^^^^ future created by async block is not `Send` +LL | fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `Sender` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr index cdb141c0e3ea2..2722c72c20a33 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -14,16 +14,12 @@ LL | | } = help: consider adding the following bound: `'a: 'b` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-one.rs:16:80 + --> $DIR/ret-impl-trait-one.rs:16:65 | -LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { - | ____________________________________--__________________________________________^ - | | | - | | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here -LL | | -LL | | (a, b) -LL | | } - | |_^ +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 2eb3a07059f7b..149692a2c6998 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -1,26 +1,19 @@ error[E0623]: lifetime mismatch - --> $DIR/ret-impl-trait-one.rs:10:85 + --> $DIR/ret-impl-trait-one.rs:10:65 | -LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { - | ______________________________________________________------_____-------------------_^ - | | | - | | this parameter and the return type are declared with different lifetimes... -LL | | -LL | | (a, b) -LL | | } - | |_^ ...but data from `a` is returned here +LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | ------ ^^^^^^^^^^^^^^^^^^^ + | | | + | | ...but data from `a` is returned here + | this parameter and the return type are declared with different lifetimes... error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-one.rs:16:80 + --> $DIR/ret-impl-trait-one.rs:16:65 | -LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { - | ____________________________________--__________________________________________^ - | | | - | | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here -LL | | -LL | | (a, b) -LL | | } - | |_^ +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index cfb0ef1b33a2b..b3c59734e036f 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -3,4 +3,3 @@ pub const async fn x() {} //~^ ERROR functions cannot be both `const` and `async` -//~| ERROR cycle detected diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index fd76c282f9629..90ec646c8c09c 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -7,36 +7,5 @@ LL | pub const async fn x() {} | | `async` because of this | `const` because of this -error[E0391]: cycle detected when computing type of `x::{opaque#0}` - --> $DIR/no-const-async.rs:4:24 - | -LL | pub const async fn x() {} - | ^ - | -note: ...which requires borrow-checking `x`... - --> $DIR/no-const-async.rs:4:1 - | -LL | pub const async fn x() {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `x`... - --> $DIR/no-const-async.rs:4:1 - | -LL | pub const async fn x() {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const checking `x`... - --> $DIR/no-const-async.rs:4:1 - | -LL | pub const async fn x() {} - | ^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing whether `impl core::future::future::Future` is freeze... - = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future: core::marker::Freeze`... - = note: ...which again requires computing type of `x::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/no-const-async.rs:4:1 - | -LL | pub const async fn x() {} - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs index edc4cb8ac5df3..aa7733194587d 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.rs +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.rs @@ -2,8 +2,7 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden when using `async` and `await`. -async fn recursive_async_function() -> () { - //~^ ERROR recursion in an `async fn` requires boxing +async fn recursive_async_function() -> () { //~ ERROR recursive_async_function().await; } diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs index 046f1dfea3238..c7c5b51e7334b 100644 --- a/src/test/ui/async-await/suggest-missing-await.rs +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -21,6 +21,7 @@ async fn dummy() {} async fn suggest_await_in_async_fn_return() { dummy() //~^ ERROR mismatched types [E0308] + //~| HELP consider using a semicolon here //~| HELP consider `await`ing on the `Future` //~| SUGGESTION .await } diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index a60571dc11df6..3cca9616a358a 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -33,9 +33,13 @@ help: consider `await`ing on the `Future` | LL | dummy().await | ++++++ +help: consider using a semicolon here + | +LL | dummy(); + | + error[E0308]: `if` and `else` have incompatible types - --> $DIR/suggest-missing-await.rs:34:9 + --> $DIR/suggest-missing-await.rs:35:9 | LL | let _x = if true { | ______________- @@ -49,20 +53,15 @@ LL | | LL | | }; | |_____- `if` and `else` have incompatible types | -note: while checking the return type of the `async fn` - --> $DIR/suggest-missing-await.rs:18:18 - | -LL | async fn dummy() {} - | ^ checked the `Output` of this `async fn`, expected opaque type - = note: expected opaque type `impl Future` - found unit type `()` + = note: expected type `impl Future` + found unit type `()` help: consider `await`ing on the `Future` | LL | dummy().await | ++++++ error[E0308]: `match` arms have incompatible types - --> $DIR/suggest-missing-await.rs:44:14 + --> $DIR/suggest-missing-await.rs:45:14 | LL | let _x = match 0usize { | ______________- @@ -90,7 +89,7 @@ LL ~ 1 => dummy().await, | error[E0308]: mismatched types - --> $DIR/suggest-missing-await.rs:52:9 + --> $DIR/suggest-missing-await.rs:53:9 | LL | () => {} | ^^ expected opaque type, found `()` @@ -108,13 +107,13 @@ LL | let _x = match dummy().await { | ++++++ error[E0308]: mismatched types - --> $DIR/suggest-missing-await.rs:66:9 + --> $DIR/suggest-missing-await.rs:67:9 | LL | Ok(_) => {} | ^^^^^ expected opaque type, found enum `Result` | note: while checking the return type of the `async fn` - --> $DIR/suggest-missing-await.rs:56:28 + --> $DIR/suggest-missing-await.rs:57:28 | LL | async fn dummy_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type @@ -126,13 +125,13 @@ LL | match dummy_result().await { | ++++++ error[E0308]: mismatched types - --> $DIR/suggest-missing-await.rs:68:9 + --> $DIR/suggest-missing-await.rs:69:9 | LL | Err(_) => {} | ^^^^^^ expected opaque type, found enum `Result` | note: while checking the return type of the `async fn` - --> $DIR/suggest-missing-await.rs:56:28 + --> $DIR/suggest-missing-await.rs:57:28 | LL | async fn dummy_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type diff --git a/src/test/ui/cast/casts-differing-anon.rs b/src/test/ui/cast/casts-differing-anon.rs index ccf41adce6bd8..d4a0f9613055e 100644 --- a/src/test/ui/cast/casts-differing-anon.rs +++ b/src/test/ui/cast/casts-differing-anon.rs @@ -18,5 +18,5 @@ fn main() { // this is an `*mut fmt::Debug` in practice let mut b_raw = Box::into_raw(b); // ... and they should not be mixable - b_raw = f_raw as *mut _; //~ ERROR mismatched types + b_raw = f_raw as *mut _; //~ ERROR is invalid } diff --git a/src/test/ui/cast/casts-differing-anon.stderr b/src/test/ui/cast/casts-differing-anon.stderr index 2d08903c5ef69..f9abfb5225f91 100644 --- a/src/test/ui/cast/casts-differing-anon.stderr +++ b/src/test/ui/cast/casts-differing-anon.stderr @@ -1,19 +1,11 @@ -error[E0308]: mismatched types +error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` is invalid --> $DIR/casts-differing-anon.rs:21:13 | -LL | fn foo() -> Box { - | ---------------------- the found opaque type -... -LL | fn bar() -> Box { - | ---------------------- the expected opaque type -... LL | b_raw = f_raw as *mut _; - | ^^^^^ expected opaque type, found a different opaque type + | ^^^^^^^^^^^^^^^ | - = note: expected opaque type `impl Debug + ?Sized` (opaque type at <$DIR/casts-differing-anon.rs:7:17>) - found opaque type `impl Debug + ?Sized` (opaque type at <$DIR/casts-differing-anon.rs:3:17>) - = note: distinct uses of `impl Trait` result in different opaque types + = note: vtable kinds may not match error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr index 46379a3815a4d..bb00465758a45 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr @@ -8,10 +8,10 @@ LL | println!("{:?}", p); | - `p` is borrowed here | note: closure is returned here - --> $DIR/borrowck-4.rs:15:5 + --> $DIR/borrowck-4.rs:8:14 | -LL | c - | ^ +LL | fn foo () -> impl FnMut()->() { + | ^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword | LL | let mut c = move || { diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr index 9dc486980aaca..63a4df242f85f 100644 --- a/src/test/ui/conservative_impl_trait.stderr +++ b/src/test/ui/conservative_impl_trait.stderr @@ -1,11 +1,8 @@ error[E0277]: `()` is not an iterator - --> $DIR/conservative_impl_trait.rs:3:60 + --> $DIR/conservative_impl_trait.rs:3:33 | -LL | fn will_ice(something: &u32) -> impl Iterator { - | ____________________________________________________________^ -LL | | -LL | | } - | |_^ `()` is not an iterator +LL | fn will_ice(something: &u32) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `Iterator` is not implemented for `()` diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index b3bd88ad7d5d8..308c121a94111 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -4,8 +4,8 @@ trait Trait {} impl Trait for Uwu {} fn rawr() -> impl Trait { - Uwu::<10, 12> //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + Uwu::<10, 12> } trait Traitor { } @@ -15,13 +15,13 @@ impl Traitor<1, 2> for u64 {} fn uwu() -> impl Traitor { - 1_u32 //~^ error: the trait bound `u32: Traitor` is not satisfied + 1_u32 } fn owo() -> impl Traitor { - 1_u64 //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied + 1_u64 } fn main() { diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index ec23952114cdf..8c8bfdc0e4847 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -1,26 +1,26 @@ error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:7:5 + --> $DIR/rp_impl_trait_fail.rs:6:14 | -LL | Uwu::<10, 12> - | ^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` +LL | fn rawr() -> impl Trait { + | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` | = help: the following implementations were found: as Trait> error[E0277]: the trait bound `u32: Traitor` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:18:5 + --> $DIR/rp_impl_trait_fail.rs:17:26 | -LL | 1_u32 - | ^^^^^ the trait `Traitor` is not implemented for `u32` +LL | fn uwu() -> impl Traitor { + | ^^^^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u32` | = help: the following implementations were found: > error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:23:5 + --> $DIR/rp_impl_trait_fail.rs:22:13 | -LL | 1_u64 - | ^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` +LL | fn owo() -> impl Traitor { + | ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` | = help: the following implementations were found: > diff --git a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs index eab5a6190ef51..e0bb7dbfae9f1 100644 --- a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs +++ b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs @@ -4,9 +4,11 @@ //~^^^ ERROR `main` function not found in crate pub mod foo { type MainFn = impl Fn(); + //~^ ERROR could not find defining uses fn bar() {} pub const BAR: MainFn = bar; + //~^ ERROR mismatched types [E0308] } use foo::BAR as main; diff --git a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr index 83a189e01e013..c731c32832222 100644 --- a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr +++ b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr @@ -12,6 +12,25 @@ LL | | use foo::BAR as main; | | | non-function item at `crate::main` is found -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/imported_main_const_fn_item_type_forbidden.rs:10:29 + | +LL | type MainFn = impl Fn(); + | --------- the expected opaque type +... +LL | pub const BAR: MainFn = bar; + | ^^^ expected opaque type, found fn item + | + = note: expected opaque type `impl Fn()` + found fn item `fn() {bar}` + +error: could not find defining uses + --> $DIR/imported_main_const_fn_item_type_forbidden.rs:6:19 + | +LL | type MainFn = impl Fn(); + | ^^^^^^^^^ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0601`. +Some errors have detailed explanations: E0308, E0601. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6dfd7f6840f1b..ea82837d4bf55 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -1,13 +1,13 @@ // ignore-compare-mode-chalk -// check-pass #![feature(type_alias_impl_trait)] use std::fmt::Debug; type Foo = impl Debug; +//~^ ERROR could not find defining uses struct Bar(Foo); fn define() -> Bar { - Bar(42) + Bar(42) //~ ERROR mismatched types } type Foo2 = impl Debug; @@ -17,18 +17,21 @@ fn define2() { } type Foo3 = impl Debug; +//~^ ERROR could not find defining uses fn define3(x: Foo3) { - let y: i32 = x; + let y: i32 = x; //~ ERROR mismatched types } fn define3_1() { - define3(42) + define3(42) //~ ERROR mismatched types } type Foo4 = impl Debug; +//~^ ERROR could not find defining uses fn define4() { let y: Foo4 = 42; + //~^ ERROR mismatched types [E0308] } fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr new file mode 100644 index 0000000000000..da3ddb1c50979 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -0,0 +1,73 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-type_alias_impl_trait.rs:10:9 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | Bar(42) + | ^^ expected opaque type, found integer + | + = note: expected opaque type `impl Debug` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/feature-gate-type_alias_impl_trait.rs:23:18 + | +LL | type Foo3 = impl Debug; + | ---------- the found opaque type +... +LL | let y: i32 = x; + | --- ^ expected `i32`, found opaque type + | | + | expected due to this + | + = note: expected type `i32` + found opaque type `impl Debug` + +error[E0308]: mismatched types + --> $DIR/feature-gate-type_alias_impl_trait.rs:26:13 + | +LL | type Foo3 = impl Debug; + | ---------- the expected opaque type +... +LL | define3(42) + | ^^ expected opaque type, found integer + | + = note: expected opaque type `impl Debug` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/feature-gate-type_alias_impl_trait.rs:33:19 + | +LL | type Foo4 = impl Debug; + | ---------- the expected opaque type +... +LL | let y: Foo4 = 42; + | ---- ^^ expected opaque type, found integer + | | + | expected due to this + | + = note: expected opaque type `impl Debug` + found type `{integer}` + +error: could not find defining uses + --> $DIR/feature-gate-type_alias_impl_trait.rs:5:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + +error: could not find defining uses + --> $DIR/feature-gate-type_alias_impl_trait.rs:19:13 + | +LL | type Foo3 = impl Debug; + | ^^^^^^^^^^ + +error: could not find defining uses + --> $DIR/feature-gate-type_alias_impl_trait.rs:29:13 + | +LL | type Foo4 = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs index c4905995a860a..ce9159b53e0f0 100644 --- a/src/test/ui/generator/issue-88653.rs +++ b/src/test/ui/generator/issue-88653.rs @@ -6,10 +6,10 @@ use std::ops::Generator; fn foo(bar: bool) -> impl Generator<(bool,)> { +//~^ ERROR: type mismatch in generator arguments [E0631] +//~| NOTE: expected signature of `fn((bool,)) -> _` |bar| { //~^ NOTE: found signature of `fn(bool) -> _` - //~| ERROR: type mismatch in generator arguments [E0631] - //~| NOTE: expected signature of `fn((bool,)) -> _` if bar { yield bar; } diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr index eaa90a8e60a23..5bd8ad129fef9 100644 --- a/src/test/ui/generator/issue-88653.stderr +++ b/src/test/ui/generator/issue-88653.stderr @@ -1,11 +1,11 @@ error[E0631]: type mismatch in generator arguments - --> $DIR/issue-88653.rs:9:5 + --> $DIR/issue-88653.rs:8:22 | +LL | fn foo(bar: bool) -> impl Generator<(bool,)> { + | ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _` +... LL | |bar| { - | ^^^^^ - | | - | expected signature of `fn((bool,)) -> _` - | found signature of `fn(bool) -> _` + | ----- found signature of `fn(bool) -> _` error: aborting due to previous error diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs index d1b16b6e10da0..7774ff48f56b7 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.rs +++ b/src/test/ui/generator/type-mismatch-signature-deduction.rs @@ -2,8 +2,8 @@ use std::ops::Generator; -fn foo() -> impl Generator { - || { //~ ERROR type mismatch +fn foo() -> impl Generator { //~ ERROR type mismatch + || { if false { return Ok(6); } diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index 3e78e5b53ba1f..3f1f33a3b123f 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -13,19 +13,13 @@ LL | return Ok(6); | ^^^^^ error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32` - --> $DIR/type-mismatch-signature-deduction.rs:6:5 + --> $DIR/type-mismatch-signature-deduction.rs:5:13 | -LL | / || { -LL | | if false { -LL | | return Ok(6); -LL | | } -... | -LL | | 5 -LL | | } - | |_____^ expected enum `Result`, found `i32` +LL | fn foo() -> impl Generator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found enum `Result` | - = note: expected enum `Result<{integer}, _>` - found type `i32` + = note: expected type `i32` + found enum `Result<{integer}, _>` error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-87258_a.rs b/src/test/ui/generic-associated-types/issue-87258_a.rs index c65f3fb2aa0a1..d9d17751fa6e2 100644 --- a/src/test/ui/generic-associated-types/issue-87258_a.rs +++ b/src/test/ui/generic-associated-types/issue-87258_a.rs @@ -16,8 +16,7 @@ pub trait Trait2 { impl<'c, S: Trait2> Trait2 for &'c mut S { type FooFuture<'a> = impl Trait1; - //~^ ERROR unconstrained opaque type - fn foo<'a>() -> Self::FooFuture<'a> { + fn foo<'a>() -> Self::FooFuture<'a> { //~ ERROR Struct(unimplemented!()) } } diff --git a/src/test/ui/generic-associated-types/issue-87258_a.stderr b/src/test/ui/generic-associated-types/issue-87258_a.stderr index db3a5c819cbf3..93513a4563f07 100644 --- a/src/test/ui/generic-associated-types/issue-87258_a.stderr +++ b/src/test/ui/generic-associated-types/issue-87258_a.stderr @@ -1,10 +1,11 @@ -error: unconstrained opaque type - --> $DIR/issue-87258_a.rs:18:26 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/issue-87258_a.rs:19:21 | -LL | type FooFuture<'a> = impl Trait1; - | ^^^^^^^^^^^ +LL | fn foo<'a>() -> Self::FooFuture<'a> { + | ^^^^^^^^^^^^^^^^^^^ | - = note: `FooFuture` must be used in combination with a concrete type within the same module + = note: hidden type `Struct<'_>` captures lifetime '_#7r error: aborting due to previous error +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/generic-associated-types/issue-87258_b.rs b/src/test/ui/generic-associated-types/issue-87258_b.rs index f59e0d7665942..b29a978f517ff 100644 --- a/src/test/ui/generic-associated-types/issue-87258_b.rs +++ b/src/test/ui/generic-associated-types/issue-87258_b.rs @@ -15,11 +15,10 @@ pub trait Trait2 { } type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; -//~^ ERROR unconstrained opaque type impl<'c, S: Trait2> Trait2 for &'c mut S { type FooFuture<'a> = Helper<'c, 'a, S>; - fn foo<'a>() -> Self::FooFuture<'a> { + fn foo<'a>() -> Self::FooFuture<'a> { //~ ERROR Struct(unimplemented!()) } } diff --git a/src/test/ui/generic-associated-types/issue-87258_b.stderr b/src/test/ui/generic-associated-types/issue-87258_b.stderr index 9faccc96124bc..e077a423400df 100644 --- a/src/test/ui/generic-associated-types/issue-87258_b.stderr +++ b/src/test/ui/generic-associated-types/issue-87258_b.stderr @@ -1,10 +1,11 @@ -error: unconstrained opaque type - --> $DIR/issue-87258_b.rs:17:49 +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/issue-87258_b.rs:21:21 | -LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; - | ^^^^^^^^^^^ +LL | fn foo<'a>() -> Self::FooFuture<'a> { + | ^^^^^^^^^^^^^^^^^^^ | - = note: `Helper` must be used in combination with a concrete type within the same module + = note: hidden type `Struct<'_>` captures lifetime '_#7r error: aborting due to previous error +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/generic-associated-types/issue-88595.rs b/src/test/ui/generic-associated-types/issue-88595.rs index ea1bd2be4529d..e397390783f66 100644 --- a/src/test/ui/generic-associated-types/issue-88595.rs +++ b/src/test/ui/generic-associated-types/issue-88595.rs @@ -18,6 +18,7 @@ struct C; impl<'a> A<'a> for C { type B<'b> = impl Clone; //~^ ERROR: lifetime bound not satisfied + //~| ERROR: could not find defining uses fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope } diff --git a/src/test/ui/generic-associated-types/issue-88595.stderr b/src/test/ui/generic-associated-types/issue-88595.stderr index e1d55fa228c2e..cb462871ccd32 100644 --- a/src/test/ui/generic-associated-types/issue-88595.stderr +++ b/src/test/ui/generic-associated-types/issue-88595.stderr @@ -16,10 +16,10 @@ LL | type B<'b> = impl Clone; | ^^ error: non-defining opaque type use in defining scope - --> $DIR/issue-88595.rs:22:35 + --> $DIR/issue-88595.rs:23:23 | LL | fn a(&'a self) -> Self::B<'a> {} - | ^^ + | ^^^^^^^^^^^ | note: lifetime used multiple times --> $DIR/issue-88595.rs:18:6 @@ -29,6 +29,12 @@ LL | impl<'a> A<'a> for C { LL | type B<'b> = impl Clone; | ^^ -error: aborting due to 2 previous errors +error: could not find defining uses + --> $DIR/issue-88595.rs:19:18 + | +LL | type B<'b> = impl Clone; + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0478`. diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr index f8c89829e1646..72ade5774d749 100644 --- a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr +++ b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr @@ -1,20 +1,18 @@ error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:24:5 + --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect(c: &'_ C) -> impl '_ + Future + Send - | - help: consider adding an explicit lifetime bound...: `C: 'a` -... -LL | async move { c.connect().await } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `C: 'a` error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:24:5 + --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect(c: &'_ C) -> impl '_ + Future + Send - | - help: consider adding an explicit lifetime bound...: `C: 'a` -... -LL | async move { c.connect().await } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `C: 'a` error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-92096.rs b/src/test/ui/generic-associated-types/issue-92096.rs index 2bc1af5506ffd..066132a5d98bb 100644 --- a/src/test/ui/generic-associated-types/issue-92096.rs +++ b/src/test/ui/generic-associated-types/issue-92096.rs @@ -18,12 +18,12 @@ trait Client { } fn call_connect(c: &'_ C) -> impl '_ + Future + Send +//[migrate]~^ ERROR the parameter +//[migrate]~| ERROR the parameter where C: Client + Send + Sync, { async move { c.connect().await } - //[migrate]~^ ERROR the parameter - //[migrate]~| ERROR the parameter } fn main() {} diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index d2452abab0254..c2fbbf94fd666 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -11,7 +11,6 @@ fn main() { // return type, which can't depend on the obligation. fn cycle1() -> impl Clone { //~^ ERROR cycle detected - //~| ERROR cycle detected send(cycle2().clone()); Rc::new(Cell::new(5)) diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 14db864f1c28a..634ff14869eb4 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -30,129 +30,47 @@ note: ...which requires building MIR for `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires computing type of `cycle2::{opaque#0}`... - --> $DIR/auto-trait-leak.rs:20:16 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/auto-trait-leak.rs:1:1 - | -LL | / use std::cell::Cell; -LL | | use std::rc::Rc; -LL | | -LL | | fn send(_: T) {} -... | -LL | | Rc::new(String::from("foo")) -LL | | } - | |_^ - -error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}` - --> $DIR/auto-trait-leak.rs:12:16 + --> $DIR/auto-trait-leak.rs:14:5 | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | send(cycle2().clone()); + | ^^^^ + = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... note: ...which requires computing type of `cycle2::{opaque#0}`... - --> $DIR/auto-trait-leak.rs:20:16 + --> $DIR/auto-trait-leak.rs:19:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:20:5 | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | send(cycle1().clone()); + | ^^^^ + = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:1:1 @@ -166,6 +84,6 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs index 35994e4a5ba3f..cf2773f4ef59d 100644 --- a/src/test/ui/impl-trait/auto-trait.rs +++ b/src/test/ui/impl-trait/auto-trait.rs @@ -19,7 +19,7 @@ impl AnotherTrait for T {} // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr index 81009413c9a26..26cd8fb6a9b5c 100644 --- a/src/test/ui/impl-trait/auto-trait.stderr +++ b/src/test/ui/impl-trait/auto-trait.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` --> $DIR/auto-trait.rs:21:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 20ddad0547ef2..8ec06e534d143 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -23,8 +23,8 @@ mod impl_trait { /// `T::Assoc` can't be normalized any further here. fn foo_fail() -> impl FooLike { - Foo(()) //~^ ERROR: type mismatch + Foo(()) } } @@ -39,9 +39,9 @@ mod lifetimes { /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - Foo(()) //~^ ERROR: type mismatch + //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + Foo(()) } } diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 01fb853e1d1f7..afa21c1a858a2 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,16 +1,16 @@ error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` - --> $DIR/bound-normalization-fail.rs:26:9 + --> $DIR/bound-normalization-fail.rs:25:32 | -LL | Foo(()) - | ^^^^^^^ type mismatch resolving ` as FooLike>::Output == ::Assoc` +LL | fn foo_fail() -> impl FooLike { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == ::Assoc` | -note: expected this to be `()` +note: expected this to be `::Assoc` --> $DIR/bound-normalization-fail.rs:14:19 | LL | type Output = T; | ^ - = note: expected unit type `()` - found associated type `::Assoc` + = note: expected associated type `::Assoc` + found unit type `()` help: consider constraining the associated type `::Assoc` to `()` | LL | fn foo_fail>() -> impl FooLike { @@ -23,18 +23,18 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` - --> $DIR/bound-normalization-fail.rs:43:9 + --> $DIR/bound-normalization-fail.rs:41:41 | -LL | Foo(()) - | ^^^^^^^ type mismatch resolving ` as FooLike>::Output == >::Assoc` +LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == >::Assoc` | -note: expected this to be `()` +note: expected this to be `>::Assoc` --> $DIR/bound-normalization-fail.rs:14:19 | LL | type Output = T; | ^ - = note: expected unit type `()` - found associated type `>::Assoc` + = note: expected associated type `>::Assoc` + found unit type `()` help: consider constraining the associated type `>::Assoc` to `()` | LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike { diff --git a/src/test/ui/impl-trait/does-not-live-long-enough.stderr b/src/test/ui/impl-trait/does-not-live-long-enough.stderr index 750687e232228..f4bd0fde3b6cb 100644 --- a/src/test/ui/impl-trait/does-not-live-long-enough.stderr +++ b/src/test/ui/impl-trait/does-not-live-long-enough.stderr @@ -7,10 +7,10 @@ LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref | may outlive borrowed value `prefix` | note: closure is returned here - --> $DIR/does-not-live-long-enough.rs:6:9 + --> $DIR/does-not-live-long-enough.rs:5:55 | -LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword | LL | self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref()) diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 59770c10da2b2..9610618ca11f6 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -17,8 +17,8 @@ fn two(x: bool) -> impl Foo { //~| expected `i32`, found `u32` } -fn sum_to(n: u32) -> impl Foo { - if n == 0 { //~ ERROR type annotations needed +fn sum_to(n: u32) -> impl Foo { //~ ERROR type annotations needed + if n == 0 { 0 } else { n + sum_to(n - 1) diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 4032fbbceba4c..d9819484a9612 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,13 +12,19 @@ error[E0308]: mismatched types --> $DIR/equality.rs:15:5 | LL | fn two(x: bool) -> impl Foo { - | -------- the expected opaque type -... + | -------- expected because this return type... +LL | if x { +LL | return 1_i32; + | ----- ...is found to be `i32` here +LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | - = note: expected opaque type `impl Foo` - found type `u32` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: if the trait `Foo` were object safe, you could return a boxed trait object + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 @@ -29,15 +35,10 @@ LL | n + sum_to(n - 1) = help: the trait `Add` is not implemented for `u32` error[E0283]: type annotations needed - --> $DIR/equality.rs:21:5 - | -LL | / if n == 0 { -LL | | 0 -LL | | } else { -LL | | n + sum_to(n - 1) -LL | | -LL | | } - | |_____^ cannot infer type for type `{integer}` + --> $DIR/equality.rs:20:22 + | +LL | fn sum_to(n: u32) -> impl Foo { + | ^^^^^^^^ cannot infer type for type `{integer}` | = note: multiple `impl`s satisfying `{integer}: ToString` found in the `alloc` crate: - impl ToString for i8; diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index fd33fa7c674f1..46053c6e7c119 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -15,7 +15,9 @@ LL | fn hide(x: T) -> impl Foo { | -------- the found opaque type ... LL | let _: u32 = hide(0_u32); - | ^^^^^^^^^^^ expected `u32`, found opaque type + | --- ^^^^^^^^^^^ expected `u32`, found opaque type + | | + | expected due to this | = note: expected type `u32` found opaque type `impl Foo` diff --git a/src/test/ui/impl-trait/fallback.rs b/src/test/ui/impl-trait/fallback.rs deleted file mode 100644 index 1e6eb5bb35588..0000000000000 --- a/src/test/ui/impl-trait/fallback.rs +++ /dev/null @@ -1,9 +0,0 @@ -// check-pass - -fn take_edge_counters( - x: &mut Option>, -) -> Option> { - x.take().map_or(None, |m| Some(m.into_iter())) -} - -fn main() {} diff --git a/src/test/ui/impl-trait/hidden-lifetimes.rs b/src/test/ui/impl-trait/hidden-lifetimes.rs index ae07c89276861..2ee004a37a6fc 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.rs +++ b/src/test/ui/impl-trait/hidden-lifetimes.rs @@ -26,8 +26,8 @@ impl Swap for Rc> { // Here we are hiding `'b` making the caller believe that `&'a mut &'s T` and // `&'a mut &'l T` are the same type. fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { - x //~^ ERROR hidden type + x } fn dangle_ref() -> &'static [i32; 3] { @@ -43,8 +43,8 @@ fn dangle_ref() -> &'static [i32; 3] { // This is different to the previous example because the concrete return type // only has a single lifetime. fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { - x //~^ ERROR hidden type + x } fn dangle_rc_refcell() -> &'static [i32; 3] { diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr index 97652f5462ef0..c6d11293eec53 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -1,10 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/hidden-lifetimes.rs:29:5 + --> $DIR/hidden-lifetimes.rs:28:54 | LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { - | -- hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here -LL | x - | ^ + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -12,12 +12,12 @@ LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/hidden-lifetimes.rs:46:5 + --> $DIR/hidden-lifetimes.rs:45:70 | LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { - | -- hidden type `Rc>` captures the lifetime `'b` as defined here -LL | x - | ^ + | -- ^^^^^^^^^^^^^^ + | | + | hidden type `Rc>` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs b/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs deleted file mode 100644 index 1b65685a6c06f..0000000000000 --- a/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs +++ /dev/null @@ -1,34 +0,0 @@ -// This doesn't work, because we don't flow information from opaque types -// into function arguments via the function's generic parameters -// FIXME(oli-obk): make `expected_inputs_for_expected_output` support this - -fn reify_as() -> Thunk Continuation> { - Thunk::new(|mut cont| { //~ ERROR type annotations needed - cont.reify_as(); - cont - }) -} - -#[must_use] -struct Thunk(F); - -impl Thunk { - fn new(f: F) -> Self - where - F: ContFn, - { - Thunk(f) - } -} - -trait ContFn {} - -impl Continuation> ContFn for F {} - -struct Continuation; - -impl Continuation { - fn reify_as(&mut self) {} -} - -fn main() {} diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr b/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr deleted file mode 100644 index e538aaeb4c5ed..0000000000000 --- a/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/hidden-type-is-opaque-2.rs:6:17 - | -LL | Thunk::new(|mut cont| { - | ^^^^^^^^ consider giving this closure parameter a type - | - = note: type must be known at this point - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque.rs b/src/test/ui/impl-trait/hidden-type-is-opaque.rs deleted file mode 100644 index b302ae36ef42c..0000000000000 --- a/src/test/ui/impl-trait/hidden-type-is-opaque.rs +++ /dev/null @@ -1,32 +0,0 @@ -// check-pass - -fn reify_as() -> Thunk { - Thunk::new(|mut cont| { - cont.reify_as(); - cont - }) -} - -#[must_use] -struct Thunk(F); - -impl Thunk { - fn new(f: F) -> Self - where - F: FnOnce(Continuation) -> Continuation, - { - Thunk(f) - } -} - -trait ContFn {} - -impl Continuation> ContFn for F {} - -struct Continuation; - -impl Continuation { - fn reify_as(&mut self) {} -} - -fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-1.rs b/src/test/ui/impl-trait/issue-55872-1.rs index a75b9b43b3e8b..46188636475db 100644 --- a/src/test/ui/impl-trait/issue-55872-1.rs +++ b/src/test/ui/impl-trait/issue-55872-1.rs @@ -10,10 +10,11 @@ impl Bar for S { type E = impl Copy; fn foo() -> Self::E { - //~^ ERROR impl has stricter requirements than trait - (S::default(), T::default()) - //~^ ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277] + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + //~| ERROR impl has stricter requirements than trait + //~| ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277] //~| ERROR the trait bound `T: Copy` is not satisfied in `(S, T)` [E0277] + (S::default(), T::default()) } } diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr index efc57da746132..2d1142fd0c52c 100644 --- a/src/test/ui/impl-trait/issue-55872-1.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -8,10 +8,10 @@ LL | fn foo() -> Self::E { | ^^^^^^^ impl has extra requirement `T: Default` error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:9 + --> $DIR/issue-55872-1.rs:12:29 | -LL | (S::default(), T::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` +LL | fn foo() -> Self::E { + | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound @@ -20,10 +20,10 @@ LL | impl Bar for S { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:9 + --> $DIR/issue-55872-1.rs:12:29 | -LL | (S::default(), T::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` +LL | fn foo() -> Self::E { + | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound @@ -31,7 +31,20 @@ help: consider further restricting this bound LL | fn foo() -> Self::E { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-1.rs:12:37 + | +LL | fn foo() -> Self::E { + | _____________________________________^ +LL | | +LL | | +LL | | +LL | | +LL | | (S::default(), T::default()) +LL | | } + | |_____^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0276, E0277. For more information about an error, try `rustc --explain E0276`. diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index f0bc0b5272784..a519397806e07 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -4,16 +4,17 @@ #![feature(type_alias_impl_trait)] pub trait Bar { - type E: Send; + type E: Copy; fn foo() -> Self::E; } impl Bar for S { - type E = impl std::marker::Send; + type E = impl std::marker::Copy; fn foo() -> Self::E { - async {} //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + //~| ERROR the trait bound `impl Future: Copy` is not satisfied + async {} } } diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 71090bdbf8061..97545ba3d1124 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,8 +1,20 @@ +error[E0277]: the trait bound `impl Future: Copy` is not satisfied + --> $DIR/issue-55872-2.rs:14:20 + | +LL | fn foo() -> Self::E { + | ^^^^^^^ the trait `Copy` is not implemented for `impl Future` + error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:15:9 + --> $DIR/issue-55872-2.rs:14:28 | -LL | async {} - | ^^^^^^^^ +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | +LL | | async {} +LL | | } + | |_____^ -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872-3.rs b/src/test/ui/impl-trait/issue-55872-3.rs deleted file mode 100644 index f50b31ff496ae..0000000000000 --- a/src/test/ui/impl-trait/issue-55872-3.rs +++ /dev/null @@ -1,20 +0,0 @@ -// edition:2018 -// ignore-compare-mode-chalk - -#![feature(type_alias_impl_trait)] - -pub trait Bar { - type E: Copy; - - fn foo() -> Self::E; -} - -impl Bar for S { - type E = impl std::marker::Copy; - fn foo() -> Self::E { - async {} - //~^ ERROR the trait bound `impl Future: Copy` is not satisfied [E0277] - } -} - -fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-3.stderr b/src/test/ui/impl-trait/issue-55872-3.stderr deleted file mode 100644 index bafd31f0083e8..0000000000000 --- a/src/test/ui/impl-trait/issue-55872-3.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `impl Future: Copy` is not satisfied - --> $DIR/issue-55872-3.rs:15:9 - | -LL | async {} - | ^^^^^^^^ the trait `Copy` is not implemented for `impl Future` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs index 65874d22ac6f3..bbd940254178c 100644 --- a/src/test/ui/impl-trait/issue-55872.rs +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -11,8 +11,8 @@ impl Bar for S { type E = impl Copy; fn foo() -> Self::E { - || () //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + || () } } diff --git a/src/test/ui/impl-trait/issue-55872.stderr b/src/test/ui/impl-trait/issue-55872.stderr index 7abcf6a059422..60654ec34610f 100644 --- a/src/test/ui/impl-trait/issue-55872.stderr +++ b/src/test/ui/impl-trait/issue-55872.stderr @@ -1,8 +1,12 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:14:9 + --> $DIR/issue-55872.rs:13:28 | -LL | || () - | ^^^^^ +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | || () +LL | | } + | |_____^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issue-72911.rs b/src/test/ui/impl-trait/issue-72911.rs index cf2c8b7e41540..dee5a41f6de37 100644 --- a/src/test/ui/impl-trait/issue-72911.rs +++ b/src/test/ui/impl-trait/issue-72911.rs @@ -5,7 +5,7 @@ pub struct Lint {} impl Lint {} pub fn gather_all() -> impl Iterator { - //~^ ERROR `()` is not an iterator + //~^ ERROR: cannot resolve opaque type lint_files().flat_map(|f| gather_from_file(&f)) } diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr index 4a990286d966d..e57fbf104dc6f 100644 --- a/src/test/ui/impl-trait/issue-72911.stderr +++ b/src/test/ui/impl-trait/issue-72911.stderr @@ -10,15 +10,25 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` LL | fn lint_files() -> impl Iterator { | ^^^ use of undeclared crate or module `foo` -error[E0277]: `()` is not an iterator +error[E0720]: cannot resolve opaque type --> $DIR/issue-72911.rs:7:24 | LL | pub fn gather_all() -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type +LL | +LL | lint_files().flat_map(|f| gather_from_file(&f)) + | ----------------------------------------------- + | | + | returning here with type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` + | returning here with type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` +... +LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { + | -------------------------- returning this opaque type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` +... +LL | fn lint_files() -> impl Iterator { + | -------------------------------------- returning this opaque type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0433. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0433, E0720. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/impl-trait/issues/issue-70877.rs b/src/test/ui/impl-trait/issues/issue-70877.rs index 1a86fa00ed1a0..853c2a82bede4 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.rs +++ b/src/test/ui/impl-trait/issues/issue-70877.rs @@ -4,7 +4,7 @@ type FooArg<'a> = &'a dyn ToString; type FooRet = impl std::fmt::Debug; type FooItem = Box FooRet>; -type Foo = impl Iterator; +type Foo = impl Iterator; //~ ERROR: type mismatch #[repr(C)] struct Bar(u8); @@ -13,7 +13,7 @@ impl Iterator for Bar { type Item = FooItem; fn next(&mut self) -> Option { - Some(Box::new(quux)) //~ ERROR mismatched types + Some(Box::new(quux)) } } @@ -28,7 +28,7 @@ fn ham() -> Foo { fn oof() -> impl std::fmt::Debug { let mut bar = ham(); let func = bar.next().unwrap(); - return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type + return func(&"oof"); } fn main() { diff --git a/src/test/ui/impl-trait/issues/issue-70877.stderr b/src/test/ui/impl-trait/issues/issue-70877.stderr index 7cbd58bdabf2f..fe48e92da5eac 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.stderr +++ b/src/test/ui/impl-trait/issues/issue-70877.stderr @@ -1,34 +1,20 @@ -error[E0308]: mismatched types - --> $DIR/issue-70877.rs:16:9 +error[E0271]: type mismatch resolving `::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + --> $DIR/issue-70877.rs:7:12 | LL | type FooRet = impl std::fmt::Debug; - | -------------------- the expected opaque type + | -------------------- the found opaque type ... -LL | fn next(&mut self) -> Option { - | ------------------ expected `Option Fn(&'r (dyn ToString + 'r)) -> FooRet + 'static)>>` because of return type -LL | Some(Box::new(quux)) - | ^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found fn item +LL | type Foo = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` | - = note: expected enum `Option Fn(&'r (dyn ToString + 'r)) -> FooRet + 'static)>>` - found enum `Option fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>` - -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/issue-70877.rs:31:12 - | -LL | return func(&"oof"); - | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/issue-70877.rs:28:13 +note: expected this to be `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + --> $DIR/issue-70877.rs:13:17 | -LL | fn oof() -> impl std::fmt::Debug { - | ^^^^^^^^^^^^^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/issue-70877.rs:4:15 - | -LL | type FooRet = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ +LL | type Item = FooItem; + | ^^^^^^^ + = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/impl-trait/issues/issue-78722.rs b/src/test/ui/impl-trait/issues/issue-78722.rs index b13ab6bad7fbe..bdbd20f9d2b88 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.rs +++ b/src/test/ui/impl-trait/issues/issue-78722.rs @@ -10,8 +10,7 @@ struct Bug { async {} } let f: F = async { 1 }; - //~^ ERROR `async` blocks are not allowed in constants - //~| ERROR destructors cannot be evaluated at compile-time + //~^ ERROR mismatched types [E0308] 1 }], } diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr index 975c771759f9b..130678de2370c 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.stderr @@ -1,22 +1,23 @@ -error[E0658]: `async` blocks are not allowed in constants +error[E0308]: mismatched types --> $DIR/issue-78722.rs:12:20 | +LL | type F = impl core::future::Future; + | -------------------------------------- the expected opaque type +... LL | let f: F = async { 1 }; - | ^^^^^^^^^^^ + | - ^^^^^^^^^^^ expected opaque type, found a different opaque type + | | + | expected due to this | - = note: see issue #85368 for more information - = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable - -error[E0493]: destructors cannot be evaluated at compile-time - --> $DIR/issue-78722.rs:12:13 + ::: $SRC_DIR/core/src/future/mod.rs:LL:COL | -LL | let f: F = async { 1 }; - | ^ constants cannot evaluate destructors -... -LL | }], - | - value is dropped here +LL | pub const fn from_generator(gen: T) -> impl Future + | ------------------------------- the found opaque type + | + = note: expected opaque type `impl Future` + found opaque type `impl Future` + = note: distinct uses of `impl Trait` result in different opaque types -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0493, E0658. -For more information about an error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/issues/issue-86201.rs b/src/test/ui/impl-trait/issues/issue-86201.rs index 0786e66ca8b06..e3386d29def02 100644 --- a/src/test/ui/impl-trait/issues/issue-86201.rs +++ b/src/test/ui/impl-trait/issues/issue-86201.rs @@ -1,10 +1,10 @@ #![feature(unboxed_closures)] #![feature(type_alias_impl_trait)] -// check-pass - type FunType = impl Fn<()>; +//~^ ERROR could not find defining uses static STATIC_FN: FunType = some_fn; +//~^ ERROR mismatched types fn some_fn() {} diff --git a/src/test/ui/impl-trait/issues/issue-86201.stderr b/src/test/ui/impl-trait/issues/issue-86201.stderr new file mode 100644 index 0000000000000..b1460096ded66 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-86201.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-86201.rs:6:29 + | +LL | type FunType = impl Fn<()>; + | ----------- the expected opaque type +LL | +LL | static STATIC_FN: FunType = some_fn; + | ^^^^^^^ expected opaque type, found fn item + | + = note: expected opaque type `impl Fn<()>` + found fn item `fn() {some_fn}` + +error: could not find defining uses + --> $DIR/issue-86201.rs:4:16 + | +LL | type FunType = impl Fn<()>; + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr deleted file mode 100644 index 9cf8ff76c87f8..0000000000000 --- a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr +++ /dev/null @@ -1,51 +0,0 @@ -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:17:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:17:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: lifetime may not live long enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | -- lifetime `'b` defined here -LL | x - | ^ returning this value requires that `'b` must outlive `'static` - | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'b`, add `'b` as a bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { - | ++++ - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: aborting due to 5 previous errors - diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs deleted file mode 100644 index f89ab7fbd364b..0000000000000 --- a/src/test/ui/impl-trait/issues/issue-88236-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// this used to cause stack overflows - -trait Hrtb<'a> { - type Assoc; -} - -impl<'a> Hrtb<'a> for () { - type Assoc = (); -} - -impl<'a> Hrtb<'a> for &'a () { - type Assoc = (); -} - -fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} -fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - &() //~ ERROR implementation of `Hrtb` is not general enough -} -fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - x //~ ERROR implementation of `Hrtb` is not general enough -} - -fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr deleted file mode 100644 index 95c4a52803698..0000000000000 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:17:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `&()` must implement `Hrtb<'0>`, for any lifetime `'0`... - = note: ...but `Hrtb<'_>` is actually implemented for the type `&()` - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/impl-trait/issues/issue-88236.rs b/src/test/ui/impl-trait/issues/issue-88236.rs deleted file mode 100644 index 2ea35270a7e3b..0000000000000 --- a/src/test/ui/impl-trait/issues/issue-88236.rs +++ /dev/null @@ -1,19 +0,0 @@ -// check-pass - -// this used to cause stack overflows - -trait Hrtb<'a> { - type Assoc; -} - -impl<'a> Hrtb<'a> for () { - type Assoc = (); -} - -impl<'a> Hrtb<'a> for &'a () { - type Assoc = (); -} - -fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} - -fn main() {} diff --git a/src/test/ui/impl-trait/lifetimes2.rs b/src/test/ui/impl-trait/lifetimes2.rs deleted file mode 100644 index 834f2dc6cb5b6..0000000000000 --- a/src/test/ui/impl-trait/lifetimes2.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass - -pub fn keys<'a>(x: &'a Result) -> impl std::fmt::Debug + 'a { - match x { - Ok(map) => Ok(map), - Err(map) => Err(map), - } -} - -fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs index f5aaf1185211b..72e9d96da3677 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs @@ -8,6 +8,7 @@ impl Copy for CopyIfEq {} type E<'a, 'b> = impl Sized; fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); // This assignment requires that `x` and `y` have the same type due to the @@ -20,7 +21,6 @@ fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { let _: &'b i32 = *u.0; } u.0 - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr index b837b64110365..40bec0da2707d 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr @@ -1,11 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/error-handling-2.rs:22:5 + --> $DIR/error-handling-2.rs:10:60 | LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { - | -- hidden type `*mut &'a i32` captures the lifetime `'a` as defined here -... -LL | u.0 - | ^^^ + | -- ^^^^^^^^^ + | | + | hidden type `*mut &'a i32` captures the lifetime `'a` as defined here error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs index 47e05bce0f8de..3a97624647efd 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -14,6 +14,7 @@ struct Ordinary<'a>(&'a u8); // by both `'a` and `'b`. fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> +//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds where 'a: 'e, 'b: 'd, @@ -26,7 +27,6 @@ where // 'a in ['d, 'e] // ``` if condition() { a } else { b } - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn condition() -> bool { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index 15476c706a7f2..32829a0a1b2fa 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -1,11 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:28:33 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> - | -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here -... -LL | if condition() { a } else { b } - | ^ + | -- ^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs index 321cb8c92a177..d4c60a4e89209 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -16,6 +16,7 @@ struct Ordinary<'a>(&'a u8); // consider the loans for both `'a` and `'b` alive. fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> +//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds { // We return a value: // @@ -29,7 +30,6 @@ fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> // // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. if condition() { a } else { b } - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn condition() -> bool { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 7315aa8e9d478..83ad23b253bb3 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -1,11 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:31:33 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - | -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here -... -LL | if condition() { a } else { b } - | ^ + | -- ^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index eb38f84d4afec..2f6bd8ff377a5 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:3:35 + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^ + | ---- ^^^^^^^^^ | | | hidden type `&i32` captures the anonymous lifetime defined here | @@ -12,10 +12,10 @@ LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:6:44 + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | -- ^ + | -- ^^^^^^^^^ | | | hidden type `&'a i32` captures the lifetime `'a` as defined here | @@ -67,12 +67,12 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } = help: consider replacing `'a` with `'static` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:34:5 + --> $DIR/must_outlive_least_region_or_bound.rs:33:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | -- hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:34:5: 34:31]` captures the lifetime `'b` as defined here -LL | move |_| println!("{}", y) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^ + | | + | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -80,10 +80,10 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:39:5 + --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | -LL | x - | ^ +LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { + | ^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'static`... diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 02ea0255912ab..69d2843ff3f01 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -31,13 +31,13 @@ fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERRO // Tests that a closure type containing 'b cannot be returned from a type where // only 'a was expected. fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - move |_| println!("{}", y) //~^ ERROR: captures lifetime that does not appear in bounds + move |_| println!("{}", y) } fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { - x //~^ ERROR the parameter type `T` may not live long enough + x } fn main() {} diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 77ba0bf908763..07ac0a8db35a9 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:3:35 + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^ + | ---- ^^^^^^^^^ | | | hidden type `&i32` captures the anonymous lifetime defined here | @@ -12,10 +12,10 @@ LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:6:44 + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | -- ^ + | -- ^^^^^^^^^ | | | hidden type `&'a i32` captures the lifetime `'a` as defined here | @@ -28,10 +28,15 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ^ ...is used and required to live as long as `'static` here + | ---- ^ ...is used here... | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:9:24 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } @@ -45,10 +50,15 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ^ ...is used and required to live as long as `'static` here + | ------- ^ ...is used here... | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:11:33 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -59,10 +69,10 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ~~~~~~~~~~~~ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:13:41 + --> $DIR/must_outlive_least_region_or_bound.rs:13:24 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } - | ---- ^ lifetime `'a` required + | ---- ^^^^^^^^^^^^^^ lifetime `'a` required | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` @@ -85,8 +95,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- this data with lifetime `'a`... ^ ...is used and required to live as long as `'static` here + | ------- this data with lifetime `'a`... ^ ...is used here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:29:34 | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } @@ -97,12 +112,12 @@ LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x | ~~~~~~~~~~~~ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:34:5 + --> $DIR/must_outlive_least_region_or_bound.rs:33:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | -- hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:34:5: 34:31]` captures the lifetime `'b` as defined here -LL | move |_| println!("{}", y) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^ + | | + | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -110,12 +125,12 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:39:5 + --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { - | -- help: consider adding an explicit lifetime bound...: `T: 'static +` -LL | x - | ^ ...so that the type `T` will meet its required lifetime bounds + | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `T: 'static +` error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/must_outlive_least_region_or_bound.rs:16:50 diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs index 70e24a3a9d029..d173fe83fb791 100644 --- a/src/test/ui/impl-trait/negative-reasoning.rs +++ b/src/test/ui/impl-trait/negative-reasoning.rs @@ -17,7 +17,7 @@ impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index 6b8cc9e737423..e39a8e53f7985 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,13 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` --> $DIR/negative-reasoning.rs:19:1 | LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` | - = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions + = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `impl OpaqueTrait` in future versions error: aborting due to previous error diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs index 6eac2dece1f12..be2c21a7743ce 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.rs +++ b/src/test/ui/impl-trait/nested_impl_trait.rs @@ -4,7 +4,6 @@ fn fine(x: impl Into) -> impl Into { x } fn bad_in_ret_position(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed -//~| ERROR `impl Into` doesn't implement `Debug` fn bad_in_fn_syntax(x: fn() -> impl Into) {} //~^ ERROR nested `impl Trait` is not allowed @@ -17,7 +16,6 @@ struct X; impl X { fn bad(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed - //~| ERROR `impl Into` doesn't implement `Debug` } fn allowed_in_assoc_type() -> impl Iterator { diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr index 87ff4ffc4fb17..59c7e4d5f4e92 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.stderr +++ b/src/test/ui/impl-trait/nested_impl_trait.stderr @@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:9:42 + --> $DIR/nested_impl_trait.rs:8:42 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ----------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:13:37 + --> $DIR/nested_impl_trait.rs:12:37 | LL | fn bad_in_arg_position(_: impl Into) { } | ----------^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into) { } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:18:44 + --> $DIR/nested_impl_trait.rs:17:44 | LL | fn bad(x: impl Into) -> impl Into { x } | ----------^^^^^^^^^^- @@ -35,40 +35,18 @@ LL | fn bad(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/nested_impl_trait.rs:9:32 + --> $DIR/nested_impl_trait.rs:8:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ^^^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/nested_impl_trait.rs:27:42 + --> $DIR/nested_impl_trait.rs:25:42 | LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into { | ^^^^^^^^^^^^^^ -error[E0277]: `impl Into` doesn't implement `Debug` - --> $DIR/nested_impl_trait.rs:5:70 - | -LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^ `impl Into` cannot be formatted using `{:?}` because it doesn't implement `Debug` - | -help: consider further restricting this bound - | -LL | fn bad_in_ret_position(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ - -error[E0277]: `impl Into` doesn't implement `Debug` - --> $DIR/nested_impl_trait.rs:18:58 - | -LL | fn bad(x: impl Into) -> impl Into { x } - | ^ `impl Into` cannot be formatted using `{:?}` because it doesn't implement `Debug` - | -help: consider further restricting this bound - | -LL | fn bad(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0277, E0562, E0666. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0562, E0666. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr index b2f7166f0ae3a..357166d112377 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -2,25 +2,46 @@ error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 | LL | fn can() -> impl NotObjectSafe { - | ------------------ the expected opaque type -... + | ------------------ expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } LL | B | ^ expected struct `A`, found struct `B` | - = note: expected opaque type `impl NotObjectSafe` - found struct `B` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: if the trait `NotObjectSafe` were object safe, you could return a boxed trait object + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 | LL | fn cat() -> impl ObjectSafe { - | --------------- the expected opaque type -... + | --------------- expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } LL | B | ^ expected struct `A`, found struct `B` | - = note: expected opaque type `impl ObjectSafe` - found struct `B` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn cat() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ return Box::new(A); +LL | } +LL ~ Box::new(B) + | error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs index 9f9a6c784e638..fa7664a83eee0 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs @@ -14,10 +14,10 @@ fn bar() -> impl std::fmt::Display { } fn baz() -> impl std::fmt::Display { - if false { //~ ERROR mismatched types + if false { return 0i32; } else { - 1u32 + 1u32 //~ ERROR mismatched types } } @@ -30,9 +30,9 @@ fn qux() -> impl std::fmt::Display { } fn bat() -> impl std::fmt::Display { - match 13 { //~ ERROR mismatched types + match 13 { 0 => return 0i32, - _ => 1u32, + _ => 1u32, //~ ERROR mismatched types } } @@ -45,12 +45,12 @@ fn can() -> impl std::fmt::Display { } fn cat() -> impl std::fmt::Display { - match 13 { //~ ERROR mismatched types + match 13 { 0 => { return 0i32; } _ => { - 1u32 + 1u32 //~ ERROR mismatched types } } } diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index db0d446e559a3..970abad5c72e9 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -2,40 +2,82 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 | LL | fn foo() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -... + | ---------------------- expected because this return type... +LL | if false { +LL | return 0i32; + | ---- ...is found to be `i32` here +LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn foo() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ return Box::new(0i32); +LL | } +LL ~ Box::new(1u32) + | error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16 | LL | fn bar() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -... + | ---------------------- expected because this return type... +LL | if false { +LL | return 0i32; + | ---- ...is found to be `i32` here +LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn bar() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ return Box::new(0i32); +LL | } else { +LL ~ return Box::new(1u32); + | error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:17:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9 | -LL | fn baz() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / if false { -LL | | return 0i32; -LL | | } else { -LL | | 1u32 -LL | | } - | |_____^ expected `i32`, found `u32` +LL | fn baz() -> impl std::fmt::Display { + | ---------------------- expected because this return type... +LL | if false { +LL | return 0i32; + | ---- ...is found to be `i32` here +LL | } else { +LL | 1u32 + | ^^^^ expected `i32`, found `u32` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn baz() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ return Box::new(0i32); +LL | } else { +LL ~ Box::new(1u32) | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9 @@ -61,50 +103,87 @@ LL ~ Box::new(1u32) | error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:33:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14 | -LL | fn bat() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / match 13 { -LL | | 0 => return 0i32, -LL | | _ => 1u32, -LL | | } - | |_____^ expected `i32`, found `u32` +LL | fn bat() -> impl std::fmt::Display { + | ---------------------- expected because this return type... +LL | match 13 { +LL | 0 => return 0i32, + | ---- ...is found to be `i32` here +LL | _ => 1u32, + | ^^^^ expected `i32`, found `u32` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn bat() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ 0 => return Box::new(0i32), +LL ~ _ => Box::new(1u32), | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5 | LL | fn can() -> impl std::fmt::Display { - | ---------------------- the expected opaque type + | ---------------------- expected because this return type... LL | / match 13 { LL | | 0 => return 0i32, + | | ---- ...is found to be `i32` here LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn can() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ Box::new(match 13 { +LL ~ 0 => return Box::new(0i32), +LL | 1 => 1u32, +LL | _ => 2u32, +LL ~ }) + | error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:48:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 | -LL | fn cat() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / match 13 { -LL | | 0 => { -LL | | return 0i32; -LL | | } -... | -LL | | } -LL | | } - | |_____^ expected `i32`, found `u32` +LL | fn cat() -> impl std::fmt::Display { + | ---------------------- expected because this return type... +... +LL | return 0i32; + | ---- ...is found to be `i32` here +... +LL | 1u32 + | ^^^^ expected `i32`, found `u32` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see + = help: you could instead create a new `enum` with a variant for each returned type +help: you could change the return type to be a boxed trait object + | +LL | fn cat() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ return Box::new(0i32); +LL | } +LL | _ => { +LL ~ Box::new(1u32) | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: `match` arms have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14 @@ -117,6 +196,16 @@ LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____- `match` arms have incompatible types + | +help: you could change the return type to be a boxed trait object + | +LL | fn dog() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ 0 => Box::new(0i32), +LL ~ 1 => Box::new(1u32), + | error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:97:9 @@ -129,6 +218,17 @@ LL | | 1u32 | | ^^^^ expected `i32`, found `u32` LL | | } | |_____- `if` and `else` have incompatible types + | +help: you could change the return type to be a boxed trait object + | +LL | fn apt() -> Box { + | ~~~~~~~ + +help: if you change the return type to expect trait objects, box the returned expressions + | +LL ~ Box::new(0i32) +LL | } else { +LL ~ Box::new(1u32) + | error[E0746]: return type cannot have an unboxed trait object --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13 diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs index 2e7cb21592cb0..b4fd6b3e74364 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs @@ -11,8 +11,8 @@ pub trait Test {} impl Test for T where T: Super {} fn test() -> impl Test { - () //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()` + () } fn main() { diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr index 5ef1e9abef631..65daabe419d3f 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -1,10 +1,10 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` - --> $DIR/projection-mismatch-in-impl-where-clause.rs:14:5 + --> $DIR/projection-mismatch-in-impl-where-clause.rs:13:14 | -LL | () - | ^^ type mismatch resolving `<() as Super>::Assoc == ()` +LL | fn test() -> impl Test { + | ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()` | -note: expected this to be `u8` +note: expected this to be `()` --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18 | LL | type Assoc = u8; diff --git a/src/test/ui/impl-trait/question_mark.rs b/src/test/ui/impl-trait/question_mark.rs deleted file mode 100644 index 211f7972dbca8..0000000000000 --- a/src/test/ui/impl-trait/question_mark.rs +++ /dev/null @@ -1,13 +0,0 @@ -// check-pass - -fn foo() -> impl MyTrait { - panic!(); - MyStruct -} - -struct MyStruct; -trait MyTrait {} - -impl MyTrait for MyStruct {} - -fn main() {} diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs index 540a280f0a319..3cc537440977c 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs @@ -1,8 +1,9 @@ -// check-pass +// Test that an `impl Trait` type that expands to itself is an error. #![allow(unconditional_recursion)] fn test() -> impl Sized { + //~^ ERROR E0720 test() } diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr new file mode 100644 index 0000000000000..5a3027ec751a9 --- /dev/null +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr @@ -0,0 +1,12 @@ +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-impl-trait-type-direct.rs:5:14 + | +LL | fn test() -> impl Sized { + | ^^^^^^^^^^ recursive opaque type +LL | +LL | test() + | ------ returning here with type `impl Sized` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs index ffc0cd9d10c34..e3c621f0c5742 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs @@ -5,7 +5,7 @@ #![allow(unconditional_recursion)] fn option(i: i32) -> impl Sized { - //~^ ERROR cannot resolve opaque type + //~^ ERROR if i < 0 { None } else { Some((option(i - 1), i)) } } diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs deleted file mode 100644 index a60e34c17b671..0000000000000 --- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![feature(type_alias_impl_trait)] - -mod a { - type Foo = impl PartialEq<(Foo, i32)>; - //~^ ERROR unconstrained opaque type - - struct Bar; - - impl PartialEq<(Bar, i32)> for Bar { - fn eq(&self, _other: &(Foo, i32)) -> bool { - true - } - } -} - -mod b { - type Foo = impl PartialEq<(Foo, i32)>; - //~^ ERROR unconstrained opaque type - - struct Bar; - - impl PartialEq<(Foo, i32)> for Bar { - fn eq(&self, _other: &(Bar, i32)) -> bool { - true - } - } -} - -fn main() {} diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr deleted file mode 100644 index eae7d38d1162b..0000000000000 --- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 - | -LL | type Foo = impl PartialEq<(Foo, i32)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - -error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:17:16 - | -LL | type Foo = impl PartialEq<(Foo, i32)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs deleted file mode 100644 index bdabc13c36a96..0000000000000 --- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ /dev/null @@ -1,37 +0,0 @@ -// check-pass - -#![feature(type_alias_impl_trait)] - -mod direct { - type Foo = impl PartialEq<(Foo, i32)>; - - struct Bar; - - impl PartialEq<(Foo, i32)> for Bar { - fn eq(&self, _other: &(Foo, i32)) -> bool { - true - } - } - - fn foo() -> Foo { - Bar - } -} - -mod indirect { - type Foo = impl PartialEq<(Foo, i32)>; - - struct Bar; - - impl PartialEq<(Bar, i32)> for Bar { - fn eq(&self, _other: &(Bar, i32)) -> bool { - true - } - } - - fn foo() -> Foo { - Bar - } -} - -fn main() {} diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs index 18e3a5bcaa449..29243699e44fd 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -13,10 +13,10 @@ trait Trait<'a> { } impl Trait<'b> for Cell<&'a u32> { } fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700] where 'x: 'y { x - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700] } fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index 690d049ec8f62..cf854f67d0456 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/region-escape-via-bound.rs:18:5 + --> $DIR/region-escape-via-bound.rs:15:29 | +LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + | ^^^^^^^^^^^^^^ +LL | LL | where 'x: 'y | -- hidden type `Cell<&'x u32>` captures the lifetime `'x` as defined here -LL | { -LL | x - | ^ | help: to declare that the `impl Trait` captures `'x`, you can add an explicit `'x` lifetime bound | diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.rs b/src/test/ui/impl-trait/static-return-lifetime-infered.rs index f940c1949d0b8..d792c6eafb32f 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.rs +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.rs @@ -4,14 +4,14 @@ struct A { impl A { fn iter_values_anon(&self) -> impl Iterator { - self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds //~| ERROR: captures lifetime that does not appear in bounds + self.x.iter().map(|a| a.0) } fn iter_values<'a>(&'a self) -> impl Iterator { - self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds //~| ERROR: captures lifetime that does not appear in bounds + self.x.iter().map(|a| a.0) } } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index bc8e39f9c504c..7424da76182ab 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,10 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:7:9 + --> $DIR/static-return-lifetime-infered.rs:6:35 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:7:27: 7:34]>` captures the anonymous lifetime defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | @@ -12,12 +12,12 @@ LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:7:9 + --> $DIR/static-return-lifetime-infered.rs:6:35 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:7:27: 7:34]>` captures the anonymous lifetime defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | @@ -25,12 +25,12 @@ LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:12:9 + --> $DIR/static-return-lifetime-infered.rs:11:37 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:34]>` captures the lifetime `'a` as defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here | help: to declare that the `impl Trait` captures `'a`, you can add an explicit `'a` lifetime bound | @@ -38,12 +38,12 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:12:9 + --> $DIR/static-return-lifetime-infered.rs:11:37 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:34]>` captures the lifetime `'a` as defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here | help: to declare that the `impl Trait` captures `'a`, you can add an explicit `'a` lifetime bound | diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other.rs b/src/test/ui/impl-trait/two_tait_defining_each_other.rs deleted file mode 100644 index 6eb2a11b22c5f..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type A = impl Foo; -type B = impl Foo; - -trait Foo {} - -fn muh(x: A) -> B { - if false { - return Bar; // B's hidden type is Bar - } - x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other - //~^ ERROR opaque type's hidden type cannot be another opaque type -} - -struct Bar; -impl Foo for Bar {} - -fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other.stderr deleted file mode 100644 index 1a42ac525a6a8..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other.rs:12:5 - | -LL | x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other - | ^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/two_tait_defining_each_other.rs:4:10 - | -LL | type B = impl Foo; - | ^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/two_tait_defining_each_other.rs:3:10 - | -LL | type A = impl Foo; - | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.rs b/src/test/ui/impl-trait/two_tait_defining_each_other2.rs deleted file mode 100644 index 3b16d0f5e047f..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other2.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type A = impl Foo; -type B = impl Foo; - -trait Foo {} - -fn muh(x: A) -> B { - x // B's hidden type is A (opaquely) - //~^ ERROR opaque type's hidden type cannot be another opaque type -} - -struct Bar; -impl Foo for Bar {} - -fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr deleted file mode 100644 index ef2089a6c5b17..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other2.rs:9:5 - | -LL | x // B's hidden type is A (opaquely) - | ^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/two_tait_defining_each_other2.rs:4:10 - | -LL | type B = impl Foo; - | ^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/two_tait_defining_each_other2.rs:3:10 - | -LL | type A = impl Foo; - | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other3.rs b/src/test/ui/impl-trait/two_tait_defining_each_other3.rs deleted file mode 100644 index 37f8ae1b84b55..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other3.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type A = impl Foo; -type B = impl Foo; - -trait Foo {} - -fn muh(x: A) -> B { - if false { - return x; // B's hidden type is A (opaquely) - //~^ ERROR opaque type's hidden type cannot be another opaque type - } - Bar // A's hidden type is `Bar`, because all the return types are compared with each other -} - -struct Bar; -impl Foo for Bar {} - -fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr deleted file mode 100644 index b06dc16d5e700..0000000000000 --- a/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other3.rs:10:16 - | -LL | return x; // B's hidden type is A (opaquely) - | ^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/two_tait_defining_each_other3.rs:4:10 - | -LL | type B = impl Foo; - | ^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/two_tait_defining_each_other3.rs:3:10 - | -LL | type A = impl Foo; - | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr index e0b77544d439d..039cb62f86656 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr @@ -1,8 +1,8 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:8:5 + --> $DIR/type_parameters_captured.rs:7:20 | -LL | x - | ^ +LL | fn foo(x: T) -> impl Any + 'static { + | ^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'static`... diff --git a/src/test/ui/impl-trait/type_parameters_captured.rs b/src/test/ui/impl-trait/type_parameters_captured.rs index 81ee7d3f8a561..6c9c9d4a42af5 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.rs +++ b/src/test/ui/impl-trait/type_parameters_captured.rs @@ -5,8 +5,8 @@ impl Any for T {} // Check that type parameters are captured and not considered 'static fn foo(x: T) -> impl Any + 'static { - x //~^ ERROR the parameter type `T` may not live long enough + x } fn main() {} diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr index c0de4f4b4a0c5..40e50b9922f8d 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.stderr @@ -1,10 +1,10 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:8:5 + --> $DIR/type_parameters_captured.rs:7:20 | LL | fn foo(x: T) -> impl Any + 'static { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | x - | ^ ...so that the type `T` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `T: 'static` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs index d5a87b5d46834..462508f306ef3 100644 --- a/src/test/ui/impl-trait/where-allowed-2.rs +++ b/src/test/ui/impl-trait/where-allowed-2.rs @@ -1,7 +1,8 @@ +//! Ideally, these tests would go in `where-allowed.rs`, but we bail out +//! too early to display them. use std::fmt::Debug; -// check-pass - -fn in_adt_in_return() -> Vec { panic!() } +// Disallowed +fn in_adt_in_return() -> Vec { panic!() } //~ ERROR cannot resolve opaque type fn main() {} diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr new file mode 100644 index 0000000000000..b8e06725cbcdd --- /dev/null +++ b/src/test/ui/impl-trait/where-allowed-2.stderr @@ -0,0 +1,13 @@ +error[E0720]: cannot resolve opaque type + --> $DIR/where-allowed-2.rs:6:30 + | +LL | fn in_adt_in_return() -> Vec { panic!() } + | ^^^^^^^^^^ -------- this returned value is of `!` type + | | + | cannot resolve opaque type + | + = help: this error will resolve once the item's body returns a concrete type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs index 89e07037afd42..fecba721ac9fd 100644 --- a/src/test/ui/issues-71798.rs +++ b/src/test/ui/issues-71798.rs @@ -1,6 +1,5 @@ fn test_ref(x: &u32) -> impl std::future::Future + '_ { - *x - //~^ ERROR `u32` is not a future + *x //~^ ERROR `u32` is not a future } fn main() { diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr index 1efa886436e0d..bc4dc9ebf9e00 100644 --- a/src/test/ui/issues-71798.stderr +++ b/src/test/ui/issues-71798.stderr @@ -1,14 +1,14 @@ error[E0425]: cannot find value `u` in this scope - --> $DIR/issues-71798.rs:7:24 + --> $DIR/issues-71798.rs:6:24 | LL | let _ = test_ref & u; | ^ not found in this scope error[E0277]: `u32` is not a future - --> $DIR/issues-71798.rs:2:5 + --> $DIR/issues-71798.rs:1:25 | -LL | *x - | ^^ `u32` is not a future +LL | fn test_ref(x: &u32) -> impl std::future::Future + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future | = help: the trait `Future` is not implemented for `u32` = note: u32 must be a future or must implement `IntoFuture` to be awaited diff --git a/src/test/ui/lang-items/lang-item-missing-generator.stderr b/src/test/ui/lang-items/lang-item-missing-generator.stderr index e5f26822f2670..fa13bf0b12719 100644 --- a/src/test/ui/lang-items/lang-item-missing-generator.stderr +++ b/src/test/ui/lang-items/lang-item-missing-generator.stderr @@ -1,8 +1,8 @@ error: requires `generator` lang_item - --> $DIR/lang-item-missing-generator.rs:15:22 + --> $DIR/lang-item-missing-generator.rs:15:17 | LL | pub fn abc() -> impl FnOnce(f32) { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs b/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs deleted file mode 100644 index 84bfa2d848755..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs +++ /dev/null @@ -1,46 +0,0 @@ -// check-pass - -#![feature(gen_future, generator_trait, negative_impls, const_fn_trait_bound, const_impl_trait)] - -use std::ops::{Generator, GeneratorState}; -use std::task::{Poll, Context}; -use std::future::{Future}; -use std::ptr::NonNull; -use std::pin::Pin; - -fn main() {} - -#[derive(Debug, Copy, Clone)] -pub struct ResumeTy(NonNull>); - -unsafe impl Send for ResumeTy {} - -unsafe impl Sync for ResumeTy {} - -pub const fn from_generator(gen: T) -> impl Future -where - T: Generator, -{ - struct GenFuture>(T); - - // We rely on the fact that async/await futures are immovable in order to create - // self-referential borrows in the underlying generator. - impl> !Unpin for GenFuture {} - - impl> Future for GenFuture { - type Output = T::Return; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - // SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection. - let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }; - - // Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The - // `.await` lowering will safely cast that back to a `&mut Context`. - match gen.resume(ResumeTy(NonNull::from(cx).cast::>())) { - GeneratorState::Yielded(()) => Poll::Pending, - GeneratorState::Complete(x) => Poll::Ready(x), - } - } - } - - GenFuture(gen) -} diff --git a/src/test/ui/lazy-type-alias-impl-trait/infer_cross_function.rs b/src/test/ui/lazy-type-alias-impl-trait/infer_cross_function.rs deleted file mode 100644 index d07d732c78570..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/infer_cross_function.rs +++ /dev/null @@ -1,27 +0,0 @@ -// check-pass - -fn main() {} - -trait Reader {} - -struct Unit(R); -struct ResDwarf(R); - -struct Context { - dwarf: ResDwarf, -} - -struct Range; - -struct ResUnit(R); - -impl Context { - fn find_dwarf_unit(&self, probe: u64) -> Option<&Unit> { - let x = self.find_units(probe); - None - } - - fn find_units(&self, probe: u64) -> impl Iterator> { - std::iter::empty() - } -} diff --git a/src/test/ui/lazy-type-alias-impl-trait/lifetime_inference.rs b/src/test/ui/lazy-type-alias-impl-trait/lifetime_inference.rs deleted file mode 100644 index f75a88aa8f064..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/lifetime_inference.rs +++ /dev/null @@ -1,7 +0,0 @@ -// check-pass - -fn main() {} - -fn nth(iter: &mut I, step: usize) -> impl FnMut() -> Option + '_ { - move || iter.nth(step) -} diff --git a/src/test/ui/lazy-type-alias-impl-trait/nested.rs b/src/test/ui/lazy-type-alias-impl-trait/nested.rs deleted file mode 100644 index f8291112739c1..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/nested.rs +++ /dev/null @@ -1,23 +0,0 @@ -// check-pass - -fn main() {} - -struct RawTableInner { - alloc: A, -} - -impl RawTableInner { - fn prepare_resize( - self, - ) -> ScopeGuard { - ScopeGuard { dropfn: move |self_| {}, value: self, } - } -} - -pub struct ScopeGuard -where - F: FnMut(&mut T), -{ - dropfn: F, - value: T, -} diff --git a/src/test/ui/lazy-type-alias-impl-trait/opaque_vs_opaque.rs b/src/test/ui/lazy-type-alias-impl-trait/opaque_vs_opaque.rs deleted file mode 100644 index 8d03b5158d662..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/opaque_vs_opaque.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass - -fn main() {} - -fn filter_fold bool, FOLD: FnMut(Acc, T) -> Acc>( - mut predicate: PRED, - mut fold: FOLD, -) -> impl FnMut(Acc, T) -> Acc { - move |acc, item| if predicate(&item) { fold(acc, item) } else { acc } -} diff --git a/src/test/ui/lazy-type-alias-impl-trait/unsized_sized_opaque.rs b/src/test/ui/lazy-type-alias-impl-trait/unsized_sized_opaque.rs deleted file mode 100644 index 007101498238d..0000000000000 --- a/src/test/ui/lazy-type-alias-impl-trait/unsized_sized_opaque.rs +++ /dev/null @@ -1,16 +0,0 @@ -// check-pass - -fn main() {} - -pub struct PairSlices<'a, 'b, T> { - pub(crate) a0: &'a mut [T], - pub(crate) a1: &'a mut [T], - pub(crate) b0: &'b [T], - pub(crate) b1: &'b [T], -} - -impl<'a, 'b, T> PairSlices<'a, 'b, T> { - pub fn remainder(self) -> impl Iterator { - IntoIterator::into_iter([self.b0, self.b1]) - } -} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs index fd49b4842a74f..ea0d0ccbc5532 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -6,8 +6,8 @@ trait Future { use std::error::Error; fn foo() -> impl Future> { +//~^ ERROR not satisfied Ok(()) - //~^ ERROR not satisfied } fn main() {} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 7f8384d7eca8d..ef1127c59ac4c 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied - --> $DIR/lifetime-elision-return-type-trait.rs:9:5 + --> $DIR/lifetime-elision-return-type-trait.rs:8:13 | -LL | Ok(()) - | ^^^^^^ the trait `Future` is not implemented for `Result<(), _>` +LL | fn foo() -> impl Future> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` error: aborting due to previous error diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.rs b/src/test/ui/lint/inline-trait-and-foreign-items.rs index 13dab7ed954f8..6321b3c76e4d1 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.rs +++ b/src/test/ui/lint/inline-trait-and-foreign-items.rs @@ -23,7 +23,7 @@ impl Trait for () { type T = Self; #[inline] //~ ERROR attribute should be applied to function or closure - type U = impl Trait; //~ ERROR unconstrained opaque type + type U = impl Trait; //~ ERROR could not find defining uses } extern "C" { diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr index fc7e89e4f4cce..6ac884c12ceb9 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr +++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr @@ -61,13 +61,11 @@ LL | #[inline] LL | type T; | ------- not a function or closure -error: unconstrained opaque type +error: could not find defining uses --> $DIR/inline-trait-and-foreign-items.rs:26:14 | LL | type U = impl Trait; | ^^^^^^^^^^ - | - = note: `U` must be used in combination with a concrete type within the same module error: aborting due to 6 previous errors; 2 warnings emitted diff --git a/src/test/ui/lint/lint-ctypes-73249-2.rs b/src/test/ui/lint/lint-ctypes-73249-2.rs index 691047c8a405b..fe578f51b63a0 100644 --- a/src/test/ui/lint/lint-ctypes-73249-2.rs +++ b/src/test/ui/lint/lint-ctypes-73249-2.rs @@ -23,7 +23,7 @@ pub struct A { } extern "C" { - pub fn lint_me() -> A<()>; //~ ERROR: uses type `Qux` + pub fn lint_me() -> A<()>; //~ ERROR: uses type `impl Baz` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73249-2.stderr b/src/test/ui/lint/lint-ctypes-73249-2.stderr index 7c85e9fa85c63..36dbe3217d75a 100644 --- a/src/test/ui/lint/lint-ctypes-73249-2.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-2.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `Qux`, which is not FFI-safe +error: `extern` block uses type `impl Baz`, which is not FFI-safe --> $DIR/lint-ctypes-73249-2.rs:26:25 | LL | pub fn lint_me() -> A<()>; diff --git a/src/test/ui/lint/lint-ctypes-73249-3.rs b/src/test/ui/lint/lint-ctypes-73249-3.rs index ef8ab7e03d2f0..ec12de00739e4 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.rs +++ b/src/test/ui/lint/lint-ctypes-73249-3.rs @@ -17,7 +17,7 @@ pub struct A { } extern "C" { - pub fn lint_me() -> A; //~ ERROR: uses type `Qux` + pub fn lint_me() -> A; //~ ERROR: uses type `impl Baz` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73249-3.stderr b/src/test/ui/lint/lint-ctypes-73249-3.stderr index 83e2a233c4335..e987ec90228c1 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-3.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `Qux`, which is not FFI-safe +error: `extern` block uses type `impl Baz`, which is not FFI-safe --> $DIR/lint-ctypes-73249-3.rs:20:25 | LL | pub fn lint_me() -> A; diff --git a/src/test/ui/lint/lint-ctypes-73249-5.rs b/src/test/ui/lint/lint-ctypes-73249-5.rs index 083fb6c5fb16d..58c2d7a501ad5 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.rs +++ b/src/test/ui/lint/lint-ctypes-73249-5.rs @@ -17,7 +17,7 @@ pub struct A { } extern "C" { - pub fn lint_me() -> A; //~ ERROR: uses type `Qux` + pub fn lint_me() -> A; //~ ERROR: uses type `impl Baz` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73249-5.stderr b/src/test/ui/lint/lint-ctypes-73249-5.stderr index 37781d78cf28c..749714c7df8d7 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-5.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `Qux`, which is not FFI-safe +error: `extern` block uses type `impl Baz`, which is not FFI-safe --> $DIR/lint-ctypes-73249-5.rs:20:25 | LL | pub fn lint_me() -> A; diff --git a/src/test/ui/lint/lint-ctypes-73251-1.rs b/src/test/ui/lint/lint-ctypes-73251-1.rs index 145ba784f7c66..dc4c7efd7ef23 100644 --- a/src/test/ui/lint/lint-ctypes-73251-1.rs +++ b/src/test/ui/lint/lint-ctypes-73251-1.rs @@ -20,7 +20,7 @@ fn assign() -> Qux { } extern "C" { - pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `Qux` + pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `impl Baz` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73251-1.stderr b/src/test/ui/lint/lint-ctypes-73251-1.stderr index 76b19d37e21a6..505ccd5a930ce 100644 --- a/src/test/ui/lint/lint-ctypes-73251-1.stderr +++ b/src/test/ui/lint/lint-ctypes-73251-1.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `Qux`, which is not FFI-safe +error: `extern` block uses type `impl Baz`, which is not FFI-safe --> $DIR/lint-ctypes-73251-1.rs:23:25 | LL | pub fn lint_me() -> ::Assoc; diff --git a/src/test/ui/lint/lint-ctypes-73251-2.rs b/src/test/ui/lint/lint-ctypes-73251-2.rs index df71a94579624..717ca4986f700 100644 --- a/src/test/ui/lint/lint-ctypes-73251-2.rs +++ b/src/test/ui/lint/lint-ctypes-73251-2.rs @@ -33,7 +33,7 @@ fn use_of_b() -> AliasB { } extern "C" { - pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `AliasA` + pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `impl TraitA` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73251-2.stderr b/src/test/ui/lint/lint-ctypes-73251-2.stderr index 64f0fb2d892a4..d7e10db441ec2 100644 --- a/src/test/ui/lint/lint-ctypes-73251-2.stderr +++ b/src/test/ui/lint/lint-ctypes-73251-2.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `AliasA`, which is not FFI-safe +error: `extern` block uses type `impl TraitA`, which is not FFI-safe --> $DIR/lint-ctypes-73251-2.rs:36:25 | LL | pub fn lint_me() -> ::Assoc; diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs index b7cc38e99fc37..3a62b6a21a56a 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs @@ -9,7 +9,7 @@ pub fn ret_closure() -> A { extern "C" { pub fn a(_: A); - //~^ ERROR `extern` block uses type `A`, which is not FFI-safe [improper_ctypes] + //~^ ERROR `extern` block uses type `impl Fn()`, which is not FFI-safe [improper_ctypes] } fn main() {} diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 62d00fd6835ee..5afbef778b3e3 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `A`, which is not FFI-safe +error: `extern` block uses type `impl Fn()`, which is not FFI-safe --> $DIR/opaque-ty-ffi-unsafe.rs:11:17 | LL | pub fn a(_: A); diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.rs b/src/test/ui/never_type/feature-gate-never_type_fallback.rs index 7d02084118001..3b896ec9d70c2 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.rs +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.rs @@ -6,8 +6,7 @@ fn main() {} trait T {} -fn should_ret_unit() { - foo(panic!()) //~ ERROR +fn should_ret_unit() -> impl T { + //~^ ERROR the trait bound `(): T` is not satisfied + panic!() } - -fn foo(_: impl T) {} diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 54abed383000d..670f76867ce45 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -1,14 +1,8 @@ error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/feature-gate-never_type_fallback.rs:10:5 + --> $DIR/feature-gate-never_type_fallback.rs:9:25 | -LL | foo(panic!()) - | ^^^ the trait `T` is not implemented for `()` - | -note: required by a bound in `foo` - --> $DIR/feature-gate-never_type_fallback.rs:13:16 - | -LL | fn foo(_: impl T) {} - | ^ required by this bound in `foo` +LL | fn should_ret_unit() -> impl T { + | ^^^^^^ the trait `T` is not implemented for `()` error: aborting due to previous error diff --git a/src/test/ui/never_type/impl_trait_fallback.rs b/src/test/ui/never_type/impl_trait_fallback.rs deleted file mode 100644 index cc9520c1b24c8..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass - -fn main() {} - -trait T {} -impl T for () {} - -fn should_ret_unit() -> impl T { - panic!() -} diff --git a/src/test/ui/never_type/impl_trait_fallback2.rs b/src/test/ui/never_type/impl_trait_fallback2.rs deleted file mode 100644 index f73d953bdbd0b..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback2.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![feature(type_alias_impl_trait)] - -fn main() {} - -trait T {} -impl T for i32 {} - -fn should_ret_unit() -> impl T { - //~^ ERROR `(): T` is not satisfied - panic!() -} - -type Foo = impl T; - -fn a() -> Foo { - panic!() -} - -fn b() -> Foo { - 42 -} diff --git a/src/test/ui/never_type/impl_trait_fallback2.stderr b/src/test/ui/never_type/impl_trait_fallback2.stderr deleted file mode 100644 index 2f50b9d245900..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback2.rs:8:25 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^ the trait `T` is not implemented for `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/never_type/impl_trait_fallback3.rs b/src/test/ui/never_type/impl_trait_fallback3.rs deleted file mode 100644 index 26ce9b93105e6..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback3.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(type_alias_impl_trait)] - -fn main() {} - -trait T { - type Assoc; -} - -type Foo = impl T; -//~^ ERROR unconstrained opaque type - -fn a() -> Foo { - // This is not a defining use, it doesn't actually constrain the opaque type. - panic!() -} diff --git a/src/test/ui/never_type/impl_trait_fallback3.stderr b/src/test/ui/never_type/impl_trait_fallback3.stderr deleted file mode 100644 index 121019d5f69ae..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback3.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: unconstrained opaque type - --> $DIR/impl_trait_fallback3.rs:9:12 - | -LL | type Foo = impl T; - | ^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - -error: aborting due to previous error - diff --git a/src/test/ui/never_type/impl_trait_fallback4.rs b/src/test/ui/never_type/impl_trait_fallback4.rs deleted file mode 100644 index fe62773fa02db..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback4.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![feature(type_alias_impl_trait)] - -trait T { - type Assoc: Cake; -} - -trait Cake: std::fmt::Display { - fn cake() -> Self; -} - -type Foo = impl T; - -fn foo() -> impl T { - //~^ ERROR `(): T` is not satisfied - panic!() -} - -fn a() -> Foo { - foo() -} - -fn main() { - println!("{}", ::Assoc::cake()); -} diff --git a/src/test/ui/never_type/impl_trait_fallback4.stderr b/src/test/ui/never_type/impl_trait_fallback4.stderr deleted file mode 100644 index f2e216e9044c0..0000000000000 --- a/src/test/ui/never_type/impl_trait_fallback4.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback4.rs:13:13 - | -LL | fn foo() -> impl T { - | ^^^^^^ the trait `T` is not implemented for `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/nll/issue-52113.rs b/src/test/ui/nll/issue-52113.rs index 2f4cbf8322bbd..0d7ee0376924d 100644 --- a/src/test/ui/nll/issue-52113.rs +++ b/src/test/ui/nll/issue-52113.rs @@ -29,9 +29,9 @@ fn produce3<'a, 'b: 'a>(data: &'a mut Vec<&'a u32>, value: &'b u32) -> impl Bazi fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { let x = move || { let value: &'a u32 = value; - data.push(value); //~ ERROR lifetime may not live long enough + data.push(value); }; - x + x //~ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/issue-52113.stderr b/src/test/ui/nll/issue-52113.stderr index 42ff1866893e6..f70ae2edd7fac 100644 --- a/src/test/ui/nll/issue-52113.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -1,13 +1,13 @@ error: lifetime may not live long enough - --> $DIR/issue-52113.rs:32:9 + --> $DIR/issue-52113.rs:34:5 | LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here ... -LL | data.push(value); - | ^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` +LL | x + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/nll/issue-73159-rpit-static.rs b/src/test/ui/nll/issue-73159-rpit-static.rs index 97dc016068bed..e29ba09b3694d 100644 --- a/src/test/ui/nll/issue-73159-rpit-static.rs +++ b/src/test/ui/nll/issue-73159-rpit-static.rs @@ -7,8 +7,8 @@ struct Foo<'a>(&'a [u8]); impl<'a> Foo<'a> { fn make_it(&self) -> impl Iterator { - self.0.iter().copied() //~^ ERROR: captures lifetime that does not appear in bounds + self.0.iter().copied() } } diff --git a/src/test/ui/nll/issue-73159-rpit-static.stderr b/src/test/ui/nll/issue-73159-rpit-static.stderr index a3e9c0b44c210..6c7cd0c825493 100644 --- a/src/test/ui/nll/issue-73159-rpit-static.stderr +++ b/src/test/ui/nll/issue-73159-rpit-static.stderr @@ -1,11 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/issue-73159-rpit-static.rs:10:9 + --> $DIR/issue-73159-rpit-static.rs:9:26 | LL | impl<'a> Foo<'a> { | -- hidden type `Copied>` captures the lifetime `'a` as defined here LL | fn make_it(&self) -> impl Iterator { -LL | self.0.iter().copied() - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/relate_tys/opaque-hrtb.rs b/src/test/ui/nll/relate_tys/opaque-hrtb.rs deleted file mode 100644 index 0fbe6a63c0b68..0000000000000 --- a/src/test/ui/nll/relate_tys/opaque-hrtb.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(nll)] - -trait MyTrait {} - -struct Foo; -impl MyTrait for Foo {} - -fn bar() -> impl MyTrait { - Foo -} - -fn foo() -> impl for<'a> MyTrait<&'a str> { - bar() //~ ERROR implementation of `MyTrait` is not general enough -} - -fn main() {} diff --git a/src/test/ui/nll/relate_tys/opaque-hrtb.stderr b/src/test/ui/nll/relate_tys/opaque-hrtb.stderr deleted file mode 100644 index 4c8b66f21abe0..0000000000000 --- a/src/test/ui/nll/relate_tys/opaque-hrtb.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `MyTrait` is not general enough - --> $DIR/opaque-hrtb.rs:13:5 - | -LL | bar() - | ^^^^^ implementation of `MyTrait` is not general enough - | - = note: `impl MyTrait<&'2 str>` must implement `MyTrait<&'1 str>`, for any lifetime `'1`... - = note: ...but it actually implements `MyTrait<&'2 str>`, for some specific lifetime `'2` - -error: aborting due to previous error - diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs index c04185d081424..8af23aad7261b 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs @@ -8,8 +8,8 @@ trait Foo<'a> { impl<'a, T> Foo<'a> for T { } fn foo<'a, T>(x: &T) -> impl Foo<'a> { +//~^ ERROR captures lifetime that does not appear in bounds x - //~^ ERROR captures lifetime that does not appear in bounds } fn main() {} diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index 42d9f057aaa08..3e6fe789a8b55 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,10 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/impl-trait-captures.rs:11:5 + --> $DIR/impl-trait-captures.rs:10:25 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { - | -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0)) T` captures the anonymous lifetime defined here -LL | x - | ^ + | -- ^^^^^^^^^^^^ + | | + | hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0)) T` captures the anonymous lifetime defined here | help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0))` lifetime bound | diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs index 3548ad03a7d3d..0c7d8acb05223 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs @@ -5,11 +5,11 @@ use std::fmt::Debug; fn no_region<'a, T>(x: Box) -> impl Debug + 'a + //~^ ERROR the parameter type `T` may not live long enough [E0309] where T: Debug, { x - //~^ ERROR the parameter type `T` may not live long enough [E0309] } fn correct_region<'a, T>(x: Box) -> impl Debug + 'a @@ -20,11 +20,11 @@ where } fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a + //~^ ERROR the parameter type `T` may not live long enough [E0309] where T: 'b + Debug, { x - //~^ ERROR the parameter type `T` may not live long enough [E0309] } fn outlives_region<'a, 'b, T>(x: Box) -> impl Debug + 'a diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr index 31ee540cce9f7..053aef951f264 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr @@ -1,16 +1,16 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/impl-trait-outlives.rs:11:5 + --> $DIR/impl-trait-outlives.rs:7:35 | -LL | x - | ^ +LL | fn no_region<'a, T>(x: Box) -> impl Debug + 'a + | ^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'a`... error[E0309]: the parameter type `T` may not live long enough - --> $DIR/impl-trait-outlives.rs:26:5 + --> $DIR/impl-trait-outlives.rs:22:42 | -LL | x - | ^ +LL | fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a + | ^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'a`... diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs index cf5d3dab4aada..91a63bafd99a9 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.rs +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -9,9 +9,8 @@ fn main() { unsafe fn ff2() {} // OK. const fn ff3() {} // OK. extern "C" fn ff4() {} // OK. - const async unsafe extern "C" fn ff5() {} + const async unsafe extern "C" fn ff5() {} // OK. //~^ ERROR functions cannot be both `const` and `async` - //~| ERROR cycle detected trait X { async fn ft1(); //~ ERROR functions in traits cannot be declared `async` @@ -27,14 +26,15 @@ fn main() { struct Y; impl X for Y { async fn ft1() {} //~ ERROR functions in traits cannot be declared `async` + //~^ ERROR method `ft1` has an incompatible type for trait unsafe fn ft2() {} // OK. const fn ft3() {} //~ ERROR functions in traits cannot be declared const extern "C" fn ft4() {} const async unsafe extern "C" fn ft5() {} //~^ ERROR functions in traits cannot be declared `async` //~| ERROR functions in traits cannot be declared const + //~| ERROR method `ft5` has an incompatible type for trait //~| ERROR functions cannot be both `const` and `async` - //~| ERROR cycle detected } impl Y { @@ -44,7 +44,6 @@ fn main() { extern "C" fn fi4() {} // OK. const async unsafe extern "C" fn fi5() {} //~^ ERROR functions cannot be both `const` and `async` - //~| ERROR cycle detected } extern "C" { diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr index 1d7460b8d3605..8eaba559a6240 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.stderr +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -1,14 +1,14 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:12:5 | -LL | const async unsafe extern "C" fn ff5() {} +LL | const async unsafe extern "C" fn ff5() {} // OK. | ^^^^^-^^^^^------------------------------ | | | | | `async` because of this | `const` because of this error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:17:9 + --> $DIR/fn-header-semantic-fail.rs:16:9 | LL | async fn ft1(); | -----^^^^^^^^^^ @@ -19,19 +19,19 @@ LL | async fn ft1(); = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:19:9 + --> $DIR/fn-header-semantic-fail.rs:18:9 | LL | const fn ft3(); | ^^^^^ functions in traits cannot be const error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:21:9 + --> $DIR/fn-header-semantic-fail.rs:20:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^ functions in traits cannot be const error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:21:9 + --> $DIR/fn-header-semantic-fail.rs:20:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | const async unsafe extern "C" fn ft5(); = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:21:9 + --> $DIR/fn-header-semantic-fail.rs:20:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^-^^^^^---------------------------- @@ -51,7 +51,7 @@ LL | const async unsafe extern "C" fn ft5(); | `const` because of this error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:29:9 + --> $DIR/fn-header-semantic-fail.rs:28:9 | LL | async fn ft1() {} | -----^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | const async unsafe extern "C" fn fi5() {} | `const` because of this error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:51:18 + --> $DIR/fn-header-semantic-fail.rs:50:18 | LL | extern "C" { | ---------- in this `extern` block @@ -116,7 +116,7 @@ LL | fn fe1(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:52:19 + --> $DIR/fn-header-semantic-fail.rs:51:19 | LL | extern "C" { | ---------- in this `extern` block @@ -130,7 +130,7 @@ LL | fn fe2(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:53:18 + --> $DIR/fn-header-semantic-fail.rs:52:18 | LL | extern "C" { | ---------- in this `extern` block @@ -144,7 +144,7 @@ LL | fn fe3(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:54:23 + --> $DIR/fn-header-semantic-fail.rs:53:23 | LL | extern "C" { | ---------- in this `extern` block @@ -158,7 +158,7 @@ LL | fn fe4(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:55:42 + --> $DIR/fn-header-semantic-fail.rs:54:42 | LL | extern "C" { | ---------- in this `extern` block @@ -172,7 +172,7 @@ LL | fn fe5(); | ~~ error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:55:9 + --> $DIR/fn-header-semantic-fail.rs:54:9 | LL | const async unsafe extern "C" fn fe5(); | ^^^^^-^^^^^---------------------------- @@ -180,115 +180,43 @@ LL | const async unsafe extern "C" fn fe5(); | | `async` because of this | `const` because of this -error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}` - --> $DIR/fn-header-semantic-fail.rs:12:44 +error[E0053]: method `ft1` has an incompatible type for trait + --> $DIR/fn-header-semantic-fail.rs:28:24 | -LL | const async unsafe extern "C" fn ff5() {} - | ^ - | -note: ...which requires borrow-checking `main::ff5`... - --> $DIR/fn-header-semantic-fail.rs:12:5 - | -LL | const async unsafe extern "C" fn ff5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `main::ff5`... - --> $DIR/fn-header-semantic-fail.rs:12:5 +LL | async fn ft1() {} + | ^ + | | + | checked the `Output` of this `async fn`, found opaque type + | expected `()`, found opaque type | -LL | const async unsafe extern "C" fn ff5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const checking `main::ff5`... - --> $DIR/fn-header-semantic-fail.rs:12:5 + = note: while checking the return type of the `async fn` +note: type in trait + --> $DIR/fn-header-semantic-fail.rs:16:23 | -LL | const async unsafe extern "C" fn ff5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing whether `impl core::future::future::Future` is freeze... - = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future: core::marker::Freeze`... - = note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/fn-header-semantic-fail.rs:5:1 - | -LL | / #![feature(const_extern_fn)] -LL | | -LL | | fn main() { -LL | | async fn ff1() {} // OK. -... | -LL | | } -LL | | } - | |_^ +LL | async fn ft1(); + | ^ + = note: expected fn pointer `fn()` + found fn pointer `fn() -> impl Future` -error[E0391]: cycle detected when computing type of `main::::ft5::{opaque#0}` +error[E0053]: method `ft5` has an incompatible type for trait --> $DIR/fn-header-semantic-fail.rs:33:48 | LL | const async unsafe extern "C" fn ft5() {} | ^ + | | + | checked the `Output` of this `async fn`, found opaque type + | expected `()`, found opaque type | -note: ...which requires borrow-checking `main::::ft5`... - --> $DIR/fn-header-semantic-fail.rs:33:9 - | -LL | const async unsafe extern "C" fn ft5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `main::::ft5`... - --> $DIR/fn-header-semantic-fail.rs:33:9 - | -LL | const async unsafe extern "C" fn ft5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const checking `main::::ft5`... - --> $DIR/fn-header-semantic-fail.rs:33:9 - | -LL | const async unsafe extern "C" fn ft5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing whether `impl core::future::future::Future` is freeze... - = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future: core::marker::Freeze`... - = note: ...which again requires computing type of `main::::ft5::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/fn-header-semantic-fail.rs:5:1 - | -LL | / #![feature(const_extern_fn)] -LL | | -LL | | fn main() { -LL | | async fn ff1() {} // OK. -... | -LL | | } -LL | | } - | |_^ - -error[E0391]: cycle detected when computing type of `main::::fi5::{opaque#0}` - --> $DIR/fn-header-semantic-fail.rs:45:48 - | -LL | const async unsafe extern "C" fn fi5() {} - | ^ - | -note: ...which requires borrow-checking `main::::fi5`... - --> $DIR/fn-header-semantic-fail.rs:45:9 + = note: while checking the return type of the `async fn` +note: type in trait + --> $DIR/fn-header-semantic-fail.rs:20:47 | -LL | const async unsafe extern "C" fn fi5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `main::::fi5`... - --> $DIR/fn-header-semantic-fail.rs:45:9 - | -LL | const async unsafe extern "C" fn fi5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const checking `main::::fi5`... - --> $DIR/fn-header-semantic-fail.rs:45:9 - | -LL | const async unsafe extern "C" fn fi5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing whether `impl core::future::future::Future` is freeze... - = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future: core::marker::Freeze`... - = note: ...which again requires computing type of `main::::fi5::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/fn-header-semantic-fail.rs:5:1 - | -LL | / #![feature(const_extern_fn)] -LL | | -LL | | fn main() { -LL | | async fn ff1() {} // OK. -... | -LL | | } -LL | | } - | |_^ +LL | const async unsafe extern "C" fn ft5(); + | ^ + = note: expected fn pointer `unsafe extern "C" fn()` + found fn pointer `unsafe extern "C" fn() -> impl Future` -error: aborting due to 21 previous errors +error: aborting due to 20 previous errors -Some errors have detailed explanations: E0379, E0391, E0706. -For more information about an error, try `rustc --explain E0379`. +Some errors have detailed explanations: E0053, E0379, E0706. +For more information about an error, try `rustc --explain E0053`. diff --git a/src/test/ui/polymorphization/generators.rs b/src/test/ui/polymorphization/generators.rs index 68ea4a026d7bf..f295cf15d08c6 100644 --- a/src/test/ui/polymorphization/generators.rs +++ b/src/test/ui/polymorphization/generators.rs @@ -32,6 +32,7 @@ where #[rustc_polymorphize_error] pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; @@ -57,6 +58,7 @@ pub fn used_type_in_return() -> impl Generator<(), Yield = u32, Retu #[rustc_polymorphize_error] pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr index 1152bcb0734a6..c4e566a42d0cf 100644 --- a/src/test/ui/polymorphization/generators.stderr +++ b/src/test/ui/polymorphization/generators.stderr @@ -8,10 +8,11 @@ LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] = note: see issue #76560 for more information error: item has unused generic parameters - --> $DIR/generators.rs:35:5 + --> $DIR/generators.rs:36:5 | LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | - generic parameter `T` is unused +LL | LL | / || { LL | | LL | | yield 1; @@ -20,10 +21,17 @@ LL | | } | |_____^ error: item has unused generic parameters - --> $DIR/generators.rs:60:5 + --> $DIR/generators.rs:34:8 + | +LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | ^^^^^^^^^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/generators.rs:62:5 | LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | - generic parameter `T` is unused +LL | LL | / || { LL | | LL | | yield 1; @@ -31,5 +39,11 @@ LL | | 2 LL | | } | |_____^ -error: aborting due to 2 previous errors; 1 warning emitted +error: item has unused generic parameters + --> $DIR/generators.rs:60:8 + | +LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | ^^^^^^^^^^^^ - generic parameter `T` is unused + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs index 49462f52fb4c2..cc36f054bc3a0 100644 --- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs +++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs @@ -14,6 +14,7 @@ trait B { impl B for A { async fn associated(); //~ ERROR without body //~^ ERROR cannot be declared `async` + //~| ERROR incompatible type for trait } fn main() {} diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr index a473f42fc2cf8..d3214458eac13 100644 --- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr +++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr @@ -44,6 +44,25 @@ LL | async fn associated(); = note: `async` trait functions are not currently supported = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait -error: aborting due to 5 previous errors +error[E0053]: method `associated` has an incompatible type for trait + --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:26 + | +LL | async fn associated(); + | ^ + | | + | checked the `Output` of this `async fn`, found opaque type + | expected `()`, found opaque type + | + = note: while checking the return type of the `async fn` +note: type in trait + --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:26 + | +LL | async fn associated(); + | ^ + = note: expected fn pointer `fn()` + found fn pointer `fn() -> impl Future` + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0706`. +Some errors have detailed explanations: E0053, E0706. +For more information about an error, try `rustc --explain E0053`. diff --git a/src/test/ui/save-analysis/issue-68621.rs b/src/test/ui/save-analysis/issue-68621.rs index 30479580f11a3..96af085c5b6b8 100644 --- a/src/test/ui/save-analysis/issue-68621.rs +++ b/src/test/ui/save-analysis/issue-68621.rs @@ -11,7 +11,7 @@ trait Service { struct Struct; impl Service for Struct { - type Future = impl Trait; //~ ERROR: unconstrained opaque type + type Future = impl Trait; //~ ERROR: could not find defining uses } fn main() {} diff --git a/src/test/ui/save-analysis/issue-68621.stderr b/src/test/ui/save-analysis/issue-68621.stderr index 4a4bf9a6996bc..3af6d0a3e076e 100644 --- a/src/test/ui/save-analysis/issue-68621.stderr +++ b/src/test/ui/save-analysis/issue-68621.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/issue-68621.rs:14:19 | LL | type Future = impl Trait; | ^^^^^^^^^^ - | - = note: `Future` must be used in combination with a concrete type within the same module error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 570a08cb58768..61ac7731777b4 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | - ^^^^^^^^ + | - ^^^^^^^^^^ | | | hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here | diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index abdc650c68e78..6f8200739b9de 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | ----- ^^^^ + | ----- ^^^^^^^^^^ | | | hidden type `Pin<&Foo>` captures the anonymous lifetime defined here | diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr index 07c1d8bccbaba..d826222a06ae5 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -1,11 +1,10 @@ error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:3:22 + --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13 | -LL | fn foo() -> impl Bar { - | ______________________^ -LL | | 5; -LL | | } - | |_^ the trait `Bar` is not implemented for `()` +LL | fn foo() -> impl Bar { + | ^^^^^^^^ the trait `Bar` is not implemented for `()` +LL | 5; + | - consider removing this semicolon error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-81098.stderr b/src/test/ui/suggestions/issue-81098.stderr index f13e653cb06bd..2a72159e5774b 100644 --- a/src/test/ui/suggestions/issue-81098.stderr +++ b/src/test/ui/suggestions/issue-81098.stderr @@ -1,23 +1,19 @@ error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:3:37 + --> $DIR/issue-81098.rs:3:13 | -LL | fn wat() -> impl core::fmt::Display { - | _____________________________________^ -LL | | fn why() {} -LL | | } - | |_^ `()` cannot be formatted with the default formatter +LL | fn wat() -> impl core::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:9:36 + --> $DIR/issue-81098.rs:9:12 | -LL | fn ok() -> impl core::fmt::Display { - | ____________________________________^ -LL | | 1; -LL | | } - | |_^ `()` cannot be formatted with the default formatter +LL | fn ok() -> impl core::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter +LL | 1; + | - consider removing this semicolon | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr index c7f1215c8cc44..a5b50634c71ea 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr @@ -7,18 +7,13 @@ LL | fn iter(&self) -> impl Iterator> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:27:23 | -LL | fn iter(&self) -> impl Iterator> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter(&self) -> impl Iterator> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter(&self) -> impl Iterator> + '_ { @@ -37,18 +32,13 @@ LL | fn iter(&self) -> impl Iterator> + '_ { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:38:23 | -LL | fn iter(&self) -> impl Iterator> + '_ { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter(&self) -> impl Iterator> + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter(&self) -> impl Iterator> + '_ { @@ -63,18 +53,13 @@ LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:49:30 | -LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { @@ -89,18 +74,13 @@ LL | fn iter<'a>(&'a self) -> impl Iterator> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:60:30 | -LL | fn iter<'a>(&'a self) -> impl Iterator> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter<'a>(&'a self) -> impl Iterator> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs index a02664ad7ca69..6aa93a24d2f04 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs @@ -16,9 +16,6 @@ fn extra_semicolon() { async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE while checking the return type of the `async fn` //~| NOTE in this expansion of desugaring of `async` block or function -//~| NOTE while checking the return type of the `async fn` -//~| NOTE in this expansion of desugaring of `async` block or function -//~| NOTE checked the `Output` of this `async fn`, expected opaque type async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE while checking the return type of the `async fn` @@ -34,7 +31,7 @@ async fn async_extra_semicolon_same() { } false => async_dummy(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~| NOTE expected type `()` //~| HELP consider `await`ing on the `Future` }; } @@ -47,7 +44,7 @@ async fn async_extra_semicolon_different() { } false => async_dummy2(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~| NOTE expected type `()` //~| HELP consider `await`ing on the `Future` }; } @@ -58,7 +55,7 @@ async fn async_different_futures() { //~| HELP consider `await`ing on both `Future`s false => async_dummy2(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected opaque type `impl Future` + //~| NOTE expected type `impl Future` //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr index 4c4b782bd6fb1..b55c51b92809a 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -1,5 +1,5 @@ error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:35:18 + --> $DIR/match-prev-arm-needing-semi.rs:32:18 | LL | let _ = match true { | _____________- @@ -20,8 +20,8 @@ note: while checking the return type of the `async fn` | LL | async fn async_dummy() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected unit type `()` - found opaque type `impl Future` + = note: expected type `()` + found opaque type `impl Future` help: consider `await`ing on the `Future` | LL | false => async_dummy().await, @@ -33,7 +33,7 @@ LL + async_dummy() | error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:48:18 + --> $DIR/match-prev-arm-needing-semi.rs:45:18 | LL | let _ = match true { | _____________- @@ -50,12 +50,12 @@ LL | | }; | |_____- `match` arms have incompatible types | note: while checking the return type of the `async fn` - --> $DIR/match-prev-arm-needing-semi.rs:22:25 + --> $DIR/match-prev-arm-needing-semi.rs:19:25 | LL | async fn async_dummy2() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected unit type `()` - found opaque type `impl Future` + = note: expected type `()` + found opaque type `impl Future` help: consider `await`ing on the `Future` | LL | false => async_dummy2().await, @@ -69,7 +69,7 @@ LL ~ false => Box::new(async_dummy2()), | error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:59:18 + --> $DIR/match-prev-arm-needing-semi.rs:56:18 | LL | let _ = match true { | _____________- @@ -84,17 +84,12 @@ LL | | }; | |_____- `match` arms have incompatible types | note: while checking the return type of the `async fn` - --> $DIR/match-prev-arm-needing-semi.rs:16:24 - | -LL | async fn async_dummy() {} - | ^ checked the `Output` of this `async fn`, expected opaque type -note: while checking the return type of the `async fn` - --> $DIR/match-prev-arm-needing-semi.rs:22:25 + --> $DIR/match-prev-arm-needing-semi.rs:19:25 | LL | async fn async_dummy2() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) - found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:22:25>) + = note: expected type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) + found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr index 133ffb0587392..e065e0aaa8e06 100644 --- a/src/test/ui/suggestions/opaque-type-error.stderr +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -1,9 +1,6 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | -LL | fn thing_one() -> impl Future> { - | ------------------------------------ the expected opaque type -... LL | fn thing_two() -> impl Future> { | ------------------------------------ the found opaque type ... @@ -16,8 +13,8 @@ LL | | thing_two() LL | | }.await | |_____- `if` and `else` have incompatible types | - = note: expected opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) - found opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) + = note: expected type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) + found opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/src/test/ui/traits/alias/issue-83613.rs b/src/test/ui/traits/alias/issue-83613.rs index 04320e7207683..0013d5d66f172 100644 --- a/src/test/ui/traits/alias/issue-83613.rs +++ b/src/test/ui/traits/alias/issue-83613.rs @@ -8,6 +8,6 @@ fn mk_opaque() -> OpaqueType { trait AnotherTrait {} impl AnotherTrait for T {} impl AnotherTrait for OpaqueType {} -//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `impl OpaqueTrait` //~| ERROR cannot implement trait on type alias impl trait fn main() {} diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr index 4f19e6607c8d9..6a3498a389375 100644 --- a/src/test/ui/traits/alias/issue-83613.stderr +++ b/src/test/ui/traits/alias/issue-83613.stderr @@ -10,13 +10,13 @@ note: type alias impl trait defined here LL | type OpaqueType = impl OpaqueTrait; | ^^^^^^^^^^^^^^^^ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `impl OpaqueTrait` --> $DIR/issue-83613.rs:10:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `impl OpaqueTrait` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/argument-types.rs b/src/test/ui/type-alias-impl-trait/argument-types.rs index 185207b9800bb..8427b5b1fe854 100644 --- a/src/test/ui/type-alias-impl-trait/argument-types.rs +++ b/src/test/ui/type-alias-impl-trait/argument-types.rs @@ -1,12 +1,14 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -// check-pass + use std::fmt::Debug; type Foo = impl Debug; +// FIXME: This should compile, but it currently doesn't fn foo1(mut x: Foo) { x = 22_u32; + //~^ ERROR: mismatched types [E0308] } fn foo2(mut x: Foo) { diff --git a/src/test/ui/type-alias-impl-trait/argument-types.stderr b/src/test/ui/type-alias-impl-trait/argument-types.stderr new file mode 100644 index 0000000000000..a87e44a048b25 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/argument-types.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/argument-types.rs:10:9 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | fn foo1(mut x: Foo) { + | --- expected due to this parameter type +LL | x = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `impl Debug` + found type `u32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr index 0664275b2ad0a..4a49d6e4ab8fd 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -2,15 +2,15 @@ error[E0277]: `Rc` cannot be sent between threads safely --> $DIR/auto-trait-leakage2.rs:17:13 | LL | type Foo = impl std::fmt::Debug; - | -------------------- within this `Foo` + | -------------------- within this `impl Debug` ... LL | is_send(m::foo()); | ------- ^^^^^^^^ `Rc` cannot be sent between threads safely | | | required by a bound introduced by this call | - = help: within `Foo`, the trait `Send` is not implemented for `Rc` - = note: required because it appears within the type `Foo` + = help: within `impl Debug`, the trait `Send` is not implemented for `Rc` + = note: required because it appears within the type `impl Debug` note: required by a bound in `is_send` --> $DIR/auto-trait-leakage2.rs:14:15 | diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs index b456b1445e784..5fb7a9473d3df 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs @@ -6,7 +6,6 @@ mod m { type Foo = impl std::fmt::Debug; //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] - //~| ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] pub fn foo() -> Foo { 22_u32 diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr index 4c44875b4a548..c0147e56c9364 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr @@ -5,10 +5,11 @@ LL | type Foo = impl std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^ | note: ...which requires type-checking `m::bar`... - --> $DIR/auto-trait-leakage3.rs:15:5 + --> $DIR/auto-trait-leakage3.rs:15:9 | -LL | pub fn bar() { - | ^^^^^^^^^^^^ +LL | is_send(foo()); + | ^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl core::fmt::Debug: core::marker::Send`... = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle note: cycle used when checking item types in module `m` --> $DIR/auto-trait-leakage3.rs:6:1 @@ -16,24 +17,6 @@ note: cycle used when checking item types in module `m` LL | mod m { | ^^^^^ -error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` - --> $DIR/auto-trait-leakage3.rs:7:16 - | -LL | type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires type-checking `m::bar`... - --> $DIR/auto-trait-leakage3.rs:15:5 - | -LL | pub fn bar() { - | ^^^^^^^^^^^^ - = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in module `m` - --> $DIR/auto-trait-leakage3.rs:6:1 - | -LL | mod m { - | ^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs index 4d2890b5de583..cee8186dd8f8c 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -7,12 +7,13 @@ trait TraitWithAssoc { } type Foo = impl Trait; +//~^ ERROR could not find defining uses trait Trait {} impl Trait for () {} fn foo_desugared(_: T) -> Foo { + //~^ ERROR non-defining opaque type use in defining scope () - //~^ ERROR non-defining opaque type use } diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index c405b1f6af205..03e696fe89803 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/bound_reduction2.rs:16:5 + --> $DIR/bound_reduction2.rs:16:46 | -LL | () - | ^^ +LL | fn foo_desugared(_: T) -> Foo { + | ^^^^^^^^^^^^^ | note: used non-generic type `::Assoc` for generic parameter --> $DIR/bound_reduction2.rs:9:10 @@ -10,5 +10,11 @@ note: used non-generic type `::Assoc` for generic parameter LL | type Foo = impl Trait; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/bound_reduction2.rs:9:15 + | +LL | type Foo = impl Trait; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs index 83d22161e4e75..eecef2338c146 100644 --- a/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs @@ -4,11 +4,11 @@ #![feature(type_alias_impl_trait)] type X<'a> = impl Into<&'static str> + From<&'a str>; +//~^ ERROR mismatched types fn f<'a: 'static>(t: &'a str) -> X<'a> { //~^ WARNING unnecessary lifetime parameter t - //~^ ERROR non-defining opaque type use } fn extend_lt<'a>(o: &'a str) -> &'static str { diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr index d87ef2ec79c1a..da9f81d6bd370 100644 --- a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr @@ -1,19 +1,26 @@ warning: unnecessary lifetime parameter `'a` - --> $DIR/bounds-are-checked.rs:8:6 + --> $DIR/bounds-are-checked.rs:9:6 | LL | fn f<'a: 'static>(t: &'a str) -> X<'a> { | ^^^^^^^^^^^ | = help: you can use the `'static` lifetime directly, in place of `'a` -error: non-defining opaque type use in defining scope - --> $DIR/bounds-are-checked.rs:10:5 +error[E0308]: mismatched types + --> $DIR/bounds-are-checked.rs:6:14 | LL | type X<'a> = impl Into<&'static str> + From<&'a str>; - | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type -... -LL | t - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected trait `From<&'a str>` + found trait `From<&'static str>` +note: the lifetime `'a` as defined here... + --> $DIR/bounds-are-checked.rs:6:8 + | +LL | type X<'a> = impl Into<&'static str> + From<&'a str>; + | ^^ + = note: ...does not necessarily outlive the static lifetime error: aborting due to previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs index 6febd07157aa6..c4bf56a919721 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs @@ -3,4 +3,4 @@ fn main() {} // declared but never defined -type Bar = impl std::fmt::Debug; //~ ERROR unconstrained opaque type +type Bar = impl std::fmt::Debug; //~ ERROR could not find defining uses diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr index 60bc24320a301..21c2e8a9db618 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/declared_but_never_defined.rs:6:12 | LL | type Bar = impl std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^ - | - = note: `Bar` must be used in combination with a concrete type within the same module error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs index 5bda5f0fceaaa..7ea517eb734a4 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs @@ -4,7 +4,7 @@ fn main() {} mod boo { // declared in module but not defined inside of it - pub type Boo = impl ::std::fmt::Debug; //~ ERROR unconstrained opaque type + pub type Boo = impl ::std::fmt::Debug; //~ ERROR could not find defining uses } fn bomp() -> boo::Boo { diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index 26308c6ff6b15..0b4c262bbb43b 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/declared_but_not_defined_in_scope.rs:7:20 | LL | pub type Boo = impl ::std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Boo` must be used in combination with a concrete type within the same module error[E0308]: mismatched types --> $DIR/declared_but_not_defined_in_scope.rs:11:5 @@ -12,11 +10,13 @@ error[E0308]: mismatched types LL | pub type Boo = impl ::std::fmt::Debug; | ---------------------- the expected opaque type ... +LL | fn bomp() -> boo::Boo { + | -------- expected `impl Debug` because of return type LL | "" | ^^ expected opaque type, found `&str` | - = note: expected opaque type `Boo` - found reference `&str` + = note: expected opaque type `impl Debug` + found reference `&'static str` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs index 7740f774ebca4..95cbcfec2dc15 100644 --- a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -1,5 +1,5 @@ #![feature(type_alias_impl_trait)] -// check-pass + fn main() {} // two definitions with different types @@ -10,9 +10,11 @@ fn foo() -> Foo { } fn bar() -> Foo { + //~^ ERROR concrete type differs from previous panic!() } fn boo() -> Foo { + //~^ ERROR concrete type differs from previous loop {} } diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr new file mode 100644 index 0000000000000..6274029e4f524 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -0,0 +1,26 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type.rs:12:1 + | +LL | fn bar() -> Foo { + | ^^^^^^^^^^^^^^^ expected `&'static str`, got `()` + | +note: previous use here + --> $DIR/different_defining_uses_never_type.rs:8:1 + | +LL | fn foo() -> Foo { + | ^^^^^^^^^^^^^^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type.rs:17:1 + | +LL | fn boo() -> Foo { + | ^^^^^^^^^^^^^^^ expected `&'static str`, got `()` + | +note: previous use here + --> $DIR/different_defining_uses_never_type.rs:8:1 + | +LL | fn foo() -> Foo { + | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/fallback.rs b/src/test/ui/type-alias-impl-trait/fallback.rs index d7e93335f47fa..fe1ca2230daca 100644 --- a/src/test/ui/type-alias-impl-trait/fallback.rs +++ b/src/test/ui/type-alias-impl-trait/fallback.rs @@ -1,5 +1,5 @@ -// Tests that we correctly handle opaque types being used opaquely, -// even within their defining scope. +// Tests that we correctly handle the instantiated +// inference variable being completely unconstrained. // // check-pass #![feature(type_alias_impl_trait)] diff --git a/src/test/ui/type-alias-impl-trait/field-types.rs b/src/test/ui/type-alias-impl-trait/field-types.rs index d99ed58127bd4..91494a82d0fb2 100644 --- a/src/test/ui/type-alias-impl-trait/field-types.rs +++ b/src/test/ui/type-alias-impl-trait/field-types.rs @@ -1,11 +1,12 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -// check-pass +// FIXME This should compile, but it currently doesn't use std::fmt::Debug; type Foo = impl Debug; +//~^ ERROR: could not find defining uses struct Bar { foo: Foo, @@ -13,6 +14,7 @@ struct Bar { fn bar() -> Bar { Bar { foo: "foo" } + //~^ ERROR: mismatched types [E0308] } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/field-types.stderr b/src/test/ui/type-alias-impl-trait/field-types.stderr new file mode 100644 index 0000000000000..18c2abbdf3721 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/field-types.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/field-types.rs:16:16 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | Bar { foo: "foo" } + | ^^^^^ expected opaque type, found `&str` + | + = note: expected opaque type `impl Debug` + found reference `&'static str` + +error: could not find defining uses + --> $DIR/field-types.rs:8:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs index c9b9e128f88e2..885aae619d6a2 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -3,9 +3,9 @@ fn main() {} type Two<'a, 'b> = impl std::fmt::Debug; - +//~^ ERROR could not find defining uses fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - t //~^ ERROR non-defining opaque type use + t } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 222aaea78d982..b99c6a51f4b1d 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:9:5 + --> $DIR/generic_duplicate_lifetime_param.rs:8:26 | -LL | t - | ^ +LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { + | ^^^^^^^^^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_lifetime_param.rs:5:10 @@ -10,5 +10,11 @@ note: lifetime used multiple times LL | type Two<'a, 'b> = impl std::fmt::Debug; | ^^ ^^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/generic_duplicate_lifetime_param.rs:5:20 + | +LL | type Two<'a, 'b> = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index 093c1c231861f..33cd2f6ba0753 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -6,23 +6,23 @@ fn main() {} // test that unused generic parameters are ok type TwoTys = impl Debug; - +//~^ ERROR could not find defining uses type TwoLifetimes<'a, 'b> = impl Debug; - +//~^ ERROR could not find defining uses type TwoConsts = impl Debug; - +//~^ ERROR could not find defining uses fn one_ty(t: T) -> TwoTys { - t //~^ ERROR non-defining opaque type use in defining scope + t } fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { - t //~^ ERROR non-defining opaque type use in defining scope + t } fn one_const(t: *mut [u8; N]) -> TwoConsts { - t //~^ ERROR non-defining opaque type use in defining scope + t } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index 922e41e0f6883..52c60d1777e49 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:16:5 + --> $DIR/generic_duplicate_param_use.rs:15:30 | -LL | t - | ^ +LL | fn one_ty(t: T) -> TwoTys { + | ^^^^^^^^^^^^ | note: type used multiple times --> $DIR/generic_duplicate_param_use.rs:8:13 @@ -10,11 +10,17 @@ note: type used multiple times LL | type TwoTys = impl Debug; | ^ ^ +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:8:21 + | +LL | type TwoTys = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:21:5 + --> $DIR/generic_duplicate_param_use.rs:20:36 | -LL | t - | ^ +LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { + | ^^^^^^^^^^^^^^^^^^^^ | note: lifetime used multiple times --> $DIR/generic_duplicate_param_use.rs:10:19 @@ -22,11 +28,17 @@ note: lifetime used multiple times LL | type TwoLifetimes<'a, 'b> = impl Debug; | ^^ ^^ +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:10:29 + | +LL | type TwoLifetimes<'a, 'b> = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:26:5 + --> $DIR/generic_duplicate_param_use.rs:25:50 | -LL | t - | ^ +LL | fn one_const(t: *mut [u8; N]) -> TwoConsts { + | ^^^^^^^^^^^^^^^ | note: constant used multiple times --> $DIR/generic_duplicate_param_use.rs:12:22 @@ -34,5 +46,11 @@ note: constant used multiple times LL | type TwoConsts = impl Debug; | ^ ^ -error: aborting due to 3 previous errors +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:12:50 + | +LL | type TwoConsts = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs index 81bf9770d02a8..04fb57b39c052 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -8,6 +8,11 @@ fn main() {} type Two = impl Debug; //~^ ERROR `T` doesn't implement `Debug` +fn one(t: T) -> Two { + //~^ ERROR non-defining opaque type use in defining scope + t +} + fn two(t: T, _: U) -> Two { t } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr index 84aa260b099b6..fca9b70d18441 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -1,3 +1,15 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use2.rs:11:27 + | +LL | fn one(t: T) -> Two { + | ^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use2.rs:8:10 + | +LL | type Two = impl Debug; + | ^ ^ + error[E0277]: `T` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use2.rs:8:18 | @@ -9,6 +21,6 @@ help: consider restricting type parameter `T` LL | type Two = impl Debug; | +++++++++++++++++ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index c95692182c278..1a755d3902612 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -8,6 +8,11 @@ fn main() {} type Two = impl Debug; //~^ ERROR `T` doesn't implement `Debug` +fn one(t: T) -> Two { + //~^ ERROR non-defining opaque type use in defining scope + t +} + fn two(t: T, _: U) -> Two { t } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index e5a70fa8ce56e..90b04c043a00c 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -1,11 +1,23 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use3.rs:11:27 + | +LL | fn one(t: T) -> Two { + | ^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use3.rs:8:10 + | +LL | type Two = impl Debug; + | ^ ^ + error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use3.rs:15:1 + --> $DIR/generic_duplicate_param_use3.rs:20:1 | LL | fn three(_: T, u: U) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `U` | note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:11:1 + --> $DIR/generic_duplicate_param_use3.rs:16:1 | LL | fn two(t: T, _: U) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,6 +33,6 @@ help: consider restricting type parameter `T` LL | type Two = impl Debug; | +++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs index aee2550e9078a..50d95c83d58e6 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -8,6 +8,11 @@ fn main() {} type Two = impl Debug; //~^ ERROR `U` doesn't implement `Debug` +fn one(t: T) -> Two { + //~^ ERROR non-defining opaque type use in defining scope + t +} + fn three(_: T, u: U) -> Two { u } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr index 0491d61030e34..c4be2fa83f130 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr @@ -1,3 +1,15 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use4.rs:11:27 + | +LL | fn one(t: T) -> Two { + | ^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use4.rs:8:10 + | +LL | type Two = impl Debug; + | ^ ^ + error[E0277]: `U` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use4.rs:8:18 | @@ -9,6 +21,6 @@ help: consider restricting type parameter `U` LL | type Two = impl Debug; | +++++++++++++++++ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs index f39741a6a625c..cf43085877f4c 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -5,25 +5,25 @@ use std::fmt::Debug; fn main() {} type OneTy = impl Debug; - +//~^ ERROR could not find defining uses type OneLifetime<'a> = impl Debug; - +//~^ ERROR could not find defining uses type OneConst = impl Debug; - +//~^ ERROR could not find defining uses // Not defining uses, because they doesn't define *all* possible generics. fn concrete_ty() -> OneTy { - 5u32 //~^ ERROR non-defining opaque type use in defining scope + 5u32 } fn concrete_lifetime() -> OneLifetime<'static> { - 6u32 //~^ ERROR non-defining opaque type use in defining scope + 6u32 } fn concrete_const() -> OneConst<{ 123 }> { - 7u32 //~^ ERROR non-defining opaque type use in defining scope + 7u32 } diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index 36694900c17b4..3aa42a25484d1 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:17:5 + --> $DIR/generic_nondefining_use.rs:16:21 | -LL | 5u32 - | ^^^^ +LL | fn concrete_ty() -> OneTy { + | ^^^^^^^^^^ | note: used non-generic type `u32` for generic parameter --> $DIR/generic_nondefining_use.rs:7:12 @@ -10,20 +10,32 @@ note: used non-generic type `u32` for generic parameter LL | type OneTy = impl Debug; | ^ +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:7:17 + | +LL | type OneTy = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:22:5 + --> $DIR/generic_nondefining_use.rs:21:27 | LL | type OneLifetime<'a> = impl Debug; | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type ... -LL | 6u32 - | ^^^^ +LL | fn concrete_lifetime() -> OneLifetime<'static> { + | ^^^^^^^^^^^^^^^^^^^^ + +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:9:24 + | +LL | type OneLifetime<'a> = impl Debug; + | ^^^^^^^^^^ error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:27:5 + --> $DIR/generic_nondefining_use.rs:26:24 | -LL | 7u32 - | ^^^^ +LL | fn concrete_const() -> OneConst<{ 123 }> { + | ^^^^^^^^^^^^^^^^^ | note: used non-generic constant `123_usize` for generic parameter --> $DIR/generic_nondefining_use.rs:11:21 @@ -31,5 +43,11 @@ note: used non-generic constant `123_usize` for generic parameter LL | type OneConst = impl Debug; | ^ -error: aborting due to 3 previous errors +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:11:33 + | +LL | type OneConst = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.rs b/src/test/ui/type-alias-impl-trait/generic_not_used.rs index c70f473cff578..dd6300a64f42e 100644 --- a/src/test/ui/type-alias-impl-trait/generic_not_used.rs +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.rs @@ -6,6 +6,6 @@ type WrongGeneric = impl 'static; //~^ ERROR: at least one trait must be specified fn wrong_generic(_: U, v: V) -> WrongGeneric { - v //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list + v } diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr index fd720239a5239..8015ff7eded90 100644 --- a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr @@ -5,10 +5,14 @@ LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/generic_not_used.rs:9:5 + --> $DIR/generic_not_used.rs:8:73 | -LL | v - | ^ +LL | fn wrong_generic(_: U, v: V) -> WrongGeneric { + | _________________________________________________________________________^ +LL | | +LL | | v +LL | | } + | |_^ error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index dc85db66d32ba..f4e1de8e50f68 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -1,29 +1,41 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:10:24 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:24 | LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ -error: non-defining opaque type use in defining scope +error[E0308]: mismatched types --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 | LL | let z: i32 = x; - | ^ + | --- ^ expected `i32`, found opaque type + | | + | expected due to this +... +LL | type WrongGeneric = impl 'static; + | ------------ the found opaque type | -note: used non-generic type `&'static i32` for generic parameter - --> $DIR/generic_type_does_not_live_long_enough.rs:10:19 + = note: expected type `i32` + found opaque type `impl Sized` + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generic_type_does_not_live_long_enough.rs:12:30 | -LL | type WrongGeneric = impl 'static; - | ^ +LL | fn wrong_generic(t: T) -> WrongGeneric { + | ^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:14:5 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:24 | -LL | t - | ^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'static`... + = note: ...so that the type `T` will meet its required lifetime bounds -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0308, E0310. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index cb90776472b5d..78d25e30e0382 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -3,14 +3,13 @@ fn main() { let y = 42; let x = wrong_generic(&y); - let z: i32 = x; - //~^ ERROR non-defining opaque type use + let z: i32 = x; //~ ERROR mismatched types } type WrongGeneric = impl 'static; //~^ ERROR: at least one trait must be specified fn wrong_generic(t: T) -> WrongGeneric { - t //~^ ERROR the parameter type `T` may not live long enough + t } diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index 15ec2eed3da4b..568784372e519 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -1,29 +1,32 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:10:24 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:24 | LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ -error: non-defining opaque type use in defining scope +error[E0308]: mismatched types --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 | LL | let z: i32 = x; - | ^ - | -note: used non-generic type `&'static i32` for generic parameter - --> $DIR/generic_type_does_not_live_long_enough.rs:10:19 - | + | --- ^ expected `i32`, found opaque type + | | + | expected due to this +... LL | type WrongGeneric = impl 'static; - | ^ + | ------------ the found opaque type + | + = note: expected type `i32` + found opaque type `impl Sized` error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:14:5 + --> $DIR/generic_type_does_not_live_long_enough.rs:12:30 | LL | fn wrong_generic(t: T) -> WrongGeneric { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | t - | ^ ...so that the type `T` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `T: 'static` error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0308, E0310. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.rs b/src/test/ui/type-alias-impl-trait/inference-cycle.rs index 608572978a351..c781e200bf8ee 100644 --- a/src/test/ui/type-alias-impl-trait/inference-cycle.rs +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.rs @@ -3,8 +3,7 @@ mod m { type Foo = impl std::fmt::Debug; - //~^ ERROR cycle detected - //~| ERROR cycle detected + //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] // Cycle: error today, but it'd be nice if it eventually worked @@ -18,6 +17,7 @@ mod m { fn baz() { let f: Foo = 22_u32; + //~^ ERROR: mismatched types [E0308] } fn is_send(_: T) {} diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr index 3ed86fae8a18d..e12124664778e 100644 --- a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr @@ -5,10 +5,11 @@ LL | type Foo = impl std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^ | note: ...which requires type-checking `m::bar`... - --> $DIR/inference-cycle.rs:15:5 + --> $DIR/inference-cycle.rs:15:9 | -LL | pub fn bar() { - | ^^^^^^^^^^^^ +LL | is_send(foo()); // Today: error + | ^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl core::fmt::Debug: core::marker::Send`... = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle note: cycle used when checking item types in module `m` --> $DIR/inference-cycle.rs:4:1 @@ -16,24 +17,21 @@ note: cycle used when checking item types in module `m` LL | mod m { | ^^^^^ -error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` - --> $DIR/inference-cycle.rs:5:16 +error[E0308]: mismatched types + --> $DIR/inference-cycle.rs:19:22 | LL | type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires type-checking `m::bar`... - --> $DIR/inference-cycle.rs:15:5 - | -LL | pub fn bar() { - | ^^^^^^^^^^^^ - = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in module `m` - --> $DIR/inference-cycle.rs:4:1 - | -LL | mod m { - | ^^^^^ + | -------------------- the expected opaque type +... +LL | let f: Foo = 22_u32; + | --- ^^^^^^ expected opaque type, found `u32` + | | + | expected due to this + | + = note: expected opaque type `impl Debug` + found type `u32` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0308, E0391. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs index 34be420274409..37b330ba4b8fc 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs @@ -18,8 +18,8 @@ impl Foo for S2 { type Item = impl Debug; fn foo(_: T) -> Self::Item { - S::(Default::default()) //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + S::(Default::default()) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.stderr index 34f0aa0d98d9a..4c8144a235930 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53598.stderr @@ -1,8 +1,12 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-53598.rs:21:9 + --> $DIR/issue-53598.rs:20:42 | -LL | S::(Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(_: T) -> Self::Item { + | __________________________________________^ +LL | | +LL | | S::(Default::default()) +LL | | } + | |_____^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr index 91daa65d6563a..a4ccae4eb7ed9 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr @@ -1,26 +1,38 @@ -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:9 +error: higher-ranked subtype error + --> $DIR/issue-57611-trait-alias.rs:21:9 + | +LL | |x| x + | ^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-57611-trait-alias.rs:21:9 | LL | |x| x - | ^^^^^ one type is more general than the other + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-57611-trait-alias.rs:17:16 + | +LL | type Bar = impl Baz; + | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&X,)>` + found type `Fn<(&'static X,)>` note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:20:9 + --> $DIR/issue-57611-trait-alias.rs:21:9 | LL | |x| x | ^^^^^ error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:9 + --> $DIR/issue-57611-trait-alias.rs:17:16 | -LL | |x| x - | ^^^^^ implementation of `FnOnce` is not general enough +LL | type Bar = impl Baz; + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` + = note: closure with signature `fn(&'static X) -> &'static X` must implement `FnOnce<(&'0 X,)>`, for any lifetime `'0`... + = note: ...but it actually implements `FnOnce<(&'static X,)>` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index 7c6e764248479..625e46b6bc012 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -17,8 +17,8 @@ impl Foo for X { type Bar = impl Baz; fn bar(&self) -> Self::Bar { - |x| x //~^ ERROR implementation of `FnOnce` is not general enough + |x| x } } diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index 45329ea292dcf..54d237159d80b 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -1,8 +1,8 @@ error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:9 + --> $DIR/issue-57611-trait-alias.rs:19:22 | -LL | |x| x - | ^^^^^ implementation of `FnOnce` is not general enough +LL | fn bar(&self) -> Self::Bar { + | ^^^^^^^^^ implementation of `FnOnce` is not general enough | = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs index ba8bda76cecf6..f1db4d3291b40 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs @@ -14,8 +14,8 @@ impl Foo for C { type Bar = impl Foo; fn foo(self: impl Deref) -> Self::Bar { - self //~^ Error type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias + self } } diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.stderr index 56ad997f84314..c701e3e74ef59 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57700.stderr @@ -1,8 +1,12 @@ error: type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-57700.rs:17:9 + --> $DIR/issue-57700.rs:16:58 | -LL | self - | ^^^^ +LL | fn foo(self: impl Deref) -> Self::Bar { + | __________________________________________________________^ +LL | | +LL | | self +LL | | } + | |_____^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-58951-2.rs b/src/test/ui/type-alias-impl-trait/issue-58951-2.rs deleted file mode 100644 index e4ba7f8e2a623..0000000000000 --- a/src/test/ui/type-alias-impl-trait/issue-58951-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -// check-pass - -#![feature(type_alias_impl_trait)] - -mod defining_use_scope { - pub type A = impl Iterator; - - pub fn def_a() -> A { - 0..1 - } -} -use defining_use_scope::*; - -pub fn use_a() { - def_a().map(|x| x); -} - -fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs index 37a2f28ce074f..9d2ba849c8667 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -11,6 +11,7 @@ impl Bug for &() { const FUN: fn() -> Self::Item = || (); //~^ ERROR the trait bound `(): Bug` is not satisfied + //~| ERROR non-defining opaque type use in defining scope } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 3666b6e97ecfd..62ab7eb456010 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -11,12 +11,21 @@ error[E0277]: the trait bound `(): Bug` is not satisfied --> $DIR/issue-60371.rs:12:40 | LL | const FUN: fn() -> Self::Item = || (); - | ^^ the trait `Bug` is not implemented for `()` + | ^ the trait `Bug` is not implemented for `()` | = help: the following implementations were found: <&() as Bug> -error: aborting due to 2 previous errors +error: non-defining opaque type use in defining scope + --> $DIR/issue-60371.rs:12:37 + | +LL | impl Bug for &() { + | - cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | const FUN: fn() -> Self::Item = || (); + | ^^^^^ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0658. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 4fc7679311a2e..44dcec2c3da98 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -6,6 +6,7 @@ trait IterBits { } type IterBitsIter = impl std::iter::Iterator; +//~^ ERROR could not find defining uses impl IterBits for T where @@ -17,8 +18,8 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) //~^ ERROR non-defining opaque type use in defining scope + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index bbc93657be32f..6b73fbef011ec 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:20:9 + --> $DIR/issue-60564.rs:20:34 | -LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn iter_bits(self, n: u8) -> Self::BitsIter { + | ^^^^^^^^^^^^^^ | note: used non-generic type `u8` for generic parameter --> $DIR/issue-60564.rs:8:25 @@ -10,5 +10,11 @@ note: used non-generic type `u8` for generic parameter LL | type IterBitsIter = impl std::iter::Iterator; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/issue-60564.rs:8:30 + | +LL | type IterBitsIter = impl std::iter::Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs index 057a908bbee74..875cce4df2390 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.rs +++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs @@ -5,10 +5,7 @@ type Closure = impl FnOnce(); fn c() -> Closure { - || -> Closure { || () } - //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| ERROR: expected a `FnOnce<()>` closure, found `()` + || -> Closure { || () } //~ ERROR: mismatched types } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr index 4b7dbbd6a56cc..5fde8c2ef1e11 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,34 +1,17 @@ -error[E0277]: expected a `FnOnce<()>` closure, found `()` - --> $DIR/issue-63279.rs:8:11 - | -LL | || -> Closure { || () } - | ^^^^^^^ expected an `FnOnce<()>` closure, found `()` - | - = help: the trait `FnOnce<()>` is not implemented for `()` - = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` - -error[E0308]: mismatched types - --> $DIR/issue-63279.rs:8:21 - | -LL | || -> Closure { || () } - | ^^^^^ expected `()`, found closure - | - = note: expected unit type `()` - found closure `[closure@$DIR/issue-63279.rs:8:21: 8:26]` - error[E0308]: mismatched types --> $DIR/issue-63279.rs:8:5 | LL | type Closure = impl FnOnce(); - | ------------- the expected opaque type + | ------------- the found opaque type ... LL | || -> Closure { || () } - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure + | ^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure | - = note: expected opaque type `Closure` - found closure `[closure@$DIR/issue-63279.rs:8:5: 8:28]` + = note: expected type `[closure@$DIR/issue-63279.rs:8:21: 8:26]` + found closure `[closure@$DIR/issue-63279.rs:8:5: 8:28]` + = note: no two closures, even if identical, have the same type + = help: consider boxing your closure and/or using it as a trait object -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-63355.rs b/src/test/ui/type-alias-impl-trait/issue-63355.rs index 7066a0535e184..ff4fd5dcec73c 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63355.rs +++ b/src/test/ui/type-alias-impl-trait/issue-63355.rs @@ -1,5 +1,6 @@ #![feature(type_alias_impl_trait)] -// check-pass +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] pub trait Foo {} @@ -27,8 +28,11 @@ impl Bar for () { } } +// FIXME(#86731): The below is illegal use of `type_alias_impl_trait` +// but the compiler doesn't report it, we should fix it. pub type FooImpl = impl Foo; pub type BarImpl = impl Bar; +//~^ ERROR: type mismatch resolving `<() as Bar>::Foo == ()` impl Baz for () { type Foo = FooImpl; diff --git a/src/test/ui/type-alias-impl-trait/issue-63355.stderr b/src/test/ui/type-alias-impl-trait/issue-63355.stderr new file mode 100644 index 0000000000000..6fc6b4bfe1f00 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63355.stderr @@ -0,0 +1,19 @@ +error[E0271]: type mismatch resolving `<() as Bar>::Foo == ()` + --> $DIR/issue-63355.rs:34:20 + | +LL | pub type FooImpl = impl Foo; + | -------- the found opaque type +LL | pub type BarImpl = impl Bar; + | ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Bar>::Foo == ()` + | +note: expected this to be `()` + --> $DIR/issue-63355.rs:24:16 + | +LL | type Foo = FooImpl; + | ^^^^^^^ + = note: expected unit type `()` + found opaque type `impl Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs index 5223fb1c702d6..2e6354088ac5a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs @@ -5,7 +5,7 @@ #![feature(type_alias_impl_trait)] trait Trait {} type Alias<'a, U> = impl Trait; - +//~^ ERROR could not find defining uses fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR non-defining opaque type use in defining scope diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr index 7fb9a0c410e83..721f99a3f0d18 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use-2.rs:9:29 + --> $DIR/issue-68368-non-defining-use-2.rs:9:15 | LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^ + | ^^^^^^^^^^^^^ | note: used non-generic type `()` for generic parameter --> $DIR/issue-68368-non-defining-use-2.rs:7:16 @@ -10,5 +10,11 @@ note: used non-generic type `()` for generic parameter LL | type Alias<'a, U> = impl Trait; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/issue-68368-non-defining-use-2.rs:7:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs index b50462bf237bb..3addd8dcc4fb3 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -5,7 +5,7 @@ #![feature(type_alias_impl_trait)] trait Trait {} type Alias<'a, U> = impl Trait; - +//~^ ERROR could not find defining uses fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR non-defining opaque type use in defining scope diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index 8059621b61a09..f5b8fccf65d16 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use.rs:9:29 + --> $DIR/issue-68368-non-defining-use.rs:9:15 | LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^ + | ^^^^^^^^^^^^^ | note: used non-generic type `()` for generic parameter --> $DIR/issue-68368-non-defining-use.rs:7:16 @@ -10,5 +10,11 @@ note: used non-generic type `()` for generic parameter LL | type Alias<'a, U> = impl Trait; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/issue-68368-non-defining-use.rs:7:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr index 38591e37f5358..f6b369dd8d518 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74280.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr @@ -1,14 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-74280.rs:9:5 | -LL | type Test = impl Copy; - | --------- the expected opaque type -... LL | 7 | ^ expected `()`, found integer - | - = note: expected opaque type `Test` - found type `{integer}` error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr index 053546e4b9285..15205ba9b419e 100644 --- a/src/test/ui/type-alias-impl-trait/issue-77179.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr @@ -5,7 +5,7 @@ LL | fn test() -> Pointer<_> { | --------^- | | | | | not allowed in type signatures - | help: replace with the correct return type: `Pointer` + | help: replace with the correct return type: `Box` error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr index 3a75dc6fe7ba0..19ed9a7476c1b 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr @@ -2,18 +2,18 @@ error[E0271]: type mismatch resolving ` as --> $DIR/issue-89686.rs:7:17 | LL | type G<'a, T> = impl Future; - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type ... LL | async move { self.f().await } - | ------------------ the expected `async` block + | ------------------ the found `async` block | ::: $SRC_DIR/core/src/future/mod.rs:LL:COL | LL | pub const fn from_generator(gen: T) -> impl Future - | ------------------------------- the expected opaque type + | ------------------------------- the found opaque type | - = note: expected associated type ` as Future>::Output` - found unit type `()` + = note: expected unit type `()` + found associated type ` as Future>::Output` = help: consider constraining the associated type ` as Future>::Output` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html diff --git a/src/test/ui/type-alias-impl-trait/issue-93411.rs b/src/test/ui/type-alias-impl-trait/issue-93411.rs deleted file mode 100644 index 1f8c789267d1b..0000000000000 --- a/src/test/ui/type-alias-impl-trait/issue-93411.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(type_alias_impl_trait)] - -// this test used to stack overflow due to infinite recursion. -// check-pass -// compile-flags: --edition=2018 - -use std::future::Future; - -fn main() { - let _ = move || async move { - let value = 0u8; - blah(&value).await; - }; -} - -type BlahFut<'a> = impl Future + Send + 'a; -fn blah<'a>(_value: &'a u8) -> BlahFut<'a> { - async {} -} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs deleted file mode 100644 index 08cb48ccf308c..0000000000000 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs +++ /dev/null @@ -1,13 +0,0 @@ -// https://github.com/rust-lang/rust/issues/73481 -// This test used to cause unsoundness, since one of the two possible -// resolutions was chosen at random instead of erroring due to conflicts. - -#![feature(type_alias_impl_trait)] - -type Y = impl std::fmt::Debug; - -fn g() -> (Y, Y) { - (42_i64, 60) //~^ ERROR concrete type differs from previous defining opaque type use -} - -fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr deleted file mode 100644 index 3f57612684e41..0000000000000 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn-infer.rs:9:1 - | -LL | fn g() -> (Y, Y) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, got `i32` - | -note: previous use here - --> $DIR/multiple-def-uses-in-one-fn-infer.rs:9:1 - | -LL | fn g() -> (Y, Y) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs deleted file mode 100644 index f39bf4aeb29ae..0000000000000 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type Foo<'a, 'b> = impl std::fmt::Debug; - -fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { - (i, i) //~^ ERROR concrete type differs from previous -} - -fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr deleted file mode 100644 index 49d08dda9f994..0000000000000 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:5:1 - | -LL | fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a i32`, got `&'b i32` - | -note: previous use here - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:5:1 - | -LL | fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs index 83fd9a1da450b..f412b2d0e7db7 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -7,15 +7,6 @@ fn f(a: A, b: B) -> (X, X) (a.clone(), a) } -type Foo<'a, 'b> = impl std::fmt::Debug; - -fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { - (i, j) -} - fn main() { println!("{}", as ToString>::to_string(&f(42_i32, String::new()).1)); - let meh = 42; - let muh = 69; - println!("{:?}", foo(&meh, &muh)); } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index 46bac5a34f5c0..da845e86147b7 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -7,8 +7,8 @@ type X = impl Into<&'static A>; fn f(a: &'static A, b: B) -> (X, X) { - (a, a) //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied + (a, a) } fn main() { diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index f4d8b4509d43d..4df2f52a9e427 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied - --> $DIR/multiple-def-uses-in-one-fn.rs:10:9 + --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 | -LL | (a, a) - | ^ the trait `From<&A>` is not implemented for `&'static B` +LL | fn f(a: &'static A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B` | = note: required because of the requirements on the impl of `Into<&'static B>` for `&A` help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index db4b60461ef38..bbe709dccab4e 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -1,9 +1,6 @@ error[E0308]: mismatched types --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 | -LL | type X = impl ToString; - | ------------- the expected opaque type -... LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | @@ -11,8 +8,8 @@ LL | fn g(a: A, b: B) -> (X, X` - found type parameter `B` + = note: expected type parameter `A` + found type parameter `B` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs index 784a6c75886d4..efb88dabf34cd 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(type_alias_impl_trait)] #![allow(dead_code)] @@ -10,9 +12,7 @@ trait Foo { } impl Foo<()> for () { } fn foo() -> impl Foo { - // FIXME(type-alias-impl-trait): We could probably make this work. () - //~^ ERROR: the trait bound `(): Foo` is not satisfied } fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr deleted file mode 100644 index 9472cac63554e..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference.rs:14:5 - | -LL | () - | ^^ the trait `Foo` is not implemented for `()` - | - = help: the following implementations were found: - <() as Foo<()>> - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs index 00bd44c493c83..9b26a65297852 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -4,6 +4,7 @@ use std::fmt::Debug; type FooX = impl Debug; +//~^ ERROR: could not find defining uses trait Foo {} @@ -11,8 +12,8 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { + //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277] () - //~^ ERROR: the trait bound `(): Foo` is not satisfied } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr index ec1b4642d0822..7e24ee644b1ce 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -1,13 +1,19 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference2.rs:14:5 +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/nested-tait-inference2.rs:14:13 | -LL | () - | ^^ the trait `Foo` is not implemented for `()` +LL | fn foo() -> impl Foo { + | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` | = help: the following implementations were found: <() as Foo<()>> <() as Foo> -error: aborting due to previous error +error: could not find defining uses + --> $DIR/nested-tait-inference2.rs:6:13 + | +LL | type FooX = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs deleted file mode 100644 index fbab5470b4f6d..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(type_alias_impl_trait)] -#![allow(dead_code)] - -use std::fmt::Debug; - -type FooX = impl Debug; -//~^ unconstrained opaque type - -trait Foo { } - -impl Foo for () { } - -fn foo() -> impl Foo { - () -} - -fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr deleted file mode 100644 index b1d947a9ccf4e..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: unconstrained opaque type - --> $DIR/nested-tait-inference3.rs:6:13 - | -LL | type FooX = impl Debug; - | ^^^^^^^^^^ - | - = note: `FooX` must be used in combination with a concrete type within the same module - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/nested.rs b/src/test/ui/type-alias-impl-trait/nested.rs deleted file mode 100644 index 6b866be7d173f..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type Foo = impl std::fmt::Debug; -type Bar = impl Trait; - -trait Trait {} - -impl Trait for U {} - -fn bar() -> Bar { - 42 -} - -fn main() { - println!("{:?}", bar()); - //~^ ERROR `Bar` doesn't implement `Debug` -} diff --git a/src/test/ui/type-alias-impl-trait/nested.stderr b/src/test/ui/type-alias-impl-trait/nested.stderr deleted file mode 100644 index cf4d23656e0e1..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0277]: `Bar` doesn't implement `Debug` - --> $DIR/nested.rs:15:22 - | -LL | println!("{:?}", bar()); - | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` - | - = help: the trait `Debug` is not implemented for `Bar` - = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 60b6e1aac6281..6282264d8fee5 100644 --- a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -1,5 +1,5 @@ #![feature(type_alias_impl_trait)] - +// build-pass (FIXME(62277): could be check-pass?) mod my_mod { use std::fmt::Debug; @@ -11,7 +11,7 @@ mod my_mod { } pub fn get_foot() -> Foot { - get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type + get_foo() } } diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr deleted file mode 100644 index fa6ecf68d28f3..0000000000000 --- a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/nested_type_alias_impl_trait.rs:14:9 - | -LL | get_foo() - | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/nested_type_alias_impl_trait.rs:7:21 - | -LL | pub type Foot = impl Debug; - | ^^^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/nested_type_alias_impl_trait.rs:6:20 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs index fed5ac07c901e..8787c023eb0c7 100644 --- a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs @@ -1,7 +1,8 @@ #![feature(type_alias_impl_trait)] -// check-pass + fn main() {} +// don't reveal the concrete type type NoReveal = impl std::fmt::Debug; fn define_no_reveal() -> NoReveal { @@ -9,6 +10,6 @@ fn define_no_reveal() -> NoReveal { } fn no_reveal(x: NoReveal) { - let _: &'static str = x; - let _ = x as &'static str; + let _: &'static str = x; //~ mismatched types + let _ = x as &'static str; //~ non-primitive cast } diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr new file mode 100644 index 0000000000000..b438f84451649 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/never_reveal_concrete_type.rs:13:27 + | +LL | type NoReveal = impl std::fmt::Debug; + | -------------------- the found opaque type +... +LL | let _: &'static str = x; + | ------------ ^ expected `&str`, found opaque type + | | + | expected due to this + | + = note: expected reference `&'static str` + found opaque type `impl Debug` + +error[E0605]: non-primitive cast: `impl Debug` as `&'static str` + --> $DIR/never_reveal_concrete_type.rs:14:13 + | +LL | let _ = x as &'static str; + | ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0605. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs index fa578eced5f2b..1197c7bc58ece 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -1,9 +1,9 @@ // Issue 52985: user code provides no use case that allows a type alias `impl Trait` -// We now emit a 'unconstrained opaque type' error +// We now emit a 'could not find defining uses' error #![feature(type_alias_impl_trait)] -type Foo = impl Copy; //~ unconstrained opaque type +type Foo = impl Copy; //~ could not find defining uses // make compiler happy about using 'Foo' fn bar(x: Foo) -> Foo { diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 009935347e66c..61025e846921e 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/no_inferrable_concrete_type.rs:6:12 | LL | type Foo = impl Copy; | ^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index e691d8781c0f1..67752acb8c9af 100644 --- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -5,10 +5,12 @@ LL | pub type Boo = impl ::std::fmt::Debug; | ---------------------- the found opaque type ... LL | let _: &str = bomp(); - | ^^^^^^ expected `&str`, found opaque type + | ---- ^^^^^^ expected `&str`, found opaque type + | | + | expected due to this | = note: expected reference `&str` - found opaque type `Boo` + found opaque type `impl Debug` error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 @@ -16,11 +18,13 @@ error[E0308]: mismatched types LL | pub type Boo = impl ::std::fmt::Debug; | ---------------------- the expected opaque type ... +LL | fn bomp() -> boo::Boo { + | -------- expected `impl Debug` because of return type LL | "" | ^^ expected opaque type, found `&str` | - = note: expected opaque type `Boo` - found reference `&str` + = note: expected opaque type `impl Debug` + found reference `&'static str` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs index 5b332b8cb6bd8..107cd39457935 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -7,6 +7,11 @@ fn main() {} type Two = impl Debug; //~^ ERROR `T` doesn't implement `Debug` +fn two(t: T) -> Two { + //~^ ERROR non-defining opaque type use in defining scope + (t, 4i8) +} + fn three(t: T) -> Two { (t, 5i8) } diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr index f946dc48a4bf9..08e49845521c6 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -1,11 +1,23 @@ +error: non-defining opaque type use in defining scope + --> $DIR/not_a_defining_use.rs:10:27 + | +LL | fn two(t: T) -> Two { + | ^^^^^^^^^^^ + | +note: used non-generic type `u32` for generic parameter + --> $DIR/not_a_defining_use.rs:7:13 + | +LL | type Two = impl Debug; + | ^ + error: concrete type differs from previous defining opaque type use - --> $DIR/not_a_defining_use.rs:24:1 + --> $DIR/not_a_defining_use.rs:29:1 | LL | fn four(t: T) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, ::Blub)` | note: previous use here - --> $DIR/not_a_defining_use.rs:10:1 + --> $DIR/not_a_defining_use.rs:15:1 | LL | fn three(t: T) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,6 +34,6 @@ help: consider restricting type parameter `T` LL | type Two = impl Debug; | +++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.rs b/src/test/ui/type-alias-impl-trait/self-referential-2.rs deleted file mode 100644 index dc7054da5ec19..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type Foo = impl std::fmt::Debug; -type Bar = impl PartialEq; - -fn bar() -> Bar { - 42_i32 //~ ERROR can't compare `i32` with `Foo` -} - -fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr deleted file mode 100644 index 6997676260dd6..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:7:5 - | -LL | 42_i32 - | ^^^^^^ no implementation for `i32 == Foo` - | - = help: the trait `PartialEq` is not implemented for `i32` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential-3.rs b/src/test/ui/type-alias-impl-trait/self-referential-3.rs deleted file mode 100644 index d40715717d49d..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential-3.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -#![feature(type_alias_impl_trait)] - -type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; - -fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - i -} - -fn main() { - let meh = 42; - let muh = 42; - assert_eq!(bar(&meh), bar(&muh)); -} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.rs b/src/test/ui/type-alias-impl-trait/self-referential-4.rs deleted file mode 100644 index 697ec56825a9c..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential-4.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; - -fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - i //~ ERROR can't compare `&i32` with `Bar<'b, 'static>` -} - -type Foo<'a, 'b> = impl PartialEq> + std::fmt::Debug; - -fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { - i //~ ERROR can't compare `&i32` with `Foo<'static, 'b>` -} - -type Moo<'a, 'b> = impl PartialEq> + std::fmt::Debug; - -fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { - i //~ ERROR can't compare `&i32` with `Moo<'static, 'a>` -} - -fn main() { - let meh = 42; - let muh = 69; - assert_eq!(bar(&meh), bar(&meh)); -} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr deleted file mode 100644 index 4a6ee2f9279d1..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0277]: can't compare `&i32` with `Bar<'b, 'static>` - --> $DIR/self-referential-4.rs:6:5 - | -LL | i - | ^ no implementation for `&i32 == Bar<'b, 'static>` - | - = help: the trait `PartialEq>` is not implemented for `&i32` - -error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` - --> $DIR/self-referential-4.rs:12:5 - | -LL | i - | ^ no implementation for `&i32 == Foo<'static, 'b>` - | - = help: the trait `PartialEq>` is not implemented for `&i32` - -error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` - --> $DIR/self-referential-4.rs:18:5 - | -LL | i - | ^ no implementation for `&i32 == Moo<'static, 'a>` - | - = help: the trait `PartialEq>` is not implemented for `&i32` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential.rs b/src/test/ui/type-alias-impl-trait/self-referential.rs deleted file mode 100644 index 4974ac72dad18..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(type_alias_impl_trait)] - -type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; - -fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - i //~ ERROR can't compare `&i32` with `Bar<'b, 'a>` -} - -type Foo<'a, 'b> = (i32, impl PartialEq> + std::fmt::Debug); - -fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { - (42, i) //~ ERROR can't compare `&i32` with `(i32, &i32)` -} - -type Moo<'a, 'b> = (i32, impl PartialEq> + std::fmt::Debug); - -fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { - (42, i) //~ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})` -} - -fn main() { - let meh = 42; - let muh = 69; - assert_eq!(bar(&meh), bar(&meh)); -} diff --git a/src/test/ui/type-alias-impl-trait/self-referential.stderr b/src/test/ui/type-alias-impl-trait/self-referential.stderr deleted file mode 100644 index 0626e6be0d5a5..0000000000000 --- a/src/test/ui/type-alias-impl-trait/self-referential.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0277]: can't compare `&i32` with `Bar<'b, 'a>` - --> $DIR/self-referential.rs:6:5 - | -LL | i - | ^ no implementation for `&i32 == Bar<'b, 'a>` - | - = help: the trait `PartialEq>` is not implemented for `&i32` - -error[E0277]: can't compare `&i32` with `(i32, &i32)` - --> $DIR/self-referential.rs:12:10 - | -LL | (42, i) - | ^ no implementation for `&i32 == (i32, &i32)` - | - = help: the trait `PartialEq<(i32, &i32)>` is not implemented for `&i32` - -error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})` - --> $DIR/self-referential.rs:18:10 - | -LL | (42, i) - | ^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})` - | - = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.rs b/src/test/ui/type-alias-impl-trait/static-const-types.rs index 748a279e43989..86b685022b20e 100644 --- a/src/test/ui/type-alias-impl-trait/static-const-types.rs +++ b/src/test/ui/type-alias-impl-trait/static-const-types.rs @@ -1,13 +1,13 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -// check-pass +// FIXME: This should compile, but it currently doesn't use std::fmt::Debug; -type Foo = impl Debug; +type Foo = impl Debug; //~ ERROR could not find defining uses -static FOO1: Foo = 22_u32; -const FOO2: Foo = 22_u32; +static FOO1: Foo = 22_u32; //~ ERROR mismatched types +const FOO2: Foo = 22_u32; //~ ERROR mismatched types fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.stderr b/src/test/ui/type-alias-impl-trait/static-const-types.stderr new file mode 100644 index 0000000000000..6f4c2944f7285 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/static-const-types.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/static-const-types.rs:10:20 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +LL | +LL | static FOO1: Foo = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `impl Debug` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/static-const-types.rs:11:19 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | const FOO2: Foo = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `impl Debug` + found type `u32` + +error: could not find defining uses + --> $DIR/static-const-types.rs:8:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs index cab742d23f57d..51a7b6454c35e 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -11,9 +11,9 @@ const fn leak_free() -> Bar { const LEAK_FREE: Bar = leak_free(); fn leak_free_test() { - match LEAK_FREE { + match todo!() { LEAK_FREE => (), - //~^ `Bar` cannot be used in patterns + //~^ `impl Send` cannot be used in patterns _ => (), } } diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr index aacc0cc7aa69b..7e41b374452a3 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,4 +1,4 @@ -error: `Bar` cannot be used in patterns +error: `impl Send` cannot be used in patterns --> $DIR/structural-match-no-leak.rs:15:9 | LL | LEAK_FREE => (), diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs index c8825c68e33cc..73558d39ad561 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match.rs @@ -12,9 +12,9 @@ const fn value() -> Foo { const VALUE: Foo = value(); fn test() { - match VALUE { + match todo!() { VALUE => (), - //~^ `Foo` cannot be used in patterns + //~^ `impl Send` cannot be used in patterns _ => (), } } diff --git a/src/test/ui/type-alias-impl-trait/structural-match.stderr b/src/test/ui/type-alias-impl-trait/structural-match.stderr index 28ae9c212d979..b43f2148dea5e 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match.stderr @@ -1,4 +1,4 @@ -error: `Foo` cannot be used in patterns +error: `impl Send` cannot be used in patterns --> $DIR/structural-match.rs:16:9 | LL | VALUE => (), diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs index 5630e036be34b..1a8113848f923 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -1,11 +1,13 @@ #![feature(type_alias_impl_trait)] -// check-pass + // Ensures that `const` items can constrain an opaque `impl Trait`. use std::fmt::Debug; pub type Foo = impl Debug; +//~^ ERROR could not find defining uses const _FOO: Foo = 5; +//~^ ERROR mismatched types [E0308] fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr new file mode 100644 index 0000000000000..e2567e87ac676 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/type-alias-impl-trait-const.rs:10:19 + | +LL | pub type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | const _FOO: Foo = 5; + | ^ expected opaque type, found integer + | + = note: expected opaque type `impl Debug` + found type `{integer}` + +error: could not find defining uses + --> $DIR/type-alias-impl-trait-const.rs:7:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs index e5e7fb677ede9..c009952eab750 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs @@ -1,7 +1,7 @@ #![feature(type_alias_impl_trait)] type Foo = impl Fn() -> Foo; -//~^ ERROR: unconstrained opaque type +//~^ ERROR: could not find defining uses fn crash(x: Foo) -> Foo { x diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr index a770eeac39b7d..726f4ea6e00f7 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12 | LL | type Foo = impl Fn() -> Foo; | ^^^^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs index 7c7a1b405bcdc..f3898bca64b9b 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs @@ -5,7 +5,7 @@ pub trait Bar { } type Foo = impl Bar; -//~^ ERROR: unconstrained opaque type +//~^ ERROR: could not find defining uses fn crash(x: Foo) -> Foo { x diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr index 3f3699ce5324a..3947cc4d27055 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr @@ -1,10 +1,8 @@ -error: unconstrained opaque type +error: could not find defining uses --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12 | LL | type Foo = impl Bar; | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs index 70c2ee4278ca2..d2c8c1f63df1c 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -1,4 +1,4 @@ -// check-pass +// run-pass #![allow(dead_code)] #![allow(unused_assignments)] diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs deleted file mode 100644 index 67f56bcde939a..0000000000000 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs +++ /dev/null @@ -1,84 +0,0 @@ -// check-pass - -#![allow(dead_code)] -#![allow(unused_assignments)] -#![allow(unused_variables)] -#![feature(type_alias_impl_trait)] - -fn main() { - assert_eq!(foo().to_string(), "foo"); - assert_eq!(bar1().to_string(), "bar1"); - assert_eq!(bar2().to_string(), "bar2"); - let mut x = bar1(); - x = bar2(); - assert_eq!(my_iter(42u8).collect::>(), vec![42u8]); -} - -use defining_use_scope::*; - -mod defining_use_scope { - // single definition - pub type Foo = impl std::fmt::Display; - - pub fn foo() -> Foo { - "foo" - } - - // two definitions - pub type Bar = impl std::fmt::Display; - - pub fn bar1() -> Bar { - "bar1" - } - - pub fn bar2() -> Bar { - "bar2" - } - - pub type MyIter = impl Iterator; - - pub fn my_iter(t: T) -> MyIter { - std::iter::once(t) - } - - fn my_iter2(t: T) -> MyIter { - std::iter::once(t) - } - - // param names should not have an effect! - fn my_iter3(u: U) -> MyIter { - std::iter::once(u) - } - - // param position should not have an effect! - fn my_iter4(_: U, v: V) -> MyIter { - std::iter::once(v) - } - - // param names should not have an effect! - type MyOtherIter = impl Iterator; - - fn my_other_iter(u: U) -> MyOtherIter { - std::iter::once(u) - } - - trait Trait {} - type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; - - fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { - t - } - - mod pass_through { - pub type Passthrough = impl Sized + 'static; - - fn define_passthrough(t: T) -> Passthrough { - t - } - } - - fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { - x - } - -} diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs index 4e9d1788b94d8..7f8e6127cca3b 100644 --- a/src/test/ui/type-alias-impl-trait/type_of_a_let.rs +++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs @@ -1,20 +1,27 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +// FIXME This should compile, but it currently doesn't + use std::fmt::Debug; type Foo = impl Debug; +//~^ ERROR: could not find defining uses fn foo1() -> u32 { let x: Foo = 22_u32; + //~^ ERROR: mismatched types [E0308] x + //~^ ERROR: mismatched types [E0308] } fn foo2() -> u32 { let x: Foo = 22_u32; + //~^ ERROR: mismatched types [E0308] let y: Foo = x; - same_type((x, y)); //~ ERROR use of moved value - y //~ ERROR use of moved value + same_type((x, y)); + y + //~^ ERROR: mismatched types [E0308] } fn same_type(x: (T, T)) {} diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr index 1dabe4586c5b9..cac8d6841afda 100644 --- a/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr +++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr @@ -1,23 +1,67 @@ -error[E0382]: use of moved value: `x` - --> $DIR/type_of_a_let.rs:16:16 +error[E0308]: mismatched types + --> $DIR/type_of_a_let.rs:12:18 | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... LL | let x: Foo = 22_u32; - | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait -LL | let y: Foo = x; - | - value moved here -LL | same_type((x, y)); - | ^ value used here after move + | --- ^^^^^^ expected opaque type, found `u32` + | | + | expected due to this + | + = note: expected opaque type `impl Debug` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/type_of_a_let.rs:14:5 + | +LL | type Foo = impl Debug; + | ---------- the found opaque type +... +LL | fn foo1() -> u32 { + | --- expected `u32` because of return type +... +LL | x + | ^ expected `u32`, found opaque type + | + = note: expected type `u32` + found opaque type `impl Debug` -error[E0382]: use of moved value: `y` - --> $DIR/type_of_a_let.rs:17:5 +error[E0308]: mismatched types + --> $DIR/type_of_a_let.rs:19:18 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | let x: Foo = 22_u32; + | --- ^^^^^^ expected opaque type, found `u32` + | | + | expected due to this | -LL | let y: Foo = x; - | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait -LL | same_type((x, y)); - | - value moved here + = note: expected opaque type `impl Debug` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/type_of_a_let.rs:23:5 + | +LL | type Foo = impl Debug; + | ---------- the found opaque type +... +LL | fn foo2() -> u32 { + | --- expected `u32` because of return type +... LL | y - | ^ value used here after move + | ^ expected `u32`, found opaque type + | + = note: expected type `u32` + found opaque type `impl Debug` + +error: could not find defining uses + --> $DIR/type_of_a_let.rs:8:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0382`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 5407b5e8ed93e..7512039a480bb 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -32,7 +32,6 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: | ty::PredicateKind::Projection(_) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::OpaqueType(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),