(Re-)Implement impl_trait_in_bindings
This commit is contained in:
parent
1da411e750
commit
d714a22e7b
45 changed files with 391 additions and 25 deletions
|
@ -1,5 +1,6 @@
|
||||||
use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
|
use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_span::sym;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
|
use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
|
||||||
|
@ -82,11 +83,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
(self.arena.alloc_from_iter(stmts), expr)
|
(self.arena.alloc_from_iter(stmts), expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an `ImplTraitContext` that allows impl trait in bindings if
|
||||||
|
/// the feature gate is enabled, or issues a feature error if it is not.
|
||||||
|
fn impl_trait_in_bindings_ctxt(&self, position: ImplTraitPosition) -> ImplTraitContext {
|
||||||
|
if self.tcx.features().impl_trait_in_bindings() {
|
||||||
|
ImplTraitContext::InBinding
|
||||||
|
} else {
|
||||||
|
ImplTraitContext::FeatureGated(position, sym::impl_trait_in_bindings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
|
fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
|
||||||
let ty = l
|
// Let statements are allowed to have impl trait in bindings.
|
||||||
.ty
|
let ty = l.ty.as_ref().map(|t| {
|
||||||
.as_ref()
|
self.lower_ty(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))
|
||||||
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
|
});
|
||||||
let init = l.kind.init().map(|init| self.lower_expr(init));
|
let init = l.kind.init().map(|init| self.lower_expr(init));
|
||||||
let hir_id = self.lower_node_id(l.id);
|
let hir_id = self.lower_node_id(l.id);
|
||||||
let pat = self.lower_pat(&l.pat);
|
let pat = self.lower_pat(&l.pat);
|
||||||
|
|
|
@ -260,6 +260,13 @@ enum ImplTraitContext {
|
||||||
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
||||||
///
|
///
|
||||||
OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
|
OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
|
||||||
|
|
||||||
|
/// Treat `impl Trait` as a "trait ascription", which is like a type
|
||||||
|
/// variable but that also enforces that a set of trait goals hold.
|
||||||
|
///
|
||||||
|
/// This is useful to guide inference for unnameable types.
|
||||||
|
InBinding,
|
||||||
|
|
||||||
/// `impl Trait` is unstably accepted in this position.
|
/// `impl Trait` is unstably accepted in this position.
|
||||||
FeatureGated(ImplTraitPosition, Symbol),
|
FeatureGated(ImplTraitPosition, Symbol),
|
||||||
/// `impl Trait` is not accepted in this position.
|
/// `impl Trait` is not accepted in this position.
|
||||||
|
@ -1327,6 +1334,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
ImplTraitContext::InBinding => {
|
||||||
|
hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
|
||||||
|
}
|
||||||
ImplTraitContext::FeatureGated(position, feature) => {
|
ImplTraitContext::FeatureGated(position, feature) => {
|
||||||
let guar = self
|
let guar = self
|
||||||
.tcx
|
.tcx
|
||||||
|
|
|
@ -997,7 +997,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind
|
if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind
|
||||||
&& let DefKind::InlineConst = tcx.def_kind(def)
|
&& let DefKind::InlineConst = tcx.def_kind(def)
|
||||||
{
|
{
|
||||||
// TODO:
|
assert!(annotation.bounds.is_empty());
|
||||||
self.check_inline_const(inferred_ty, def.expect_local(), args, span);
|
self.check_inline_const(inferred_ty, def.expect_local(), args, span);
|
||||||
} else {
|
} else {
|
||||||
self.ascribe_user_type(inferred_ty, annotation, span);
|
self.ascribe_user_type(inferred_ty, annotation, span);
|
||||||
|
|
|
@ -126,9 +126,6 @@ declare_features! (
|
||||||
better implied higher-ranked implied bounds support"
|
better implied higher-ranked implied bounds support"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
|
|
||||||
(removed, impl_trait_in_bindings, "1.55.0", Some(63065),
|
|
||||||
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
|
|
||||||
(removed, import_shadowing, "1.0.0", None, None),
|
(removed, import_shadowing, "1.0.0", None, None),
|
||||||
/// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
|
/// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
|
||||||
(removed, in_band_lifetimes, "1.23.0", Some(44524),
|
(removed, in_band_lifetimes, "1.23.0", Some(44524),
|
||||||
|
|
|
@ -517,6 +517,8 @@ declare_features! (
|
||||||
(unstable, if_let_guard, "1.47.0", Some(51114)),
|
(unstable, if_let_guard, "1.47.0", Some(51114)),
|
||||||
/// Allows `impl Trait` to be used inside associated types (RFC 2515).
|
/// Allows `impl Trait` to be used inside associated types (RFC 2515).
|
||||||
(unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
|
(unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
|
||||||
|
/// Allows `impl Trait` in bindings (`let`).
|
||||||
|
(unstable, impl_trait_in_bindings, "1.64.0", Some(63065)),
|
||||||
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
|
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
|
||||||
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
|
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
|
||||||
/// Allows associated types in inherent impls.
|
/// Allows associated types in inherent impls.
|
||||||
|
|
|
@ -2906,6 +2906,8 @@ pub enum TyKind<'hir> {
|
||||||
Path(QPath<'hir>),
|
Path(QPath<'hir>),
|
||||||
/// An opaque type definition itself. This is only used for `impl Trait`.
|
/// An opaque type definition itself. This is only used for `impl Trait`.
|
||||||
OpaqueDef(&'hir OpaqueTy<'hir>),
|
OpaqueDef(&'hir OpaqueTy<'hir>),
|
||||||
|
/// A trait ascription type, which is `impl Trait` within a local binding.
|
||||||
|
TraitAscription(GenericBounds<'hir>),
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
||||||
|
|
|
@ -900,6 +900,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
|
||||||
TyKind::OpaqueDef(opaque) => {
|
TyKind::OpaqueDef(opaque) => {
|
||||||
try_visit!(visitor.visit_opaque_ty(opaque));
|
try_visit!(visitor.visit_opaque_ty(opaque));
|
||||||
}
|
}
|
||||||
|
TyKind::TraitAscription(bounds) => {
|
||||||
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
|
}
|
||||||
TyKind::Array(ref ty, ref length) => {
|
TyKind::Array(ref ty, ref length) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
try_visit!(visitor.visit_const_arg(length));
|
try_visit!(visitor.visit_const_arg(length));
|
||||||
|
|
|
@ -29,7 +29,7 @@ use rustc_errors::{
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{self, Visitor, walk_generics};
|
use rustc_hir::intravisit::{self, Visitor, walk_generics};
|
||||||
use rustc_hir::{self as hir, GenericParamKind, Node};
|
use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
|
@ -436,6 +436,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
||||||
ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
|
ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_trait_ascription_bounds(
|
||||||
|
&self,
|
||||||
|
_: Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
|
_: HirId,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
self.dcx().span_delayed_bug(span, "trait ascription type not allowed here");
|
||||||
|
}
|
||||||
|
|
||||||
fn probe_ty_param_bounds(
|
fn probe_ty_param_bounds(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -852,6 +852,21 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
self.with(scope, |this| this.visit_ty(mt.ty));
|
self.with(scope, |this| this.visit_ty(mt.ty));
|
||||||
}
|
}
|
||||||
|
hir::TyKind::TraitAscription(bounds) => {
|
||||||
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
|
self.with(scope, |this| {
|
||||||
|
let scope = Scope::LateBoundary {
|
||||||
|
s: this.scope,
|
||||||
|
what: "`impl Trait` in binding",
|
||||||
|
deny_late_regions: true,
|
||||||
|
};
|
||||||
|
this.with(scope, |this| {
|
||||||
|
for bound in bounds {
|
||||||
|
this.visit_param_bound(bound);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
_ => intravisit::walk_ty(self, ty),
|
_ => intravisit::walk_ty(self, ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,13 @@ pub trait HirTyLowerer<'tcx> {
|
||||||
/// Returns the const to use when a const is omitted.
|
/// Returns the const to use when a const is omitted.
|
||||||
fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
|
fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
|
||||||
|
|
||||||
|
fn register_trait_ascription_bounds(
|
||||||
|
&self,
|
||||||
|
bounds: Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
|
hir_id: HirId,
|
||||||
|
span: Span,
|
||||||
|
);
|
||||||
|
|
||||||
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
|
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
|
||||||
///
|
///
|
||||||
/// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
|
/// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
|
||||||
|
@ -2375,6 +2382,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
|
|
||||||
self.lower_opaque_ty(opaque_ty.def_id, in_trait)
|
self.lower_opaque_ty(opaque_ty.def_id, in_trait)
|
||||||
}
|
}
|
||||||
|
hir::TyKind::TraitAscription(hir_bounds) => {
|
||||||
|
// Impl trait in bindings lower as an infer var with additional
|
||||||
|
// set of type bounds.
|
||||||
|
let self_ty = self.ty_infer(None, hir_ty.span);
|
||||||
|
let mut bounds = Bounds::default();
|
||||||
|
self.lower_bounds(
|
||||||
|
self_ty,
|
||||||
|
hir_bounds.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
PredicateFilter::All,
|
||||||
|
);
|
||||||
|
self.register_trait_ascription_bounds(
|
||||||
|
bounds.clauses().collect(),
|
||||||
|
hir_ty.hir_id,
|
||||||
|
hir_ty.span,
|
||||||
|
);
|
||||||
|
self_ty
|
||||||
|
}
|
||||||
// If we encounter a type relative path with RTN generics, then it must have
|
// If we encounter a type relative path with RTN generics, then it must have
|
||||||
// *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
|
// *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
|
||||||
// it's certainly in an illegal position.
|
// it's certainly in an illegal position.
|
||||||
|
|
|
@ -292,6 +292,9 @@ impl<'a> State<'a> {
|
||||||
self.print_unsafe_binder(unsafe_binder);
|
self.print_unsafe_binder(unsafe_binder);
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
||||||
|
hir::TyKind::TraitAscription(bounds) => {
|
||||||
|
self.print_bounds("impl", bounds);
|
||||||
|
}
|
||||||
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
|
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
|
||||||
if syntax == ast::TraitObjectSyntax::Dyn {
|
if syntax == ast::TraitObjectSyntax::Dyn {
|
||||||
|
|
|
@ -4,11 +4,11 @@ use std::slice;
|
||||||
use rustc_abi::FieldIdx;
|
use rustc_abi::FieldIdx;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
|
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{ExprKind, GenericArg, HirId, Node, QPath};
|
use rustc_hir::{self as hir, ExprKind, GenericArg, HirId, Node, QPath, intravisit};
|
||||||
use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend;
|
use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend;
|
||||||
use rustc_hir_analysis::hir_ty_lowering::generics::{
|
use rustc_hir_analysis::hir_ty_lowering::generics::{
|
||||||
check_generic_arg_count_for_call, lower_generic_args,
|
check_generic_arg_count_for_call, lower_generic_args,
|
||||||
|
@ -460,8 +460,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
LoweredTy::from_raw(self, hir_ty.span, ty)
|
LoweredTy::from_raw(self, hir_ty.span, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Walk a `hir_ty` and collect any clauses that may have come from a type
|
||||||
|
/// within the `hir_ty`. These clauses will be canonicalized with a user type
|
||||||
|
/// annotation so that we can enforce these bounds in borrowck, too.
|
||||||
|
pub(crate) fn collect_impl_trait_clauses_from_hir_ty(
|
||||||
|
&self,
|
||||||
|
hir_ty: &'tcx hir::Ty<'tcx>,
|
||||||
|
) -> ty::Clauses<'tcx> {
|
||||||
|
struct CollectClauses<'a, 'tcx> {
|
||||||
|
clauses: Vec<ty::Clause<'tcx>>,
|
||||||
|
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> intravisit::Visitor<'tcx> for CollectClauses<'_, 'tcx> {
|
||||||
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
|
if let Some(clauses) = self.fcx.trait_ascriptions.borrow().get(&ty.hir_id.local_id)
|
||||||
|
{
|
||||||
|
self.clauses.extend(clauses.iter().cloned());
|
||||||
|
}
|
||||||
|
intravisit::walk_ty(self, ty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut clauses = CollectClauses { clauses: vec![], fcx: self };
|
||||||
|
clauses.visit_ty(hir_ty);
|
||||||
|
self.tcx.mk_clauses(&clauses.clauses)
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip_all)]
|
#[instrument(level = "debug", skip_all)]
|
||||||
pub(crate) fn lower_ty_saving_user_provided_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
pub(crate) fn lower_ty_saving_user_provided_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||||
let ty = self.lower_ty(hir_ty);
|
let ty = self.lower_ty(hir_ty);
|
||||||
debug!(?ty);
|
debug!(?ty);
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,11 @@ use std::ops::Deref;
|
||||||
|
|
||||||
use hir::def_id::CRATE_DEF_ID;
|
use hir::def_id::CRATE_DEF_ID;
|
||||||
use rustc_errors::DiagCtxtHandle;
|
use rustc_errors::DiagCtxtHandle;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
|
use rustc_hir::{self as hir, HirId, ItemLocalMap};
|
||||||
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
|
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
|
||||||
use rustc_infer::infer;
|
use rustc_infer::infer;
|
||||||
|
use rustc_infer::traits::Obligation;
|
||||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
@ -114,6 +115,12 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
pub(super) diverging_fallback_behavior: DivergingFallbackBehavior,
|
pub(super) diverging_fallback_behavior: DivergingFallbackBehavior,
|
||||||
pub(super) diverging_block_behavior: DivergingBlockBehavior,
|
pub(super) diverging_block_behavior: DivergingBlockBehavior,
|
||||||
|
|
||||||
|
/// Clauses that we lowered as part of the `impl_trait_in_bindings` feature.
|
||||||
|
///
|
||||||
|
/// These are stored here so we may collect them when canonicalizing user
|
||||||
|
/// type ascriptions later.
|
||||||
|
pub(super) trait_ascriptions: RefCell<ItemLocalMap<Vec<ty::Clause<'tcx>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
@ -141,6 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fallback_has_occurred: Cell::new(false),
|
fallback_has_occurred: Cell::new(false),
|
||||||
diverging_fallback_behavior,
|
diverging_fallback_behavior,
|
||||||
diverging_block_behavior,
|
diverging_block_behavior,
|
||||||
|
trait_ascriptions: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +260,30 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_trait_ascription_bounds(
|
||||||
|
&self,
|
||||||
|
bounds: Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
|
hir_id: HirId,
|
||||||
|
_span: Span,
|
||||||
|
) {
|
||||||
|
for (clause, span) in bounds {
|
||||||
|
if clause.has_escaping_bound_vars() {
|
||||||
|
self.dcx().span_delayed_bug(span, "clause should have no escaping bound vars");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.trait_ascriptions.borrow_mut().entry(hir_id.local_id).or_default().push(clause);
|
||||||
|
|
||||||
|
let clause = self.normalize(span, clause);
|
||||||
|
self.register_predicate(Obligation::new(
|
||||||
|
self.tcx,
|
||||||
|
self.misc(span),
|
||||||
|
self.param_env,
|
||||||
|
clause,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn probe_ty_param_bounds(
|
fn probe_ty_param_bounds(
|
||||||
&self,
|
&self,
|
||||||
_: Span,
|
_: Span,
|
||||||
|
|
|
@ -92,9 +92,12 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
|
||||||
Some(ref ty) => {
|
Some(ref ty) => {
|
||||||
let o_ty = self.fcx.lower_ty(ty);
|
let o_ty = self.fcx.lower_ty(ty);
|
||||||
|
|
||||||
let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
|
let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(
|
||||||
|
ty::UserType::new_with_bounds(
|
||||||
ty::UserTypeKind::Ty(o_ty.raw),
|
ty::UserTypeKind::Ty(o_ty.raw),
|
||||||
));
|
self.fcx.collect_impl_trait_clauses_from_hir_ty(ty),
|
||||||
|
),
|
||||||
|
);
|
||||||
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
|
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
|
||||||
self.fcx
|
self.fcx
|
||||||
.typeck_results
|
.typeck_results
|
||||||
|
|
|
@ -323,7 +323,7 @@ macro_rules! define_callbacks {
|
||||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
if mem::size_of::<Key<'static>>() > 80 {
|
if mem::size_of::<Key<'static>>() > 88 {
|
||||||
panic!("{}", concat!(
|
panic!("{}", concat!(
|
||||||
"the query `",
|
"the query `",
|
||||||
stringify!($name),
|
stringify!($name),
|
||||||
|
|
|
@ -704,11 +704,18 @@ pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
|
||||||
#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct UserType<'tcx> {
|
pub struct UserType<'tcx> {
|
||||||
pub kind: UserTypeKind<'tcx>,
|
pub kind: UserTypeKind<'tcx>,
|
||||||
|
pub bounds: ty::Clauses<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UserType<'tcx> {
|
impl<'tcx> UserType<'tcx> {
|
||||||
pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
|
pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
|
||||||
UserType { kind }
|
UserType { kind, bounds: ty::ListWithCachedTypeInfo::empty() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A user type annotation with additional bounds that need to be enforced.
|
||||||
|
/// These bounds are lowered from `impl Trait` in bindings.
|
||||||
|
pub fn new_with_bounds(kind: UserTypeKind<'tcx>, bounds: ty::Clauses<'tcx>) -> UserType<'tcx> {
|
||||||
|
UserType { kind, bounds }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,7 +740,9 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||||
/// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
|
/// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
|
||||||
/// i.e., each thing is mapped to a canonical variable with the same index.
|
/// i.e., each thing is mapped to a canonical variable with the same index.
|
||||||
fn is_identity(&self) -> bool {
|
fn is_identity(&self) -> bool {
|
||||||
// TODO:
|
if !self.value.bounds.is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
match self.value.kind {
|
match self.value.kind {
|
||||||
UserTypeKind::Ty(_) => false,
|
UserTypeKind::Ty(_) => false,
|
||||||
|
@ -779,9 +788,13 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> std::fmt::Display for UserType<'tcx> {
|
impl<'tcx> std::fmt::Display for UserType<'tcx> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// TODO:
|
if self.bounds.is_empty() {
|
||||||
|
|
||||||
self.kind.fmt(f)
|
self.kind.fmt(f)
|
||||||
|
} else {
|
||||||
|
self.kind.fmt(f)?;
|
||||||
|
write!(f, " + ")?;
|
||||||
|
std::fmt::Debug::fmt(&self.bounds, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -371,6 +371,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
Tup,
|
Tup,
|
||||||
Path,
|
Path,
|
||||||
OpaqueDef,
|
OpaqueDef,
|
||||||
|
TraitAscription,
|
||||||
TraitObject,
|
TraitObject,
|
||||||
Typeof,
|
Typeof,
|
||||||
Infer,
|
Infer,
|
||||||
|
|
|
@ -52,6 +52,12 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
|
||||||
relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
|
relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enforce any bounds that come from impl trait in bindings.
|
||||||
|
ocx.register_obligations(user_ty.bounds.iter().map(|clause| {
|
||||||
|
Obligation::new(ocx.infcx.tcx, ObligationCause::dummy_with_span(span), param_env, clause)
|
||||||
|
}));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1839,11 +1839,15 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
DynTrait(bounds, lifetime)
|
DynTrait(bounds, lifetime)
|
||||||
}
|
}
|
||||||
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
|
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
|
||||||
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
|
|
||||||
TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) | TyKind::InferDelegation(..) => Infer,
|
|
||||||
TyKind::UnsafeBinder(..) => {
|
TyKind::UnsafeBinder(..) => {
|
||||||
unimplemented!("unsafe binders are not supported yet")
|
unimplemented!("unsafe binders are not supported yet")
|
||||||
}
|
}
|
||||||
|
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
|
||||||
|
TyKind::Infer
|
||||||
|
| TyKind::Err(_)
|
||||||
|
| TyKind::Typeof(..)
|
||||||
|
| TyKind::InferDelegation(..)
|
||||||
|
| TyKind::TraitAscription(_) => Infer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -814,6 +814,7 @@ impl TyCoercionStability {
|
||||||
| TyKind::Tup(_)
|
| TyKind::Tup(_)
|
||||||
| TyKind::Path(_) => Self::Deref,
|
| TyKind::Path(_) => Self::Deref,
|
||||||
TyKind::OpaqueDef(..)
|
TyKind::OpaqueDef(..)
|
||||||
|
| TyKind::TraitAscription(..)
|
||||||
| TyKind::Infer
|
| TyKind::Infer
|
||||||
| TyKind::Typeof(..)
|
| TyKind::Typeof(..)
|
||||||
| TyKind::TraitObject(..)
|
| TyKind::TraitObject(..)
|
||||||
|
|
|
@ -1260,7 +1260,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
| TyKind::Infer
|
| TyKind::Infer
|
||||||
| TyKind::Never
|
| TyKind::Never
|
||||||
| TyKind::InferDelegation(..)
|
| TyKind::InferDelegation(..)
|
||||||
| TyKind::OpaqueDef(_) => {},
|
| TyKind::OpaqueDef(_)
|
||||||
|
| TyKind::TraitAscription(_) => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let x: impl Sized = ();
|
||||||
|
//~^ ERROR `impl Trait` is not allowed in the type of variable bindings
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
|
||||||
|
--> $DIR/feature-gate-impl-trait-in-bindings.rs:2:12
|
||||||
|
|
|
||||||
|
LL | let x: impl Sized = ();
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0562`.
|
10
tests/ui/impl-trait/in-bindings/bad-nesting.rs
Normal file
10
tests/ui/impl-trait/in-bindings/bad-nesting.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Foo<T> {}
|
||||||
|
|
||||||
|
impl Foo<()> for () {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: impl Foo<impl Sized> = ();
|
||||||
|
//~^ ERROR nested `impl Trait` is not allowed
|
||||||
|
}
|
12
tests/ui/impl-trait/in-bindings/bad-nesting.stderr
Normal file
12
tests/ui/impl-trait/in-bindings/bad-nesting.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0666]: nested `impl Trait` is not allowed
|
||||||
|
--> $DIR/bad-nesting.rs:8:21
|
||||||
|
|
|
||||||
|
LL | let x: impl Foo<impl Sized> = ();
|
||||||
|
| ---------^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | nested `impl Trait` here
|
||||||
|
| outer `impl Trait`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0666`.
|
14
tests/ui/impl-trait/in-bindings/escaping-bound-var.rs
Normal file
14
tests/ui/impl-trait/in-bindings/escaping-bound-var.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Foo<'a> {
|
||||||
|
type Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Foo<'a> for () {
|
||||||
|
type Out = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: &dyn for<'a> Foo<'a, Out = impl Sized + 'a> = &();
|
||||||
|
//~^ ERROR cannot capture late-bound lifetime in `impl Trait` in binding
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: cannot capture late-bound lifetime in `impl Trait` in binding
|
||||||
|
--> $DIR/escaping-bound-var.rs:12:52
|
||||||
|
|
|
||||||
|
LL | let x: &dyn for<'a> Foo<'a, Out = impl Sized + 'a> = &();
|
||||||
|
| -- lifetime defined here ^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
12
tests/ui/impl-trait/in-bindings/lifetime-failure.rs
Normal file
12
tests/ui/impl-trait/in-bindings/lifetime-failure.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Static: 'static {}
|
||||||
|
impl<T: 'static> Static for T {}
|
||||||
|
|
||||||
|
struct W<T>(T);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let local = 0;
|
||||||
|
let _: W<impl Static> = W(&local);
|
||||||
|
//~^ ERROR `local` does not live long enough
|
||||||
|
}
|
16
tests/ui/impl-trait/in-bindings/lifetime-failure.stderr
Normal file
16
tests/ui/impl-trait/in-bindings/lifetime-failure.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0597]: `local` does not live long enough
|
||||||
|
--> $DIR/lifetime-failure.rs:10:31
|
||||||
|
|
|
||||||
|
LL | let local = 0;
|
||||||
|
| ----- binding `local` declared here
|
||||||
|
LL | let _: W<impl Static> = W(&local);
|
||||||
|
| -------------- ^^^^^^ borrowed value does not live long enough
|
||||||
|
| |
|
||||||
|
| type annotation requires that `local` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
|
LL | }
|
||||||
|
| - `local` dropped here while still borrowed
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0597`.
|
10
tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs
Normal file
10
tests/ui/impl-trait/in-bindings/nesting-lifetime-failure.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Static {}
|
||||||
|
impl<T: 'static> Static for T {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let local = 0;
|
||||||
|
let _: impl IntoIterator<Item = impl Static> = [&local];
|
||||||
|
//~^ ERROR `local` does not live long enough
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0597]: `local` does not live long enough
|
||||||
|
--> $DIR/nesting-lifetime-failure.rs:8:53
|
||||||
|
|
|
||||||
|
LL | let local = 0;
|
||||||
|
| ----- binding `local` declared here
|
||||||
|
LL | let _: impl IntoIterator<Item = impl Static> = [&local];
|
||||||
|
| ------------------------------------- ^^^^^^ borrowed value does not live long enough
|
||||||
|
| |
|
||||||
|
| type annotation requires that `local` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
|
LL | }
|
||||||
|
| - `local` dropped here while still borrowed
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0597`.
|
7
tests/ui/impl-trait/in-bindings/nesting.rs
Normal file
7
tests/ui/impl-trait/in-bindings/nesting.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: impl IntoIterator<Item = impl Sized> = ["hello", " world"];
|
||||||
|
}
|
10
tests/ui/impl-trait/in-bindings/simple.rs
Normal file
10
tests/ui/impl-trait/in-bindings/simple.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Foo {}
|
||||||
|
impl Foo for () {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: impl Foo = ();
|
||||||
|
}
|
13
tests/ui/impl-trait/in-bindings/trait-failure.rs
Normal file
13
tests/ui/impl-trait/in-bindings/trait-failure.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
trait Foo {}
|
||||||
|
|
||||||
|
struct W<T>(T);
|
||||||
|
impl<T> Foo for W<T> where T: Foo {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: impl Foo = W(());
|
||||||
|
//~^ ERROR the trait bound `(): Foo` is not satisfied
|
||||||
|
let x: W<impl Foo> = W(());
|
||||||
|
//~^ ERROR the trait bound `(): Foo` is not satisfied
|
||||||
|
}
|
24
tests/ui/impl-trait/in-bindings/trait-failure.stderr
Normal file
24
tests/ui/impl-trait/in-bindings/trait-failure.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
|
--> $DIR/trait-failure.rs:9:17
|
||||||
|
|
|
||||||
|
LL | let x: impl Foo = W(());
|
||||||
|
| ^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
|
|
||||||
|
= help: the trait `Foo` is implemented for `W<T>`
|
||||||
|
note: required for `W<()>` to implement `Foo`
|
||||||
|
--> $DIR/trait-failure.rs:6:9
|
||||||
|
|
|
||||||
|
LL | impl<T> Foo for W<T> where T: Foo {}
|
||||||
|
| ^^^ ^^^^ --- unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
|
--> $DIR/trait-failure.rs:11:19
|
||||||
|
|
|
||||||
|
LL | let x: W<impl Foo> = W(());
|
||||||
|
| ^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
|
|
||||||
|
= help: the trait `Foo` is implemented for `W<T>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -5,6 +5,9 @@ LL | let x: Option<impl Debug> = Some(44_u32);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ LL | let j: &impl Add = &i;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ LL | let gens: [impl Coroutine<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ LL | let x: Wrap<impl Lam> = Wrap(B);
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ LL | let x : (impl Copy,) = (true,);
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ LL | let f: impl core::future::Future<Output = u8> = async { 1 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ LL | let _x: impl Trait = ();
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ LL | let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,9 @@ LL | let _in_local_variable: impl Fn() = || {};
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in closure return types
|
error[E0562]: `impl Trait` is not allowed in closure return types
|
||||||
--> $DIR/where-allowed.rs:253:46
|
--> $DIR/where-allowed.rs:253:46
|
||||||
|
|
|
@ -11,6 +11,9 @@ LL | let _: S<impl Oops> = S;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
|
||||||
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue