Auto merge of #121078 - oli-obk:rollup-p11zsav, r=oli-obk
Rollup of 13 pull requests Successful merges: - #116387 (Additional doc links and explanation of `Wake`.) - #118738 (Netbsd10 update) - #118890 (Clarify the lifetimes of allocations returned by the `Allocator` trait) - #120498 (Uplift `TypeVisitableExt` into `rustc_type_ir`) - #120530 (Be less confident when `dyn` suggestion is not checked for object safety) - #120915 (Fix suggestion span for `?Sized` when param type has default) - #121015 (Optimize `delayed_bug` handling.) - #121024 (implement `Default` for `AsciiChar`) - #121039 (Correctly compute adjustment casts in GVN) - #121045 (Fix two UI tests with incorrect directive / invalid revision) - #121049 (Do not point at `#[allow(_)]` as the reason for compat lint triggering) - #121071 (Use fewer delayed bugs.) - #121073 (Fix typos in `OneLock` doc) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
340bb19fea
93 changed files with 966 additions and 589 deletions
|
@ -323,9 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||||
ExprKind::Err => {
|
ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
|
||||||
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
|
|
||||||
}
|
|
||||||
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
||||||
|
|
||||||
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
|
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
|
||||||
|
|
|
@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
|
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
|
||||||
match block {
|
match block {
|
||||||
Some(block) => self.lower_block_expr(block),
|
Some(block) => self.lower_block_expr(block),
|
||||||
None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")),
|
None => self.expr_err(span, self.dcx().has_errors().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1285,9 +1285,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
|
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
|
||||||
let kind = match &t.kind {
|
let kind = match &t.kind {
|
||||||
TyKind::Infer => hir::TyKind::Infer,
|
TyKind::Infer => hir::TyKind::Infer,
|
||||||
TyKind::Err => {
|
TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
|
||||||
hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered"))
|
|
||||||
}
|
|
||||||
// Lower the anonymous structs or unions in a nested lowering context.
|
// Lower the anonymous structs or unions in a nested lowering context.
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
|
|
|
@ -117,18 +117,14 @@ struct CfgChecker<'a, 'tcx> {
|
||||||
impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
|
impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn fail(&self, location: Location, msg: impl AsRef<str>) {
|
fn fail(&self, location: Location, msg: impl AsRef<str>) {
|
||||||
let span = self.body.source_info(location).span;
|
// We might see broken MIR when other errors have already occurred.
|
||||||
// We use `span_delayed_bug` as we might see broken MIR when other errors have already
|
assert!(
|
||||||
// occurred.
|
self.tcx.dcx().has_errors().is_some(),
|
||||||
self.tcx.dcx().span_delayed_bug(
|
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||||
span,
|
self.body.source.instance,
|
||||||
format!(
|
self.when,
|
||||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
location,
|
||||||
self.body.source.instance,
|
msg.as_ref(),
|
||||||
self.when,
|
|
||||||
location,
|
|
||||||
msg.as_ref()
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
|
||||||
self.future_breakage_diagnostics.push(diagnostic.clone());
|
self.future_breakage_diagnostics.push(diagnostic.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that because this comes before the `match` below,
|
||||||
|
// `-Zeagerly-emit-delayed-bugs` continues to work even after we've
|
||||||
|
// issued an error and stopped recording new delayed bugs.
|
||||||
if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
|
if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
|
||||||
diagnostic.level = Error;
|
diagnostic.level = Error;
|
||||||
}
|
}
|
||||||
|
@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
|
||||||
diagnostic.level = Bug;
|
diagnostic.level = Bug;
|
||||||
}
|
}
|
||||||
DelayedBug => {
|
DelayedBug => {
|
||||||
// FIXME(eddyb) this should check for `has_errors` and stop pushing
|
// If we have already emitted at least one error, we don't need
|
||||||
// once *any* errors were emitted (and truncate `delayed_bugs`
|
// to record the delayed bug, because it'll never be used.
|
||||||
// when an error is first emitted, also), but maybe there's a case
|
return if let Some(guar) = self.has_errors_or_lint_errors() {
|
||||||
// in which that's not sound? otherwise this is really inefficient.
|
Some(guar)
|
||||||
let backtrace = std::backtrace::Backtrace::capture();
|
} else {
|
||||||
// This `unchecked_error_guaranteed` is valid. It is where the
|
let backtrace = std::backtrace::Backtrace::capture();
|
||||||
// `ErrorGuaranteed` for delayed bugs originates.
|
// This `unchecked_error_guaranteed` is valid. It is where the
|
||||||
#[allow(deprecated)]
|
// `ErrorGuaranteed` for delayed bugs originates.
|
||||||
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
|
#[allow(deprecated)]
|
||||||
self.delayed_bugs
|
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
|
||||||
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
|
self.delayed_bugs
|
||||||
return Some(guar);
|
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
|
||||||
|
Some(guar)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Warning if !self.flags.can_emit_warnings => {
|
Warning if !self.flags.can_emit_warnings => {
|
||||||
if diagnostic.has_future_breakage() {
|
if diagnostic.has_future_breakage() {
|
||||||
|
@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_error {
|
if is_error {
|
||||||
|
// If we have any delayed bugs recorded, we can discard them
|
||||||
|
// because they won't be used. (This should only occur if there
|
||||||
|
// have been no errors previously emitted, because we don't add
|
||||||
|
// new delayed bugs once the first error is emitted.)
|
||||||
|
if !self.delayed_bugs.is_empty() {
|
||||||
|
assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
|
||||||
|
self.delayed_bugs.clear();
|
||||||
|
self.delayed_bugs.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
// This `unchecked_error_guaranteed` is valid. It is where the
|
// This `unchecked_error_guaranteed` is valid. It is where the
|
||||||
// `ErrorGuaranteed` for errors and lint errors originates.
|
// `ErrorGuaranteed` for errors and lint errors originates.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
|
|
@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>(
|
||||||
if try_success_result.is_ok() {
|
if try_success_result.is_ok() {
|
||||||
// Nonterminal parser recovery might turn failed matches into successful ones,
|
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||||
// but for that it must have emitted an error already
|
// but for that it must have emitted an error already
|
||||||
tracker
|
assert!(
|
||||||
.cx
|
tracker.cx.dcx().has_errors().is_some(),
|
||||||
.dcx()
|
"Macro matching returned a success on the second try"
|
||||||
.span_delayed_bug(sp, "Macro matching returned a success on the second try");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(result) = tracker.result {
|
if let Some(result) = tracker.result {
|
||||||
|
|
|
@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
|
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
|
||||||
if self_ty.span.can_be_used_for_suggestions() {
|
if self_ty.span.can_be_used_for_suggestions() {
|
||||||
lint.multipart_suggestion_verbose(
|
lint.multipart_suggestion_verbose(
|
||||||
"use `dyn`",
|
"if this is an object-safe trait, use `dyn`",
|
||||||
sugg,
|
sugg,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
|
|
|
@ -758,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// since we should have emitten an error for them earlier, and they will
|
// since we should have emitten an error for them earlier, and they will
|
||||||
// not be well-formed!
|
// not be well-formed!
|
||||||
if polarity == ty::ImplPolarity::Negative {
|
if polarity == ty::ImplPolarity::Negative {
|
||||||
self.tcx().dcx().span_delayed_bug(
|
assert!(
|
||||||
binding.span,
|
self.tcx().dcx().has_errors().is_some(),
|
||||||
"negative trait bounds should not have bindings",
|
"negative trait bounds should not have bindings",
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>(
|
||||||
let hir_param = &hir_generics.params[index];
|
let hir_param = &hir_generics.params[index];
|
||||||
|
|
||||||
if ty_param.def_id != hir_param.def_id.into() {
|
if ty_param.def_id != hir_param.def_id.into() {
|
||||||
// valid programs always have lifetimes before types in the generic parameter list
|
// Valid programs always have lifetimes before types in the generic parameter list.
|
||||||
// ty_generics are normalized to be in this required order, and variances are built
|
// ty_generics are normalized to be in this required order, and variances are built
|
||||||
// from ty generics, not from hir generics. but we need hir generics to get
|
// from ty generics, not from hir generics. but we need hir generics to get
|
||||||
// a span out
|
// a span out.
|
||||||
//
|
//
|
||||||
// if they aren't in the same order, then the user has written invalid code, and already
|
// If they aren't in the same order, then the user has written invalid code, and already
|
||||||
// got an error about it (or I'm wrong about this)
|
// got an error about it (or I'm wrong about this).
|
||||||
tcx.dcx().span_delayed_bug(
|
tcx.dcx().span_delayed_bug(
|
||||||
hir_param.span,
|
hir_param.span,
|
||||||
"hir generics and ty generics in different order",
|
"hir generics and ty generics in different order",
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub(super) fn check_item(
|
||||||
|
|
||||||
(_, _, Unsafety::Unsafe, Negative) => {
|
(_, _, Unsafety::Unsafe, Negative) => {
|
||||||
// Reported in AST validation
|
// Reported in AST validation
|
||||||
tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "unsafe negative impl");
|
assert!(tcx.dcx().has_errors().is_some(), "unsafe negative impl");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(_, _, Unsafety::Normal, Negative)
|
(_, _, Unsafety::Normal, Negative)
|
||||||
|
|
|
@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Dynamic(_, _, ty::DynStar)
|
| ty::Dynamic(_, _, ty::DynStar)
|
||||||
| ty::Error(_) => {
|
| ty::Error(_) => {
|
||||||
let reported = self
|
let guar = self
|
||||||
.dcx()
|
.dcx()
|
||||||
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
|
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
|
||||||
return Err(reported);
|
return Err(guar);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,8 +221,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
if base_ty.is_none() {
|
if base_ty.is_none() {
|
||||||
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
|
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
|
||||||
// that isn't in the type table. We assume more relevant errors have already been
|
// that isn't in the type table. We assume more relevant errors have already been
|
||||||
// emitted, so we delay an ICE if none have. (#64638)
|
// emitted. (#64638)
|
||||||
self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`"));
|
assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`");
|
||||||
}
|
}
|
||||||
if let Some(base_ty) = base_ty
|
if let Some(base_ty) = base_ty
|
||||||
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
|
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
|
||||||
|
|
|
@ -802,14 +802,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errors in earlier passes can yield error variables without
|
// Errors in earlier passes can yield error variables without
|
||||||
// resolution errors here; delay ICE in favor of those errors.
|
// resolution errors here; ICE if no errors have been emitted yet.
|
||||||
self.tcx().dcx().span_delayed_bug(
|
assert!(
|
||||||
self.var_infos[node_idx].origin.span(),
|
self.tcx().dcx().has_errors().is_some(),
|
||||||
format!(
|
"collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
|
||||||
"collect_error_for_expanding_node() could not find \
|
universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
|
||||||
error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
|
upper_bounds={upper_bounds:#?}",
|
||||||
upper_bounds={upper_bounds:#?}"
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -300,9 +300,9 @@ where
|
||||||
self.components_must_outlive(origin, subcomponents, region, category);
|
self.components_must_outlive(origin, subcomponents, region, category);
|
||||||
}
|
}
|
||||||
Component::UnresolvedInferenceVariable(v) => {
|
Component::UnresolvedInferenceVariable(v) => {
|
||||||
// ignore this, we presume it will yield an error
|
// Ignore this, we presume it will yield an error later,
|
||||||
// later, since if a type variable is not resolved by
|
// since if a type variable is not resolved by this point
|
||||||
// this point it never will be
|
// it never will be.
|
||||||
self.tcx.dcx().span_delayed_bug(
|
self.tcx.dcx().span_delayed_bug(
|
||||||
origin.span(),
|
origin.span(),
|
||||||
format!("unresolved inference variable in outlives: {v:?}"),
|
format!("unresolved inference variable in outlives: {v:?}"),
|
||||||
|
|
|
@ -172,13 +172,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
self.bound_from_components(components, visited)
|
self.bound_from_components(components, visited)
|
||||||
}
|
}
|
||||||
Component::UnresolvedInferenceVariable(v) => {
|
Component::UnresolvedInferenceVariable(v) => {
|
||||||
// ignore this, we presume it will yield an error
|
// Ignore this, we presume it will yield an error later, since
|
||||||
// later, since if a type variable is not resolved by
|
// if a type variable is not resolved by this point it never
|
||||||
// this point it never will be
|
// will be.
|
||||||
self.tcx
|
self.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
|
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
|
||||||
// add a bound that never holds
|
// Add a bound that never holds.
|
||||||
VerifyBound::AnyBound(vec![])
|
VerifyBound::AnyBound(vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,14 +431,13 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
|
||||||
// If not, that means that we somehow buffered a lint for a node id
|
// If not, that means that we somehow buffered a lint for a node id
|
||||||
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
|
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
|
||||||
for (id, lints) in cx.context.buffered.map {
|
for (id, lints) in cx.context.buffered.map {
|
||||||
for early_lint in lints {
|
if !lints.is_empty() {
|
||||||
sess.dcx().span_delayed_bug(
|
assert!(
|
||||||
early_lint.span,
|
sess.dcx().has_errors().is_some(),
|
||||||
format!(
|
"failed to process buffered lint here (dummy = {})",
|
||||||
"failed to process buffered lint here (dummy = {})",
|
id == ast::DUMMY_NODE_ID
|
||||||
id == ast::DUMMY_NODE_ID
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,6 +207,11 @@ pub fn explain_lint_level_source(
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
) {
|
) {
|
||||||
let name = lint.name_lower();
|
let name = lint.name_lower();
|
||||||
|
if let Level::Allow = level {
|
||||||
|
// Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint
|
||||||
|
// triggering. (#121009)
|
||||||
|
return;
|
||||||
|
}
|
||||||
match src {
|
match src {
|
||||||
LintLevelSource::Default => {
|
LintLevelSource::Default => {
|
||||||
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name));
|
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name));
|
||||||
|
|
|
@ -35,6 +35,16 @@ impl<'tcx> IntoKind for Const<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
|
||||||
|
fn flags(&self) -> TypeFlags {
|
||||||
|
self.0.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
|
||||||
|
self.0.outer_exclusive_binder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
|
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
|
||||||
fn ty(self) -> Ty<'tcx> {
|
fn ty(self) -> Ty<'tcx> {
|
||||||
self.ty()
|
self.ty()
|
||||||
|
@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> {
|
||||||
self.0.kind
|
self.0.kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn flags(self) -> TypeFlags {
|
pub fn flags(self) -> TypeFlags {
|
||||||
self.0.flags
|
self.0.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
||||||
self.0.outer_exclusive_binder
|
self.0.outer_exclusive_binder
|
||||||
|
|
|
@ -28,7 +28,7 @@ use crate::ty::{
|
||||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
|
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
|
||||||
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
|
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
|
||||||
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
||||||
Visibility,
|
TypeVisitable, Visibility,
|
||||||
};
|
};
|
||||||
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||||
use rustc_ast::{self as ast, attr};
|
use rustc_ast::{self as ast, attr};
|
||||||
|
@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||||
type GenericArg = ty::GenericArg<'tcx>;
|
type GenericArg = ty::GenericArg<'tcx>;
|
||||||
type Term = ty::Term<'tcx>;
|
type Term = ty::Term<'tcx>;
|
||||||
|
|
||||||
type Binder<T> = Binder<'tcx, T>;
|
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
|
||||||
|
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
||||||
|
type BoundVar = ty::BoundVariableKind;
|
||||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||||
|
|
||||||
type Ty = Ty<'tcx>;
|
type Ty = Ty<'tcx>;
|
||||||
|
@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||||
) -> Self::Const {
|
) -> Self::Const {
|
||||||
Const::new_bound(self, debruijn, var, ty)
|
Const::new_bound(self, debruijn, var, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expect_error_or_delayed_bug() {
|
||||||
|
let has_errors = ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs());
|
||||||
|
assert!(has_errors.is_some());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||||
|
|
|
@ -504,6 +504,16 @@ impl<'tcx> IntoKind for Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> {
|
||||||
|
fn flags(&self) -> TypeFlags {
|
||||||
|
self.0.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outer_exclusive_binder(&self) -> DebruijnIndex {
|
||||||
|
self.0.outer_exclusive_binder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EarlyParamRegion {
|
impl EarlyParamRegion {
|
||||||
/// Does this early bound region have a name? Early bound regions normally
|
/// Does this early bound region have a name? Early bound regions normally
|
||||||
/// always have names except when using anonymous lifetimes (`'_`).
|
/// always have names except when using anonymous lifetimes (`'_`).
|
||||||
|
|
|
@ -29,6 +29,16 @@ pub struct Predicate<'tcx>(
|
||||||
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
|
||||||
|
fn flags(&self) -> TypeFlags {
|
||||||
|
self.0.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||||
|
self.0.outer_exclusive_binder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Predicate<'tcx> {
|
impl<'tcx> Predicate<'tcx> {
|
||||||
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
|
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -36,11 +46,13 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
self.0.internee
|
self.0.internee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn flags(self) -> TypeFlags {
|
pub fn flags(self) -> TypeFlags {
|
||||||
self.0.flags
|
self.0.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
|
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
|
||||||
self.0.outer_exclusive_binder
|
self.0.outer_exclusive_binder
|
||||||
|
|
|
@ -26,6 +26,19 @@ impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::visit::Flags for Region<'tcx> {
|
||||||
|
fn flags(&self) -> TypeFlags {
|
||||||
|
self.type_flags()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||||
|
match **self {
|
||||||
|
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
|
||||||
|
_ => ty::INNERMOST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Region<'tcx> {
|
impl<'tcx> Region<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_early_param(
|
pub fn new_early_param(
|
||||||
|
|
|
@ -942,6 +942,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||||
|
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
|
||||||
|
self.bound_vars
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_no_bound_vars(&self) -> bool {
|
||||||
|
self.bound_vars.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx, T> Binder<'tcx, T> {
|
impl<'tcx, T> Binder<'tcx, T> {
|
||||||
/// Skips the binder and returns the "bound" value. This is a
|
/// Skips the binder and returns the "bound" value. This is a
|
||||||
/// risky thing to do because it's easy to get confused about
|
/// risky thing to do because it's easy to get confused about
|
||||||
|
@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> {
|
||||||
self.0.0
|
self.0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn flags(self) -> TypeFlags {
|
pub fn flags(self) -> TypeFlags {
|
||||||
self.0.0.flags
|
self.0.0.flags
|
||||||
|
|
|
@ -1320,6 +1320,7 @@ impl<'tcx> Ty<'tcx> {
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(compiler-errors): Think about removing this.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
||||||
self.0.outer_exclusive_binder
|
self.0.outer_exclusive_binder
|
||||||
|
|
|
@ -1,140 +1,10 @@
|
||||||
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sso::SsoHashSet;
|
use rustc_data_structures::sso::SsoHashSet;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
|
|
||||||
pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
|
|
||||||
/// Returns `true` if `self` has any late-bound regions that are either
|
|
||||||
/// bound by `binder` or bound by some binder outside of `binder`.
|
|
||||||
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
|
||||||
/// there are any late-bound regions that appear free.
|
|
||||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
|
||||||
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if this type has any regions that escape `binder` (and
|
|
||||||
/// hence are not bound by it).
|
|
||||||
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
|
||||||
self.has_vars_bound_at_or_above(binder.shifted_in(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return `true` if this type has regions that are not a part of the type.
|
|
||||||
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
|
|
||||||
/// would return `true`. The latter can occur when traversing through the
|
|
||||||
/// former.
|
|
||||||
///
|
|
||||||
/// See [`HasEscapingVarsVisitor`] for more information.
|
|
||||||
fn has_escaping_bound_vars(&self) -> bool {
|
|
||||||
self.has_vars_bound_at_or_above(ty::INNERMOST)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
|
||||||
let res =
|
|
||||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
|
|
||||||
trace!(?self, ?flags, ?res, "has_type_flags");
|
|
||||||
res
|
|
||||||
}
|
|
||||||
fn has_projections(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_PROJECTION)
|
|
||||||
}
|
|
||||||
fn has_inherent_projections(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
|
|
||||||
}
|
|
||||||
fn has_opaque_types(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
|
||||||
}
|
|
||||||
fn has_coroutines(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
|
|
||||||
}
|
|
||||||
fn references_error(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_ERROR)
|
|
||||||
}
|
|
||||||
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
|
||||||
if self.references_error() {
|
|
||||||
// We must include lint errors and delayed bugs here.
|
|
||||||
if let Some(reported) =
|
|
||||||
ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs())
|
|
||||||
{
|
|
||||||
Err(reported)
|
|
||||||
} else {
|
|
||||||
bug!("expected some kind of error in `error_reported`");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn has_non_region_param(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
|
|
||||||
}
|
|
||||||
fn has_infer_regions(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_RE_INFER)
|
|
||||||
}
|
|
||||||
fn has_infer_types(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_TY_INFER)
|
|
||||||
}
|
|
||||||
fn has_non_region_infer(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
|
|
||||||
}
|
|
||||||
fn has_infer(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_INFER)
|
|
||||||
}
|
|
||||||
fn has_placeholders(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
|
|
||||||
}
|
|
||||||
fn has_non_region_placeholders(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
|
|
||||||
}
|
|
||||||
fn has_param(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_PARAM)
|
|
||||||
}
|
|
||||||
/// "Free" regions in this context means that it has any region
|
|
||||||
/// that is not (a) erased or (b) late-bound.
|
|
||||||
fn has_free_regions(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_erased_regions(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True if there are any un-erased free regions.
|
|
||||||
fn has_erasable_regions(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indicates whether this value references only 'global'
|
|
||||||
/// generic parameters that are the same regardless of what fn we are
|
|
||||||
/// in. This is used for caching.
|
|
||||||
fn is_global(&self) -> bool {
|
|
||||||
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True if there are any late-bound regions
|
|
||||||
fn has_bound_regions(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
|
|
||||||
}
|
|
||||||
/// True if there are any late-bound non-region variables
|
|
||||||
fn has_non_region_bound_vars(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
|
|
||||||
}
|
|
||||||
/// True if there are any bound variables
|
|
||||||
fn has_bound_vars(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indicates whether this value still has parameters/placeholders/inference variables
|
|
||||||
/// which could be replaced later, in a way that would change the results of `impl`
|
|
||||||
/// specialization.
|
|
||||||
fn still_further_specializable(&self) -> bool {
|
|
||||||
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Region folder
|
// Region folder
|
||||||
|
@ -370,185 +240,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
|
||||||
struct FoundEscapingVars;
|
|
||||||
|
|
||||||
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
|
|
||||||
/// bound region or a bound type.
|
|
||||||
///
|
|
||||||
/// So, for example, consider a type like the following, which has two binders:
|
|
||||||
///
|
|
||||||
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
|
|
||||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
|
|
||||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
|
|
||||||
///
|
|
||||||
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
|
|
||||||
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
|
|
||||||
/// fn type*, that type has an escaping region: `'a`.
|
|
||||||
///
|
|
||||||
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
|
|
||||||
/// we already use the term "free var". It refers to the regions or types that we use to represent
|
|
||||||
/// bound regions or type params on a fn definition while we are type checking its body.
|
|
||||||
///
|
|
||||||
/// To clarify, conceptually there is no particular difference between
|
|
||||||
/// an "escaping" var and a "free" var. However, there is a big
|
|
||||||
/// difference in practice. Basically, when "entering" a binding
|
|
||||||
/// level, one is generally required to do some sort of processing to
|
|
||||||
/// a bound var, such as replacing it with a fresh/placeholder
|
|
||||||
/// var, or making an entry in the environment to represent the
|
|
||||||
/// scope to which it is attached, etc. An escaping var represents
|
|
||||||
/// a bound var for which this processing has not yet been done.
|
|
||||||
struct HasEscapingVarsVisitor {
|
|
||||||
/// Anything bound by `outer_index` or "above" is escaping.
|
|
||||||
outer_index: ty::DebruijnIndex,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
|
|
||||||
type BreakTy = FoundEscapingVars;
|
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
|
||||||
&mut self,
|
|
||||||
t: &Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.outer_index.shift_in(1);
|
|
||||||
let result = t.super_visit_with(self);
|
|
||||||
self.outer_index.shift_out(1);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// If the outer-exclusive-binder is *strictly greater* than
|
|
||||||
// `outer_index`, that means that `t` contains some content
|
|
||||||
// bound at `outer_index` or above (because
|
|
||||||
// `outer_exclusive_binder` is always 1 higher than the
|
|
||||||
// content in `t`). Therefore, `t` has some escaping vars.
|
|
||||||
if t.outer_exclusive_binder() > self.outer_index {
|
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// If the region is bound by `outer_index` or anything outside
|
|
||||||
// of outer index, then it escapes the binders we have
|
|
||||||
// visited.
|
|
||||||
if r.bound_at_or_above_binder(self.outer_index) {
|
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// If the outer-exclusive-binder is *strictly greater* than
|
|
||||||
// `outer_index`, that means that `ct` contains some content
|
|
||||||
// bound at `outer_index` or above (because
|
|
||||||
// `outer_exclusive_binder` is always 1 higher than the
|
|
||||||
// content in `t`). Therefore, `t` has some escaping vars.
|
|
||||||
if ct.outer_exclusive_binder() > self.outer_index {
|
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if predicate.outer_exclusive_binder() > self.outer_index {
|
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
|
||||||
struct FoundFlags;
|
|
||||||
|
|
||||||
// FIXME: Optimize for checking for infer flags
|
|
||||||
struct HasTypeFlagsVisitor {
|
|
||||||
flags: ty::TypeFlags,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for HasTypeFlagsVisitor {
|
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.flags.fmt(fmt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: this visitor traverses values down to the level of
|
|
||||||
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
|
|
||||||
// type flags at the outer layer are enough. So it's faster than it first
|
|
||||||
// looks, particular for `Ty`/`Predicate` where it's just a field access.
|
|
||||||
//
|
|
||||||
// N.B. The only case where this isn't totally true is binders, which also
|
|
||||||
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
|
|
||||||
// are present, regardless of whether those bound variables are used. This
|
|
||||||
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
|
||||||
// specifically detect this case in `visit_binder`.
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
|
||||||
type BreakTy = FoundFlags;
|
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
|
||||||
&mut self,
|
|
||||||
t: &Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
|
||||||
// binder has vars. This won't be present in the binder's bound
|
|
||||||
// value, so we need to check here too.
|
|
||||||
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.bound_vars().is_empty() {
|
|
||||||
return ControlFlow::Break(FoundFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
t.super_visit_with(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// Note: no `super_visit_with` call.
|
|
||||||
let flags = t.flags();
|
|
||||||
if flags.intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// Note: no `super_visit_with` call, as usual for `Region`.
|
|
||||||
let flags = r.type_flags();
|
|
||||||
if flags.intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// Note: no `super_visit_with` call.
|
|
||||||
if c.flags().intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
// Note: no `super_visit_with` call.
|
|
||||||
if predicate.flags().intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
|
||||||
} else {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Collects all the late-bound regions at the innermost binding level
|
/// Collects all the late-bound regions at the innermost binding level
|
||||||
/// into a hash set.
|
/// into a hash set.
|
||||||
struct LateBoundRegionsCollector {
|
struct LateBoundRegionsCollector {
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
||||||
body_target_features: &'tcx [Symbol],
|
body_target_features: &'tcx [Symbol],
|
||||||
/// When inside the LHS of an assignment to a field, this is the type
|
/// When inside the LHS of an assignment to a field, this is the type
|
||||||
/// of the LHS and the span of the assignment expression.
|
/// of the LHS and the span of the assignment expression.
|
||||||
assignment_info: Option<(Ty<'tcx>, Span)>,
|
assignment_info: Option<Ty<'tcx>>,
|
||||||
in_union_destructure: bool,
|
in_union_destructure: bool,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
inside_adt: bool,
|
inside_adt: bool,
|
||||||
|
@ -473,10 +473,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
if let ty::Adt(adt_def, _) = lhs.ty.kind()
|
if let ty::Adt(adt_def, _) = lhs.ty.kind()
|
||||||
&& adt_def.is_union()
|
&& adt_def.is_union()
|
||||||
{
|
{
|
||||||
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
|
if let Some(assigned_ty) = self.assignment_info {
|
||||||
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
||||||
// This would be unsafe, but should be outright impossible since we reject such unions.
|
// This would be unsafe, but should be outright impossible since we
|
||||||
self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
|
// reject such unions.
|
||||||
|
assert!(
|
||||||
|
self.tcx.dcx().has_errors().is_some(),
|
||||||
|
"union fields that need dropping should be impossible: \
|
||||||
|
{assigned_ty}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.requires_unsafe(expr.span, AccessToUnionField);
|
self.requires_unsafe(expr.span, AccessToUnionField);
|
||||||
|
@ -492,14 +497,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
|
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second, check for accesses to union fields
|
// Second, check for accesses to union fields. Don't have any
|
||||||
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
|
// special handling for AssignOp since it causes a read *and*
|
||||||
|
// write to lhs.
|
||||||
if matches!(expr.kind, ExprKind::Assign { .. }) {
|
if matches!(expr.kind, ExprKind::Assign { .. }) {
|
||||||
self.assignment_info = Some((lhs.ty, expr.span));
|
self.assignment_info = Some(lhs.ty);
|
||||||
visit::walk_expr(self, lhs);
|
visit::walk_expr(self, lhs);
|
||||||
self.assignment_info = None;
|
self.assignment_info = None;
|
||||||
visit::walk_expr(self, &self.thir()[rhs]);
|
visit::walk_expr(self, &self.thir()[rhs]);
|
||||||
return; // we have already visited everything by now
|
return; // We have already visited everything by now.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Borrow { borrow_kind, arg } => {
|
ExprKind::Borrow { borrow_kind, arg } => {
|
||||||
|
|
|
@ -153,8 +153,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// a hard error when we don't have a valtree or when we find something in
|
// a hard error when we don't have a valtree or when we find something in
|
||||||
// the valtree that is not structural; then this can all be made a lot simpler.
|
// the valtree that is not structural; then this can all be made a lot simpler.
|
||||||
|
|
||||||
let structural =
|
let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty());
|
||||||
traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
|
|
||||||
debug!(
|
debug!(
|
||||||
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
|
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
|
||||||
cv.ty(),
|
cv.ty(),
|
||||||
|
|
|
@ -243,10 +243,11 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
||||||
// old value is being dropped.
|
// old value is being dropped.
|
||||||
let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
||||||
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
||||||
// This would be unsafe, but should be outright impossible since we reject such unions.
|
// This would be unsafe, but should be outright impossible since we reject
|
||||||
self.tcx.dcx().span_delayed_bug(
|
// such unions.
|
||||||
self.source_info.span,
|
assert!(
|
||||||
format!("union fields that need dropping should be impossible: {assigned_ty}")
|
self.tcx.dcx().has_errors().is_some(),
|
||||||
|
"union fields that need dropping should be impossible: {assigned_ty}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -561,9 +561,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
.ok()?;
|
.ok()?;
|
||||||
dest.into()
|
dest.into()
|
||||||
}
|
}
|
||||||
CastKind::FnPtrToPtr
|
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
|
||||||
| CastKind::PtrToPtr
|
let src = self.evaluated[value].as_ref()?;
|
||||||
| CastKind::PointerCoercion(
|
let src = self.ecx.read_immediate(src).ok()?;
|
||||||
|
let to = self.ecx.layout_of(to).ok()?;
|
||||||
|
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
||||||
|
ret.into()
|
||||||
|
}
|
||||||
|
CastKind::PointerCoercion(
|
||||||
ty::adjustment::PointerCoercion::MutToConstPointer
|
ty::adjustment::PointerCoercion::MutToConstPointer
|
||||||
| ty::adjustment::PointerCoercion::ArrayToPointer
|
| ty::adjustment::PointerCoercion::ArrayToPointer
|
||||||
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
|
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
|
||||||
|
@ -571,8 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
let src = self.evaluated[value].as_ref()?;
|
let src = self.evaluated[value].as_ref()?;
|
||||||
let src = self.ecx.read_immediate(src).ok()?;
|
let src = self.ecx.read_immediate(src).ok()?;
|
||||||
let to = self.ecx.layout_of(to).ok()?;
|
let to = self.ecx.layout_of(to).ok()?;
|
||||||
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
ImmTy::from_immediate(*src, to).into()
|
||||||
ret.into()
|
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
|
|
|
@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||||
let body = &tcx.mir_const(def).borrow();
|
let body = &tcx.mir_const(def).borrow();
|
||||||
|
|
||||||
if body.return_ty().references_error() {
|
if body.return_ty().references_error() {
|
||||||
tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
|
assert!(tcx.dcx().has_errors().is_some(), "mir_const_qualif: MIR had errors");
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
|
use rustc_type_ir::visit::TypeVisitableExt;
|
||||||
use rustc_type_ir::{
|
use rustc_type_ir::{
|
||||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
||||||
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
||||||
|
@ -62,8 +63,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
|
||||||
|
|
||||||
let value = value.fold_with(&mut canonicalizer);
|
let value = value.fold_with(&mut canonicalizer);
|
||||||
// FIXME: Restore these assertions. Should we uplift type flags?
|
// FIXME: Restore these assertions. Should we uplift type flags?
|
||||||
// assert!(!value.has_infer(), "unexpected infer in {value:?}");
|
assert!(!value.has_infer(), "unexpected infer in {value:?}");
|
||||||
// assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
|
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
|
||||||
|
|
||||||
let (max_universe, variables) = canonicalizer.finalize();
|
let (max_universe, variables) = canonicalizer.finalize();
|
||||||
|
|
||||||
|
|
|
@ -429,16 +429,16 @@ where
|
||||||
let formatter = query.format_value();
|
let formatter = query.format_value();
|
||||||
if old_hash != new_hash {
|
if old_hash != new_hash {
|
||||||
// We have an inconsistency. This can happen if one of the two
|
// We have an inconsistency. This can happen if one of the two
|
||||||
// results is tainted by errors. In this case, delay a bug to
|
// results is tainted by errors.
|
||||||
// ensure compilation is doomed.
|
assert!(
|
||||||
qcx.dep_context().sess().dcx().delayed_bug(format!(
|
qcx.dep_context().sess().dcx().has_errors().is_some(),
|
||||||
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
|
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
|
||||||
computed={:#?}\nfed={:#?}",
|
computed={:#?}\nfed={:#?}",
|
||||||
query.dep_kind(),
|
query.dep_kind(),
|
||||||
key,
|
key,
|
||||||
formatter(&result),
|
formatter(&result),
|
||||||
formatter(&cached_result),
|
formatter(&cached_result),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>(
|
||||||
|
|
||||||
match unexpanded_ct.kind() {
|
match unexpanded_ct.kind() {
|
||||||
ty::ConstKind::Expr(_) => {
|
ty::ConstKind::Expr(_) => {
|
||||||
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but
|
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete,
|
||||||
// currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it
|
// but currently it is not possible to evaluate `ConstKind::Expr` so we are unable
|
||||||
// is evaluatable or not. For now we just ICE until this is implemented.
|
// to tell if it is evaluatable or not. For now we just ICE until this is
|
||||||
|
// implemented.
|
||||||
Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
|
Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
|
||||||
span,
|
span,
|
||||||
"evaluating `ConstKind::Expr` is not currently supported",
|
"evaluating `ConstKind::Expr` is not currently supported",
|
||||||
|
|
|
@ -3041,7 +3041,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
this = "the implicit `Sized` requirement on this type parameter";
|
this = "the implicit `Sized` requirement on this type parameter";
|
||||||
}
|
}
|
||||||
if let Some(hir::Node::TraitItem(hir::TraitItem {
|
if let Some(hir::Node::TraitItem(hir::TraitItem {
|
||||||
ident,
|
generics,
|
||||||
kind: hir::TraitItemKind::Type(bounds, None),
|
kind: hir::TraitItemKind::Type(bounds, None),
|
||||||
..
|
..
|
||||||
})) = tcx.hir().get_if_local(item_def_id)
|
})) = tcx.hir().get_if_local(item_def_id)
|
||||||
|
@ -3053,7 +3053,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let (span, separator) = if let [.., last] = bounds {
|
let (span, separator) = if let [.., last] = bounds {
|
||||||
(last.span().shrink_to_hi(), " +")
|
(last.span().shrink_to_hi(), " +")
|
||||||
} else {
|
} else {
|
||||||
(ident.span.shrink_to_hi(), ":")
|
(generics.span.shrink_to_hi(), ":")
|
||||||
};
|
};
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -236,9 +236,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It could be that we don't report an error because we have seen an `ErrorReported` from another source.
|
// It could be that we don't report an error because we have seen an `ErrorReported` from
|
||||||
// We should probably be able to fix most of these, but some are delayed bugs that get a proper error
|
// another source. We should probably be able to fix most of these, but some are delayed
|
||||||
// after this function.
|
// bugs that get a proper error after this function.
|
||||||
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
|
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +519,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
span,
|
span,
|
||||||
) {
|
) {
|
||||||
GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"),
|
GetSafeTransmuteErrorAndReason::Silent => {
|
||||||
|
return self.dcx().span_delayed_bug(
|
||||||
|
span, "silent safe transmute error"
|
||||||
|
);
|
||||||
|
}
|
||||||
GetSafeTransmuteErrorAndReason::Error {
|
GetSafeTransmuteErrorAndReason::Error {
|
||||||
err_msg,
|
err_msg,
|
||||||
safe_transmute_explanation,
|
safe_transmute_explanation,
|
||||||
|
@ -2990,7 +2994,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
{
|
{
|
||||||
(s, " +")
|
(s, " +")
|
||||||
} else {
|
} else {
|
||||||
(span.shrink_to_hi(), ":")
|
(param.name.ident().span.shrink_to_hi(), ":")
|
||||||
};
|
};
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -555,7 +555,7 @@ fn virtual_call_violations_for_method<'tcx>(
|
||||||
|
|
||||||
// NOTE: This check happens last, because it results in a lint, and not a
|
// NOTE: This check happens last, because it results in a lint, and not a
|
||||||
// hard error.
|
// hard error.
|
||||||
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| {
|
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, _span)| {
|
||||||
// dyn Trait is okay:
|
// dyn Trait is okay:
|
||||||
//
|
//
|
||||||
// trait Trait {
|
// trait Trait {
|
||||||
|
@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>(
|
||||||
// would already have reported an error at the definition of the
|
// would already have reported an error at the definition of the
|
||||||
// auto trait.
|
// auto trait.
|
||||||
if pred_trait_ref.args.len() != 1 {
|
if pred_trait_ref.args.len() != 1 {
|
||||||
tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters");
|
assert!(
|
||||||
|
tcx.dcx().has_errors().is_some(),
|
||||||
|
"auto traits cannot have generic parameters"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||||
use rustc_span::Span;
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
/// This method traverses the structure of `ty`, trying to find an
|
/// This method traverses the structure of `ty`, trying to find an
|
||||||
|
@ -30,19 +29,16 @@ use std::ops::ControlFlow;
|
||||||
/// that arose when the requirement was not enforced completely, see
|
/// that arose when the requirement was not enforced completely, see
|
||||||
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
|
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
|
||||||
pub fn search_for_structural_match_violation<'tcx>(
|
pub fn search_for_structural_match_violation<'tcx>(
|
||||||
span: Span,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> Option<Ty<'tcx>> {
|
) -> Option<Ty<'tcx>> {
|
||||||
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
|
ty.visit_with(&mut Search { tcx, seen: FxHashSet::default() }).break_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This implements the traversal over the structure of a given type to try to
|
/// This implements the traversal over the structure of a given type to try to
|
||||||
/// find instances of ADTs (specifically structs or enums) that do not implement
|
/// find instances of ADTs (specifically structs or enums) that do not implement
|
||||||
/// `StructuralPartialEq`.
|
/// `StructuralPartialEq`.
|
||||||
struct Search<'tcx> {
|
struct Search<'tcx> {
|
||||||
span: Span,
|
|
||||||
|
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
/// Tracks ADTs previously encountered during search, so that
|
/// Tracks ADTs previously encountered during search, so that
|
||||||
|
@ -138,7 +134,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
||||||
bug!("unexpected type during structural-match checking: {:?}", ty);
|
bug!("unexpected type during structural-match checking: {:?}", ty);
|
||||||
}
|
}
|
||||||
ty::Error(_) => {
|
ty::Error(_) => {
|
||||||
self.tcx.dcx().span_delayed_bug(self.span, "ty::Error in structural-match check");
|
|
||||||
// We still want to check other types after encountering an error,
|
// We still want to check other types after encountering an error,
|
||||||
// as this may still emit relevant errors.
|
// as this may still emit relevant errors.
|
||||||
return ControlFlow::Continue(());
|
return ControlFlow::Continue(());
|
||||||
|
|
7
compiler/rustc_type_ir/src/binder.rs
Normal file
7
compiler/rustc_type_ir/src/binder.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use crate::Interner;
|
||||||
|
|
||||||
|
pub trait BoundVars<I: Interner> {
|
||||||
|
fn bound_vars(&self) -> I::BoundVars;
|
||||||
|
|
||||||
|
fn has_no_bound_vars(&self) -> bool;
|
||||||
|
}
|
|
@ -2,9 +2,10 @@ use smallvec::SmallVec;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
|
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
|
||||||
UniverseIndex,
|
TyKind, UniverseIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Interner: Sized {
|
pub trait Interner: Sized {
|
||||||
|
@ -19,7 +20,10 @@ pub trait Interner: Sized {
|
||||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type Term: Copy + Debug + Hash + Ord;
|
type Term: Copy + Debug + Hash + Ord;
|
||||||
|
|
||||||
type Binder<T>;
|
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
|
||||||
|
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
||||||
|
type BoundVar;
|
||||||
|
|
||||||
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
||||||
|
|
||||||
// Kinds of tys
|
// Kinds of tys
|
||||||
|
@ -28,7 +32,9 @@ pub trait Interner: Sized {
|
||||||
+ Hash
|
+ Hash
|
||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = TyKind<Self>>;
|
+ IntoKind<Kind = TyKind<Self>>
|
||||||
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ Flags;
|
||||||
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
||||||
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type ParamTy: Copy + Debug + Hash + Ord;
|
type ParamTy: Copy + Debug + Hash + Ord;
|
||||||
|
@ -48,7 +54,9 @@ pub trait Interner: Sized {
|
||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = ConstKind<Self>>
|
+ IntoKind<Kind = ConstKind<Self>>
|
||||||
+ ConstTy<Self>;
|
+ ConstTy<Self>
|
||||||
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ Flags;
|
||||||
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
|
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||||
type ParamConst: Copy + Debug + Hash + Ord;
|
type ParamConst: Copy + Debug + Hash + Ord;
|
||||||
|
@ -62,7 +70,8 @@ pub trait Interner: Sized {
|
||||||
+ Hash
|
+ Hash
|
||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = RegionKind<Self>>;
|
+ IntoKind<Kind = RegionKind<Self>>
|
||||||
|
+ Flags;
|
||||||
type EarlyParamRegion: Copy + Debug + Hash + Ord;
|
type EarlyParamRegion: Copy + Debug + Hash + Ord;
|
||||||
type LateParamRegion: Copy + Debug + Hash + Ord;
|
type LateParamRegion: Copy + Debug + Hash + Ord;
|
||||||
type BoundRegion: Copy + Debug + Hash + Ord;
|
type BoundRegion: Copy + Debug + Hash + Ord;
|
||||||
|
@ -70,7 +79,7 @@ pub trait Interner: Sized {
|
||||||
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
|
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||||
|
|
||||||
// Predicates
|
// Predicates
|
||||||
type Predicate: Copy + Debug + Hash + Eq;
|
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||||
type TraitPredicate: Copy + Debug + Hash + Eq;
|
type TraitPredicate: Copy + Debug + Hash + Eq;
|
||||||
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
|
@ -86,6 +95,9 @@ pub trait Interner: Sized {
|
||||||
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
|
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
|
||||||
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
|
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
|
||||||
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
|
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
|
||||||
|
|
||||||
|
/// Assert that an error has been delayed or emitted.
|
||||||
|
fn expect_error_or_delayed_bug();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Common capabilities of placeholder kinds
|
/// Common capabilities of placeholder kinds
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub mod visit;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
mod binder;
|
||||||
mod canonical;
|
mod canonical;
|
||||||
mod const_kind;
|
mod const_kind;
|
||||||
mod debug;
|
mod debug;
|
||||||
|
@ -39,6 +40,7 @@ mod interner;
|
||||||
mod predicate_kind;
|
mod predicate_kind;
|
||||||
mod region_kind;
|
mod region_kind;
|
||||||
|
|
||||||
|
pub use binder::*;
|
||||||
pub use canonical::*;
|
pub use canonical::*;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub use codec::*;
|
pub use codec::*;
|
||||||
|
|
|
@ -45,8 +45,7 @@ use rustc_index::{Idx, IndexVec};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use crate::Interner;
|
use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
|
||||||
use crate::Lrc;
|
|
||||||
|
|
||||||
/// This trait is implemented for every type that can be visited,
|
/// This trait is implemented for every type that can be visited,
|
||||||
/// providing the skeleton of the traversal.
|
/// providing the skeleton of the traversal.
|
||||||
|
@ -88,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized {
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
type BreakTy;
|
type BreakTy;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
where
|
&mut self,
|
||||||
I::Binder<T>: TypeSuperVisitable<I>,
|
t: &I::Binder<T>,
|
||||||
{
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy>
|
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Ty: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default region visitor is a no-op because `Region` is non-recursive
|
// The default region visitor is a no-op because `Region` is non-recursive
|
||||||
// and has no `super_visit_with` method to call. That also explains the
|
// and has no `super_visit_with` method to call.
|
||||||
// lack of `I::Region: TypeSuperVisitable<I>` bound.
|
|
||||||
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy>
|
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Const: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
c.super_visit_with(self)
|
c.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy>
|
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Predicate: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
p.super_visit_with(self)
|
p.super_visit_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,3 +189,363 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
|
||||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Flags {
|
||||||
|
fn flags(&self) -> TypeFlags;
|
||||||
|
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
|
||||||
|
fn has_type_flags(&self, flags: TypeFlags) -> bool;
|
||||||
|
|
||||||
|
/// Returns `true` if `self` has any late-bound regions that are either
|
||||||
|
/// bound by `binder` or bound by some binder outside of `binder`.
|
||||||
|
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
||||||
|
/// there are any late-bound regions that appear free.
|
||||||
|
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool;
|
||||||
|
|
||||||
|
/// Returns `true` if this type has any regions that escape `binder` (and
|
||||||
|
/// hence are not bound by it).
|
||||||
|
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||||
|
self.has_vars_bound_at_or_above(binder.shifted_in(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return `true` if this type has regions that are not a part of the type.
|
||||||
|
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
|
||||||
|
/// would return `true`. The latter can occur when traversing through the
|
||||||
|
/// former.
|
||||||
|
///
|
||||||
|
/// See [`HasEscapingVarsVisitor`] for more information.
|
||||||
|
fn has_escaping_bound_vars(&self) -> bool {
|
||||||
|
self.has_vars_bound_at_or_above(ty::INNERMOST)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_projections(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_PROJECTION)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_inherent_projections(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_opaque_types(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_coroutines(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn references_error(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>;
|
||||||
|
|
||||||
|
fn has_non_region_param(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_infer_regions(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_RE_INFER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_infer_types(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_TY_INFER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_non_region_infer(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_infer(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_INFER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_placeholders(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_non_region_placeholders(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_param(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_PARAM)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "Free" regions in this context means that it has any region
|
||||||
|
/// that is not (a) erased or (b) late-bound.
|
||||||
|
fn has_free_regions(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_erased_regions(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True if there are any un-erased free regions.
|
||||||
|
fn has_erasable_regions(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates whether this value references only 'global'
|
||||||
|
/// generic parameters that are the same regardless of what fn we are
|
||||||
|
/// in. This is used for caching.
|
||||||
|
fn is_global(&self) -> bool {
|
||||||
|
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True if there are any late-bound regions
|
||||||
|
fn has_bound_regions(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
|
||||||
|
}
|
||||||
|
/// True if there are any late-bound non-region variables
|
||||||
|
fn has_non_region_bound_vars(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
|
||||||
|
}
|
||||||
|
/// True if there are any bound variables
|
||||||
|
fn has_bound_vars(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates whether this value still has parameters/placeholders/inference variables
|
||||||
|
/// which could be replaced later, in a way that would change the results of `impl`
|
||||||
|
/// specialization.
|
||||||
|
fn still_further_specializable(&self) -> bool {
|
||||||
|
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
|
||||||
|
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||||
|
let res =
|
||||||
|
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||||
|
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
|
||||||
|
if self.references_error() {
|
||||||
|
if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) {
|
||||||
|
Err(guar)
|
||||||
|
} else {
|
||||||
|
panic!("type flags said there was an error, but now there is not")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
struct FoundFlags;
|
||||||
|
|
||||||
|
// FIXME: Optimize for checking for infer flags
|
||||||
|
struct HasTypeFlagsVisitor {
|
||||||
|
flags: ty::TypeFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for HasTypeFlagsVisitor {
|
||||||
|
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.flags.fmt(fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this visitor traverses values down to the level of
|
||||||
|
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
|
||||||
|
// type flags at the outer layer are enough. So it's faster than it first
|
||||||
|
// looks, particular for `Ty`/`Predicate` where it's just a field access.
|
||||||
|
//
|
||||||
|
// N.B. The only case where this isn't totally true is binders, which also
|
||||||
|
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
|
||||||
|
// are present, regardless of whether those bound variables are used. This
|
||||||
|
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
||||||
|
// specifically detect this case in `visit_binder`.
|
||||||
|
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
||||||
|
type BreakTy = FoundFlags;
|
||||||
|
|
||||||
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
|
&mut self,
|
||||||
|
t: &I::Binder<T>,
|
||||||
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
||||||
|
// binder has vars. This won't be present in the binder's bound
|
||||||
|
// value, so we need to check here too.
|
||||||
|
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.has_no_bound_vars() {
|
||||||
|
return ControlFlow::Break(FoundFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
t.super_visit_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
|
let flags = t.flags();
|
||||||
|
if flags.intersects(self.flags) {
|
||||||
|
ControlFlow::Break(FoundFlags)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call, as usual for `Region`.
|
||||||
|
let flags = r.flags();
|
||||||
|
if flags.intersects(self.flags) {
|
||||||
|
ControlFlow::Break(FoundFlags)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
|
if c.flags().intersects(self.flags) {
|
||||||
|
ControlFlow::Break(FoundFlags)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
|
if predicate.flags().intersects(self.flags) {
|
||||||
|
ControlFlow::Break(FoundFlags)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
struct FoundEscapingVars;
|
||||||
|
|
||||||
|
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
|
||||||
|
/// bound region or a bound type.
|
||||||
|
///
|
||||||
|
/// So, for example, consider a type like the following, which has two binders:
|
||||||
|
///
|
||||||
|
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
|
||||||
|
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
|
||||||
|
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
|
||||||
|
///
|
||||||
|
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
|
||||||
|
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
|
||||||
|
/// fn type*, that type has an escaping region: `'a`.
|
||||||
|
///
|
||||||
|
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
|
||||||
|
/// we already use the term "free var". It refers to the regions or types that we use to represent
|
||||||
|
/// bound regions or type params on a fn definition while we are type checking its body.
|
||||||
|
///
|
||||||
|
/// To clarify, conceptually there is no particular difference between
|
||||||
|
/// an "escaping" var and a "free" var. However, there is a big
|
||||||
|
/// difference in practice. Basically, when "entering" a binding
|
||||||
|
/// level, one is generally required to do some sort of processing to
|
||||||
|
/// a bound var, such as replacing it with a fresh/placeholder
|
||||||
|
/// var, or making an entry in the environment to represent the
|
||||||
|
/// scope to which it is attached, etc. An escaping var represents
|
||||||
|
/// a bound var for which this processing has not yet been done.
|
||||||
|
struct HasEscapingVarsVisitor {
|
||||||
|
/// Anything bound by `outer_index` or "above" is escaping.
|
||||||
|
outer_index: ty::DebruijnIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
||||||
|
type BreakTy = FoundEscapingVars;
|
||||||
|
|
||||||
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
|
&mut self,
|
||||||
|
t: &I::Binder<T>,
|
||||||
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
|
self.outer_index.shift_in(1);
|
||||||
|
let result = t.super_visit_with(self);
|
||||||
|
self.outer_index.shift_out(1);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// If the outer-exclusive-binder is *strictly greater* than
|
||||||
|
// `outer_index`, that means that `t` contains some content
|
||||||
|
// bound at `outer_index` or above (because
|
||||||
|
// `outer_exclusive_binder` is always 1 higher than the
|
||||||
|
// content in `t`). Therefore, `t` has some escaping vars.
|
||||||
|
if t.outer_exclusive_binder() > self.outer_index {
|
||||||
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// If the region is bound by `outer_index` or anything outside
|
||||||
|
// of outer index, then it escapes the binders we have
|
||||||
|
// visited.
|
||||||
|
if r.outer_exclusive_binder() > self.outer_index {
|
||||||
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_const(&mut self, ct: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// If the outer-exclusive-binder is *strictly greater* than
|
||||||
|
// `outer_index`, that means that `ct` contains some content
|
||||||
|
// bound at `outer_index` or above (because
|
||||||
|
// `outer_exclusive_binder` is always 1 higher than the
|
||||||
|
// content in `t`). Therefore, `t` has some escaping vars.
|
||||||
|
if ct.outer_exclusive_binder() > self.outer_index {
|
||||||
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if predicate.outer_exclusive_binder() > self.outer_index {
|
||||||
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HasErrorVisitor;
|
||||||
|
|
||||||
|
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
||||||
|
type BreakTy = I::ErrorGuaranteed;
|
||||||
|
|
||||||
|
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if let ty::Error(guar) = t.kind() {
|
||||||
|
ControlFlow::Break(guar)
|
||||||
|
} else {
|
||||||
|
t.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if let ty::ConstKind::Error(guar) = c.kind() {
|
||||||
|
ControlFlow::Break(guar)
|
||||||
|
} else {
|
||||||
|
c.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_region(&mut self, r: <I as Interner>::Region) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if let ty::ReError(guar) = r.kind() {
|
||||||
|
ControlFlow::Break(guar)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ use core::task::Waker;
|
||||||
/// The implementation of waking a task on an executor.
|
/// The implementation of waking a task on an executor.
|
||||||
///
|
///
|
||||||
/// This trait can be used to create a [`Waker`]. An executor can define an
|
/// This trait can be used to create a [`Waker`]. An executor can define an
|
||||||
/// implementation of this trait, and use that to construct a Waker to pass
|
/// implementation of this trait, and use that to construct a [`Waker`] to pass
|
||||||
/// to the tasks that are executed on that executor.
|
/// to the tasks that are executed on that executor.
|
||||||
///
|
///
|
||||||
/// This trait is a memory-safe and ergonomic alternative to constructing a
|
/// This trait is a memory-safe and ergonomic alternative to constructing a
|
||||||
|
@ -28,7 +28,14 @@ use core::task::Waker;
|
||||||
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
|
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
|
||||||
/// exists as an alternative for those systems.
|
/// exists as an alternative for those systems.
|
||||||
///
|
///
|
||||||
/// [arc]: ../../std/sync/struct.Arc.html
|
/// To construct a [`Waker`] from some type `W` implementing this trait,
|
||||||
|
/// wrap it in an [`Arc<W>`](Arc) and call `Waker::from()` on that.
|
||||||
|
/// It is also possible to convert to [`RawWaker`] in the same way.
|
||||||
|
///
|
||||||
|
/// <!-- Ideally we'd link to the `From` impl, but rustdoc doesn't generate any page for it within
|
||||||
|
/// `alloc` because `alloc` neither defines nor re-exports `From` or `Waker`, and we can't
|
||||||
|
/// link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker
|
||||||
|
/// without getting a link-checking error in CI. -->
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -100,7 +107,7 @@ pub trait Wake {
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
||||||
/// Use a `Wake`-able type as a `Waker`.
|
/// Use a [`Wake`]-able type as a `Waker`.
|
||||||
///
|
///
|
||||||
/// No heap allocations or atomic operations are used for this conversion.
|
/// No heap allocations or atomic operations are used for this conversion.
|
||||||
fn from(waker: Arc<W>) -> Waker {
|
fn from(waker: Arc<W>) -> Waker {
|
||||||
|
|
|
@ -95,8 +95,10 @@ impl fmt::Display for AllocError {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to
|
/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to
|
||||||
/// valid memory and retain their validity while they are [*currently allocated*] and at
|
/// valid memory and retain their validity while they are [*currently allocated*] and the shorter
|
||||||
/// least one of the instance and all of its clones has not been dropped.
|
/// of:
|
||||||
|
/// - the borrow-checker lifetime of the allocator type itself.
|
||||||
|
/// - as long as at least one of the instance and all of its clones has not been dropped.
|
||||||
///
|
///
|
||||||
/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this
|
/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this
|
||||||
/// allocator. A copied or cloned allocator must behave like the same allocator, and
|
/// allocator. A copied or cloned allocator must behave like the same allocator, and
|
||||||
|
@ -114,6 +116,10 @@ pub unsafe trait Allocator {
|
||||||
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
|
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
|
||||||
/// not have its contents initialized.
|
/// not have its contents initialized.
|
||||||
///
|
///
|
||||||
|
/// The returned block of memory remains valid as long as it is [*currently allocated*] and the shorter of:
|
||||||
|
/// - the borrow-checker lifetime of the allocator type itself.
|
||||||
|
/// - as long as at the allocator and all its clones has not been dropped.
|
||||||
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
|
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
|
||||||
|
|
|
@ -58,7 +58,7 @@ use crate::mem::transmute;
|
||||||
#[unstable(feature = "ascii_char", issue = "110998")]
|
#[unstable(feature = "ascii_char", issue = "110998")]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum AsciiChar {
|
pub enum AsciiChar {
|
||||||
/// U+0000
|
/// U+0000 (The default variant)
|
||||||
#[unstable(feature = "ascii_char_variants", issue = "110998")]
|
#[unstable(feature = "ascii_char_variants", issue = "110998")]
|
||||||
Null = 0,
|
Null = 0,
|
||||||
/// U+0001
|
/// U+0001
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
|
use crate::ascii::Char as AsciiChar;
|
||||||
|
|
||||||
/// A trait for giving a type a useful default value.
|
/// A trait for giving a type a useful default value.
|
||||||
///
|
///
|
||||||
/// Sometimes, you want to fall back to some kind of default value, and
|
/// Sometimes, you want to fall back to some kind of default value, and
|
||||||
|
@ -158,6 +160,7 @@ macro_rules! default_impl {
|
||||||
default_impl! { (), (), "Returns the default value of `()`" }
|
default_impl! { (), (), "Returns the default value of `()`" }
|
||||||
default_impl! { bool, false, "Returns the default value of `false`" }
|
default_impl! { bool, false, "Returns the default value of `false`" }
|
||||||
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
|
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
|
||||||
|
default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" }
|
||||||
|
|
||||||
default_impl! { usize, 0, "Returns the default value of `0`" }
|
default_impl! { usize, 0, "Returns the default value of `0`" }
|
||||||
default_impl! { u8, 0, "Returns the default value of `0`" }
|
default_impl! { u8, 0, "Returns the default value of `0`" }
|
||||||
|
|
|
@ -9,10 +9,14 @@ use crate::ptr;
|
||||||
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
|
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
|
||||||
/// or a [`LocalWaker`] which provides customized wakeup behavior.
|
/// or a [`LocalWaker`] which provides customized wakeup behavior.
|
||||||
///
|
///
|
||||||
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
|
|
||||||
///
|
|
||||||
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
|
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
|
||||||
/// that customizes the behavior of the `RawWaker`.
|
/// that customizes the behavior of the `RawWaker`.
|
||||||
|
///
|
||||||
|
/// `RawWaker`s are unsafe to use.
|
||||||
|
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
|
||||||
|
///
|
||||||
|
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
|
||||||
|
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||||
pub struct RawWaker {
|
pub struct RawWaker {
|
||||||
|
@ -355,8 +359,12 @@ impl<'a> ContextBuilder<'a> {
|
||||||
/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker
|
/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker
|
||||||
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
|
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
|
||||||
///
|
///
|
||||||
|
/// Constructing a `Waker` from a [`RawWaker`] is unsafe.
|
||||||
|
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
|
||||||
|
///
|
||||||
/// [`Future::poll()`]: core::future::Future::poll
|
/// [`Future::poll()`]: core::future::Future::poll
|
||||||
/// [`Poll::Pending`]: core::task::Poll::Pending
|
/// [`Poll::Pending`]: core::task::Poll::Pending
|
||||||
|
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||||
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||||
pub struct Waker {
|
pub struct Waker {
|
||||||
|
@ -438,9 +446,15 @@ impl Waker {
|
||||||
|
|
||||||
/// Creates a new `Waker` from [`RawWaker`].
|
/// Creates a new `Waker` from [`RawWaker`].
|
||||||
///
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
/// The behavior of the returned `Waker` is undefined if the contract defined
|
/// The behavior of the returned `Waker` is undefined if the contract defined
|
||||||
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
|
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
|
||||||
/// Therefore this method is unsafe.
|
///
|
||||||
|
/// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
|
||||||
|
/// cost of a required heap allocation.)
|
||||||
|
///
|
||||||
|
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||||
|
|
|
@ -7,7 +7,9 @@ fn main() {
|
||||||
let target_vendor =
|
let target_vendor =
|
||||||
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
|
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
|
||||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
|
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
|
||||||
|
if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
|
||||||
|
println!("cargo:rustc-cfg=netbsd10");
|
||||||
|
}
|
||||||
if target_os == "linux"
|
if target_os == "linux"
|
||||||
|| target_os == "android"
|
|| target_os == "android"
|
||||||
|| target_os == "netbsd"
|
|| target_os == "netbsd"
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::sync::Once;
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Using `OnceCell` to store a function’s previously computed value (a.k.a.
|
/// Using `OnceLock` to store a function’s previously computed value (a.k.a.
|
||||||
/// ‘lazy static’ or ‘memoizing’):
|
/// ‘lazy static’ or ‘memoizing’):
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -62,7 +62,7 @@ mod imp {
|
||||||
unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
|
unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd"))]
|
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))]
|
||||||
fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
|
fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
|
||||||
unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
|
unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ mod imp {
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "espidf",
|
target_os = "espidf",
|
||||||
target_os = "horizon",
|
target_os = "horizon",
|
||||||
target_os = "freebsd"
|
target_os = "freebsd",
|
||||||
|
netbsd10
|
||||||
)))]
|
)))]
|
||||||
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
|
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
|
||||||
false
|
false
|
||||||
|
@ -83,7 +84,8 @@ mod imp {
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "espidf",
|
target_os = "espidf",
|
||||||
target_os = "horizon",
|
target_os = "horizon",
|
||||||
target_os = "freebsd"
|
target_os = "freebsd",
|
||||||
|
netbsd10
|
||||||
))]
|
))]
|
||||||
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
||||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -230,7 +232,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: once the 10.x release becomes the minimum, this can be dropped for simplification.
|
// FIXME: once the 10.x release becomes the minimum, this can be dropped for simplification.
|
||||||
#[cfg(target_os = "netbsd")]
|
#[cfg(all(target_os = "netbsd", not(netbsd10)))]
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
|
||||||
(Some(Mode::Std), "no_global_oom_handling", None),
|
(Some(Mode::Std), "no_global_oom_handling", None),
|
||||||
(Some(Mode::Std), "no_rc", None),
|
(Some(Mode::Std), "no_rc", None),
|
||||||
(Some(Mode::Std), "no_sync", None),
|
(Some(Mode::Std), "no_sync", None),
|
||||||
|
(Some(Mode::Std), "netbsd10", None),
|
||||||
(Some(Mode::Std), "backtrace_in_libstd", None),
|
(Some(Mode::Std), "backtrace_in_libstd", None),
|
||||||
/* Extra values not defined in the built-in targets yet, but used in std */
|
/* Extra values not defined in the built-in targets yet, but used in std */
|
||||||
(Some(Mode::Std), "target_env", Some(&["libnx"])),
|
(Some(Mode::Std), "target_env", Some(&["libnx"])),
|
||||||
|
|
25
tests/mir-opt/issue_120925_unsafefncast.rs
Normal file
25
tests/mir-opt/issue_120925_unsafefncast.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Verify that we do not ICE when attempting to interpret casts between fn types.
|
||||||
|
// skip-filecheck
|
||||||
|
|
||||||
|
static FOO: fn() = || assert_ne!(42, 43);
|
||||||
|
static BAR: fn(i32, i32) = |a, b| assert_ne!(a, b);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
FOO();
|
||||||
|
|
||||||
|
let bar: unsafe fn(i32, i32) = BAR;
|
||||||
|
|
||||||
|
let f: fn() = || {};
|
||||||
|
f();
|
||||||
|
|
||||||
|
f();
|
||||||
|
|
||||||
|
f();
|
||||||
|
|
||||||
|
let g: fn(i32) = |i| assert_eq!(i, 2);
|
||||||
|
g(2);
|
||||||
|
|
||||||
|
g(2);
|
||||||
|
|
||||||
|
g(2);
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:38:15
|
--> $DIR/inline-syntax.rs:35:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix", "nop");
|
LL | asm!(".intel_syntax noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -25,7 +25,7 @@ LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:42:15
|
--> $DIR/inline-syntax.rs:39:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:46:15
|
--> $DIR/inline-syntax.rs:43:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax noprefix", "nop");
|
LL | asm!(".att_syntax noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -49,7 +49,7 @@ LL | .att_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:50:15
|
--> $DIR/inline-syntax.rs:47:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:54:15
|
--> $DIR/inline-syntax.rs:51:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix; nop");
|
LL | asm!(".intel_syntax noprefix; nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:61:13
|
--> $DIR/inline-syntax.rs:58:13
|
||||||
|
|
|
|
||||||
LL | .intel_syntax noprefix
|
LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
|
@ -15,7 +15,7 @@ LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:38:15
|
--> $DIR/inline-syntax.rs:35:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix", "nop");
|
LL | asm!(".intel_syntax noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -27,7 +27,7 @@ LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:42:15
|
--> $DIR/inline-syntax.rs:39:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -39,7 +39,7 @@ LL | .intel_syntax aaa noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:46:15
|
--> $DIR/inline-syntax.rs:43:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax noprefix", "nop");
|
LL | asm!(".att_syntax noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -51,7 +51,7 @@ LL | .att_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:50:15
|
--> $DIR/inline-syntax.rs:47:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -63,7 +63,7 @@ LL | .att_syntax bbb noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:54:15
|
--> $DIR/inline-syntax.rs:51:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix; nop");
|
LL | asm!(".intel_syntax noprefix; nop");
|
||||||
| ^
|
| ^
|
||||||
|
@ -75,7 +75,7 @@ LL | .intel_syntax noprefix; nop
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: unknown directive
|
error: unknown directive
|
||||||
--> $DIR/inline-syntax.rs:61:13
|
--> $DIR/inline-syntax.rs:58:13
|
||||||
|
|
|
|
||||||
LL | .intel_syntax noprefix
|
LL | .intel_syntax noprefix
|
||||||
| ^
|
| ^
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
||||||
//[x86_64] check-pass
|
//[x86_64] check-pass
|
||||||
//[x86_64] needs-llvm-components: x86
|
//[x86_64] needs-llvm-components: x86
|
||||||
//[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu
|
|
||||||
//[x86_64_allowed] check-pass
|
|
||||||
//[x86_64_allowed] needs-llvm-components: x86
|
|
||||||
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
|
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||||
//[arm] build-fail
|
//[arm] build-fail
|
||||||
//[arm] needs-llvm-components: arm
|
//[arm] needs-llvm-components: arm
|
||||||
//[arm] ignore-llvm-version: 18 - 99
|
//[arm] ignore-llvm-version: 18 - 99
|
||||||
// Newer LLVM produces extra error notes.
|
//Newer LLVM produces extra error notes.
|
||||||
//[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
|
//[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||||
//[arm_llvm_18] build-fail
|
//[arm_llvm_18] build-fail
|
||||||
//[arm_llvm_18] needs-llvm-components: arm
|
//[arm_llvm_18] needs-llvm-components: arm
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||||
--> $DIR/inline-syntax.rs:70:14
|
--> $DIR/inline-syntax.rs:67:14
|
||||||
|
|
|
|
||||||
LL | global_asm!(".intel_syntax noprefix", "nop");
|
LL | global_asm!(".intel_syntax noprefix", "nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
|
||||||
= note: `#[warn(bad_asm_style)]` on by default
|
= note: `#[warn(bad_asm_style)]` on by default
|
||||||
|
|
||||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||||
--> $DIR/inline-syntax.rs:38:15
|
--> $DIR/inline-syntax.rs:35:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix", "nop");
|
LL | asm!(".intel_syntax noprefix", "nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||||
--> $DIR/inline-syntax.rs:42:15
|
--> $DIR/inline-syntax.rs:39:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
||||||
--> $DIR/inline-syntax.rs:46:15
|
--> $DIR/inline-syntax.rs:43:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax noprefix", "nop");
|
LL | asm!(".att_syntax noprefix", "nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
||||||
--> $DIR/inline-syntax.rs:50:15
|
--> $DIR/inline-syntax.rs:47:15
|
||||||
|
|
|
|
||||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||||
--> $DIR/inline-syntax.rs:54:15
|
--> $DIR/inline-syntax.rs:51:15
|
||||||
|
|
|
|
||||||
LL | asm!(".intel_syntax noprefix; nop");
|
LL | asm!(".intel_syntax noprefix; nop");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||||
--> $DIR/inline-syntax.rs:61:13
|
--> $DIR/inline-syntax.rs:58:13
|
||||||
|
|
|
|
||||||
LL | .intel_syntax noprefix
|
LL | .intel_syntax noprefix
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
18
tests/ui/borrowck/copy-suggestion-region-vid.fixed
Normal file
18
tests/ui/borrowck/copy-suggestion-region-vid.fixed
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// run-rustfix
|
||||||
|
pub struct DataStruct();
|
||||||
|
|
||||||
|
pub struct HelperStruct<'n> {
|
||||||
|
pub helpers: [Vec<&'n i64>; 2],
|
||||||
|
pub is_empty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataStruct {
|
||||||
|
pub fn f(&self) -> HelperStruct {
|
||||||
|
let helpers = [vec![], vec![]];
|
||||||
|
|
||||||
|
HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() }
|
||||||
|
//~^ ERROR borrow of moved value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,4 +1,4 @@
|
||||||
//@run-rustfix
|
// run-rustfix
|
||||||
pub struct DataStruct();
|
pub struct DataStruct();
|
||||||
|
|
||||||
pub struct HelperStruct<'n> {
|
pub struct HelperStruct<'n> {
|
||||||
|
|
|
@ -9,9 +9,4 @@ LL | FOO => todo!(),
|
||||||
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/issue-89088.rs:5:10
|
|
||||||
|
|
|
||||||
LL | #![allow(indirect_structural_match)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | type H = <dyn Fn(u8) -> (u8)>::Output;
|
LL | type H = <dyn Fn(u8) -> (u8)>::Output;
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #[deny(bare_trait_objects)]
|
LL | #[deny(bare_trait_objects)]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
|
LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
|
||||||
| +++
|
| +++
|
||||||
|
@ -24,7 +24,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
|
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
|
||||||
| +++
|
| +++
|
||||||
|
@ -37,7 +37,7 @@ LL | let _x: &SomeTrait = todo!();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let _x: &dyn SomeTrait = todo!();
|
LL | let _x: &dyn SomeTrait = todo!();
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(bare_trait_objects)]
|
LL | #![deny(bare_trait_objects)]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | <dyn fmt::Debug>::fmt(self, f)
|
LL | <dyn fmt::Debug>::fmt(self, f)
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
|
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
|
LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -35,7 +35,7 @@ LL | let g = BitXor::bitor;
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let g = <dyn BitXor>::bitor;
|
LL | let g = <dyn BitXor>::bitor;
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | Trait::nonexistent(());
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | <dyn Trait>::nonexistent(());
|
LL | <dyn Trait>::nonexistent(());
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
|
@ -21,7 +21,7 @@ LL | eq::<dyn, Foo>
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | eq::<dyn, dyn Foo>
|
LL | eq::<dyn, dyn Foo>
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | let _: Dyn::Ty;
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let _: <dyn Dyn>::Ty;
|
LL | let _: <dyn Dyn>::Ty;
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -26,7 +26,7 @@ LL | Dyn::func();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | <dyn Dyn>::func();
|
LL | <dyn Dyn>::func();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -39,7 +39,7 @@ LL | ::Dyn::func();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | <dyn (::Dyn)>::func();
|
LL | <dyn (::Dyn)>::func();
|
||||||
| ++++++ ++
|
| ++++++ ++
|
||||||
|
@ -52,7 +52,7 @@ LL | Dyn::CONST;
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | <dyn Dyn>::CONST;
|
LL | <dyn Dyn>::CONST;
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: requested on the command line with `--force-warn bare-trait-objects`
|
= note: requested on the command line with `--force-warn bare-trait-objects`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: requested on the command line with `--force-warn bare-trait-objects`
|
= note: requested on the command line with `--force-warn bare-trait-objects`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
|
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
|
||||||
--> $DIR/future-incompat-json-test.rs:9:9
|
--> $DIR/future-incompat-json-test.rs:9:9
|
||||||
|
|
|
|
||||||
LL | let x = 1;
|
LL | let x = 1;
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||||
|
|
|
||||||
= note: `-A unused-variables` implied by `-A unused`
|
|
||||||
= help: to override `-A unused` add `#[allow(unused_variables)]`
|
|
||||||
|
|
||||||
"}}]}
|
"}}]}
|
||||||
|
|
|
@ -4,7 +4,4 @@ warning: unused variable: `x`
|
||||||
|
|
|
|
||||||
LL | let x = 1;
|
LL | let x = 1;
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||||
|
|
|
||||||
= note: `-A unused-variables` implied by `-A unused`
|
|
||||||
= help: to override `-A unused` add `#[allow(unused_variables)]`
|
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,6 @@ LL | foo!(first)
|
||||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||||
= note: macro invocations at the end of a block are treated as expressions
|
= note: macro invocations at the end of a block are treated as expressions
|
||||||
= note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
|
= note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/semicolon-in-expressions-from-macros.rs:24:13
|
|
||||||
|
|
|
||||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
|
@ -79,11 +74,6 @@ LL | let _ = foo!(second);
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/semicolon-in-expressions-from-macros.rs:29:13
|
|
||||||
|
|
|
||||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
|
@ -98,11 +88,6 @@ LL | let _ = foo!(third);
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/semicolon-in-expressions-from-macros.rs:32:13
|
|
||||||
|
|
|
||||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
|
@ -117,11 +102,6 @@ LL | let _ = foo!(fourth);
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/semicolon-in-expressions-from-macros.rs:37:13
|
|
||||||
|
|
|
||||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize {
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn id<F>(f: dyn Copy) -> usize {
|
LL | fn id<F>(f: dyn Copy) -> usize {
|
||||||
| +++
|
| +++
|
||||||
|
@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize {
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn id<F>(f: dyn Copy) -> usize {
|
LL | fn id<F>(f: dyn Copy) -> usize {
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; }
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait B { fn f(a: dyn A) -> A; }
|
LL | trait B { fn f(a: dyn A) -> A; }
|
||||||
| +++
|
| +++
|
||||||
|
@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; }
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait B { fn f(a: A) -> dyn A; }
|
LL | trait B { fn f(a: A) -> dyn A; }
|
||||||
| +++
|
| +++
|
||||||
|
@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; }
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait A { fn g(b: dyn B) -> B; }
|
LL | trait A { fn g(b: dyn B) -> B; }
|
||||||
| +++
|
| +++
|
||||||
|
@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; }
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait A { fn g(b: B) -> dyn B; }
|
LL | trait A { fn g(b: B) -> dyn B; }
|
||||||
| +++
|
| +++
|
||||||
|
@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; }
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait B { fn f(a: dyn A) -> A; }
|
LL | trait B { fn f(a: dyn A) -> A; }
|
||||||
| +++
|
| +++
|
||||||
|
@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; }
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | trait A { fn g(b: dyn B) -> B; }
|
LL | trait A { fn g(b: dyn B) -> B; }
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
|
LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(bare_trait_objects)]
|
LL | #![deny(bare_trait_objects)]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn ord_prefer_dot(s: String) -> dyn Ord {
|
LL | fn ord_prefer_dot(s: String) -> dyn Ord {
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -25,7 +25,7 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
|
LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
|
||||||
| +++
|
| +++
|
||||||
|
@ -49,7 +49,7 @@ LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
||||||
| +++
|
| +++
|
||||||
|
@ -73,7 +73,7 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -20,10 +20,4 @@ LL | if let CONSTANT = &&MyType {
|
||||||
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/const-partial_eq-fallback-ice.rs:1:10
|
|
||||||
|
|
|
||||||
LL | #![allow(warnings)]
|
|
||||||
| ^^^^^^^^
|
|
||||||
= note: `#[allow(indirect_structural_match)]` implied by `#[allow(warnings)]`
|
|
||||||
|
|
||||||
|
|
|
@ -139,11 +139,6 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/generate-mod.rs:30:10
|
|
||||||
|
|
|
||||||
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
|
@ -155,10 +150,5 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/generate-mod.rs:30:10
|
|
||||||
|
|
|
||||||
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
23
tests/ui/suggestions/issue-116434-2015.rs
Normal file
23
tests/ui/suggestions/issue-116434-2015.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
trait Foo {
|
||||||
|
type Clone;
|
||||||
|
fn foo() -> Clone;
|
||||||
|
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||||
|
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||||
|
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
//~| ERROR the trait `Clone` cannot be made into an object [E0038]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait DbHandle: Sized {}
|
||||||
|
|
||||||
|
trait DbInterface {
|
||||||
|
type DbHandle;
|
||||||
|
fn handle() -> DbHandle;
|
||||||
|
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||||
|
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||||
|
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
//~| ERROR the trait `DbHandle` cannot be made into an object [E0038]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
81
tests/ui/suggestions/issue-116434-2015.stderr
Normal file
81
tests/ui/suggestions/issue-116434-2015.stderr
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
|
--> $DIR/issue-116434-2015.rs:3:17
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Clone;
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
||||||
|
LL | fn foo() -> dyn Clone;
|
||||||
|
| +++
|
||||||
|
|
||||||
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
|
--> $DIR/issue-116434-2015.rs:15:20
|
||||||
|
|
|
||||||
|
LL | fn handle() -> DbHandle;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
||||||
|
LL | fn handle() -> dyn DbHandle;
|
||||||
|
| +++
|
||||||
|
|
||||||
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
|
--> $DIR/issue-116434-2015.rs:3:17
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Clone;
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
||||||
|
LL | fn foo() -> dyn Clone;
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error[E0038]: the trait `Clone` cannot be made into an object
|
||||||
|
--> $DIR/issue-116434-2015.rs:3:17
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Clone;
|
||||||
|
| ^^^^^ `Clone` cannot be made into an object
|
||||||
|
|
|
||||||
|
= note: the trait cannot be made into an object because it requires `Self: Sized`
|
||||||
|
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||||
|
|
||||||
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
|
--> $DIR/issue-116434-2015.rs:15:20
|
||||||
|
|
|
||||||
|
LL | fn handle() -> DbHandle;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
||||||
|
LL | fn handle() -> dyn DbHandle;
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error[E0038]: the trait `DbHandle` cannot be made into an object
|
||||||
|
--> $DIR/issue-116434-2015.rs:15:20
|
||||||
|
|
|
||||||
|
LL | fn handle() -> DbHandle;
|
||||||
|
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
||||||
|
|
|
||||||
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||||
|
--> $DIR/issue-116434-2015.rs:11:17
|
||||||
|
|
|
||||||
|
LL | trait DbHandle: Sized {}
|
||||||
|
| -------- ^^^^^ ...because it requires `Self: Sized`
|
||||||
|
| |
|
||||||
|
| this trait cannot be made into an object...
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 4 warnings emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0038`.
|
17
tests/ui/suggestions/issue-116434-2021.rs
Normal file
17
tests/ui/suggestions/issue-116434-2021.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
type Clone;
|
||||||
|
fn foo() -> Clone;
|
||||||
|
//~^ ERROR the trait `Clone` cannot be made into an object [E0038]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait DbHandle: Sized {}
|
||||||
|
|
||||||
|
trait DbInterface {
|
||||||
|
type DbHandle;
|
||||||
|
fn handle() -> DbHandle;
|
||||||
|
//~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
26
tests/ui/suggestions/issue-116434-2021.stderr
Normal file
26
tests/ui/suggestions/issue-116434-2021.stderr
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
error[E0038]: the trait `Clone` cannot be made into an object
|
||||||
|
--> $DIR/issue-116434-2021.rs:5:17
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Clone;
|
||||||
|
| ^^^^^ `Clone` cannot be made into an object
|
||||||
|
|
|
||||||
|
= note: the trait cannot be made into an object because it requires `Self: Sized`
|
||||||
|
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||||
|
|
||||||
|
error[E0038]: the trait `DbHandle` cannot be made into an object
|
||||||
|
--> $DIR/issue-116434-2021.rs:13:20
|
||||||
|
|
|
||||||
|
LL | fn handle() -> DbHandle;
|
||||||
|
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
||||||
|
|
|
||||||
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||||
|
--> $DIR/issue-116434-2021.rs:9:17
|
||||||
|
|
|
||||||
|
LL | trait DbHandle: Sized {}
|
||||||
|
| -------- ^^^^^ ...because it requires `Self: Sized`
|
||||||
|
| |
|
||||||
|
| this trait cannot be made into an object...
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0038`.
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(bare_trait_objects)]
|
LL | #![deny(bare_trait_objects)]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | bar: Box<dyn Bar>,
|
LL | bar: Box<dyn Bar>,
|
||||||
| +++
|
| +++
|
||||||
|
@ -24,7 +24,7 @@ LL | pub struct Foo {
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | dyn pub struct Foo {
|
LL | dyn pub struct Foo {
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
|
LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
|
||||||
| +++
|
| +++
|
||||||
|
|
20
tests/ui/trait-bounds/suggest-maybe-sized-bound.rs
Normal file
20
tests/ui/trait-bounds/suggest-maybe-sized-bound.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// issue: 120878
|
||||||
|
fn main() {
|
||||||
|
struct StructA<A, B = A> {
|
||||||
|
_marker: std::marker::PhantomData<fn() -> (A, B)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructB {
|
||||||
|
a: StructA<isize, [u8]>,
|
||||||
|
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type P<X>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for () {
|
||||||
|
type P<X> = [u8];
|
||||||
|
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
|
||||||
|
}
|
||||||
|
}
|
37
tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr
Normal file
37
tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/suggest-maybe-sized-bound.rs:8:12
|
||||||
|
|
|
||||||
|
LL | a: StructA<isize, [u8]>,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
|
note: required by an implicit `Sized` bound in `StructA`
|
||||||
|
--> $DIR/suggest-maybe-sized-bound.rs:3:23
|
||||||
|
|
|
||||||
|
LL | struct StructA<A, B = A> {
|
||||||
|
| ^^^^^ required by the implicit `Sized` requirement on this type parameter in `StructA`
|
||||||
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
||||||
|
LL | struct StructA<A, B: ?Sized = A> {
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/suggest-maybe-sized-bound.rs:17:21
|
||||||
|
|
|
||||||
|
LL | type P<X> = [u8];
|
||||||
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
|
note: required by a bound in `Trait::P`
|
||||||
|
--> $DIR/suggest-maybe-sized-bound.rs:13:9
|
||||||
|
|
|
||||||
|
LL | type P<X>;
|
||||||
|
| ^^^^^^^^^^ required by this bound in `Trait::P`
|
||||||
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
||||||
|
LL | type P<X>: ?Sized;
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) {
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | fn foo(_x: dyn Foo + Send) {
|
LL | fn foo(_x: dyn Foo + Send) {
|
||||||
| +++
|
| +++
|
||||||
|
|
|
@ -36,8 +36,8 @@ LL | pub trait Bar: Foo<Assoc=()> + Sized {
|
||||||
| +++++++
|
| +++++++
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | pub trait Foo<RHS=Self: ?Sized> {
|
LL | pub trait Foo<RHS: ?Sized=Self> {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||||
--> $DIR/issue-28576.rs:5:16
|
--> $DIR/issue-28576.rs:5:16
|
||||||
|
@ -56,8 +56,8 @@ LL | ) where Self: Sized;
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | pub trait Foo<RHS=Self: ?Sized> {
|
LL | pub trait Foo<RHS: ?Sized=Self> {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,4 @@ LL | impl Trait0 for dyn Send {}
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/issue-33140-hack-boundaries.rs:2:10
|
|
||||||
|
|
|
||||||
LL | #![allow(order_dependent_trait_objects)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | let a = Foo::lol();
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
= note: `#[warn(bare_trait_objects)]` on by default
|
= note: `#[warn(bare_trait_objects)]` on by default
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let a = <dyn Foo>::lol();
|
LL | let a = <dyn Foo>::lol();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -26,7 +26,7 @@ LL | let b = Foo::<_>::lol();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let b = <dyn Foo::<_>>::lol();
|
LL | let b = <dyn Foo::<_>>::lol();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -45,7 +45,7 @@ LL | let c = Bar::lol();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let c = <dyn Bar>::lol();
|
LL | let c = <dyn Bar>::lol();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -64,7 +64,7 @@ LL | let d = Bar::<usize, _>::lol();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let d = <dyn Bar::<usize, _>>::lol();
|
LL | let d = <dyn Bar::<usize, _>>::lol();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
@ -83,7 +83,7 @@ LL | let e = Bar::<usize>::lol();
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||||
help: use `dyn`
|
help: if this is an object-safe trait, use `dyn`
|
||||||
|
|
|
|
||||||
LL | let e = <dyn Bar::<usize>>::lol();
|
LL | let e = <dyn Bar::<usize>>::lol();
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue