mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Correctly deny late-bound lifetimes from parent in anon consts and TAITs
This commit is contained in:
parent
ab45885dec
commit
52aff53812
@ -21,12 +21,16 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
|
|||||||
.label = deref recursion limit reached
|
.label = deref recursion limit reached
|
||||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||||
|
|
||||||
hir_analysis_cannot_capture_late_bound_const_in_anon_const =
|
hir_analysis_cannot_capture_late_bound_const =
|
||||||
cannot capture late-bound const parameter in a constant
|
cannot capture late-bound const parameter in {$what}
|
||||||
.label = parameter defined here
|
.label = parameter defined here
|
||||||
|
|
||||||
hir_analysis_cannot_capture_late_bound_ty_in_anon_const =
|
hir_analysis_cannot_capture_late_bound_lifetime =
|
||||||
cannot capture late-bound type parameter in a constant
|
cannot capture late-bound lifetime in {$what}
|
||||||
|
.label = lifetime defined here
|
||||||
|
|
||||||
|
hir_analysis_cannot_capture_late_bound_ty =
|
||||||
|
cannot capture late-bound type parameter in {$what}
|
||||||
.label = parameter defined here
|
.label = parameter defined here
|
||||||
|
|
||||||
hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}`
|
hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}`
|
||||||
|
@ -268,9 +268,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
// (*) -- not late-bound, won't change
|
// (*) -- not late-bound, won't change
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(rbv::ResolvedArg::Error(_)) => {
|
Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar),
|
||||||
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(|| {
|
||||||
|
@ -158,13 +158,14 @@ enum Scope<'a> {
|
|||||||
s: ScopeRef<'a>,
|
s: ScopeRef<'a>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Disallows capturing non-lifetime binders from parent scopes.
|
/// Disallows capturing late-bound vars from parent scopes.
|
||||||
///
|
///
|
||||||
/// This is necessary for something like `for<T> [(); { /* references T */ }]:`,
|
/// This is necessary for something like `for<T> [(); { /* references T */ }]:`,
|
||||||
/// since we don't do something more correct like replacing any captured
|
/// since we don't do something more correct like replacing any captured
|
||||||
/// late-bound vars with early-bound params in the const's own generics.
|
/// late-bound vars with early-bound params in the const's own generics.
|
||||||
AnonConstBoundary {
|
LateBoundary {
|
||||||
s: ScopeRef<'a>,
|
s: ScopeRef<'a>,
|
||||||
|
what: &'static str,
|
||||||
},
|
},
|
||||||
|
|
||||||
Root {
|
Root {
|
||||||
@ -216,7 +217,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
|
|||||||
.field("s", &"..")
|
.field("s", &"..")
|
||||||
.finish(),
|
.finish(),
|
||||||
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
|
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
|
||||||
Scope::AnonConstBoundary { s: _ } => f.debug_struct("AnonConstBoundary").finish(),
|
Scope::LateBoundary { s: _, what } => {
|
||||||
|
f.debug_struct("LateBoundary").field("what", what).finish()
|
||||||
|
}
|
||||||
Scope::Root { opt_parent_item } => {
|
Scope::Root { opt_parent_item } => {
|
||||||
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
|
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
|
||||||
}
|
}
|
||||||
@ -318,7 +321,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
break (vec![], BinderScopeType::Normal);
|
break (vec![], BinderScopeType::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope::ObjectLifetimeDefault { s, .. } | Scope::AnonConstBoundary { s } => {
|
Scope::ObjectLifetimeDefault { s, .. } | Scope::LateBoundary { s, .. } => {
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,9 +700,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||||||
}) => {
|
}) => {
|
||||||
intravisit::walk_ty(self, ty);
|
intravisit::walk_ty(self, ty);
|
||||||
|
|
||||||
// Elided lifetimes are not allowed in non-return
|
// Elided lifetimes and late-bound lifetimes (from the parent)
|
||||||
// position impl Trait
|
// are not allowed in non-return position impl Trait
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::LateBoundary {
|
||||||
|
s: &Scope::TraitRefBoundary { s: self.scope },
|
||||||
|
what: "type alias impl trait",
|
||||||
|
};
|
||||||
self.with(scope, |this| intravisit::walk_item(this, opaque_ty));
|
self.with(scope, |this| intravisit::walk_item(this, opaque_ty));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -979,7 +985,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
|
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
|
||||||
self.with(Scope::AnonConstBoundary { s: self.scope }, |this| {
|
self.with(Scope::LateBoundary { s: self.scope, what: "constant" }, |this| {
|
||||||
intravisit::walk_anon_const(this, c);
|
intravisit::walk_anon_const(this, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1174,6 +1180,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
let mut late_depth = 0;
|
let mut late_depth = 0;
|
||||||
let mut scope = self.scope;
|
let mut scope = self.scope;
|
||||||
let mut outermost_body = None;
|
let mut outermost_body = None;
|
||||||
|
let mut crossed_late_boundary = None;
|
||||||
let result = loop {
|
let result = loop {
|
||||||
match *scope {
|
match *scope {
|
||||||
Scope::Body { id, s } => {
|
Scope::Body { id, s } => {
|
||||||
@ -1258,8 +1265,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
|
|
||||||
Scope::ObjectLifetimeDefault { s, .. }
|
Scope::ObjectLifetimeDefault { s, .. }
|
||||||
| Scope::Supertrait { s, .. }
|
| Scope::Supertrait { s, .. }
|
||||||
| Scope::TraitRefBoundary { s, .. }
|
| Scope::TraitRefBoundary { s, .. } => {
|
||||||
| Scope::AnonConstBoundary { s } => {
|
scope = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scope::LateBoundary { s, what } => {
|
||||||
|
crossed_late_boundary = Some(what);
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1268,6 +1279,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
if let Some(mut def) = result {
|
if let Some(mut def) = result {
|
||||||
if let ResolvedArg::EarlyBound(..) = def {
|
if let ResolvedArg::EarlyBound(..) = def {
|
||||||
// Do not free early-bound regions, only late-bound ones.
|
// Do not free early-bound regions, only late-bound ones.
|
||||||
|
} else if let ResolvedArg::LateBound(_, _, param_def_id) = def
|
||||||
|
&& let Some(what) = crossed_late_boundary
|
||||||
|
{
|
||||||
|
let use_span = lifetime_ref.ident.span;
|
||||||
|
let def_span = self.tcx.def_span(param_def_id);
|
||||||
|
let guar = match self.tcx.def_kind(param_def_id) {
|
||||||
|
DefKind::LifetimeParam => {
|
||||||
|
self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Lifetime {
|
||||||
|
use_span,
|
||||||
|
def_span,
|
||||||
|
what,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
def = ResolvedArg::Error(guar);
|
||||||
} else if let Some(body_id) = outermost_body {
|
} else if let Some(body_id) = outermost_body {
|
||||||
let fn_id = self.tcx.hir().body_owner(body_id);
|
let fn_id = self.tcx.hir().body_owner(body_id);
|
||||||
match self.tcx.hir().get(fn_id) {
|
match self.tcx.hir().get(fn_id) {
|
||||||
@ -1322,7 +1349,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
| Scope::ObjectLifetimeDefault { s, .. }
|
| Scope::ObjectLifetimeDefault { s, .. }
|
||||||
| Scope::Supertrait { s, .. }
|
| Scope::Supertrait { s, .. }
|
||||||
| Scope::TraitRefBoundary { s, .. }
|
| Scope::TraitRefBoundary { s, .. }
|
||||||
| Scope::AnonConstBoundary { s } => {
|
| Scope::LateBoundary { s, .. } => {
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1341,7 +1368,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
// search.
|
// search.
|
||||||
let mut late_depth = 0;
|
let mut late_depth = 0;
|
||||||
let mut scope = self.scope;
|
let mut scope = self.scope;
|
||||||
let mut crossed_anon_const = false;
|
let mut crossed_late_boundary = None;
|
||||||
|
|
||||||
let result = loop {
|
let result = loop {
|
||||||
match *scope {
|
match *scope {
|
||||||
@ -1376,28 +1403,32 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope::AnonConstBoundary { s } => {
|
Scope::LateBoundary { s, what } => {
|
||||||
crossed_anon_const = true;
|
crossed_late_boundary = Some(what);
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(def) = result {
|
if let Some(def) = result {
|
||||||
if let ResolvedArg::LateBound(..) = def && crossed_anon_const {
|
if let ResolvedArg::LateBound(..) = def
|
||||||
|
&& let Some(what) = crossed_late_boundary
|
||||||
|
{
|
||||||
let use_span = self.tcx.hir().span(hir_id);
|
let use_span = self.tcx.hir().span(hir_id);
|
||||||
let def_span = self.tcx.def_span(param_def_id);
|
let def_span = self.tcx.def_span(param_def_id);
|
||||||
let guar = match self.tcx.def_kind(param_def_id) {
|
let guar = match self.tcx.def_kind(param_def_id) {
|
||||||
DefKind::ConstParam => {
|
DefKind::ConstParam => {
|
||||||
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const {
|
self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Const {
|
||||||
use_span,
|
use_span,
|
||||||
def_span,
|
def_span,
|
||||||
|
what,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DefKind::TyParam => {
|
DefKind::TyParam => {
|
||||||
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type {
|
self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Type {
|
||||||
use_span,
|
use_span,
|
||||||
def_span,
|
def_span,
|
||||||
|
what,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -1446,7 +1477,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
| Scope::ObjectLifetimeDefault { s, .. }
|
| Scope::ObjectLifetimeDefault { s, .. }
|
||||||
| Scope::Supertrait { s, .. }
|
| Scope::Supertrait { s, .. }
|
||||||
| Scope::TraitRefBoundary { s, .. }
|
| Scope::TraitRefBoundary { s, .. }
|
||||||
| Scope::AnonConstBoundary { s } => {
|
| Scope::LateBoundary { s, .. } => {
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1526,7 +1557,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
| Scope::ObjectLifetimeDefault { s, .. }
|
| Scope::ObjectLifetimeDefault { s, .. }
|
||||||
| Scope::Supertrait { s, .. }
|
| Scope::Supertrait { s, .. }
|
||||||
| Scope::TraitRefBoundary { s, .. }
|
| Scope::TraitRefBoundary { s, .. }
|
||||||
| Scope::AnonConstBoundary { s } => {
|
| Scope::LateBoundary { s, .. } => {
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1831,7 +1862,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||||||
|
|
||||||
Scope::Supertrait { s, .. }
|
Scope::Supertrait { s, .. }
|
||||||
| Scope::TraitRefBoundary { s, .. }
|
| Scope::TraitRefBoundary { s, .. }
|
||||||
| Scope::AnonConstBoundary { s } => {
|
| Scope::LateBoundary { s, .. } => {
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,20 +430,30 @@ pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
pub(crate) enum CannotCaptureLateBoundInAnonConst {
|
pub(crate) enum CannotCaptureLateBound {
|
||||||
#[diag(hir_analysis_cannot_capture_late_bound_ty_in_anon_const)]
|
#[diag(hir_analysis_cannot_capture_late_bound_ty)]
|
||||||
Type {
|
Type {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
use_span: Span,
|
use_span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
def_span: Span,
|
def_span: Span,
|
||||||
|
what: &'static str,
|
||||||
},
|
},
|
||||||
#[diag(hir_analysis_cannot_capture_late_bound_const_in_anon_const)]
|
#[diag(hir_analysis_cannot_capture_late_bound_const)]
|
||||||
Const {
|
Const {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
use_span: Span,
|
use_span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
def_span: Span,
|
def_span: Span,
|
||||||
|
what: &'static str,
|
||||||
|
},
|
||||||
|
#[diag(hir_analysis_cannot_capture_late_bound_lifetime)]
|
||||||
|
Lifetime {
|
||||||
|
#[primary_span]
|
||||||
|
use_span: Span,
|
||||||
|
#[label]
|
||||||
|
def_span: Span,
|
||||||
|
what: &'static str,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,13 @@
|
|||||||
// failure-status: 1
|
|
||||||
// known-bug: unknown
|
// known-bug: unknown
|
||||||
// error-pattern:internal compiler error
|
|
||||||
// normalize-stderr-test "internal compiler error.*" -> ""
|
// If we want this to compile, then we'd need to do something like RPITs do,
|
||||||
// normalize-stderr-test "DefId\([^)]*\)" -> "..."
|
// where nested associated constants have early-bound versions of their captured
|
||||||
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
|
// late-bound vars inserted into their generics. This gives us substitutable
|
||||||
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
|
// lifetimes to actually use when borrow-checking the associated const, which is
|
||||||
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
|
// lowered as a totally separate body from its parent. Since this doesn't exist,
|
||||||
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
|
// so we should just error rather than resolving this late-bound var with no
|
||||||
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
|
// binder to actually attach it to, or worse, as a free region that can't even be
|
||||||
// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> ""
|
// substituted correctly, and ICEing. - @compiler-errors
|
||||||
// normalize-stderr-test "stack backtrace:\n" -> ""
|
|
||||||
// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
|
|
||||||
// normalize-stderr-test "\s at .*\n" -> ""
|
|
||||||
// normalize-stderr-test ".*note: Some details.*\n" -> ""
|
|
||||||
// normalize-stderr-test "\n[ ]*\n" -> ""
|
|
||||||
// normalize-stderr-test "compiler/.*: projection" -> "projection"
|
|
||||||
// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> ""
|
|
||||||
// normalize-stderr-test "error: [\s\n]*query stack during panic:\n" -> ""
|
|
||||||
// this should run-pass
|
|
||||||
|
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}`
|
error: cannot capture late-bound lifetime in constant
|
||||||
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}`
|
--> $DIR/in_closure.rs:24:29
|
||||||
#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE
|
|
|
||||||
#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
|
LL | fn test<'a>() {
|
||||||
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
|
| -- lifetime defined here
|
||||||
#5 [eval_to_valtree] evaluating type-level constant
|
LL | let _ = || {
|
||||||
#6 [typeck] type-checking `test`
|
LL | let _: [u8; inner::<'a>()];
|
||||||
#7 [analysis] running analysis passes on this crate
|
| ^^
|
||||||
end of query stack
|
|
||||||
error: aborting due to previous error
|
error: cannot capture late-bound lifetime in constant
|
||||||
|
--> $DIR/in_closure.rs:25:29
|
||||||
|
|
|
||||||
|
LL | fn test<'a>() {
|
||||||
|
| -- lifetime defined here
|
||||||
|
...
|
||||||
|
LL | let _ = [0; inner::<'a>()];
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
// failure-status: 101
|
|
||||||
// known-bug: unknown
|
// known-bug: unknown
|
||||||
// error-pattern:internal compiler error
|
|
||||||
// normalize-stderr-test "internal compiler error.*" -> ""
|
// If we want this to compile, then we'd need to do something like RPITs do,
|
||||||
// normalize-stderr-test "DefId\([^)]*\)" -> "..."
|
// where nested associated constants have early-bound versions of their captured
|
||||||
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
|
// late-bound vars inserted into their generics. This gives us substitutable
|
||||||
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
|
// lifetimes to actually use when borrow-checking the associated const, which is
|
||||||
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
|
// lowered as a totally separate body from its parent. Since this doesn't exist,
|
||||||
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
|
// so we should just error rather than resolving this late-bound var with no
|
||||||
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
|
// binder to actually attach it to, or worse, as a free region that can't even be
|
||||||
// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> ""
|
// substituted correctly, and ICEing. - @compiler-errors
|
||||||
// normalize-stderr-test "stack backtrace:\n" -> ""
|
|
||||||
// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
|
|
||||||
// normalize-stderr-test "\s at .*\n" -> ""
|
|
||||||
// normalize-stderr-test ".*note: Some details.*\n" -> ""
|
|
||||||
// normalize-stderr-test "\n\n[ ]*\n" -> ""
|
|
||||||
// normalize-stderr-test "compiler/.*: projection" -> "projection"
|
|
||||||
// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> ""
|
|
||||||
// normalize-stderr-test "error: [\s\n]*query stack" -> "error: query stack"
|
|
||||||
|
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
error: query stack during panic:
|
error: cannot capture late-bound lifetime in constant
|
||||||
#0 [mir_borrowck] borrow-checking `test::{constant#1}`
|
--> $DIR/simple.rs:20:25
|
||||||
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}`
|
|
|
||||||
#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE
|
LL | fn test<'a>() {
|
||||||
#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
|
| -- lifetime defined here
|
||||||
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
|
LL | let _: [u8; inner::<'a>()];
|
||||||
#5 [eval_to_valtree] evaluating type-level constant
|
| ^^
|
||||||
#6 [typeck] type-checking `test`
|
|
||||||
#7 [analysis] running analysis passes on this crate
|
error: cannot capture late-bound lifetime in constant
|
||||||
end of query stack
|
--> $DIR/simple.rs:21:25
|
||||||
error: aborting due to previous error
|
|
|
||||||
|
LL | fn test<'a>() {
|
||||||
|
| -- lifetime defined here
|
||||||
|
LL | let _: [u8; inner::<'a>()];
|
||||||
|
LL | let _ = [0; inner::<'a>()];
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
13
tests/ui/consts/escaping-bound-var.rs
Normal file
13
tests/ui/consts/escaping-bound-var.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
//~^ WARN the feature `generic_const_exprs` is incomplete
|
||||||
|
|
||||||
|
fn test<'a>(
|
||||||
|
_: &'a (),
|
||||||
|
) -> [(); {
|
||||||
|
let x: &'a ();
|
||||||
|
//~^ ERROR cannot capture late-bound lifetime in constant
|
||||||
|
1
|
||||||
|
}] {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
20
tests/ui/consts/escaping-bound-var.stderr
Normal file
20
tests/ui/consts/escaping-bound-var.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/escaping-bound-var.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(generic_const_exprs)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: cannot capture late-bound lifetime in constant
|
||||||
|
--> $DIR/escaping-bound-var.rs:7:13
|
||||||
|
|
|
||||||
|
LL | fn test<'a>(
|
||||||
|
| -- lifetime defined here
|
||||||
|
...
|
||||||
|
LL | let x: &'a ();
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
@ -4,7 +4,7 @@
|
|||||||
fn b()
|
fn b()
|
||||||
where
|
where
|
||||||
for<const C: usize> [(); C]: Copy,
|
for<const C: usize> [(); C]: Copy,
|
||||||
//~^ ERROR cannot capture late-bound const parameter in a constant
|
//~^ ERROR cannot capture late-bound const parameter in constant
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ LL | #![feature(non_lifetime_binders)]
|
|||||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> 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: cannot capture late-bound const parameter in a constant
|
error: cannot capture late-bound const parameter in constant
|
||||||
--> $DIR/capture-late-ct-in-anon.rs:6:30
|
--> $DIR/capture-late-ct-in-anon.rs:6:30
|
||||||
|
|
|
|
||||||
LL | for<const C: usize> [(); C]: Copy,
|
LL | for<const C: usize> [(); C]: Copy,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
fn foo() -> usize
|
fn foo() -> usize
|
||||||
where
|
where
|
||||||
for<T> [i32; { let _: T = todo!(); 0 }]:,
|
for<T> [i32; { let _: T = todo!(); 0 }]:,
|
||||||
//~^ ERROR cannot capture late-bound type parameter in a constant
|
//~^ ERROR cannot capture late-bound type parameter in constant
|
||||||
{}
|
{}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -15,7 +15,7 @@ LL | #![feature(non_lifetime_binders, generic_const_exprs)]
|
|||||||
|
|
|
|
||||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
|
||||||
error: cannot capture late-bound type parameter in a constant
|
error: cannot capture late-bound type parameter in constant
|
||||||
--> $DIR/late-bound-in-anon-ct.rs:7:27
|
--> $DIR/late-bound-in-anon-ct.rs:7:27
|
||||||
|
|
|
|
||||||
LL | for<T> [i32; { let _: T = todo!(); 0 }]:,
|
LL | for<T> [i32; { let _: T = todo!(); 0 }]:,
|
||||||
|
22
tests/ui/type-alias-impl-trait/escaping-bound-var.rs
Normal file
22
tests/ui/type-alias-impl-trait/escaping-bound-var.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
pub trait Trait<'a> {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Test<'a> {}
|
||||||
|
|
||||||
|
pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||||
|
//~^ ERROR cannot capture late-bound lifetime in type alias impl trait
|
||||||
|
|
||||||
|
impl Trait<'_> for () {
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Test<'_> for () {}
|
||||||
|
|
||||||
|
fn constrain() -> Foo {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
Normal file
8
tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: cannot capture late-bound lifetime in type alias impl trait
|
||||||
|
--> $DIR/escaping-bound-var.rs:9:57
|
||||||
|
|
|
||||||
|
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||||
|
| -- lifetime defined here ^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -9,42 +9,36 @@ type NotCapturedEarly<'a> = impl Sized; //~ [o]
|
|||||||
|
|
||||||
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
|
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
|
||||||
|
|
||||||
|
// TAIT does *not* capture `'b`
|
||||||
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
|
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
|
||||||
|
|
||||||
type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>; //~ [o]
|
// TAIT does *not* capture `'b`
|
||||||
|
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
|
||||||
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; //~ [o]
|
|
||||||
|
|
||||||
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
|
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
|
||||||
|
|
||||||
trait Foo<'i> {
|
trait Foo<'i> {
|
||||||
type ImplicitCapturedEarly<'a>;
|
type ImplicitCapture<'a>;
|
||||||
|
|
||||||
type ExplicitCaptureEarly<'a>;
|
type ExplicitCaptureFromHeader<'a>;
|
||||||
|
|
||||||
type ImplicitCaptureLate<'a>;
|
type ExplicitCaptureFromGat<'a>;
|
||||||
|
|
||||||
type ExplicitCaptureLate<'a>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> Foo<'i> for &'i () {
|
impl<'i> Foo<'i> for &'i () {
|
||||||
type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o]
|
type ImplicitCapture<'a> = impl Sized; //~ [o, o]
|
||||||
|
|
||||||
type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
||||||
|
|
||||||
type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o]
|
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
||||||
|
|
||||||
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> Foo<'i> for () {
|
impl<'i> Foo<'i> for () {
|
||||||
type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o]
|
type ImplicitCapture<'a> = impl Sized; //~ [o, o]
|
||||||
|
|
||||||
type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
||||||
|
|
||||||
type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o]
|
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
||||||
|
|
||||||
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -11,22 +11,16 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o]
|
error: [o]
|
||||||
--> $DIR/variance.rs:12:56
|
--> $DIR/variance.rs:13:56
|
||||||
|
|
|
|
||||||
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o]
|
|
||||||
--> $DIR/variance.rs:14:53
|
|
||||||
|
|
|
||||||
LL | type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: [o]
|
error: [o]
|
||||||
--> $DIR/variance.rs:16:49
|
--> $DIR/variance.rs:16:49
|
||||||
|
|
|
|
||||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>;
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o, o]
|
error: [o, o, o]
|
||||||
--> $DIR/variance.rs:18:27
|
--> $DIR/variance.rs:18:27
|
||||||
@ -35,52 +29,40 @@ LL | type Bar<'a, 'b: 'b, T> = impl Sized;
|
|||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:31:38
|
--> $DIR/variance.rs:29:32
|
||||||
|
|
|
|
||||||
LL | type ImplicitCapturedEarly<'a> = impl Sized;
|
LL | type ImplicitCapture<'a> = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:33:37
|
--> $DIR/variance.rs:31:42
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>;
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:35:36
|
--> $DIR/variance.rs:33:39
|
||||||
|
|
|
|
||||||
LL | type ImplicitCaptureLate<'a> = impl Sized;
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:37:36
|
--> $DIR/variance.rs:37:32
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>;
|
LL | type ImplicitCapture<'a> = impl Sized;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:41:38
|
--> $DIR/variance.rs:39:42
|
||||||
|
|
|
|
||||||
LL | type ImplicitCapturedEarly<'a> = impl Sized;
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [o, o]
|
||||||
--> $DIR/variance.rs:43:37
|
--> $DIR/variance.rs:41:39
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>;
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: aborting due to 11 previous errors
|
||||||
--> $DIR/variance.rs:45:36
|
|
||||||
|
|
|
||||||
LL | type ImplicitCaptureLate<'a> = impl Sized;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error: [o, o]
|
|
||||||
--> $DIR/variance.rs:47:36
|
|
||||||
|
|
|
||||||
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 14 previous errors
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user