Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 67 additions & 3 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
@@ -9,17 +9,21 @@
//! which creates a new `TypeckResults` which doesn't contain any inference variables.
use std::mem;
use std::ops::ControlFlow;

use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::ExtendUnord;
use rustc_errors::ErrorGuaranteed;
use rustc_errors::{E0720, ErrorGuaranteed};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_infer::traits::solve::Goal;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::{
self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt, fold_regions,
self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
fold_regions,
};
use rustc_span::{Span, sym};
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
@@ -595,6 +599,35 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
entry.span = prev.span.substitute_dummy(hidden_type.span);
}
}

let recursive_opaques: Vec<_> = self
.typeck_results
.concrete_opaque_types
.iter()
.filter(|&(&def_id, hidden_ty)| {
hidden_ty
.ty
.visit_with(&mut HasRecursiveOpaque {
def_id,
seen: Default::default(),
opaques: &self.typeck_results.concrete_opaque_types,
tcx,
})
.is_break()
})
.map(|(def_id, hidden_ty)| (*def_id, hidden_ty.span))
.collect();
for (def_id, span) in recursive_opaques {
let guar = self
.fcx
.dcx()
.struct_span_err(span, "cannot resolve opaque type")
.with_code(E0720)
.emit();
self.typeck_results
.concrete_opaque_types
.insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
}
}

fn visit_field_id(&mut self, hir_id: HirId) {
@@ -959,3 +992,34 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
self.tcx.try_normalize_erasing_regions(self.typing_env, ct).unwrap_or(ct)
}
}

struct HasRecursiveOpaque<'a, 'tcx> {
def_id: LocalDefId,
seen: FxHashSet<LocalDefId>,
opaques: &'a FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRecursiveOpaque<'_, 'tcx> {
type Result = ControlFlow<()>;

fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Opaque, alias_ty) = *t.kind()
&& let Some(def_id) = alias_ty.def_id.as_local()
{
if self.def_id == def_id {
return ControlFlow::Break(());
}

if self.seen.insert(def_id)
&& let Some(hidden_ty) = self.opaques.get(&def_id)
{
ty::EarlyBinder::bind(hidden_ty.ty)
.instantiate(self.tcx, alias_ty.args)
.visit_with(self)?;
}
}

t.super_visit_with(self)
}
}
40 changes: 5 additions & 35 deletions compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt;
use std::iter::once;
use std::ops::ControlFlow;

use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
use rustc_arena::DroplessArena;
@@ -12,8 +11,7 @@ use rustc_middle::mir::{self, Const};
use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, VariantDef,
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
@@ -137,22 +135,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
/// Returns the hidden type corresponding to this key if the body under analysis is allowed to
/// know it.
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
if let Some(hidden_ty) = self.typeck_results.concrete_opaque_types.get(&key.def_id) {
let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args);
if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() {
Some(ty)
} else {
// HACK: We skip revealing opaque types which recursively expand
// to themselves. This is because we may infer hidden types like
// `Opaque<T> = Opaque<Opaque<T>>` or `Opaque<T> = Opaque<(T,)>`
// in hir typeck.
None
}
} else {
None
}
self.typeck_results
.concrete_opaque_types
.get(&key.def_id)
.map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
}

// This can take a non-revealed `Ty` because it reveals opaques itself.
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
@@ -1177,20 +1164,3 @@ fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
}
Ok(())
}

struct RecursiveOpaque {
def_id: DefId,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for RecursiveOpaque {
type Result = ControlFlow<()>;

fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Opaque, alias_ty) = t.kind() {
if alias_ty.def_id == self.def_id {
return ControlFlow::Break(());
}
}

if t.has_opaque_types() { t.super_visit_with(self) } else { ControlFlow::Continue(()) }
}
}
15 changes: 6 additions & 9 deletions tests/ui/impl-trait/issues/issue-100075-2.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075-2.rs:1:23
|
LL | fn opaque<T>(t: T) -> impl Sized {
| ^^^^^^^^^^

warning: function cannot return without recursing
--> $DIR/issue-100075-2.rs:1:1
|
@@ -10,15 +16,6 @@ LL | opaque(Some(t))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default

error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075-2.rs:1:23
|
LL | fn opaque<T>(t: T) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | opaque(Some(t))
| --------------- returning here with type `impl Sized`

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0720`.
5 changes: 1 addition & 4 deletions tests/ui/impl-trait/issues/issue-100075.stderr
Original file line number Diff line number Diff line change
@@ -2,10 +2,7 @@ error[E0720]: cannot resolve opaque type
--> $DIR/issue-100075.rs:13:37
|
LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
| ^^^^^^^^^^^ recursive opaque type
...
LL | return _g(t);
| ----- returning here with type `&impl Marker`
| ^^^^^^^^^^^

error: aborting due to 1 previous error

5 changes: 2 additions & 3 deletions tests/ui/impl-trait/issues/issue-103599.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//@ check-pass

trait T {}

fn wrap(x: impl T) -> impl T {
//~^ WARN function cannot return without recursing
//~^ ERROR cannot resolve opaque type
//~| WARN function cannot return without recursing
wrap(wrap(x))
}

13 changes: 10 additions & 3 deletions tests/ui/impl-trait/issues/issue-103599.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-103599.rs:3:23
|
LL | fn wrap(x: impl T) -> impl T {
| ^^^^^^

warning: function cannot return without recursing
--> $DIR/issue-103599.rs:5:1
--> $DIR/issue-103599.rs:3:1
|
LL | fn wrap(x: impl T) -> impl T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
...
LL | wrap(wrap(x))
| ------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default

warning: 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0720`.
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/issues/issue-87450.rs
Original file line number Diff line number Diff line change
@@ -3,8 +3,8 @@ fn bar() -> impl Fn() {
}

fn foo() -> impl Fn() {
//~^ WARNING 5:1: 5:22: function cannot return without recursing [unconditional_recursion]
//~| ERROR 5:13: 5:22: cannot resolve opaque type [E0720]
//~^ WARN function cannot return without recursing
//~| ERROR cannot resolve opaque type
wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
}

18 changes: 6 additions & 12 deletions tests/ui/impl-trait/issues/issue-87450.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/issue-87450.rs:5:13
|
LL | fn foo() -> impl Fn() {
| ^^^^^^^^^

warning: function cannot return without recursing
--> $DIR/issue-87450.rs:5:1
|
@@ -10,18 +16,6 @@ LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default

error[E0720]: cannot resolve opaque type
--> $DIR/issue-87450.rs:5:13
|
LL | fn foo() -> impl Fn() {
| ^^^^^^^^^ recursive opaque type
...
LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
| ----------------------------------------------- returning here with type `impl Fn()`
...
LL | fn wrap(f: impl Fn()) -> impl Fn() {
| --------- returning this opaque type `impl Fn()`

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0720`.
73 changes: 14 additions & 59 deletions tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
Original file line number Diff line number Diff line change
@@ -2,112 +2,67 @@ error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:6:22
|
LL | fn option(i: i32) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | if i < 0 { None } else { Some((option(i - 1), i)) }
| ---- ------------------------ returning here with type `Option<(impl Sized, i32)>`
| |
| returning here with type `Option<(impl Sized, i32)>`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:11:15
|
LL | fn tuple() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | (tuple(),)
| ---------- returning here with type `(impl Sized,)`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:16:15
|
LL | fn array() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | [array()]
| --------- returning here with type `[impl Sized; 1]`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:21:13
|
LL | fn ptr() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | &ptr() as *const _
| ------------------ returning here with type `*const impl Sized`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:26:16
|
LL | fn fn_ptr() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | fn_ptr as fn() -> _
| ------------------- returning here with type `fn() -> impl Sized`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:31:25
|
LL | fn closure_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | x;
| | - closure captures itself here
LL | | }
| |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:34:5: 34:12}`
LL | fn closure_capture() -> impl Sized {
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:39:29
|
LL | fn closure_ref_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | &x;
| | - closure captures itself here
LL | | }
| |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:42:5: 42:12}`
LL | fn closure_ref_capture() -> impl Sized {
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:47:21
|
LL | fn closure_sig() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | || closure_sig()
| ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:49:5: 49:7}`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:52:23
|
LL | fn coroutine_sig() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | || coroutine_sig()
| ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:57:27
|
LL | fn coroutine_capture() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | / move || {
LL | | yield;
LL | | x;
| | - coroutine captures itself here
LL | | }
| |_____- returning here with type `{coroutine@$DIR/recursive-impl-trait-type-indirect.rs:62:5: 62:12}`
LL | fn coroutine_capture() -> impl Sized {
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:68:35
|
LL | fn substs_change<T: 'static>() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
LL |
LL | (substs_change::<&T>(),)
| ------------------------ returning here with type `(impl Sized,)`
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:78:26
53 changes: 9 additions & 44 deletions tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr
Original file line number Diff line number Diff line change
@@ -1,56 +1,21 @@
warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:17:1
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:17:22
|
LL | fn build<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
LL | let (x,) = (build(x),);
| -------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default

warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:27:1
|
LL | fn build2<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
LL | let (x,) = (build2(x),);
| --------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
| ^^^^^^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:27:23
|
LL | fn build2<T>(x: T) -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | (build2(x),)
| ------------ returning here with type `(impl Sized,)`
| ^^^^^^^^^^

warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:40:1
|
LL | fn build3<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL |
LL | let (x,) = (build3((x,)),);
| ------------ recursive call site
|
= help: a `loop` may express intention better if this is on purpose

error[E0792]: expected generic type parameter, found `(T,)`
--> $DIR/recursive-in-exhaustiveness.rs:49:5
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-in-exhaustiveness.rs:39:23
|
LL | fn build3<T>(x: T) -> impl Sized {
| - this generic parameter must be used with a generic type parameter
...
LL | build3(x)
| ^^^^^^^^^
| ^^^^^^^^^^

error: aborting due to 2 previous errors; 3 warnings emitted
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0720, E0792.
For more information about an error, try `rustc --explain E0720`.
For more information about this error, try `rustc --explain E0720`.
18 changes: 9 additions & 9 deletions tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
Original file line number Diff line number Diff line change
@@ -5,19 +5,19 @@ LL | let (x,) = (build(x),);
| ^^^^^^^^ cannot satisfy `impl Sized == _`

error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:6
--> $DIR/recursive-in-exhaustiveness.rs:30:6
|
LL | (build2(x),)
| ^^^^^^^^^ types differ

error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:5
--> $DIR/recursive-in-exhaustiveness.rs:30:5
|
LL | (build2(x),)
| ^^^^^^^^^^^^ types differ

error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
--> $DIR/recursive-in-exhaustiveness.rs:31:5
--> $DIR/recursive-in-exhaustiveness.rs:30:5
|
LL | (build2(x),)
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -26,13 +26,13 @@ LL | (build2(x),)
= note: tuples must have a statically known size to be initialized

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ

error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -41,7 +41,7 @@ LL | let (x,) = (build3((x,)),);
= note: tuples must have a statically known size to be initialized

error[E0308]: mismatched types
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | fn build3<T>(x: T) -> impl Sized {
| ---------- the found opaque type
@@ -53,21 +53,21 @@ LL | let (x,) = (build3((x,)),);
found tuple `(impl Sized,)`

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
|
= note: the return type of a function must have a statically known size

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:41:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ types differ

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:41:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
6 changes: 2 additions & 4 deletions tests/ui/impl-trait/recursive-in-exhaustiveness.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@
// We unfortunately accept this today, and due to how opaque type relating is implemented
// in the NLL type relation, this defines `Opaque<T> = T`.
fn build<T>(x: T) -> impl Sized {
//[current]~^ WARN function cannot return without recursing
//[current]~^ ERROR cannot resolve opaque type
let (x,) = (build(x),);
//[next]~^ ERROR type annotations needed
build(x)
@@ -26,7 +26,6 @@ fn build<T>(x: T) -> impl Sized {
// Not allowed today. Detected as recursive.
fn build2<T>(x: T) -> impl Sized {
//[current]~^ ERROR cannot resolve opaque type
//[current]~| WARN function cannot return without recursing
let (x,) = (build2(x),);
(build2(x),)
//[next]~^ ERROR type mismatch resolving
@@ -38,7 +37,7 @@ fn build2<T>(x: T) -> impl Sized {
//
// Not allowed today. Detected as not defining.
fn build3<T>(x: T) -> impl Sized {
//[current]~^ WARN function cannot return without recursing
//[current]~^ ERROR cannot resolve opaque type
let (x,) = (build3((x,)),);
//[next]~^ ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
@@ -47,7 +46,6 @@ fn build3<T>(x: T) -> impl Sized {
//[next]~| ERROR the size for values of type
//[next]~| ERROR mismatched types
build3(x)
//[current]~^ ERROR expected generic type parameter, found `(T,)`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#![feature(type_alias_impl_trait)]

type T = impl Copy;
//~^ ERROR cannot resolve opaque type

#[define_opaque(T)]
fn foo() -> T {
//~^ ERROR cannot resolve opaque type
None::<&'static T>
}

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0720]: cannot resolve opaque type
--> $DIR/infinite-cycle-involving-weak.rs:3:10
--> $DIR/infinite-cycle-involving-weak.rs:6:13
|
LL | type T = impl Copy;
| ^^^^^^^^^ cannot resolve opaque type
LL | fn foo() -> T {
| ^

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//@ known-bug: #139817
#![feature(type_alias_impl_trait)]

fn enum_upvar() {
type T = impl Copy;
let foo: T = Some((42, std::marker::PhantomData::<T>));
let x = move || match foo {
None => (),
//~^ ERROR cannot resolve opaque type
};
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/match-upvar-discriminant-of-opaque.rs:7:9
|
LL | None => (),
| ^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0720`.
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ pub fn add(
n: Diff,
m: Diff,
) -> Diff {
//~^ ERROR concrete type differs
//~^ ERROR cannot resolve opaque type
move |x: usize| m(n(x))
}

11 changes: 3 additions & 8 deletions tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-fn-tait.rs:15:6
|
LL | ) -> Diff {
| ^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:17:5: 17:20}`
|
note: previous use here
--> $DIR/recursive-fn-tait.rs:7:18
|
LL | pub fn lift() -> Diff {
| ^^^^
| ^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0720`.
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ fn transform<S>() -> impl std::fmt::Display {
}
#[define_opaque(Op)]
fn bad() -> Op {
//~^ ERROR concrete type differs from previous defining opaque type use
//~^ ERROR cannot resolve opaque type
transform::<Op>()
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-tait-conflicting-defn-2.rs:15:13
|
LL | fn bad() -> Op {
| ^^ expected `&&str`, got `impl std::fmt::Display`
|
note: previous use here
--> $DIR/recursive-tait-conflicting-defn-2.rs:7:13
|
LL | fn foo() -> Op {
| ^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0720`.
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub fn test() -> TestImpl {

#[define_opaque(TestImpl)]
fn make_option2() -> Option<TestImpl> {
//~^ ERROR concrete type differs from previous defining opaque type use
//~^ ERROR cannot resolve opaque type
let inner = make_option().unwrap();
Some(B { inner })
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
error: concrete type differs from previous defining opaque type use
error[E0720]: cannot resolve opaque type
--> $DIR/recursive-tait-conflicting-defn.rs:25:22
|
LL | fn make_option2() -> Option<TestImpl> {
| ^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
|
note: previous use here
--> $DIR/recursive-tait-conflicting-defn.rs:20:18
|
LL | pub fn test() -> TestImpl {
| ^^^^^^^^
| ^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0720`.