Skip to content

Error for RPIT if they are not defined during MIR borrowck #125285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ hir_analysis_typeof_reserved_keyword_used =
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same {$what}

hir_analysis_undefined_opaque_type = undefined opaque type

hir_analysis_unnamed_fields_repr_field_defined = unnamed field defined here

hir_analysis_unnamed_fields_repr_field_missing_repr_c =
Expand Down
17 changes: 4 additions & 13 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};

use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType};
use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType, UndefinedOpaqueType};

pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
let mut res = Ok(());
Expand Down Expand Up @@ -389,18 +389,9 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
// the `concrete_opaque_types` table.
Ty::new_error(tcx, guar)
} else {
// Fall back to the RPIT we inferred during HIR typeck
if let Some(hir_opaque_ty) = hir_opaque_ty {
hir_opaque_ty.ty
} else {
// We failed to resolve the opaque type or it
// resolves to itself. We interpret this as the
// no values of the hidden type ever being constructed,
// so we can just make the hidden type be `!`.
// For backwards compatibility reasons, we fall back to
// `()` until we the diverging default is changed.
Ty::new_diverging_default(tcx)
}
// Error if we couldn't define the RPIT during MIR borrowck
let err = tcx.dcx().emit_err(UndefinedOpaqueType { span: tcx.def_span(def_id) });
Ty::new_error(tcx, err)
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,13 @@ pub struct UnconstrainedOpaqueType {
pub what: &'static str,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_undefined_opaque_type)]
pub struct UndefinedOpaqueType {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_tait_forward_compat)]
#[note]
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/borrowck/opaque-types-deadcode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ compile-flags:-Zverbose-internals

#![feature(rustc_attrs)]
#![rustc_hidden_type_of_opaques]

trait CallMeMaybe<'a, 'b> {
fn mk() -> Self;
fn subtype<T>(self, x: &'b T) -> &'a T;
}

struct Foo<'a, 'b: 'a>(&'a (), &'b ());
impl<'a, 'b> CallMeMaybe<'a, 'b> for Foo<'a, 'b> {
fn mk() -> Self {
Foo(&(), &())
}

fn subtype<T>(self, x: &'b T) -> &'a T {
x
}
}

fn good_bye() -> ! {
panic!();
}

fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
//~^ ERROR: {type error}
//~| ERROR: undefined opaque type
good_bye();
Foo(&(), &())
}

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/borrowck/opaque-types-deadcode.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: undefined opaque type
--> $DIR/opaque-types-deadcode.rs:26:25
|
LL | fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: {type error}
--> $DIR/opaque-types-deadcode.rs:26:25
|
LL | fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

2 changes: 2 additions & 0 deletions tests/ui/delegation/not-supported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ mod opaque {

pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
pub fn opaque_ret() -> impl Trait { unimplemented!() }
//~^ ERROR undefined opaque type
}
reuse to_reuse::opaque_arg;
//~^ ERROR delegation with early bound generics is not supported yet

trait ToReuse {
fn opaque_ret() -> impl Trait { unimplemented!() }
//~^ ERROR undefined opaque type
}

// FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
Expand Down
42 changes: 27 additions & 15 deletions tests/ui/delegation/not-supported.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -107,62 +107,74 @@ LL | reuse Trait::foo2 { &self.0 }
| ^^^^

error: delegation with early bound generics is not supported yet
--> $DIR/not-supported.rs:74:21
--> $DIR/not-supported.rs:75:21
|
LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
| --------------------------------------- callee defined here
...
LL | reuse to_reuse::opaque_arg;
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`
--> $DIR/not-supported.rs:83:25
error: undefined opaque type
--> $DIR/not-supported.rs:79:28
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>::{synthetic#0}`
--> $DIR/not-supported.rs:85:25
|
LL | reuse to_reuse::opaque_ret;
| ^^^^^^^^^^
|
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
--> $DIR/not-supported.rs:83:25
--> $DIR/not-supported.rs:85:25
|
LL | reuse to_reuse::opaque_ret;
| ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>` is well-formed
--> $DIR/not-supported.rs:82:5
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>` is well-formed
--> $DIR/not-supported.rs:84:5
|
LL | impl ToReuse for u8 {
| ^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`
--> $DIR/not-supported.rs:86:24
error: undefined opaque type
--> $DIR/not-supported.rs:72:32
|
LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>::{synthetic#0}`
--> $DIR/not-supported.rs:88:24
|
LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^
|
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
--> $DIR/not-supported.rs:86:24
--> $DIR/not-supported.rs:88:24
|
LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>` is well-formed
--> $DIR/not-supported.rs:85:5
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>` is well-formed
--> $DIR/not-supported.rs:87:5
|
LL | impl ToReuse for u16 {
| ^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: recursive delegation is not supported yet
--> $DIR/not-supported.rs:99:22
--> $DIR/not-supported.rs:101:22
|
LL | pub reuse to_reuse2::foo;
| --- callee defined here
...
LL | reuse to_reuse1::foo;
| ^^^

error: aborting due to 16 previous errors
error: aborting due to 18 previous errors

Some errors have detailed explanations: E0049, E0195, E0391.
For more information about an error, try `rustc --explain E0049`.
3 changes: 1 addition & 2 deletions tests/ui/impl-trait/divergence.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ check-pass

fn foo() -> impl MyTrait {
//~^ ERROR undefined opaque type
panic!();
MyStruct
}
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/impl-trait/divergence.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: undefined opaque type
--> $DIR/divergence.rs:1:13
|
LL | fn foo() -> impl MyTrait {
| ^^^^^^^^^^^^

error: aborting due to 1 previous error

1 change: 1 addition & 0 deletions tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {

fn d() -> impl Fn() -> (impl Debug + '_) {
//~^ ERROR missing lifetime specifier
//~| ERROR undefined opaque type
|| ()
}

Expand Down
8 changes: 7 additions & 1 deletion tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ note: lifetime declared here
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
| ^^

error: aborting due to 4 previous errors
error: undefined opaque type
--> $DIR/impl-fn-hrtb-bounds.rs:19:25
|
LL | fn d() -> impl Fn() -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0106, E0657.
For more information about an error, try `rustc --explain E0106`.
1 change: 1 addition & 0 deletions tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fn a() -> impl Fn(&u8) -> impl Debug + '_ {

fn b() -> impl Fn() -> impl Debug + Send {
//~^ ERROR ambiguous `+` in a type
//~| ERROR undefined opaque type
|| ()
}

Expand Down
8 changes: 7 additions & 1 deletion tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ note: lifetime declared here
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^

error: aborting due to 3 previous errors
error: undefined opaque type
--> $DIR/impl-fn-parsing-ambiguities.rs:10:24
|
LL | fn b() -> impl Fn() -> impl Debug + Send {
| ^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0657`.
5 changes: 4 additions & 1 deletion tests/ui/impl-trait/impl_fn_associativity.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
//@ run-pass
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn f_debug() -> impl Fn() -> impl Debug {
//~^ ERROR undefined opaque type
|| ()
}

fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
//~^ ERROR undefined opaque type
//~| ERROR undefined opaque type
|| f_debug()
}

fn multi() -> impl Fn() -> (impl Debug + Send) {
//~^ ERROR undefined opaque type
|| ()
}

Expand Down
26 changes: 26 additions & 0 deletions tests/ui/impl-trait/impl_fn_associativity.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:4:30
|
LL | fn f_debug() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:9:31
|
LL | fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:9:44
|
LL | fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:15:29
|
LL | fn multi() -> impl Fn() -> (impl Debug + Send) {
| ^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

14 changes: 8 additions & 6 deletions tests/ui/impl-trait/impl_trait_projections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> {
}

fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Trait` is not allowed in path parameters
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Trait` is not allowed in path parameters
x.next().unwrap()
}

fn projection_with_named_trait_is_disallowed(mut x: impl Iterator)
-> <impl Iterator as Iterator>::Item
fn projection_with_named_trait_is_disallowed(
mut x: impl Iterator,
) -> <impl Iterator as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
{
x.next().unwrap()
}

fn projection_with_named_trait_inside_path_is_disallowed()
-> <::std::ops::Range<impl Debug> as Iterator>::Item
-> <::std::ops::Range<impl Debug> as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Debug: Step` is not satisfied
{
Expand All @@ -32,8 +33,9 @@ fn projection_with_named_trait_inside_path_is_disallowed()
}

fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR undefined opaque type
{
panic!()
}
Expand Down
Loading
Loading