mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 14:31:55 +00:00
Relax recursive opaque type check
This commit is contained in:
parent
8d361cbd91
commit
7db5f81853
@ -3,7 +3,6 @@
|
|||||||
// substitutions.
|
// substitutions.
|
||||||
|
|
||||||
use crate::FnCtxt;
|
use crate::FnCtxt;
|
||||||
use hir::def_id::LocalDefId;
|
|
||||||
use rustc_data_structures::unord::ExtendUnord;
|
use rustc_data_structures::unord::ExtendUnord;
|
||||||
use rustc_errors::{ErrorGuaranteed, StashKey};
|
use rustc_errors::{ErrorGuaranteed, StashKey};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -11,13 +10,12 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Entry point
|
// Entry point
|
||||||
@ -565,23 +563,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
|
let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
|
||||||
let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
|
let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
|
||||||
|
|
||||||
struct RecursionChecker {
|
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
|
||||||
def_id: LocalDefId,
|
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
|
||||||
}
|
&& alias_ty.args == opaque_type_key.args
|
||||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker {
|
|
||||||
type BreakTy = ();
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() {
|
|
||||||
if def_id == self.def_id.to_def_id() {
|
|
||||||
return ControlFlow::Break(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.super_visit_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hidden_type
|
|
||||||
.visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id })
|
|
||||||
.is_break()
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
// issue: 113596
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait Test {}
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
impl Test for A {}
|
||||||
|
|
||||||
|
struct B<T> {
|
||||||
|
inner: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Test> Test for B<T> {}
|
||||||
|
|
||||||
|
type TestImpl = impl Test;
|
||||||
|
|
||||||
|
fn test() -> TestImpl {
|
||||||
|
A
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_option() -> Option<TestImpl> {
|
||||||
|
Some(test())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_option2() -> Option<TestImpl> {
|
||||||
|
let inner = make_option().unwrap();
|
||||||
|
|
||||||
|
Some(B { inner })
|
||||||
|
//~^ ERROR concrete type differs from previous defining opaque type use
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,14 @@
|
|||||||
|
error: concrete type differs from previous defining opaque type use
|
||||||
|
--> $DIR/recursive-tait-conflicting-defn.rs:30:3
|
||||||
|
|
|
||||||
|
LL | Some(B { inner })
|
||||||
|
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
||||||
|
|
|
||||||
|
note: previous use here
|
||||||
|
--> $DIR/recursive-tait-conflicting-defn.rs:20:3
|
||||||
|
|
|
||||||
|
LL | A
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Reference in New Issue
Block a user