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 base_universe: Option<ty::UniverseIndex>,
pub region_constraints: Option<RegionConstraintData<'tcx>>,
pub obligation: PredicateObligation<'tcx>,
pub obligations: Vec<PredicateObligation<'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>> {
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);
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::traits::ObligationCause;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{self, Const, Ty};
use rustc_span::Span;
@ -136,7 +137,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
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 span = self.span();
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.category,
InstantiateOpaqueType {
obligation: self.type_checker.infcx.opaque_ty_obligation(
a,
b,
a_is_expected,
param_env,
cause,
),
obligations: self
.type_checker
.infcx
.handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
.obligations,
// These fields are filled in during exectuion of the operation
base_universe: None,
region_constraints: None,
},
)
.unwrap();
Ok(())
}
}

View File

@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
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 {
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);
obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
}
Ok(InferOk { value: result_subst, obligations })
@ -718,13 +719,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
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(),
));
fn register_opaque_type(
&mut self,
a: Ty<'tcx>,
b: Ty<'tcx>,
a_is_expected: bool,
) -> Result<(), TypeError<'tcx>> {
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, ..))
if self.fields.define_opaque_types && did.is_local() =>
{
self.fields.obligations.push(infcx.opaque_ty_obligation(
self.fields.obligations.extend(
infcx
.handle_opaque_type(
a,
b,
self.a_is_expected(),
&self.fields.trace.cause,
self.param_env(),
self.fields.trace.cause.clone(),
));
)?
.obligations,
);
}
_ => {

View File

@ -111,13 +111,11 @@ where
(&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(),
)]);
this.add_obligations(
infcx
.handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
.obligations,
);
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 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.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -590,7 +595,7 @@ where
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
_ => 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");
Ok(a)
}

View File

@ -1,5 +1,5 @@
use crate::infer::{InferCtxt, InferOk};
use crate::traits::{self, PredicateObligation};
use crate::traits;
use hir::def_id::{DefId, LocalDefId};
use hir::OpaqueTyOrigin;
use rustc_data_structures::sync::Lrc;
@ -42,13 +42,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&self,
a: Ty<'tcx>,
b: Ty<'tcx>,
a_is_expected: bool,
cause: &ObligationCause<'tcx>,
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 (a, b) = if a_is_expected { (a, b) } else { (b, a) };
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Opaque(def_id, substs) => {
if let ty::Opaque(did2, _) = *b.kind() {
@ -57,8 +58,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// no one encounters it in practice.
// 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.
if let Some(OpaqueTyOrigin::TyAlias) =
self.opaque_type_origin(did2, cause.span)
if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
{
self.tcx
.sess
@ -83,6 +83,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
cause.clone(),
param_env,
b,
if self.defining_use_anchor.is_some() {
// 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
@ -117,7 +118,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// 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,
@ -138,28 +142,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
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![] }),
}
}
}
/// Given the map `opaque_types` containing the opaque
@ -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")]
pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option<OpaqueTyOrigin> {
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::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))

View File

@ -146,13 +146,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
(_, &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(),
));
self.fields.obligations.extend(
infcx
.handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
.obligations,
);
Ok(a)
}

View File

@ -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.

View File

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

View File

@ -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);
}
}
}

View File

@ -632,11 +632,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
@ -1004,7 +999,6 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::TypeOutlives(..)
| PredicateKind::ConstEvaluatable(..)
| PredicateKind::ConstEquate(..)
| PredicateKind::OpaqueType(..)
| PredicateKind::TypeWellFormedFromEnv(..) => None,
}
}
@ -1023,7 +1017,6 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::ClosureKind(..)
| PredicateKind::ConstEvaluatable(..)
| PredicateKind::ConstEquate(..)
| PredicateKind::OpaqueType(..)
| PredicateKind::TypeWellFormedFromEnv(..) => None,
}
}

View File

@ -2654,9 +2654,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) ,"`")
}
}
}

View File

@ -198,9 +198,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())
}
}
}
}
@ -474,9 +471,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)?))
}
}
}
}

View File

@ -352,7 +352,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

View File

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

View File

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

View File

@ -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,
}
}
@ -345,7 +344,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,
}
})

View File

@ -673,19 +673,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),
}
}
}
});

View File

@ -148,10 +148,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")
}

View File

@ -110,7 +110,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::ConstEvaluatable(..)
| 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::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::ConstEquate(..) => {
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::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("unexpected predicate {}", &self)
}
@ -753,7 +750,6 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::OpaqueType(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("unexpected predicate {}", &self)
}

View File

@ -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);

View File

@ -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,
}
}

View File

@ -661,13 +661,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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,
)]);
self.register_predicates(
self.infcx
.handle_opaque_type(ty, ty_var, true, &cause, self.param_env)
.unwrap()
.obligations,
);
ty_var
}
_ => ty,

View File

@ -732,7 +732,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))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,12 +53,7 @@ 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<Output = ()>`
= note: expected type `impl Future<Output = ()>`
found unit type `()`
help: consider `await`ing on the `Future`
|
@ -62,7 +61,7 @@ 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 | let _x = match dummy() {
| ------- this expression has type `impl Future<Output = ()>`
@ -110,7 +109,7 @@ 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 | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@ -119,7 +118,7 @@ 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
@ -131,7 +130,7 @@ LL | match dummy_result().await {
| ++++++
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:68:9
--> $DIR/suggest-missing-await.rs:69:9
|
LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@ -140,7 +139,7 @@ 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

View File

@ -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
}

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
|
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 _;
| ^^^^^ 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`.

View File

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

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

@ -15,7 +15,9 @@ LL | fn hide<T: Foo>(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`

View File

@ -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"); //~ ERROR opaque type's hidden type cannot be another opaque type
}
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}>>`
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 | | 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
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

View File

@ -21,6 +21,7 @@ mod b {
impl PartialEq<(Foo, i32)> for Bar {
fn eq(&self, _other: &(Bar, i32)) -> bool {
//~^ ERROR impl has stricter requirements than trait
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
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)]
type A = impl Foo;
type A = impl Foo; //~ ERROR unconstrained opaque type
type B = impl 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
--> $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;
| ^^^^^^^^
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> + '_ {
//~^ ERROR `u32` is not a future
//~| ERROR `u32` is not a future
*x
}

View File

@ -1,5 +1,5 @@
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;
| ^ 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`
= 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.
For more information about an error, try `rustc --explain E0277`.

View File

@ -27,6 +27,7 @@ fn main() {
struct Y;
impl X for Y {
async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
//~^ ERROR impl has stricter requirements than trait
unsafe fn ft2() {} // OK.
const fn ft3() {} //~ ERROR functions in traits cannot be declared const
extern "C" fn ft4() {}
@ -35,6 +36,7 @@ fn main() {
//~| ERROR functions in traits cannot be declared const
//~| ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
//~| ERROR impl has stricter requirements than trait
}
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
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() {}
| ^^^^^ functions in traits cannot be 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() {}
| ^^^^^ functions in traits cannot be const
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() {}
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -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
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() {}
| ^^^^^-^^^^^------------------------------
@ -94,7 +94,7 @@ LL | const async unsafe extern "C" fn ft5() {}
| `const` because of this
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() {}
| ^^^^^-^^^^^------------------------------
@ -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:53: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:54: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:55: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:56: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:57: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:57:9
|
LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^----------------------------
@ -216,30 +216,48 @@ 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}`
--> $DIR/fn-header-semantic-fail.rs:33:48
error[E0276]: impl has stricter requirements than trait
--> $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() {}
| ^
|
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9
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:34:9
|
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`...
--> $DIR/fn-header-semantic-fail.rs:33:9
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:34:9
|
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`...
--> $DIR/fn-header-semantic-fail.rs:33:9
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:34:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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 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
--> $DIR/fn-header-semantic-fail.rs:5:1
|
@ -252,30 +270,30 @@ 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}`
--> $DIR/fn-header-semantic-fail.rs:45:48
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:47:48
|
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`...
--> $DIR/fn-header-semantic-fail.rs:45:9
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:47:9
|
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`...
--> $DIR/fn-header-semantic-fail.rs:45:9
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:47:9
|
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`...
--> $DIR/fn-header-semantic-fail.rs:45:9
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:47:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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 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
--> $DIR/fn-header-semantic-fail.rs:5:1
|
@ -288,7 +306,7 @@ LL | | }
LL | | }
| |_^
error: aborting due to 21 previous errors
error: aborting due to 23 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: E0276, E0379, E0391, E0706.
For more information about an error, try `rustc --explain E0276`.

View File

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

View File

@ -44,6 +44,16 @@ 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[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
//~| 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<Output = ()>`
//~| NOTE expected type `impl Future<Output = ()>`
//~| NOTE distinct uses of `impl Trait` result in different opaque types
};
}

View File

@ -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,7 +20,7 @@ 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 `()`
= note: expected type `()`
found opaque type `impl Future<Output = ()>`
help: consider `await`ing on the `Future`
|
@ -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,11 +50,11 @@ 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 `()`
= note: expected type `()`
found opaque type `impl Future<Output = ()>`
help: consider `await`ing on the `Future`
|
@ -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<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>)
= 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:19:25>)
= note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s
|

View File

@ -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<Output = Result<(), ()>> {
| ------------------------------------ the expected opaque type
...
LL | fn thing_two() -> impl Future<Output = Result<(), ()>> {
| ------------------------------------ the found opaque type
...
@ -16,7 +13,7 @@ LL | | thing_two()
LL | | }.await
| |_____- `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>)
= note: distinct uses of `impl Trait` result in different opaque types
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;
| ---------------------- the expected opaque type
...
LL | fn bomp() -> boo::Boo {
| -------- expected `Boo` because of return type
LL | ""
| ^^ expected opaque type, found `&str`
|
= note: expected opaque type `Boo`
found reference `&str`
found reference `&'static str`
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
...
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`
@ -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 `Boo` because of return type
LL | ""
| ^^ expected opaque type, found `&str`
|
= note: expected opaque type `Boo`
found reference `&str`
found reference `&'static str`
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::ConstEquate(..)
| ty::PredicateKind::Trait(..)
| 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),