Rollup merge of #108186 - compiler-errors:closures-with-late-bound-types-r-bad, r=cjgillot
Deny non-lifetime bound vars in `for<..> ||` closure binders Moves the check for illegal bound var types from astconv to resolve_bound_vars. If a binder is defined to have a type or const late-bound var that's not allowed, we'll resolve any usages to ty error or const error values, so we shouldn't ever see late-bound types or consts in places they aren't expected. Fixes #108184 Fixes #108181 Fixes #108192
This commit is contained in:
commit
d3d5163921
23 changed files with 210 additions and 102 deletions
|
@ -474,7 +474,7 @@ declare_features! (
|
||||||
/// Allows using the `non_exhaustive_omitted_patterns` lint.
|
/// Allows using the `non_exhaustive_omitted_patterns` lint.
|
||||||
(active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
|
(active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
|
||||||
/// Allows `for<T>` binders in where-clauses
|
/// Allows `for<T>` binders in where-clauses
|
||||||
(incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(1), None),
|
(incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(108185), None),
|
||||||
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
|
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
|
||||||
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
|
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
|
||||||
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
|
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
|
||||||
|
|
|
@ -252,6 +252,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// (*) -- not late-bound, won't change
|
// (*) -- not late-bound, won't change
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(rbv::ResolvedArg::Error(_)) => {
|
||||||
|
bug!("only ty/ct should resolve as ResolvedArg::Error")
|
||||||
|
}
|
||||||
|
|
||||||
None => {
|
None => {
|
||||||
self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
|
self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
|
||||||
debug!(?lifetime, "unelided lifetime in signature");
|
debug!(?lifetime, "unelided lifetime in signature");
|
||||||
|
@ -2689,6 +2693,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
|
||||||
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
|
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
|
||||||
}
|
}
|
||||||
|
Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar),
|
||||||
arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
|
arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2893,22 +2898,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
hir::TyKind::BareFn(bf) => {
|
hir::TyKind::BareFn(bf) => {
|
||||||
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
|
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
|
||||||
|
|
||||||
let fn_ptr_ty = tcx.mk_fn_ptr(self.ty_of_fn(
|
tcx.mk_fn_ptr(self.ty_of_fn(
|
||||||
ast_ty.hir_id,
|
ast_ty.hir_id,
|
||||||
bf.unsafety,
|
bf.unsafety,
|
||||||
bf.abi,
|
bf.abi,
|
||||||
bf.decl,
|
bf.decl,
|
||||||
None,
|
None,
|
||||||
Some(ast_ty),
|
Some(ast_ty),
|
||||||
));
|
))
|
||||||
|
|
||||||
if let Some(guar) =
|
|
||||||
deny_non_region_late_bound(tcx, bf.generic_params, "function pointer")
|
|
||||||
{
|
|
||||||
tcx.ty_error_with_guaranteed(guar)
|
|
||||||
} else {
|
|
||||||
fn_ptr_ty
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
||||||
self.maybe_lint_bare_trait(ast_ty, in_path);
|
self.maybe_lint_bare_trait(ast_ty, in_path);
|
||||||
|
@ -2917,21 +2914,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
TraitObjectSyntax::DynStar => ty::DynStar,
|
TraitObjectSyntax::DynStar => ty::DynStar,
|
||||||
};
|
};
|
||||||
|
|
||||||
let object_ty = self.conv_object_ty_poly_trait_ref(
|
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
|
||||||
ast_ty.span,
|
|
||||||
bounds,
|
|
||||||
lifetime,
|
|
||||||
borrowed,
|
|
||||||
repr,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(guar) = bounds.iter().find_map(|trait_ref| {
|
|
||||||
deny_non_region_late_bound(tcx, trait_ref.bound_generic_params, "trait object")
|
|
||||||
}) {
|
|
||||||
tcx.ty_error_with_guaranteed(guar)
|
|
||||||
} else {
|
|
||||||
object_ty
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||||
debug!(?maybe_qself, ?path);
|
debug!(?maybe_qself, ?path);
|
||||||
|
@ -3392,24 +3375,3 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deny_non_region_late_bound(
|
|
||||||
tcx: TyCtxt<'_>,
|
|
||||||
params: &[hir::GenericParam<'_>],
|
|
||||||
where_: &str,
|
|
||||||
) -> Option<ErrorGuaranteed> {
|
|
||||||
params.iter().find_map(|bad_param| {
|
|
||||||
let what = match bad_param.kind {
|
|
||||||
hir::GenericParamKind::Type { .. } => "type",
|
|
||||||
hir::GenericParamKind::Const { .. } => "const",
|
|
||||||
hir::GenericParamKind::Lifetime { .. } => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut diag = tcx.sess.struct_span_err(
|
|
||||||
bad_param.span,
|
|
||||||
format!("late-bound {what} parameter not allowed on {where_} types"),
|
|
||||||
);
|
|
||||||
|
|
||||||
Some(if tcx.features().non_lifetime_binders { diag.emit() } else { diag.delay_as_bug() })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -398,7 +398,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {}
|
Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {}
|
||||||
Some(rbv::ResolvedArg::LateBound(debruijn, _, _))
|
Some(rbv::ResolvedArg::LateBound(debruijn, _, _))
|
||||||
if debruijn < self.outer_index => {}
|
if debruijn < self.outer_index => {}
|
||||||
Some(rbv::ResolvedArg::LateBound(..) | rbv::ResolvedArg::Free(..)) | None => {
|
Some(
|
||||||
|
rbv::ResolvedArg::LateBound(..)
|
||||||
|
| rbv::ResolvedArg::Free(..)
|
||||||
|
| rbv::ResolvedArg::Error(_),
|
||||||
|
)
|
||||||
|
| None => {
|
||||||
self.has_late_bound_regions = Some(lt.ident.span);
|
self.has_late_bound_regions = Some(lt.ident.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl RegionExt for ResolvedArg {
|
||||||
|
|
||||||
fn id(&self) -> Option<DefId> {
|
fn id(&self) -> Option<DefId> {
|
||||||
match *self {
|
match *self {
|
||||||
ResolvedArg::StaticLifetime => None,
|
ResolvedArg::StaticLifetime | ResolvedArg::Error(_) => None,
|
||||||
|
|
||||||
ResolvedArg::EarlyBound(id)
|
ResolvedArg::EarlyBound(id)
|
||||||
| ResolvedArg::LateBound(_, _, id)
|
| ResolvedArg::LateBound(_, _, id)
|
||||||
|
@ -336,7 +336,57 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_poly_trait_ref_inner(
|
||||||
|
&mut self,
|
||||||
|
trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
|
||||||
|
non_lifetime_binder_allowed: NonLifetimeBinderAllowed,
|
||||||
|
) {
|
||||||
|
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
||||||
|
|
||||||
|
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
|
||||||
|
|
||||||
|
let initial_bound_vars = binders.len() as u32;
|
||||||
|
let mut bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = FxIndexMap::default();
|
||||||
|
let binders_iter =
|
||||||
|
trait_ref.bound_generic_params.iter().enumerate().map(|(late_bound_idx, param)| {
|
||||||
|
let pair = ResolvedArg::late(initial_bound_vars + late_bound_idx as u32, param);
|
||||||
|
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
|
||||||
|
bound_vars.insert(pair.0, pair.1);
|
||||||
|
r
|
||||||
|
});
|
||||||
|
binders.extend(binders_iter);
|
||||||
|
|
||||||
|
if let NonLifetimeBinderAllowed::Deny(where_) = non_lifetime_binder_allowed {
|
||||||
|
deny_non_region_late_bound(self.tcx, &mut bound_vars, where_);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!(?binders);
|
||||||
|
self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders);
|
||||||
|
|
||||||
|
// Always introduce a scope here, even if this is in a where clause and
|
||||||
|
// we introduced the binders around the bounded Ty. In that case, we
|
||||||
|
// just reuse the concatenation functionality also present in nested trait
|
||||||
|
// refs.
|
||||||
|
let scope = Scope::Binder {
|
||||||
|
hir_id: trait_ref.trait_ref.hir_ref_id,
|
||||||
|
bound_vars,
|
||||||
|
s: self.scope,
|
||||||
|
scope_type,
|
||||||
|
where_bound_origin: None,
|
||||||
|
};
|
||||||
|
self.with(scope, |this| {
|
||||||
|
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
||||||
|
this.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum NonLifetimeBinderAllowed {
|
||||||
|
Deny(&'static str),
|
||||||
|
Allow,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
type NestedFilter = nested_filter::OnlyBodies;
|
type NestedFilter = nested_filter::OnlyBodies;
|
||||||
|
|
||||||
|
@ -400,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
|
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
|
||||||
bound_generic_params
|
bound_generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -411,6 +461,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
|
deny_non_region_late_bound(self.tcx, &mut bound_vars, "closures");
|
||||||
|
|
||||||
self.record_late_bound_vars(e.hir_id, binders);
|
self.record_late_bound_vars(e.hir_id, binders);
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
hir_id: e.hir_id,
|
hir_id: e.hir_id,
|
||||||
|
@ -567,7 +619,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
hir::TyKind::BareFn(c) => {
|
hir::TyKind::BareFn(c) => {
|
||||||
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c
|
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c
|
||||||
.generic_params
|
.generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -577,6 +629,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
(pair, r)
|
(pair, r)
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
|
deny_non_region_late_bound(self.tcx, &mut bound_vars, "function pointer types");
|
||||||
|
|
||||||
self.record_late_bound_vars(ty.hir_id, binders);
|
self.record_late_bound_vars(ty.hir_id, binders);
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
hir_id: ty.hir_id,
|
hir_id: ty.hir_id,
|
||||||
|
@ -596,7 +651,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |this| {
|
self.with(scope, |this| {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_poly_trait_ref(bound);
|
this.visit_poly_trait_ref_inner(
|
||||||
|
bound,
|
||||||
|
NonLifetimeBinderAllowed::Deny("trait object types"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match lifetime.res {
|
match lifetime.res {
|
||||||
|
@ -967,39 +1025,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
|
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
|
||||||
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
|
||||||
|
|
||||||
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
|
|
||||||
|
|
||||||
let initial_bound_vars = binders.len() as u32;
|
|
||||||
let mut bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = FxIndexMap::default();
|
|
||||||
let binders_iter =
|
|
||||||
trait_ref.bound_generic_params.iter().enumerate().map(|(late_bound_idx, param)| {
|
|
||||||
let pair = ResolvedArg::late(initial_bound_vars + late_bound_idx as u32, param);
|
|
||||||
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
|
|
||||||
bound_vars.insert(pair.0, pair.1);
|
|
||||||
r
|
|
||||||
});
|
|
||||||
binders.extend(binders_iter);
|
|
||||||
|
|
||||||
debug!(?binders);
|
|
||||||
self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders);
|
|
||||||
|
|
||||||
// Always introduce a scope here, even if this is in a where clause and
|
|
||||||
// we introduced the binders around the bounded Ty. In that case, we
|
|
||||||
// just reuse the concatenation functionality also present in nested trait
|
|
||||||
// refs.
|
|
||||||
let scope = Scope::Binder {
|
|
||||||
hir_id: trait_ref.trait_ref.hir_ref_id,
|
|
||||||
bound_vars,
|
|
||||||
s: self.scope,
|
|
||||||
scope_type,
|
|
||||||
where_bound_origin: None,
|
|
||||||
};
|
|
||||||
self.with(scope, |this| {
|
|
||||||
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
|
||||||
this.visit_trait_ref(&trait_ref.trait_ref);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,7 +1390,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
span_bug!(self.tcx.hir().span(hir_id), "could not resolve {param_def_id:?}",);
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(self.tcx.hir().span(hir_id), "could not resolve {param_def_id:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
@ -1915,3 +1943,37 @@ fn is_late_bound_map(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deny_non_region_late_bound(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
bound_vars: &mut FxIndexMap<LocalDefId, ResolvedArg>,
|
||||||
|
where_: &str,
|
||||||
|
) {
|
||||||
|
let mut first = true;
|
||||||
|
|
||||||
|
for (var, arg) in bound_vars {
|
||||||
|
let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else {
|
||||||
|
bug!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let what = match param.kind {
|
||||||
|
hir::GenericParamKind::Type { .. } => "type",
|
||||||
|
hir::GenericParamKind::Const { .. } => "const",
|
||||||
|
hir::GenericParamKind::Lifetime { .. } => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut diag = tcx.sess.struct_span_err(
|
||||||
|
param.span,
|
||||||
|
format!("late-bound {what} parameter not allowed on {where_}"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let guar = if tcx.features().non_lifetime_binders && first {
|
||||||
|
diag.emit()
|
||||||
|
} else {
|
||||||
|
diag.delay_as_bug()
|
||||||
|
};
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
*arg = ResolvedArg::Error(guar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -134,7 +134,8 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||||
rbv::ResolvedArg::StaticLifetime
|
rbv::ResolvedArg::StaticLifetime
|
||||||
| rbv::ResolvedArg::Free(_, _)
|
| rbv::ResolvedArg::Free(_, _)
|
||||||
| rbv::ResolvedArg::EarlyBound(_)
|
| rbv::ResolvedArg::EarlyBound(_)
|
||||||
| rbv::ResolvedArg::LateBound(_, _, _),
|
| rbv::ResolvedArg::LateBound(_, _, _)
|
||||||
|
| rbv::ResolvedArg::Error(_),
|
||||||
)
|
)
|
||||||
| None,
|
| None,
|
||||||
_,
|
_,
|
||||||
|
@ -211,7 +212,8 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
|
||||||
rbv::ResolvedArg::StaticLifetime
|
rbv::ResolvedArg::StaticLifetime
|
||||||
| rbv::ResolvedArg::EarlyBound(_)
|
| rbv::ResolvedArg::EarlyBound(_)
|
||||||
| rbv::ResolvedArg::LateBound(_, _, _)
|
| rbv::ResolvedArg::LateBound(_, _, _)
|
||||||
| rbv::ResolvedArg::Free(_, _),
|
| rbv::ResolvedArg::Free(_, _)
|
||||||
|
| rbv::ResolvedArg::Error(_),
|
||||||
)
|
)
|
||||||
| None,
|
| None,
|
||||||
_,
|
_,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use crate::ty;
|
use crate::ty;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{ItemLocalId, OwnerId};
|
use rustc_hir::{ItemLocalId, OwnerId};
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
|
@ -13,6 +14,7 @@ pub enum ResolvedArg {
|
||||||
EarlyBound(/* decl */ DefId),
|
EarlyBound(/* decl */ DefId),
|
||||||
LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ DefId),
|
LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ DefId),
|
||||||
Free(DefId, /* lifetime decl */ DefId),
|
Free(DefId, /* lifetime decl */ DefId),
|
||||||
|
Error(ErrorGuaranteed),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set containing, at most, one known element.
|
/// A set containing, at most, one known element.
|
||||||
|
|
|
@ -149,6 +149,9 @@ impl<'tcx> Const<'tcx> {
|
||||||
ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)),
|
ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)),
|
||||||
ty,
|
ty,
|
||||||
)),
|
)),
|
||||||
|
Some(rbv::ResolvedArg::Error(guar)) => {
|
||||||
|
Some(tcx.const_error_with_guaranteed(ty, guar))
|
||||||
|
}
|
||||||
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
|
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | type D = for<'a, T> fn();
|
LL | type D = for<'a, T> fn();
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
|
@ -31,7 +31,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | type E = dyn for<T> Fn();
|
LL | type E = dyn for<T> Fn();
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
7
tests/ui/closures/binder/const-bound.rs
Normal file
7
tests/ui/closures/binder/const-bound.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
//~^ WARN is incomplete and may not be safe to use
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for<const N: i32> || -> () {};
|
||||||
|
//~^ ERROR late-bound const parameter not allowed on closures
|
||||||
|
}
|
17
tests/ui/closures/binder/const-bound.stderr
Normal file
17
tests/ui/closures/binder/const-bound.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/const-bound.rs:1:37
|
||||||
|
|
|
||||||
|
LL | #![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: late-bound const parameter not allowed on closures
|
||||||
|
--> $DIR/const-bound.rs:5:9
|
||||||
|
|
|
||||||
|
LL | for<const N: i32> || -> () {};
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | for<const N: i32> || -> () {};
|
LL | for<const N: i32> || -> () {};
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | for<T> || -> () {};
|
LL | for<T> || -> () {};
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
7
tests/ui/closures/binder/type-bound-2.rs
Normal file
7
tests/ui/closures/binder/type-bound-2.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
//~^ WARN is incomplete and may not be safe to use
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for<T> || -> () {};
|
||||||
|
//~^ ERROR late-bound type parameter not allowed on closures
|
||||||
|
}
|
17
tests/ui/closures/binder/type-bound-2.stderr
Normal file
17
tests/ui/closures/binder/type-bound-2.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/type-bound-2.rs:1:37
|
||||||
|
|
|
||||||
|
LL | #![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: late-bound type parameter not allowed on closures
|
||||||
|
--> $DIR/type-bound-2.rs:5:9
|
||||||
|
|
|
||||||
|
LL | for<T> || -> () {};
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
7
tests/ui/closures/binder/type-bound.rs
Normal file
7
tests/ui/closures/binder/type-bound.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
//~^ WARN is incomplete and may not be safe to use
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for<T> || -> T {};
|
||||||
|
//~^ ERROR late-bound type parameter not allowed on closures
|
||||||
|
}
|
17
tests/ui/closures/binder/type-bound.stderr
Normal file
17
tests/ui/closures/binder/type-bound.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/type-bound.rs:1:37
|
||||||
|
|
|
||||||
|
LL | #![feature(closure_lifetime_binder, non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: late-bound type parameter not allowed on closures
|
||||||
|
--> $DIR/type-bound.rs:5:9
|
||||||
|
|
|
||||||
|
LL | for<T> || -> T {};
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
|
@ -34,7 +34,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
|
LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
|
@ -43,7 +43,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
|
LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
|
@ -52,7 +52,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
|
LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | fn foo() where for<T> T:, {}
|
LL | fn foo() where for<T> T:, {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | fn a() where for<T> T: Copy {}
|
LL | fn a() where for<T> T: Copy {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: only lifetime parameters can be used in this context
|
error[E0658]: only lifetime parameters can be used in this context
|
||||||
|
@ -13,7 +13,7 @@ error[E0658]: only lifetime parameters can be used in this context
|
||||||
LL | fn b() where for<const C: usize> [(); C]: Copy {}
|
LL | fn b() where for<const C: usize> [(); C]: Copy {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -4,7 +4,7 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to
|
||||||
LL | #![feature(non_lifetime_binders)]
|
LL | #![feature(non_lifetime_binders)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
|
@ -4,7 +4,7 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to
|
||||||
LL | #![feature(non_lifetime_binders)]
|
LL | #![feature(non_lifetime_binders)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: Trait` is not satisfied
|
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||||
|
|
|
@ -4,7 +4,7 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to
|
||||||
LL | #![feature(non_lifetime_binders)]
|
LL | #![feature(non_lifetime_binders)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error: late-bound type parameter not allowed on trait object types
|
error: late-bound type parameter not allowed on trait object types
|
||||||
|
|
|
@ -4,7 +4,7 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to
|
||||||
LL | #![feature(non_lifetime_binders)]
|
LL | #![feature(non_lifetime_binders)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error: late-bound type parameter not allowed on function pointer types
|
error: late-bound type parameter not allowed on function pointer types
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue