Remove opaque type obligation and just register opaque types as they are encountered.

This also registers obligations for the hidden type immediately.
This commit is contained in:
Oli Scherer 2022-02-17 13:28:06 +00:00
parent 86e1860495
commit 1163aa7e72
60 changed files with 290 additions and 311 deletions

View File

@ -2646,7 +2646,7 @@ impl NormalizeLocation for Location {
pub(super) struct InstantiateOpaqueType<'tcx> { pub(super) struct InstantiateOpaqueType<'tcx> {
pub base_universe: Option<ty::UniverseIndex>, pub base_universe: Option<ty::UniverseIndex>,
pub region_constraints: Option<RegionConstraintData<'tcx>>, pub region_constraints: Option<RegionConstraintData<'tcx>>,
pub obligation: PredicateObligation<'tcx>, pub obligations: Vec<PredicateObligation<'tcx>>,
} }
impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
@ -2660,7 +2660,7 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> { fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
let (mut output, region_constraints) = scrape_region_constraints(infcx, || { let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
Ok(InferOk { value: (), obligations: vec![self.obligation.clone()] }) Ok(InferOk { value: (), obligations: self.obligations.clone() })
})?; })?;
self.region_constraints = Some(region_constraints); self.region_constraints = Some(region_constraints);
output.error_info = Some(self); output.error_info = Some(self);

View File

@ -2,6 +2,7 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{self, Const, Ty}; use rustc_middle::ty::{self, Const, Ty};
use rustc_span::Span; use rustc_span::Span;
@ -136,7 +137,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
true true
} }
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) { fn register_opaque_type(
&mut self,
a: Ty<'tcx>,
b: Ty<'tcx>,
a_is_expected: bool,
) -> Result<(), TypeError<'tcx>> {
let param_env = self.param_env(); let param_env = self.param_env();
let span = self.span(); let span = self.span();
let def_id = self.type_checker.body.source.def_id().expect_local(); let def_id = self.type_checker.body.source.def_id().expect_local();
@ -147,18 +153,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
self.locations, self.locations,
self.category, self.category,
InstantiateOpaqueType { InstantiateOpaqueType {
obligation: self.type_checker.infcx.opaque_ty_obligation( obligations: self
a, .type_checker
b, .infcx
a_is_expected, .handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
param_env, .obligations,
cause,
),
// These fields are filled in during exectuion of the operation // These fields are filled in during exectuion of the operation
base_universe: None, base_universe: None,
region_constraints: None, region_constraints: None,
}, },
) )
.unwrap(); .unwrap();
Ok(())
} }
} }

View File

@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::arena::ArenaAllocatable; use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
@ -499,7 +500,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
for &(a, b) in &query_response.value.opaque_types { for &(a, b) in &query_response.value.opaque_types {
let a = substitute_value(self.tcx, &result_subst, a); let a = substitute_value(self.tcx, &result_subst, a);
let b = substitute_value(self.tcx, &result_subst, b); let b = substitute_value(self.tcx, &result_subst, b);
obligations.extend(self.handle_opaque_type(a, b, cause, param_env)?.obligations); obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
} }
Ok(InferOk { value: result_subst, obligations }) Ok(InferOk { value: result_subst, obligations })
@ -718,13 +719,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
true true
} }
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) { fn register_opaque_type(
self.obligations.push(self.infcx.opaque_ty_obligation( &mut self,
a, a: Ty<'tcx>,
b, b: Ty<'tcx>,
a_is_expected, a_is_expected: bool,
self.param_env, ) -> Result<(), TypeError<'tcx>> {
self.cause.clone(), self.obligations.extend(
)); self.infcx
.handle_opaque_type(a, b, a_is_expected, &self.cause, self.param_env)?
.obligations,
);
Ok(())
} }
} }

View File

@ -98,13 +98,17 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
if self.fields.define_opaque_types && did.is_local() => if self.fields.define_opaque_types && did.is_local() =>
{ {
self.fields.obligations.push(infcx.opaque_ty_obligation( self.fields.obligations.extend(
a, infcx
b, .handle_opaque_type(
self.a_is_expected(), a,
self.param_env(), b,
self.fields.trace.cause.clone(), self.a_is_expected(),
)); &self.fields.trace.cause,
self.param_env(),
)?
.obligations,
);
} }
_ => { _ => {

View File

@ -111,13 +111,11 @@ where
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
if this.define_opaque_types() && did.is_local() => if this.define_opaque_types() && did.is_local() =>
{ {
this.add_obligations(vec![infcx.opaque_ty_obligation( this.add_obligations(
a, infcx
b, .handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
this.a_is_expected(), .obligations,
this.param_env(), );
this.cause().clone(),
)]);
Ok(a) Ok(a)
} }

View File

@ -91,7 +91,12 @@ pub trait TypeRelatingDelegate<'tcx> {
); );
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>); fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool); fn register_opaque_type(
&mut self,
a: Ty<'tcx>,
b: Ty<'tcx>,
a_is_expected: bool,
) -> Result<(), TypeError<'tcx>>;
/// Creates a new universe index. Used when instantiating placeholders. /// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex; fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -590,7 +595,7 @@ where
(_, &ty::Opaque(..)) => (generalize(a, true)?, b), (_, &ty::Opaque(..)) => (generalize(a, true)?, b),
_ => unreachable!(), _ => unreachable!(),
}; };
self.delegate.register_opaque_type(a, b, true); self.delegate.register_opaque_type(a, b, true)?;
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated"); trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
Ok(a) Ok(a)
} }

View File

@ -1,5 +1,5 @@
use crate::infer::{InferCtxt, InferOk}; use crate::infer::{InferCtxt, InferOk};
use crate::traits::{self, PredicateObligation}; use crate::traits;
use hir::def_id::{DefId, LocalDefId}; use hir::def_id::{DefId, LocalDefId};
use hir::OpaqueTyOrigin; use hir::OpaqueTyOrigin;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -42,25 +42,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&self, &self,
a: Ty<'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>, b: Ty<'tcx>,
a_is_expected: bool,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> InferResult<'tcx, ()> { ) -> InferResult<'tcx, ()> {
if a.references_error() || b.references_error() { if a.references_error() || b.references_error() {
return Ok(InferOk { value: (), obligations: vec![] }); return Ok(InferOk { value: (), obligations: vec![] });
} }
if self.defining_use_anchor.is_some() { let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Opaque(def_id, substs) => { ty::Opaque(def_id, substs) => {
if let ty::Opaque(did2, _) = *b.kind() { if let ty::Opaque(did2, _) = *b.kind() {
// We could accept this, but there are various ways to handle this situation, and we don't // 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 // want to make a decision on it right now. Likely this case is so super rare anyway, that
// no one encounters it in practice. // no one encounters it in practice.
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`, // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
// where it is of no concern, so we only check for TAITs. // where it is of no concern, so we only check for TAITs.
if let Some(OpaqueTyOrigin::TyAlias) = if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
self.opaque_type_origin(did2, cause.span) {
{ self.tcx
self.tcx
.sess .sess
.struct_span_err( .struct_span_err(
cause.span, cause.span,
@ -76,13 +76,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"opaque type being used as hidden type", "opaque type being used as hidden type",
) )
.emit(); .emit();
}
} }
Some(self.register_hidden_type( }
OpaqueTypeKey { def_id, substs }, Some(self.register_hidden_type(
cause.clone(), OpaqueTypeKey { def_id, substs },
param_env, cause.clone(),
b, param_env,
b,
if self.defining_use_anchor.is_some() {
// Check that this is `impl Trait` type is // Check that this is `impl Trait` type is
// declared by `parent_def_id` -- i.e., one whose // declared by `parent_def_id` -- i.e., one whose
// value we are inferring. At present, this is // value we are inferring. At present, this is
@ -117,47 +118,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// let x = || foo(); // returns the Opaque assoc with `foo` // let x = || foo(); // returns the Opaque assoc with `foo`
// } // }
// ``` // ```
self.opaque_type_origin(def_id, cause.span)?, self.opaque_type_origin(def_id, cause.span)?
)) } else {
} self.opaque_ty_origin_unchecked(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.kind(), b.kind())
),
Err(e) => Err(e),
}
} }
_ => None,
};
if let Some(res) = process(a, b) {
res
} else if let Some(res) = process(b, a) {
res
} else { } else {
let (opaque_type, hidden_ty) = match (a.kind(), b.kind()) { // Rerun equality check, but this time error out due to
(ty::Opaque(..), _) => (a, b), // different types.
(_, ty::Opaque(..)) => (b, a), match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
types => span_bug!( Ok(_) => span_bug!(
cause.span, cause.span,
"opaque type obligations only work for opaque types: {:#?}", "opaque types are never equal to anything but themselves: {:#?}",
types (a.kind(), b.kind())
), ),
}; Err(e) => Err(e),
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![] }),
} }
} }
} }
@ -363,22 +345,6 @@ 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")] #[instrument(skip(self), level = "trace")]
pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option<OpaqueTyOrigin> { pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option<OpaqueTyOrigin> {
let def_id = opaque_def_id.as_local()?; let def_id = opaque_def_id.as_local()?;

View File

@ -28,7 +28,6 @@ pub fn explicit_outlives_bounds<'tcx>(
| ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None, | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
Some(OutlivesBound::RegionSubRegion(r_b, r_a)) Some(OutlivesBound::RegionSubRegion(r_b, r_a))

View File

@ -146,13 +146,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
(_, &ty::Opaque(..)) => (generalize(a, false)?, b), (_, &ty::Opaque(..)) => (generalize(a, false)?, b),
_ => unreachable!(), _ => unreachable!(),
}; };
self.fields.obligations.push(infcx.opaque_ty_obligation( self.fields.obligations.extend(
a, infcx
b, .handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
true, .obligations,
self.param_env(), );
self.fields.trace.cause.clone(),
));
Ok(a) Ok(a)
} }

View File

@ -167,9 +167,6 @@ impl<'tcx> Elaborator<'tcx> {
// Currently, we do not elaborate WF predicates, // Currently, we do not elaborate WF predicates,
// although we easily could. // although we easily could.
} }
ty::PredicateKind::OpaqueType(..) => {
todo!("{:#?}", obligation)
}
ty::PredicateKind::ObjectSafe(..) => { ty::PredicateKind::ObjectSafe(..) => {
// Currently, we do not elaborate object-safe // Currently, we do not elaborate object-safe
// predicates. // predicates.

View File

@ -1675,7 +1675,6 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
Coerce(..) | Coerce(..) |
ConstEvaluatable(..) | ConstEvaluatable(..) |
ConstEquate(..) | ConstEquate(..) |
OpaqueType(..) |
TypeWellFormedFromEnv(..) => continue, TypeWellFormedFromEnv(..) => continue,
}; };
if predicate.is_global() { if predicate.is_global() {

View File

@ -265,10 +265,6 @@ impl FlagComputation {
ty::PredicateKind::TypeWellFormedFromEnv(ty) => { ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
self.add_ty(ty); self.add_ty(ty);
} }
ty::PredicateKind::OpaqueType(opaque, ty) => {
self.add_ty(opaque);
self.add_ty(ty);
}
} }
} }

View File

@ -632,11 +632,6 @@ pub enum PredicateKind<'tcx> {
/// ///
/// Only used for Chalk. /// Only used for Chalk.
TypeWellFormedFromEnv(Ty<'tcx>), 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 /// The crate outlives map is computed during typeck and contains the
@ -1004,7 +999,6 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::TypeOutlives(..) | PredicateKind::TypeOutlives(..)
| PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEvaluatable(..)
| PredicateKind::ConstEquate(..) | PredicateKind::ConstEquate(..)
| PredicateKind::OpaqueType(..)
| PredicateKind::TypeWellFormedFromEnv(..) => None, | PredicateKind::TypeWellFormedFromEnv(..) => None,
} }
} }
@ -1023,7 +1017,6 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::ClosureKind(..) | PredicateKind::ClosureKind(..)
| PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEvaluatable(..)
| PredicateKind::ConstEquate(..) | PredicateKind::ConstEquate(..)
| PredicateKind::OpaqueType(..)
| PredicateKind::TypeWellFormedFromEnv(..) => None, | PredicateKind::TypeWellFormedFromEnv(..) => None,
} }
} }

View File

@ -2654,9 +2654,6 @@ define_print_and_forward_display! {
ty::PredicateKind::TypeWellFormedFromEnv(ty) => { ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
p!("the type `", print(ty), "` is found in the environment") p!("the type `", print(ty), "` is found in the environment")
} }
ty::PredicateKind::OpaqueType(a, b) => {
p!("opaque type assigment with `", print(a), "` == `", print(b) ,"`")
}
} }
} }

View File

@ -198,9 +198,6 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
ty::PredicateKind::TypeWellFormedFromEnv(ty) => { ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
write!(f, "TypeWellFormedFromEnv({:?})", ty) write!(f, "TypeWellFormedFromEnv({:?})", ty)
} }
ty::PredicateKind::OpaqueType(a, b) => {
write!(f, "OpaqueType({:?}, {:?})", a.kind(), b.kind())
}
} }
} }
} }
@ -474,9 +471,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
ty::PredicateKind::TypeWellFormedFromEnv(ty) => { ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv) tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv)
} }
ty::PredicateKind::OpaqueType(opaque, ty) => {
Some(ty::PredicateKind::OpaqueType(tcx.lift(opaque)?, tcx.lift(ty)?))
}
} }
} }
} }

View File

@ -352,7 +352,6 @@ crate fn required_region_bounds<'tcx>(
| ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None, | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
// Search for a bound of the form `erased_self_ty // Search for a bound of the form `erased_self_ty

View File

@ -865,7 +865,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
| ty::PredicateKind::Subtype(..) | ty::PredicateKind::Subtype(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {} | ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
}; };
} }

View File

@ -797,10 +797,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
span, span,
"TypeWellFormedFromEnv predicate should only exist in the environment" "TypeWellFormedFromEnv predicate should only exist in the environment"
), ),
ty::PredicateKind::OpaqueType(..) => {
todo!("{:#?}", obligation);
}
} }
} }

View File

@ -413,9 +413,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
ty::PredicateKind::TypeWellFormedFromEnv(..) => { ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk") bug!("TypeWellFormedFromEnv is only used for Chalk")
} }
ty::PredicateKind::OpaqueType(..) => {
todo!("{:#?}", obligation);
}
}, },
Some(pred) => match pred { Some(pred) => match pred {
ty::PredicateKind::Trait(data) => { ty::PredicateKind::Trait(data) => {
@ -665,20 +662,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
ty::PredicateKind::TypeWellFormedFromEnv(..) => { ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk") 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,
)),
}
}
}, },
} }
} }

View File

@ -313,7 +313,6 @@ fn predicate_references_self<'tcx>(
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None, | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
} }
} }
@ -345,7 +344,6 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
| ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => false, | ty::PredicateKind::TypeWellFormedFromEnv(..) => false,
} }
}) })

View File

@ -673,19 +673,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::PredicateKind::TypeWellFormedFromEnv(..) => { ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for chalk") 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),
}
}
} }
}); });

View File

@ -148,10 +148,6 @@ pub fn predicate_obligations<'a, 'tcx>(
wf.compute(c1.into()); wf.compute(c1.into());
wf.compute(c2.into()); wf.compute(c2.into());
} }
ty::PredicateKind::OpaqueType(opaque, ty) => {
wf.compute(opaque.into());
wf.compute(ty.into());
}
ty::PredicateKind::TypeWellFormedFromEnv(..) => { ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk") bug!("TypeWellFormedFromEnv is only used for Chalk")
} }

View File

@ -110,7 +110,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
| ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..) | ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate), | ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
}; };
@ -203,7 +202,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
ty::PredicateKind::ClosureKind(..) ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::ConstEquate(..) => { | ty::PredicateKind::ConstEquate(..) => {
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
} }
@ -623,7 +621,6 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => { | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("unexpected predicate {}", &self) bug!("unexpected predicate {}", &self)
} }
@ -753,7 +750,6 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => { | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("unexpected predicate {}", &self) bug!("unexpected predicate {}", &self)
} }

View File

@ -105,7 +105,6 @@ fn compute_implied_outlives_bounds<'tcx>(
| ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![], | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![],
ty::PredicateKind::WellFormed(arg) => { ty::PredicateKind::WellFormed(arg) => {
wf_args.push(arg); wf_args.push(arg);

View File

@ -69,7 +69,6 @@ fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true, | ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
} }
} }

View File

@ -661,13 +661,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span, span,
}); });
let cause = ObligationCause::misc(span, body_id); let cause = ObligationCause::misc(span, body_id);
self.register_predicates(vec![self.infcx.opaque_ty_obligation( self.register_predicates(
ty, self.infcx
ty_var, .handle_opaque_type(ty, ty_var, true, &cause, self.param_env)
true, .unwrap()
self.param_env, .obligations,
cause, );
)]);
ty_var ty_var
} }
_ => ty, _ => ty,

View File

@ -732,7 +732,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// inference variable. // inference variable.
ty::PredicateKind::ClosureKind(..) => None, ty::PredicateKind::ClosureKind(..) => None,
ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::OpaqueType(..) => None,
} }
}) })
.filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root)) .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))

View File

@ -858,7 +858,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
| ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None, | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
} }
}); });

View File

@ -425,7 +425,6 @@ fn trait_predicate_kind<'tcx>(
| ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None, | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
} }
} }

View File

@ -59,7 +59,6 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
| ty::PredicateKind::Coerce(..) | ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (), | ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
} }
} }

View File

@ -306,7 +306,6 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
| ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"), | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
} }
} }

View File

@ -22,6 +22,7 @@ async fn suggest_await_in_async_fn_return() {
dummy() dummy()
//~^ ERROR mismatched types [E0308] //~^ ERROR mismatched types [E0308]
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
//~| HELP consider using a semicolon here
//~| SUGGESTION .await //~| SUGGESTION .await
} }

View File

@ -33,9 +33,13 @@ help: consider `await`ing on the `Future`
| |
LL | dummy().await LL | dummy().await
| ++++++ | ++++++
help: consider using a semicolon here
|
LL | dummy();
| +
error[E0308]: `if` and `else` have incompatible types 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 { LL | let _x = if true {
| ______________- | ______________-
@ -49,20 +53,15 @@ LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
note: while checking the return type of the `async fn` = note: expected type `impl Future<Output = ()>`
--> $DIR/suggest-missing-await.rs:18:18 found unit type `()`
|
LL | async fn dummy() {}
| ^ checked the `Output` of this `async fn`, expected opaque type
= note: expected opaque type `impl Future<Output = ()>`
found unit type `()`
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | dummy().await LL | dummy().await
| ++++++ | ++++++
error[E0308]: `match` arms have incompatible types 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 { LL | let _x = match 0usize {
| ______________- | ______________-
@ -90,7 +89,7 @@ LL ~ 1 => dummy().await,
| |
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:52:9 --> $DIR/suggest-missing-await.rs:53:9
| |
LL | let _x = match dummy() { LL | let _x = match dummy() {
| ------- this expression has type `impl Future<Output = ()>` | ------- this expression has type `impl Future<Output = ()>`
@ -110,7 +109,7 @@ LL | let _x = match dummy().await {
| ++++++ | ++++++
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:66:9 --> $DIR/suggest-missing-await.rs:67:9
| |
LL | match dummy_result() { LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>` | -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@ -119,7 +118,7 @@ LL | Ok(_) => {}
| ^^^^^ expected opaque type, found enum `Result` | ^^^^^ expected opaque type, found enum `Result`
| |
note: while checking the return type of the `async fn` 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<(), ()> { LL | async fn dummy_result() -> Result<(), ()> {
| ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type | ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
@ -131,7 +130,7 @@ LL | match dummy_result().await {
| ++++++ | ++++++
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:68:9 --> $DIR/suggest-missing-await.rs:69:9
| |
LL | match dummy_result() { LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>` | -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@ -140,7 +139,7 @@ LL | Err(_) => {}
| ^^^^^^ expected opaque type, found enum `Result` | ^^^^^^ expected opaque type, found enum `Result`
| |
note: while checking the return type of the `async fn` 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<(), ()> { LL | async fn dummy_result() -> Result<(), ()> {
| ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type | ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type

View File

@ -18,5 +18,5 @@ fn main() {
// this is an `*mut fmt::Debug` in practice // this is an `*mut fmt::Debug` in practice
let mut b_raw = Box::into_raw(b); let mut b_raw = Box::into_raw(b);
// ... and they should not be mixable // ... and they should not be mixable
b_raw = f_raw as *mut _; //~ ERROR mismatched types b_raw = f_raw as *mut _; //~ ERROR is invalid
} }

View File

@ -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 --> $DIR/casts-differing-anon.rs:21:13
| |
LL | fn foo() -> Box<impl fmt::Debug+?Sized> {
| ---------------------- the found opaque type
...
LL | fn bar() -> Box<impl fmt::Debug+?Sized> {
| ---------------------- the expected opaque type
...
LL | b_raw = f_raw as *mut _; 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>) = note: vtable kinds may not match
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
error: aborting due to previous error 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`.

View File

@ -2,6 +2,7 @@
fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
//~^ ERROR `()` is not an iterator //~^ ERROR `()` is not an iterator
//~| ERROR `()` is not an iterator
} }
fn main() {} fn main() {}

View File

@ -6,6 +6,18 @@ LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
| |
= help: the trait `Iterator` is not implemented for `()` = help: the trait `Iterator` is not implemented for `()`
error: aborting due to previous error error[E0277]: `()` is not an iterator
--> $DIR/conservative_impl_trait.rs:3:60
|
LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
| ____________________________________________________________^
LL | |
LL | |
LL | | }
| |_^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,19 @@
// check-pass
use std::path::Path;
use std::ffi::OsStr;
use std::ops::Deref;
fn frob(path: &str) -> impl Deref<Target = Path> + '_ {
OsStr::new(path).as_ref()
}
fn open_parent<'path>(_path: &'path Path) {
todo!()
}
fn main() {
let old_path = frob("hello");
open_parent(&old_path);
}

View File

@ -42,4 +42,4 @@ fn muh3() -> Result<(), impl std::fmt::Debug> {
Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied
} }
fn main() {} fn main() {}

View File

@ -15,7 +15,9 @@ LL | fn hide<T: Foo>(x: T) -> impl Foo {
| -------- the found opaque type | -------- the found opaque type
... ...
LL | let _: u32 = hide(0_u32); LL | let _: u32 = hide(0_u32);
| ^^^^^^^^^^^ expected `u32`, found opaque type | --- ^^^^^^^^^^^ expected `u32`, found opaque type
| |
| expected due to this
| |
= note: expected type `u32` = note: expected type `u32`
found opaque type `impl Foo` found opaque type `impl Foo`

View File

@ -28,7 +28,7 @@ fn ham() -> Foo {
fn oof() -> impl std::fmt::Debug { fn oof() -> impl std::fmt::Debug {
let mut bar = ham(); let mut bar = ham();
let func = bar.next().unwrap(); let func = bar.next().unwrap();
return func(&"oof"); //~^^^ ERROR opaque type's hidden type cannot be another opaque type return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
} }
fn main() { fn main() {

View File

@ -13,15 +13,10 @@ LL | Some(Box::new(quux))
found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>` found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>`
error: opaque type's hidden type cannot be another opaque type from the same scope error: opaque type's hidden type cannot be another opaque type from the same scope
--> $DIR/issue-70877.rs:28:34 --> $DIR/issue-70877.rs:31:12
| |
LL | fn oof() -> impl std::fmt::Debug { LL | return func(&"oof");
| __________________________________^ | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
LL | | let mut bar = ham();
LL | | let func = bar.next().unwrap();
LL | | return func(&"oof");
LL | | }
| |_^ one of the two opaque types used here has to be outside its defining scope
| |
note: opaque type whose hidden type is being assigned note: opaque type whose hidden type is being assigned
--> $DIR/issue-70877.rs:28:13 --> $DIR/issue-70877.rs:28:13

View File

@ -26,4 +26,4 @@ fn run<F>(f: F)
fn main() { fn main() {
run(|_| {}); run(|_| {});
} }

View File

@ -27,4 +27,4 @@ pub fn direct() -> Result<(), impl Debug> {
Err(Target) Err(Target)
} }
fn main() {} fn main() {}

View File

@ -21,6 +21,7 @@ mod b {
impl PartialEq<(Foo, i32)> for Bar { impl PartialEq<(Foo, i32)> for Bar {
fn eq(&self, _other: &(Bar, i32)) -> bool { fn eq(&self, _other: &(Bar, i32)) -> bool {
//~^ ERROR impl has stricter requirements than trait
true true
} }
} }

View File

@ -14,5 +14,12 @@ LL | type Foo = impl PartialEq<(Foo, i32)>;
| |
= note: `Foo` must be used in combination with a concrete type within the same module = note: `Foo` must be used in combination with a concrete type within the same module
error: aborting due to 2 previous errors error[E0276]: impl has stricter requirements than trait
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:23:9
|
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `b::Bar: PartialEq<(b::Bar, i32)>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0276`.

View File

@ -1,6 +1,6 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
type A = impl Foo; type A = impl Foo; //~ ERROR unconstrained opaque type
type B = impl Foo; type B = impl Foo;
trait Foo {} trait Foo {}

View File

@ -1,3 +1,11 @@
error: unconstrained opaque type
--> $DIR/two_tait_defining_each_other2.rs:3:10
|
LL | type A = impl Foo;
| ^^^^^^^^
|
= note: `A` must be used in combination with a concrete type within the same module
error: opaque type's hidden type cannot be another opaque type from the same scope error: opaque type's hidden type cannot be another opaque type from the same scope
--> $DIR/two_tait_defining_each_other2.rs:9:5 --> $DIR/two_tait_defining_each_other2.rs:9:5
| |
@ -15,5 +23,5 @@ note: opaque type being used as hidden type
LL | type A = impl Foo; LL | type A = impl Foo;
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to previous error error: aborting due to 2 previous errors

View File

@ -1,5 +1,6 @@
fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
//~^ ERROR `u32` is not a future //~^ ERROR `u32` is not a future
//~| ERROR `u32` is not a future
*x *x
} }

View File

@ -1,5 +1,5 @@
error[E0425]: cannot find value `u` in this scope error[E0425]: cannot find value `u` in this scope
--> $DIR/issues-71798.rs:7:24 --> $DIR/issues-71798.rs:8:24
| |
LL | let _ = test_ref & u; LL | let _ = test_ref & u;
| ^ not found in this scope | ^ not found in this scope
@ -13,7 +13,21 @@ LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
= help: the trait `Future` is not implemented for `u32` = help: the trait `Future` is not implemented for `u32`
= note: u32 must be a future or must implement `IntoFuture` to be awaited = note: u32 must be a future or must implement `IntoFuture` to be awaited
error: aborting due to 2 previous errors error[E0277]: `u32` is not a future
--> $DIR/issues-71798.rs:1:69
|
LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
| _____________________________________________________________________^
LL | |
LL | |
LL | | *x
LL | | }
| |_^ `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
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0425. Some errors have detailed explanations: E0277, E0425.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View File

@ -27,6 +27,7 @@ fn main() {
struct Y; struct Y;
impl X for Y { impl X for Y {
async fn ft1() {} //~ ERROR functions in traits cannot be declared `async` async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
//~^ ERROR impl has stricter requirements than trait
unsafe fn ft2() {} // OK. unsafe fn ft2() {} // OK.
const fn ft3() {} //~ ERROR functions in traits cannot be declared const const fn ft3() {} //~ ERROR functions in traits cannot be declared const
extern "C" fn ft4() {} extern "C" fn ft4() {}
@ -35,6 +36,7 @@ fn main() {
//~| ERROR functions in traits cannot be declared const //~| ERROR functions in traits cannot be declared const
//~| ERROR functions cannot be both `const` and `async` //~| ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected //~| ERROR cycle detected
//~| ERROR impl has stricter requirements than trait
} }
impl Y { impl Y {

View File

@ -62,19 +62,19 @@ LL | async fn ft1() {}
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0379]: functions in traits cannot be declared const error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:31:9 --> $DIR/fn-header-semantic-fail.rs:32:9
| |
LL | const fn ft3() {} LL | const fn ft3() {}
| ^^^^^ functions in traits cannot be const | ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^ functions in traits cannot be const | ^^^^^ functions in traits cannot be const
error[E0706]: functions in traits cannot be declared `async` error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -85,7 +85,7 @@ LL | const async unsafe extern "C" fn ft5() {}
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: functions cannot be both `const` and `async` error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^-^^^^^------------------------------ | ^^^^^-^^^^^------------------------------
@ -94,7 +94,7 @@ LL | const async unsafe extern "C" fn ft5() {}
| `const` because of this | `const` because of this
error: functions cannot be both `const` and `async` error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:45:9 --> $DIR/fn-header-semantic-fail.rs:47:9
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^-^^^^^------------------------------ | ^^^^^-^^^^^------------------------------
@ -103,7 +103,7 @@ LL | const async unsafe extern "C" fn fi5() {}
| `const` because of this | `const` because of this
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:51:18 --> $DIR/fn-header-semantic-fail.rs:53:18
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
@ -116,7 +116,7 @@ LL | fn fe1();
| ~~ | ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:52:19 --> $DIR/fn-header-semantic-fail.rs:54:19
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
@ -130,7 +130,7 @@ LL | fn fe2();
| ~~ | ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:53:18 --> $DIR/fn-header-semantic-fail.rs:55:18
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
@ -144,7 +144,7 @@ LL | fn fe3();
| ~~ | ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:54:23 --> $DIR/fn-header-semantic-fail.rs:56:23
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
@ -158,7 +158,7 @@ LL | fn fe4();
| ~~ | ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:55:42 --> $DIR/fn-header-semantic-fail.rs:57:42
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
@ -172,7 +172,7 @@ LL | fn fe5();
| ~~ | ~~
error: functions cannot be both `const` and `async` error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:55:9 --> $DIR/fn-header-semantic-fail.rs:57:9
| |
LL | const async unsafe extern "C" fn fe5(); LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^---------------------------- | ^^^^^-^^^^^----------------------------
@ -216,30 +216,48 @@ LL | | }
LL | | } LL | | }
| |_^ | |_^
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5::{opaque#0}` error[E0276]: impl has stricter requirements than trait
--> $DIR/fn-header-semantic-fail.rs:33:48 --> $DIR/fn-header-semantic-fail.rs:29:9
|
LL | async fn ft1();
| --------------- definition of `ft1` from trait
...
LL | async fn ft1() {}
| ^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
error[E0276]: impl has stricter requirements than trait
--> $DIR/fn-header-semantic-fail.rs:34:9
|
LL | const async unsafe extern "C" fn ft5();
| --------------------------------------- definition of `ft5` from trait
...
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:34:48
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^ | ^
| |
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5`... note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5`... note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5`... note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9 --> $DIR/fn-header-semantic-fail.rs:34:9
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1 --> $DIR/fn-header-semantic-fail.rs:5:1
| |
@ -252,30 +270,30 @@ LL | | }
LL | | } LL | | }
| |_^ | |_^
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5::{opaque#0}` error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:45:48 --> $DIR/fn-header-semantic-fail.rs:47:48
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^ | ^
| |
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`... note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9 --> $DIR/fn-header-semantic-fail.rs:47:9
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`... note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9 --> $DIR/fn-header-semantic-fail.rs:47:9
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`... note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9 --> $DIR/fn-header-semantic-fail.rs:47:9
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1 --> $DIR/fn-header-semantic-fail.rs:5:1
| |
@ -288,7 +306,7 @@ LL | | }
LL | | } LL | | }
| |_^ | |_^
error: aborting due to 21 previous errors error: aborting due to 23 previous errors
Some errors have detailed explanations: E0379, E0391, E0706. Some errors have detailed explanations: E0276, E0379, E0391, E0706.
For more information about an error, try `rustc --explain E0379`. For more information about an error, try `rustc --explain E0276`.

View File

@ -14,6 +14,7 @@ trait B {
impl B for A { impl B for A {
async fn associated(); //~ ERROR without body async fn associated(); //~ ERROR without body
//~^ ERROR cannot be declared `async` //~^ ERROR cannot be declared `async`
//~| ERROR impl has stricter requirements than trait
} }
fn main() {} fn main() {}

View File

@ -44,6 +44,16 @@ LL | async fn associated();
= note: `async` trait functions are not currently supported = note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: aborting due to 5 previous errors error[E0276]: impl has stricter requirements than trait
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
|
LL | async fn associated();
| ---------------------- definition of `associated` from trait
...
LL | async fn associated();
| ^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
For more information about this error, try `rustc --explain E0706`. error: aborting due to 6 previous errors
Some errors have detailed explanations: E0276, E0706.
For more information about an error, try `rustc --explain E0276`.

View File

@ -16,9 +16,6 @@ fn extra_semicolon() {
async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type 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 while checking the return type of the `async fn`
//~| NOTE in this expansion of desugaring of `async` block or function //~| 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 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 checked the `Output` of this `async fn`, found opaque type
//~| NOTE while checking the return type of the `async fn` //~| 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 false => async_dummy(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found opaque type
//~| NOTE expected unit type `()` //~| NOTE expected type `()`
//~| HELP consider `await`ing on the `Future` //~| 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 false => async_dummy2(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found opaque type
//~| NOTE expected unit type `()` //~| NOTE expected type `()`
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
}; };
} }
@ -58,7 +55,7 @@ async fn async_different_futures() {
//~| HELP consider `await`ing on both `Future`s //~| HELP consider `await`ing on both `Future`s
false => async_dummy2(), //~ ERROR `match` arms have incompatible types false => async_dummy2(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected opaque type, found a different opaque type //~^ NOTE expected opaque type, found a different opaque type
//~| NOTE expected opaque type `impl Future<Output = ()>` //~| NOTE expected type `impl Future<Output = ()>`
//~| NOTE distinct uses of `impl Trait` result in different opaque types //~| NOTE distinct uses of `impl Trait` result in different opaque types
}; };
} }

View File

@ -1,5 +1,5 @@
error[E0308]: `match` arms have incompatible types 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 { LL | let _ = match true {
| _____________- | _____________-
@ -20,8 +20,8 @@ note: while checking the return type of the `async fn`
| |
LL | async fn async_dummy() {} LL | async fn async_dummy() {}
| ^ checked the `Output` of this `async fn`, found opaque type | ^ checked the `Output` of this `async fn`, found opaque type
= note: expected unit type `()` = note: expected type `()`
found opaque type `impl Future<Output = ()>` found opaque type `impl Future<Output = ()>`
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | false => async_dummy().await, LL | false => async_dummy().await,
@ -33,7 +33,7 @@ LL + async_dummy()
| |
error[E0308]: `match` arms have incompatible types 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 { LL | let _ = match true {
| _____________- | _____________-
@ -50,12 +50,12 @@ LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
note: while checking the return type of the `async fn` 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() {} LL | async fn async_dummy2() {}
| ^ checked the `Output` of this `async fn`, found opaque type | ^ checked the `Output` of this `async fn`, found opaque type
= note: expected unit type `()` = note: expected type `()`
found opaque type `impl Future<Output = ()>` found opaque type `impl Future<Output = ()>`
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | false => async_dummy2().await, LL | false => async_dummy2().await,
@ -69,7 +69,7 @@ LL ~ false => Box::new(async_dummy2()),
| |
error[E0308]: `match` arms have incompatible types 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 { LL | let _ = match true {
| _____________- | _____________-
@ -84,17 +84,12 @@ LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
note: while checking the return type of the `async fn` note: while checking the return type of the `async fn`
--> $DIR/match-prev-arm-needing-semi.rs:16:24 --> $DIR/match-prev-arm-needing-semi.rs:19:25
|
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
| |
LL | async fn async_dummy2() {} LL | async fn async_dummy2() {}
| ^ checked the `Output` of this `async fn`, found opaque type | ^ checked the `Output` of this `async fn`, found opaque type
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) = note: expected type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:22:25>) found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>)
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s help: consider `await`ing on both `Future`s
| |

View File

@ -1,9 +1,6 @@
error[E0308]: `if` and `else` have incompatible types error[E0308]: `if` and `else` have incompatible types
--> $DIR/opaque-type-error.rs:20:9 --> $DIR/opaque-type-error.rs:20:9
| |
LL | fn thing_one() -> impl Future<Output = Result<(), ()>> {
| ------------------------------------ the expected opaque type
...
LL | fn thing_two() -> impl Future<Output = Result<(), ()>> { LL | fn thing_two() -> impl Future<Output = Result<(), ()>> {
| ------------------------------------ the found opaque type | ------------------------------------ the found opaque type
... ...
@ -16,8 +13,8 @@ LL | | thing_two()
LL | | }.await LL | | }.await
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
= note: expected opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) = note: expected type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s help: consider `await`ing on both `Future`s
| |

View File

@ -12,11 +12,13 @@ error[E0308]: mismatched types
LL | pub type Boo = impl ::std::fmt::Debug; LL | pub type Boo = impl ::std::fmt::Debug;
| ---------------------- the expected opaque type | ---------------------- the expected opaque type
... ...
LL | fn bomp() -> boo::Boo {
| -------- expected `Boo` because of return type
LL | "" LL | ""
| ^^ expected opaque type, found `&str` | ^^ expected opaque type, found `&str`
| |
= note: expected opaque type `Boo` = note: expected opaque type `Boo`
found reference `&str` found reference `&'static str`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -5,7 +5,9 @@ LL | pub type Boo = impl ::std::fmt::Debug;
| ---------------------- the found opaque type | ---------------------- the found opaque type
... ...
LL | let _: &str = bomp(); LL | let _: &str = bomp();
| ^^^^^^ expected `&str`, found opaque type | ---- ^^^^^^ expected `&str`, found opaque type
| |
| expected due to this
| |
= note: expected reference `&str` = note: expected reference `&str`
found opaque type `Boo` found opaque type `Boo`
@ -16,11 +18,13 @@ error[E0308]: mismatched types
LL | pub type Boo = impl ::std::fmt::Debug; LL | pub type Boo = impl ::std::fmt::Debug;
| ---------------------- the expected opaque type | ---------------------- the expected opaque type
... ...
LL | fn bomp() -> boo::Boo {
| -------- expected `Boo` because of return type
LL | "" LL | ""
| ^^ expected opaque type, found `&str` | ^^ expected opaque type, found `&str`
| |
= note: expected opaque type `Boo` = note: expected opaque type `Boo`
found reference `&str` found reference `&'static str`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -33,7 +33,6 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
| ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Trait(..) | ty::PredicateKind::Trait(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate), ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),