allow opaques to be defined by trait queries
This commit is contained in:
parent
33a2c2487a
commit
281c2271be
@ -1,5 +1,5 @@
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use crate::traits::{self, ObligationCtxt};
|
||||
use crate::traits::{self, DefiningAnchor, ObligationCtxt};
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
@ -80,7 +80,7 @@ fn type_implements_trait(
|
||||
|
||||
pub trait InferCtxtBuilderExt<'tcx> {
|
||||
fn enter_canonical_trait_query<K, R>(
|
||||
&mut self,
|
||||
self,
|
||||
canonical_key: &Canonical<'tcx, K>,
|
||||
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
||||
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
|
||||
@ -108,7 +108,7 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
|
||||
/// have `'tcx` be free on this function so that we can talk about
|
||||
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
|
||||
fn enter_canonical_trait_query<K, R>(
|
||||
&mut self,
|
||||
self,
|
||||
canonical_key: &Canonical<'tcx, K>,
|
||||
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
||||
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
|
||||
@ -117,8 +117,9 @@ fn enter_canonical_trait_query<K, R>(
|
||||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
|
||||
{
|
||||
let (infcx, key, canonical_inference_vars) =
|
||||
self.build_with_canonical(DUMMY_SP, canonical_key);
|
||||
let (infcx, key, canonical_inference_vars) = self
|
||||
.with_opaque_type_inference(DefiningAnchor::Bubble)
|
||||
.build_with_canonical(DUMMY_SP, canonical_key);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let value = operation(&ocx, key)?;
|
||||
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
|
||||
|
12
tests/ui/impl-trait/defined-by-trait-resolution.rs
Normal file
12
tests/ui/impl-trait/defined-by-trait-resolution.rs
Normal file
@ -0,0 +1,12 @@
|
||||
//! The trait query `foo: Fn() -> u8` is a valid defining use of RPIT.
|
||||
|
||||
// build-pass
|
||||
|
||||
fn returns_u8(_: impl Fn() -> u8) {}
|
||||
|
||||
pub fn foo() -> impl Sized {
|
||||
returns_u8(foo);
|
||||
0u8
|
||||
}
|
||||
|
||||
fn main() {}
|
19
tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs
Normal file
19
tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// User type annotation in fn bodies is a a valid defining site for opaque types.
|
||||
// check-pass
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait Equate { type Proj; }
|
||||
impl<T> Equate for T { type Proj = T; }
|
||||
|
||||
trait Indirect { type Ty; }
|
||||
impl<A, B: Equate<Proj = A>> Indirect for (A, B) { type Ty = (); }
|
||||
|
||||
type Opq = impl Sized;
|
||||
fn define_1(_: Opq) {
|
||||
let _ = None::<<(Opq, u8) as Indirect>::Ty>;
|
||||
}
|
||||
fn define_2() -> Opq {
|
||||
0u8
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user