mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Rollup merge of #66431 - Aaron1011:fix/opaque-type-infer, r=varkor
Fix 'type annotations needed' error with opaque types Related: #66426 This commit adds handling for opaque types during inference variable fallback. Type variables generated from the instantiation of opaque types now fallback to the opaque type itself. Normally, the type variable for an instantiated opaque type is either unified with the concrete type, or with the opaque type itself (e.g when a function returns an opaque type by calling another function). However, it's possible for the type variable to be left completely unconstrained. This can occur in code like this: ```rust pub type Foo = impl Copy; fn produce() -> Option<Foo> { None } ``` Here, we'll instantatiate the `Foo` in `Option<Foo>` to a fresh type variable, but we will never unify it with anything due to the fact that we return a `None`. This results in the error message: ``` type annotations needed: cannot resolve `_: std::marker::Copy ``` pointing at `pub type Foo = impl Copy`. This message is not only confusing, it's incorrect. When an opaque type inference variable is completely unconstrained, we can always fall back to using the opaque type itself. This effectively turns that particular use of the opaque type into a non-defining use, even if it appears in a defining scope.
This commit is contained in:
commit
ee535a0f95
@ -24,6 +24,10 @@ pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
|
||||
/// appear in the return type).
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct OpaqueTypeDecl<'tcx> {
|
||||
|
||||
/// The opaque type (`ty::Opaque`) for this declaration.
|
||||
pub opaque_type: Ty<'tcx>,
|
||||
|
||||
/// The substitutions that we apply to the opaque type that this
|
||||
/// `impl Trait` desugars to. e.g., if:
|
||||
///
|
||||
@ -1150,6 +1154,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
self.opaque_types.insert(
|
||||
def_id,
|
||||
OpaqueTypeDecl {
|
||||
opaque_type: ty,
|
||||
substs,
|
||||
definition_span,
|
||||
concrete_ty: ty_var,
|
||||
|
@ -147,7 +147,7 @@ use crate::TypeAndSubsts;
|
||||
use crate::lint;
|
||||
use crate::util::captures::Captures;
|
||||
use crate::util::common::{ErrorReported, indenter};
|
||||
use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashSet, HirIdMap};
|
||||
use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, HirIdMap};
|
||||
|
||||
pub use self::Expectation::*;
|
||||
use self::autoderef::Autoderef;
|
||||
@ -231,6 +231,13 @@ pub struct Inherited<'a, 'tcx> {
|
||||
// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
|
||||
opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
|
||||
|
||||
/// A map from inference variables created from opaque
|
||||
/// type instantiations (`ty::Infer`) to the actual opaque
|
||||
/// type (`ty::Opaque`). Used during fallback to map unconstrained
|
||||
/// opaque type inference variables to their corresponding
|
||||
/// opaque type.
|
||||
opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
|
||||
|
||||
/// Each type parameter has an implicit region bound that
|
||||
/// indicates it must outlive at least the function body (the user
|
||||
/// may specify stronger requirements). This field indicates the
|
||||
@ -696,6 +703,7 @@ impl Inherited<'a, 'tcx> {
|
||||
deferred_cast_checks: RefCell::new(Vec::new()),
|
||||
deferred_generator_interiors: RefCell::new(Vec::new()),
|
||||
opaque_types: RefCell::new(Default::default()),
|
||||
opaque_types_vars: RefCell::new(Default::default()),
|
||||
implicit_region_bound,
|
||||
body_id,
|
||||
}
|
||||
@ -937,9 +945,46 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
|
||||
// All type checking constraints were added, try to fallback unsolved variables.
|
||||
fcx.select_obligations_where_possible(false, |_| {});
|
||||
let mut fallback_has_occurred = false;
|
||||
|
||||
// We do fallback in two passes, to try to generate
|
||||
// better error messages.
|
||||
// The first time, we do *not* replace opaque types.
|
||||
for ty in &fcx.unsolved_variables() {
|
||||
fallback_has_occurred |= fcx.fallback_if_possible(ty);
|
||||
fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
|
||||
}
|
||||
// We now see if we can make progress. This might
|
||||
// cause us to unify inference variables for opaque types,
|
||||
// since we may have unified some other type variables
|
||||
// during the first phase of fallback.
|
||||
// This means that we only replace inference variables with their underlying
|
||||
// opaque types as a last resort.
|
||||
//
|
||||
// In code like this:
|
||||
//
|
||||
// ```rust
|
||||
// type MyType = impl Copy;
|
||||
// fn produce() -> MyType { true }
|
||||
// fn bad_produce() -> MyType { panic!() }
|
||||
// ```
|
||||
//
|
||||
// we want to unify the opaque inference variable in `bad_produce`
|
||||
// with the diverging fallback for `panic!` (e.g. `()` or `!`).
|
||||
// This will produce a nice error message about conflicting concrete
|
||||
// types for `MyType`.
|
||||
//
|
||||
// If we had tried to fallback the opaque inference variable to `MyType`,
|
||||
// we will generate a confusing type-check error that does not explicitly
|
||||
// refer to opaque types.
|
||||
fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
|
||||
|
||||
// We now run fallback again, but this time we allow it to replace
|
||||
// unconstrained opaque type variables, in addition to performing
|
||||
// other kinds of fallback.
|
||||
for ty in &fcx.unsolved_variables() {
|
||||
fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
|
||||
}
|
||||
|
||||
// See if we can make any more progress.
|
||||
fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
|
||||
|
||||
// Even though coercion casts provide type hints, we check casts after fallback for
|
||||
@ -2499,6 +2544,16 @@ enum TupleArgumentsFlag {
|
||||
TupleArguments,
|
||||
}
|
||||
|
||||
/// Controls how we perform fallback for unconstrained
|
||||
/// type variables.
|
||||
enum FallbackMode {
|
||||
/// Do not fallback type variables to opaque types.
|
||||
NoOpaque,
|
||||
/// Perform all possible kinds of fallback, including
|
||||
/// turning type variables to opaque types.
|
||||
All,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub fn new(
|
||||
inh: &'a Inherited<'a, 'tcx>,
|
||||
@ -2864,8 +2919,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
|
||||
let mut opaque_types = self.opaque_types.borrow_mut();
|
||||
let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
|
||||
for (ty, decl) in opaque_type_map {
|
||||
let _ = opaque_types.insert(ty, decl);
|
||||
let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
|
||||
}
|
||||
|
||||
value
|
||||
@ -3078,7 +3135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Fallback becomes very dubious if we have encountered type-checking errors.
|
||||
// In that case, fallback to Error.
|
||||
// The return value indicates whether fallback has occurred.
|
||||
fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
|
||||
fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
|
||||
use rustc::ty::error::UnconstrainedNumeric::Neither;
|
||||
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
|
||||
|
||||
@ -3088,7 +3145,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
UnconstrainedInt => self.tcx.types.i32,
|
||||
UnconstrainedFloat => self.tcx.types.f64,
|
||||
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
|
||||
Neither => return false,
|
||||
Neither => {
|
||||
// This type variable was created from the instantiation of an opaque
|
||||
// type. The fact that we're attempting to perform fallback for it
|
||||
// means that the function neither constrained it to a concrete
|
||||
// type, nor to the opaque type itself.
|
||||
//
|
||||
// For example, in this code:
|
||||
//
|
||||
//```
|
||||
// type MyType = impl Copy;
|
||||
// fn defining_use() -> MyType { true }
|
||||
// fn other_use() -> MyType { defining_use() }
|
||||
// ```
|
||||
//
|
||||
// `defining_use` will constrain the instantiated inference
|
||||
// variable to `bool`, while `other_use` will constrain
|
||||
// the instantiated inference variable to `MyType`.
|
||||
//
|
||||
// When we process opaque types during writeback, we
|
||||
// will handle cases like `other_use`, and not count
|
||||
// them as defining usages
|
||||
//
|
||||
// However, we also need to handle cases like this:
|
||||
//
|
||||
// ```rust
|
||||
// pub type Foo = impl Copy;
|
||||
// fn produce() -> Option<Foo> {
|
||||
// None
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// In the above snippet, the inference varaible created by
|
||||
// instantiating `Option<Foo>` will be completely unconstrained.
|
||||
// We treat this as a non-defining use by making the inference
|
||||
// variable fall back to the opaque type itself.
|
||||
if let FallbackMode::All = mode {
|
||||
if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
|
||||
debug!("fallback_if_possible: falling back opaque type var {:?} to {:?}",
|
||||
ty, opaque_ty);
|
||||
*opaque_ty
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
|
||||
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
|
||||
|
9
src/test/ui/impl-trait/where-allowed-2.rs
Normal file
9
src/test/ui/impl-trait/where-allowed-2.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//! Ideally, these tests would go in `where-allowed.rs`, but we bail out
|
||||
//! too early to display them.
|
||||
use std::fmt::Debug;
|
||||
|
||||
// Disallowed
|
||||
fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
|
||||
//~^ ERROR opaque type expands to a recursive type
|
||||
|
||||
fn main() {}
|
11
src/test/ui/impl-trait/where-allowed-2.stderr
Normal file
11
src/test/ui/impl-trait/where-allowed-2.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0720]: opaque type expands to a recursive type
|
||||
--> $DIR/where-allowed-2.rs:6:30
|
||||
|
|
||||
LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
|
||||
| ^^^^^^^^^^ expands to a recursive type
|
||||
|
|
||||
= note: type resolves to itself
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0720`.
|
@ -11,10 +11,6 @@ fn in_return() -> impl Debug { panic!() }
|
||||
// Allowed
|
||||
fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
|
||||
|
||||
// Disallowed
|
||||
fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
|
||||
//~^ ERROR type annotations needed
|
||||
|
||||
// Disallowed
|
||||
fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
|
||||
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
|
||||
@ -60,7 +56,6 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
|
||||
fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
|
||||
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
|
||||
//~| ERROR nested `impl Trait` is not allowed
|
||||
//~| ERROR type annotations needed
|
||||
|
||||
// Disallowed
|
||||
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0666]: nested `impl Trait` is not allowed
|
||||
--> $DIR/where-allowed.rs:51:51
|
||||
--> $DIR/where-allowed.rs:47:51
|
||||
|
|
||||
LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
|
||||
| --------^^^^^^^^^^-
|
||||
@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
|
||||
| outer `impl Trait`
|
||||
|
||||
error[E0666]: nested `impl Trait` is not allowed
|
||||
--> $DIR/where-allowed.rs:60:57
|
||||
--> $DIR/where-allowed.rs:56:57
|
||||
|
|
||||
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
|
||||
| --------^^^^^^^^^^-
|
||||
@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
|
||||
| outer `impl Trait`
|
||||
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:124:16
|
||||
--> $DIR/where-allowed.rs:119:16
|
||||
|
|
||||
LL | type Out = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
@ -26,7 +26,7 @@ LL | type Out = impl Debug;
|
||||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:160:23
|
||||
--> $DIR/where-allowed.rs:155:23
|
||||
|
|
||||
LL | type InTypeAlias<R> = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug;
|
||||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:164:39
|
||||
--> $DIR/where-allowed.rs:159:39
|
||||
|
|
||||
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
@ -44,205 +44,205 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:19:40
|
||||
--> $DIR/where-allowed.rs:15:40
|
||||
|
|
||||
LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:23:42
|
||||
--> $DIR/where-allowed.rs:19:42
|
||||
|
|
||||
LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:27:38
|
||||
--> $DIR/where-allowed.rs:23:38
|
||||
|
|
||||
LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:31:40
|
||||
--> $DIR/where-allowed.rs:27:40
|
||||
|
|
||||
LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:35:49
|
||||
--> $DIR/where-allowed.rs:31:49
|
||||
|
|
||||
LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:39:51
|
||||
--> $DIR/where-allowed.rs:35:51
|
||||
|
|
||||
LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:43:55
|
||||
--> $DIR/where-allowed.rs:39:55
|
||||
|
|
||||
LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:47:57
|
||||
--> $DIR/where-allowed.rs:43:57
|
||||
|
|
||||
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:51:51
|
||||
--> $DIR/where-allowed.rs:47:51
|
||||
|
|
||||
LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:56:53
|
||||
--> $DIR/where-allowed.rs:52:53
|
||||
|
|
||||
LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:60:57
|
||||
--> $DIR/where-allowed.rs:56:57
|
||||
|
|
||||
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:66:59
|
||||
--> $DIR/where-allowed.rs:61:59
|
||||
|
|
||||
LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:70:38
|
||||
--> $DIR/where-allowed.rs:65:38
|
||||
|
|
||||
LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:74:40
|
||||
--> $DIR/where-allowed.rs:69:40
|
||||
|
|
||||
LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:87:32
|
||||
--> $DIR/where-allowed.rs:82:32
|
||||
|
|
||||
LL | struct InBraceStructField { x: impl Debug }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:91:41
|
||||
--> $DIR/where-allowed.rs:86:41
|
||||
|
|
||||
LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:95:27
|
||||
--> $DIR/where-allowed.rs:90:27
|
||||
|
|
||||
LL | struct InTupleStructField(impl Debug);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:100:25
|
||||
--> $DIR/where-allowed.rs:95:25
|
||||
|
|
||||
LL | InBraceVariant { x: impl Debug },
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:102:20
|
||||
--> $DIR/where-allowed.rs:97:20
|
||||
|
|
||||
LL | InTupleVariant(impl Debug),
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:113:23
|
||||
--> $DIR/where-allowed.rs:108:23
|
||||
|
|
||||
LL | fn in_return() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:131:34
|
||||
--> $DIR/where-allowed.rs:126:34
|
||||
|
|
||||
LL | fn in_trait_impl_return() -> impl Debug { () }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:144:33
|
||||
--> $DIR/where-allowed.rs:139:33
|
||||
|
|
||||
LL | fn in_foreign_parameters(_: impl Debug);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:147:31
|
||||
--> $DIR/where-allowed.rs:142:31
|
||||
|
|
||||
LL | fn in_foreign_return() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:164:39
|
||||
--> $DIR/where-allowed.rs:159:39
|
||||
|
|
||||
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:169:16
|
||||
--> $DIR/where-allowed.rs:164:16
|
||||
|
|
||||
LL | impl PartialEq<impl Debug> for () {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:174:24
|
||||
--> $DIR/where-allowed.rs:169:24
|
||||
|
|
||||
LL | impl PartialEq<()> for impl Debug {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:179:6
|
||||
--> $DIR/where-allowed.rs:174:6
|
||||
|
|
||||
LL | impl impl Debug {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:185:24
|
||||
--> $DIR/where-allowed.rs:180:24
|
||||
|
|
||||
LL | impl InInherentImplAdt<impl Debug> {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:191:11
|
||||
--> $DIR/where-allowed.rs:186:11
|
||||
|
|
||||
LL | where impl Debug: Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:198:15
|
||||
--> $DIR/where-allowed.rs:193:15
|
||||
|
|
||||
LL | where Vec<impl Debug>: Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:205:24
|
||||
--> $DIR/where-allowed.rs:200:24
|
||||
|
|
||||
LL | where T: PartialEq<impl Debug>
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:212:17
|
||||
--> $DIR/where-allowed.rs:207:17
|
||||
|
|
||||
LL | where T: Fn(impl Debug)
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:219:22
|
||||
--> $DIR/where-allowed.rs:214:22
|
||||
|
|
||||
LL | where T: Fn() -> impl Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:225:29
|
||||
--> $DIR/where-allowed.rs:220:29
|
||||
|
|
||||
LL | let _in_local_variable: impl Fn() = || {};
|
||||
| ^^^^^^^^^
|
||||
@ -250,36 +250,24 @@ LL | let _in_local_variable: impl Fn() = || {};
|
||||
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:227:46
|
||||
--> $DIR/where-allowed.rs:222:46
|
||||
|
|
||||
LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/where-allowed.rs:15:30
|
||||
|
|
||||
LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
|
||||
| ^^^^^^^^^^ cannot infer type
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/where-allowed.rs:60:49
|
||||
|
|
||||
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/where-allowed.rs:160:1
|
||||
--> $DIR/where-allowed.rs:155:1
|
||||
|
|
||||
LL | type InTypeAlias<R> = impl Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/where-allowed.rs:124:5
|
||||
--> $DIR/where-allowed.rs:119:5
|
||||
|
|
||||
LL | type Out = impl Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 44 previous errors
|
||||
error: aborting due to 42 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0562, E0658, E0666.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
Some errors have detailed explanations: E0562, E0658, E0666.
|
||||
For more information about an error, try `rustc --explain E0562`.
|
||||
|
28
src/test/ui/type-alias-impl-trait/fallback.rs
Normal file
28
src/test/ui/type-alias-impl-trait/fallback.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// Tests that we correctly handle the instantiated
|
||||
// inference variable being completely unconstrained.
|
||||
//
|
||||
// check-pass
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Copy;
|
||||
|
||||
enum Wrapper<T> {
|
||||
First(T),
|
||||
Second
|
||||
}
|
||||
|
||||
// This method constrains `Foo` to be `bool`
|
||||
fn constrained_foo() -> Foo {
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
// This method does not constrain `Foo`.
|
||||
// Per RFC 2071, function bodies may either
|
||||
// fully constrain an opaque type, or place no
|
||||
// constraints on it.
|
||||
fn unconstrained_foo() -> Wrapper<Foo> {
|
||||
Wrapper::Second
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user