mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 06:22:00 +00:00
Relax recursive opaque type check
This commit is contained in:
parent
8d361cbd91
commit
7db5f81853
@ -3,7 +3,6 @@
|
||||
// substitutions.
|
||||
|
||||
use crate::FnCtxt;
|
||||
use hir::def_id::LocalDefId;
|
||||
use rustc_data_structures::unord::ExtendUnord;
|
||||
use rustc_errors::{ErrorGuaranteed, StashKey};
|
||||
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_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
||||
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_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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 opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
|
||||
|
||||
struct RecursionChecker {
|
||||
def_id: LocalDefId,
|
||||
}
|
||||
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()
|
||||
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
|
||||
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
|
||||
&& alias_ty.args == opaque_type_key.args
|
||||
{
|
||||
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