allow opaques to be defined by trait queries
This commit is contained in:
parent
33a2c2487a
commit
281c2271be
3 changed files with 37 additions and 5 deletions
|
@ -1,5 +1,5 @@
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
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::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
|
@ -80,7 +80,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
|
|
||||||
pub trait InferCtxtBuilderExt<'tcx> {
|
pub trait InferCtxtBuilderExt<'tcx> {
|
||||||
fn enter_canonical_trait_query<K, R>(
|
fn enter_canonical_trait_query<K, R>(
|
||||||
&mut self,
|
self,
|
||||||
canonical_key: &Canonical<'tcx, K>,
|
canonical_key: &Canonical<'tcx, K>,
|
||||||
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
||||||
) -> Result<CanonicalQueryResponse<'tcx, 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
|
/// have `'tcx` be free on this function so that we can talk about
|
||||||
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
|
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
|
||||||
fn enter_canonical_trait_query<K, R>(
|
fn enter_canonical_trait_query<K, R>(
|
||||||
&mut self,
|
self,
|
||||||
canonical_key: &Canonical<'tcx, K>,
|
canonical_key: &Canonical<'tcx, K>,
|
||||||
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
|
||||||
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
|
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
|
||||||
|
@ -117,8 +117,9 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
|
||||||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||||
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
|
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
|
||||||
{
|
{
|
||||||
let (infcx, key, canonical_inference_vars) =
|
let (infcx, key, canonical_inference_vars) = self
|
||||||
self.build_with_canonical(DUMMY_SP, canonical_key);
|
.with_opaque_type_inference(DefiningAnchor::Bubble)
|
||||||
|
.build_with_canonical(DUMMY_SP, canonical_key);
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
let value = operation(&ocx, key)?;
|
let value = operation(&ocx, key)?;
|
||||||
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
|
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…
Add table
Add a link
Reference in a new issue