Auto merge of #120649 - matthiaskrgr:rollup-ek80j61, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #119759 (Add FileCheck annotations to dataflow-const-prop tests) - #120323 (On E0277 be clearer about implicit `Sized` bounds on type params and assoc types) - #120473 (Only suggest removal of `as_*` and `to_` conversion methods on E0308) - #120540 (add test for try-block-in-match-arm) - #120547 (`#![feature(inline_const_pat)]` is no longer incomplete) - #120552 (Correctly check `never_type` feature gating) - #120555 (put pnkfelix (me) back on the review queue.) - #120556 (Improve the diagnostics for unused generic parameters) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4d87c4ad62
161 changed files with 1150 additions and 540 deletions
|
@ -362,6 +362,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) {
|
||||||
|
// This check needs to happen here because the never type can be returned from a function,
|
||||||
|
// but cannot be used in any other context. If this check was in `visit_fn_ret_ty`, it
|
||||||
|
// include both functions and generics like `impl Fn() -> !`.
|
||||||
|
if let ast::GenericArgs::Parenthesized(generic_args) = args
|
||||||
|
&& let ast::FnRetTy::Ty(ref ty) = generic_args.output
|
||||||
|
&& matches!(ty.kind, ast::TyKind::Never)
|
||||||
|
{
|
||||||
|
gate!(&self, never_type, ty.span, "the `!` type is experimental");
|
||||||
|
}
|
||||||
|
visit::walk_generic_args(self, args);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::TryBlock(_) => {
|
ast::ExprKind::TryBlock(_) => {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
An unnecessary type or const parameter was given in a type alias.
|
An unnecessary type parameter was given in a type alias.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0091
|
```compile_fail,E0091
|
||||||
type Foo<T> = u32; // error: type parameter `T` is unused
|
type Foo<T> = u32; // error: type parameter `T` is never used
|
||||||
// or:
|
// or:
|
||||||
type Foo<A,B> = Box<A>; // error: type parameter `B` is unused
|
type Foo<A, B> = Box<A>; // error: type parameter `B` is never used
|
||||||
```
|
```
|
||||||
|
|
||||||
Please check you didn't write too many parameters. Example:
|
Please check you didn't write too many parameters. Example:
|
||||||
|
|
|
@ -496,7 +496,7 @@ declare_features! (
|
||||||
/// Allow anonymous constants from an inline `const` block
|
/// Allow anonymous constants from an inline `const` block
|
||||||
(unstable, inline_const, "1.49.0", Some(76001)),
|
(unstable, inline_const, "1.49.0", Some(76001)),
|
||||||
/// Allow anonymous constants from an inline `const` block in pattern position
|
/// Allow anonymous constants from an inline `const` block in pattern position
|
||||||
(incomplete, inline_const_pat, "1.58.0", Some(76001)),
|
(unstable, inline_const_pat, "1.58.0", Some(76001)),
|
||||||
/// Allows using `pointer` and `reference` in intra-doc links
|
/// Allows using `pointer` and `reference` in intra-doc links
|
||||||
(unstable, intra_doc_pointers, "1.51.0", Some(80896)),
|
(unstable, intra_doc_pointers, "1.51.0", Some(80896)),
|
||||||
// Allows setting the threshold for the `large_assignments` lint.
|
// Allows setting the threshold for the `large_assignments` lint.
|
||||||
|
|
|
@ -434,6 +434,17 @@ hir_analysis_unused_associated_type_bounds =
|
||||||
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||||
.suggestion = remove this bound
|
.suggestion = remove this bound
|
||||||
|
|
||||||
|
hir_analysis_unused_generic_parameter =
|
||||||
|
{$param_def_kind} `{$param_name}` is never used
|
||||||
|
.label = unused {$param_def_kind}
|
||||||
|
.const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead
|
||||||
|
hir_analysis_unused_generic_parameter_adt_help =
|
||||||
|
consider removing `{$param_name}`, referring to it in a field, or using a marker such as `{$phantom_data}`
|
||||||
|
hir_analysis_unused_generic_parameter_adt_no_phantom_data_help =
|
||||||
|
consider removing `{$param_name}` or referring to it in a field
|
||||||
|
hir_analysis_unused_generic_parameter_ty_alias_help =
|
||||||
|
consider removing `{$param_name}` or referring to it in the body of the type alias
|
||||||
|
|
||||||
hir_analysis_value_of_associated_struct_already_specified =
|
hir_analysis_value_of_associated_struct_already_specified =
|
||||||
the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified
|
the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified
|
||||||
.label = re-bound here
|
.label = re-bound here
|
||||||
|
|
|
@ -28,6 +28,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let sized_def_id = tcx.lang_items().sized_trait();
|
let sized_def_id = tcx.lang_items().sized_trait();
|
||||||
let mut seen_negative_sized_bound = false;
|
let mut seen_negative_sized_bound = false;
|
||||||
|
let mut seen_positive_sized_bound = false;
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
|
@ -45,6 +46,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
seen_negative_sized_bound = true;
|
seen_negative_sized_bound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::TraitBoundModifier::None => {
|
||||||
|
if let Some(sized_def_id) = sized_def_id
|
||||||
|
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
|
||||||
|
{
|
||||||
|
seen_positive_sized_bound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,11 +90,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if seen_sized_unbound || seen_negative_sized_bound {
|
if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {
|
||||||
// There was in fact a `?Sized` or `!Sized` bound;
|
// There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound;
|
||||||
// we don't need to do anything.
|
// we don't need to do anything.
|
||||||
} else if sized_def_id.is_some() {
|
} else if sized_def_id.is_some() {
|
||||||
// There was no `?Sized` or `!Sized` bound;
|
// There was no `?Sized`, `!Sized` or explicit `Sized` bound;
|
||||||
// add `Sized` if it's available.
|
// add `Sized` if it's available.
|
||||||
bounds.push_sized(tcx, self_ty, span);
|
bounds.push_sized(tcx, self_ty, span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
|
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
|
||||||
use rustc_type_ir::fold::TypeFoldable;
|
use rustc_type_ir::fold::TypeFoldable;
|
||||||
|
|
||||||
|
use std::cell::LazyCell;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
|
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
|
||||||
|
@ -520,9 +521,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::TyAlias => {
|
DefKind::TyAlias => {
|
||||||
let pty_ty = tcx.type_of(def_id).instantiate_identity();
|
check_type_alias_type_params_are_used(tcx, def_id);
|
||||||
let generics = tcx.generics_of(def_id);
|
|
||||||
check_type_params_are_used(tcx, generics, pty_ty);
|
|
||||||
}
|
}
|
||||||
DefKind::ForeignMod => {
|
DefKind::ForeignMod => {
|
||||||
let it = tcx.hir().expect_item(def_id);
|
let it = tcx.hir().expect_item(def_id);
|
||||||
|
@ -1269,28 +1268,51 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn check_type_params_are_used<'tcx>(
|
fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||||
tcx: TyCtxt<'tcx>,
|
if tcx.type_alias_is_lazy(def_id) {
|
||||||
generics: &ty::Generics,
|
// Since we compute the variances for lazy type aliases and already reject bivariant
|
||||||
ty: Ty<'tcx>,
|
// parameters as unused, we can and should skip this check for lazy type aliases.
|
||||||
) {
|
return;
|
||||||
debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
|
}
|
||||||
|
|
||||||
assert_eq!(generics.parent, None);
|
|
||||||
|
|
||||||
|
let generics = tcx.generics_of(def_id);
|
||||||
if generics.own_counts().types == 0 {
|
if generics.own_counts().types == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut params_used = BitSet::new_empty(generics.params.len());
|
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||||
|
|
||||||
if ty.references_error() {
|
if ty.references_error() {
|
||||||
// If there is already another error, do not emit
|
// If there is already another error, do not emit an error for not using a type parameter.
|
||||||
// an error for not using a type parameter.
|
|
||||||
assert!(tcx.dcx().has_errors().is_some());
|
assert!(tcx.dcx().has_errors().is_some());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lazily calculated because it is only needed in case of an error.
|
||||||
|
let bounded_params = LazyCell::new(|| {
|
||||||
|
tcx.explicit_predicates_of(def_id)
|
||||||
|
.predicates
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(predicate, span)| {
|
||||||
|
let bounded_ty = match predicate.kind().skip_binder() {
|
||||||
|
ty::ClauseKind::Trait(pred) => pred.trait_ref.self_ty(),
|
||||||
|
ty::ClauseKind::TypeOutlives(pred) => pred.0,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
if let ty::Param(param) = bounded_ty.kind() {
|
||||||
|
Some((param.index, span))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// FIXME: This assumes that elaborated `Sized` bounds come first (which does hold at the
|
||||||
|
// time of writing). This is a bit fragile since we later use the span to detect elaborated
|
||||||
|
// `Sized` bounds. If they came last for example, this would break `Trait + /*elab*/Sized`
|
||||||
|
// since it would overwrite the span of the user-written bound. This could be fixed by
|
||||||
|
// folding the spans with `Span::to` which requires a bit of effort I think.
|
||||||
|
.collect::<FxHashMap<_, _>>()
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut params_used = BitSet::new_empty(generics.params.len());
|
||||||
for leaf in ty.walk() {
|
for leaf in ty.walk() {
|
||||||
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
|
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
|
||||||
&& let ty::Param(param) = leaf_ty.kind()
|
&& let ty::Param(param) = leaf_ty.kind()
|
||||||
|
@ -1305,15 +1327,24 @@ pub(super) fn check_type_params_are_used<'tcx>(
|
||||||
&& let ty::GenericParamDefKind::Type { .. } = param.kind
|
&& let ty::GenericParamDefKind::Type { .. } = param.kind
|
||||||
{
|
{
|
||||||
let span = tcx.def_span(param.def_id);
|
let span = tcx.def_span(param.def_id);
|
||||||
struct_span_code_err!(
|
let param_name = Ident::new(param.name, span);
|
||||||
tcx.dcx(),
|
|
||||||
|
// The corresponding predicates are post-`Sized`-elaboration. Therefore we
|
||||||
|
// * check for emptiness to detect lone user-written `?Sized` bounds
|
||||||
|
// * compare the param span to the pred span to detect lone user-written `Sized` bounds
|
||||||
|
let has_explicit_bounds = bounded_params.is_empty()
|
||||||
|
|| (*bounded_params).get(¶m.index).is_some_and(|&&pred_sp| pred_sp != span);
|
||||||
|
let const_param_help = (!has_explicit_bounds).then_some(());
|
||||||
|
|
||||||
|
let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
|
||||||
span,
|
span,
|
||||||
E0091,
|
param_name,
|
||||||
"type parameter `{}` is unused",
|
param_def_kind: tcx.def_descr(param.def_id),
|
||||||
param.name,
|
help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
|
||||||
)
|
const_param_help,
|
||||||
.with_span_label(span, "unused type parameter")
|
});
|
||||||
.emit();
|
diag.code(E0091);
|
||||||
|
diag.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::autoderef::Autoderef;
|
use crate::autoderef::Autoderef;
|
||||||
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
||||||
|
use crate::errors;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||||
use rustc_errors::{
|
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
|
||||||
codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
|
|
||||||
};
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
|
@ -21,7 +20,7 @@ use rustc_middle::ty::{
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||||
|
@ -1869,7 +1868,7 @@ fn check_variances_for_type_defn<'tcx>(
|
||||||
hir::ParamName::Error => {}
|
hir::ParamName::Error => {}
|
||||||
_ => {
|
_ => {
|
||||||
let has_explicit_bounds = explicitly_bounded_params.contains(¶meter);
|
let has_explicit_bounds = explicitly_bounded_params.contains(¶meter);
|
||||||
report_bivariance(tcx, hir_param, has_explicit_bounds);
|
report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1879,30 +1878,38 @@ fn report_bivariance(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
param: &rustc_hir::GenericParam<'_>,
|
param: &rustc_hir::GenericParam<'_>,
|
||||||
has_explicit_bounds: bool,
|
has_explicit_bounds: bool,
|
||||||
|
item_kind: ItemKind<'_>,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let span = param.span;
|
let param_name = param.name.ident();
|
||||||
let param_name = param.name.ident().name;
|
|
||||||
let mut err = error_392(tcx, span, param_name);
|
|
||||||
|
|
||||||
let suggested_marker_id = tcx.lang_items().phantom_data();
|
let help = match item_kind {
|
||||||
// Help is available only in presence of lang items.
|
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||||
let msg = if let Some(def_id) = suggested_marker_id {
|
if let Some(def_id) = tcx.lang_items().phantom_data() {
|
||||||
format!(
|
errors::UnusedGenericParameterHelp::Adt {
|
||||||
"consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
|
param_name,
|
||||||
param_name,
|
phantom_data: tcx.def_path_str(def_id),
|
||||||
tcx.def_path_str(def_id),
|
}
|
||||||
)
|
} else {
|
||||||
} else {
|
errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name }
|
||||||
format!("consider removing `{param_name}` or referring to it in a field")
|
}
|
||||||
|
}
|
||||||
|
ItemKind::TyAlias(..) => errors::UnusedGenericParameterHelp::TyAlias { param_name },
|
||||||
|
item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
|
||||||
};
|
};
|
||||||
err.help(msg);
|
|
||||||
|
|
||||||
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
|
let const_param_help =
|
||||||
err.help(format!(
|
matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
|
||||||
"if you intended `{param_name}` to be a const parameter, use `const {param_name}: usize` instead"
|
.then_some(());
|
||||||
));
|
|
||||||
}
|
let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
|
||||||
err.emit()
|
span: param.span,
|
||||||
|
param_name,
|
||||||
|
param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
|
||||||
|
help,
|
||||||
|
const_param_help,
|
||||||
|
});
|
||||||
|
diag.code(E0392);
|
||||||
|
diag.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
|
@ -1967,11 +1974,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
|
|
||||||
struct_span_code_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used")
|
|
||||||
.with_span_label(span, "unused parameter")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
|
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1511,3 +1511,27 @@ pub struct NotSupportedDelegation<'a> {
|
||||||
#[label]
|
#[label]
|
||||||
pub callee_span: Span,
|
pub callee_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_unused_generic_parameter)]
|
||||||
|
pub(crate) struct UnusedGenericParameter {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub param_name: Ident,
|
||||||
|
pub param_def_kind: &'static str,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub help: UnusedGenericParameterHelp,
|
||||||
|
#[help(hir_analysis_const_param_help)]
|
||||||
|
pub const_param_help: Option<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
pub(crate) enum UnusedGenericParameterHelp {
|
||||||
|
#[help(hir_analysis_unused_generic_parameter_adt_help)]
|
||||||
|
Adt { param_name: Ident, phantom_data: String },
|
||||||
|
#[help(hir_analysis_unused_generic_parameter_adt_no_phantom_data_help)]
|
||||||
|
AdtNoPhantomData { param_name: Ident },
|
||||||
|
#[help(hir_analysis_unused_generic_parameter_ty_alias_help)]
|
||||||
|
TyAlias { param_name: Ident },
|
||||||
|
}
|
||||||
|
|
|
@ -261,6 +261,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expr.kind
|
expr.kind
|
||||||
&& let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr)
|
&& let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr)
|
||||||
&& self.can_coerce(recv_ty, expected)
|
&& self.can_coerce(recv_ty, expected)
|
||||||
|
&& let name = method.name.as_str()
|
||||||
|
&& (name.starts_with("to_") || name.starts_with("as_") || name == "into")
|
||||||
{
|
{
|
||||||
let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) {
|
let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) {
|
||||||
expr.span.with_lo(recv_span.hi())
|
expr.span.with_lo(recv_span.hi())
|
||||||
|
|
|
@ -3009,35 +3009,44 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let descr = format!("required by a bound in `{item_name}`");
|
let mut a = "a";
|
||||||
if span.is_visible(sm) {
|
let mut this = "this bound";
|
||||||
let msg = format!("required by this bound in `{short_item_name}`");
|
let mut note = None;
|
||||||
multispan.push_span_label(span, msg);
|
let mut help = None;
|
||||||
err.span_note(multispan, descr);
|
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
|
||||||
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
|
&& let ty::ClauseKind::Trait(trait_pred) = clause
|
||||||
&& let ty::ClauseKind::Trait(trait_pred) = clause
|
{
|
||||||
{
|
let def_id = trait_pred.def_id();
|
||||||
let def_id = trait_pred.def_id();
|
let visible_item = if let Some(local) = def_id.as_local() {
|
||||||
let visible_item = if let Some(local) = def_id.as_local() {
|
// Check for local traits being reachable.
|
||||||
// Check for local traits being reachable.
|
let vis = &tcx.resolutions(()).effective_visibilities;
|
||||||
let vis = &tcx.resolutions(()).effective_visibilities;
|
// Account for non-`pub` traits in the root of the local crate.
|
||||||
// Account for non-`pub` traits in the root of the local crate.
|
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
|
||||||
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
|
vis.is_reachable(local) || is_locally_reachable
|
||||||
vis.is_reachable(local) || is_locally_reachable
|
} else {
|
||||||
} else {
|
// Check for foreign traits being reachable.
|
||||||
// Check for foreign traits being reachable.
|
tcx.visible_parent_map(()).get(&def_id).is_some()
|
||||||
tcx.visible_parent_map(()).get(&def_id).is_some()
|
};
|
||||||
};
|
if Some(def_id) == tcx.lang_items().sized_trait() {
|
||||||
if Some(def_id) == tcx.lang_items().sized_trait()
|
// Check if this is an implicit bound, even in foreign crates.
|
||||||
&& let Some(hir::Node::TraitItem(hir::TraitItem {
|
if tcx
|
||||||
ident,
|
.generics_of(item_def_id)
|
||||||
kind: hir::TraitItemKind::Type(bounds, None),
|
.params
|
||||||
..
|
.iter()
|
||||||
})) = tcx.hir().get_if_local(item_def_id)
|
.any(|param| tcx.def_span(param.def_id) == span)
|
||||||
// Do not suggest relaxing if there is an explicit `Sized` obligation.
|
{
|
||||||
&& !bounds.iter()
|
a = "an implicit `Sized`";
|
||||||
.filter_map(|bound| bound.trait_ref())
|
this = "the implicit `Sized` requirement on this type parameter";
|
||||||
.any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait())
|
}
|
||||||
|
if let Some(hir::Node::TraitItem(hir::TraitItem {
|
||||||
|
ident,
|
||||||
|
kind: hir::TraitItemKind::Type(bounds, None),
|
||||||
|
..
|
||||||
|
})) = tcx.hir().get_if_local(item_def_id)
|
||||||
|
// Do not suggest relaxing if there is an explicit `Sized` obligation.
|
||||||
|
&& !bounds.iter()
|
||||||
|
.filter_map(|bound| bound.trait_ref())
|
||||||
|
.any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait())
|
||||||
{
|
{
|
||||||
let (span, separator) = if let [.., last] = bounds {
|
let (span, separator) = if let [.., last] = bounds {
|
||||||
(last.span().shrink_to_hi(), " +")
|
(last.span().shrink_to_hi(), " +")
|
||||||
|
@ -3051,52 +3060,64 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if let DefKind::Trait = tcx.def_kind(item_def_id)
|
}
|
||||||
&& !visible_item
|
if let DefKind::Trait = tcx.def_kind(item_def_id)
|
||||||
{
|
&& !visible_item
|
||||||
err.note(format!(
|
{
|
||||||
"`{short_item_name}` is a \"sealed trait\", because to implement \
|
note = Some(format!(
|
||||||
it you also need to implement `{}`, which is not accessible; \
|
"`{short_item_name}` is a \"sealed trait\", because to implement it \
|
||||||
this is usually done to force you to use one of the provided \
|
you also need to implement `{}`, which is not accessible; this is \
|
||||||
types that already implement it",
|
usually done to force you to use one of the provided types that \
|
||||||
with_no_trimmed_paths!(tcx.def_path_str(def_id)),
|
already implement it",
|
||||||
));
|
with_no_trimmed_paths!(tcx.def_path_str(def_id)),
|
||||||
let impls_of = tcx.trait_impls_of(def_id);
|
));
|
||||||
let impls = impls_of
|
let impls_of = tcx.trait_impls_of(def_id);
|
||||||
.non_blanket_impls()
|
let impls = impls_of
|
||||||
.values()
|
.non_blanket_impls()
|
||||||
.flatten()
|
.values()
|
||||||
.chain(impls_of.blanket_impls().iter())
|
.flatten()
|
||||||
|
.chain(impls_of.blanket_impls().iter())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !impls.is_empty() {
|
||||||
|
let len = impls.len();
|
||||||
|
let mut types = impls
|
||||||
|
.iter()
|
||||||
|
.map(|t| {
|
||||||
|
with_no_trimmed_paths!(format!(
|
||||||
|
" {}",
|
||||||
|
tcx.type_of(*t).instantiate_identity(),
|
||||||
|
))
|
||||||
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if !impls.is_empty() {
|
let post = if types.len() > 9 {
|
||||||
let len = impls.len();
|
types.truncate(8);
|
||||||
let mut types = impls
|
format!("\nand {} others", len - 8)
|
||||||
.iter()
|
} else {
|
||||||
.map(|t| {
|
String::new()
|
||||||
with_no_trimmed_paths!(format!(
|
};
|
||||||
" {}",
|
help = Some(format!(
|
||||||
tcx.type_of(*t).instantiate_identity(),
|
"the following type{} implement{} the trait:\n{}{post}",
|
||||||
))
|
pluralize!(len),
|
||||||
})
|
if len == 1 { "s" } else { "" },
|
||||||
.collect::<Vec<_>>();
|
types.join("\n"),
|
||||||
let post = if types.len() > 9 {
|
));
|
||||||
types.truncate(8);
|
|
||||||
format!("\nand {} others", len - 8)
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
};
|
|
||||||
err.help(format!(
|
|
||||||
"the following type{} implement{} the trait:\n{}{post}",
|
|
||||||
pluralize!(len),
|
|
||||||
if len == 1 { "s" } else { "" },
|
|
||||||
types.join("\n"),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
let descr = format!("required by {a} bound in `{item_name}`");
|
||||||
|
if span.is_visible(sm) {
|
||||||
|
let msg = format!("required by {this} in `{short_item_name}`");
|
||||||
|
multispan.push_span_label(span, msg);
|
||||||
|
err.span_note(multispan, descr);
|
||||||
} else {
|
} else {
|
||||||
err.span_note(tcx.def_span(item_def_id), descr);
|
err.span_note(tcx.def_span(item_def_id), descr);
|
||||||
}
|
}
|
||||||
|
if let Some(note) = note {
|
||||||
|
err.note(note);
|
||||||
|
}
|
||||||
|
if let Some(help) = help {
|
||||||
|
err.help(help);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ObligationCauseCode::Coercion { source, target } => {
|
ObligationCauseCode::Coercion { source, target } => {
|
||||||
let mut file = None;
|
let mut file = None;
|
||||||
|
|
|
@ -559,10 +559,10 @@ trait TraitAddBuiltinBoundToMethodTypeParameter {
|
||||||
#[cfg(not(any(cfail1,cfail4)))]
|
#[cfg(not(any(cfail1,cfail4)))]
|
||||||
#[rustc_clean(cfg="cfail2")]
|
#[rustc_clean(cfg="cfail2")]
|
||||||
#[rustc_clean(cfg="cfail3")]
|
#[rustc_clean(cfg="cfail3")]
|
||||||
#[rustc_clean(cfg="cfail5")]
|
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")]
|
||||||
#[rustc_clean(cfg="cfail6")]
|
#[rustc_clean(cfg="cfail6")]
|
||||||
trait TraitAddBuiltinBoundToMethodTypeParameter {
|
trait TraitAddBuiltinBoundToMethodTypeParameter {
|
||||||
#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail2")]
|
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")]
|
||||||
#[rustc_clean(cfg="cfail3")]
|
#[rustc_clean(cfg="cfail3")]
|
||||||
#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")]
|
#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")]
|
||||||
#[rustc_clean(cfg="cfail6")]
|
#[rustc_clean(cfg="cfail6")]
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
// EMIT_MIR array_index.main.DataflowConstProp.diff
|
// EMIT_MIR array_index.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main() -> () {
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: let mut [[array_lit:_.*]]: [u32; 4];
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||||
|
// CHECK-NOT: {{_.*}} = Len(
|
||||||
|
// CHECK-NOT: {{_.*}} = Lt(
|
||||||
|
// CHECK-NOT: assert(move _
|
||||||
|
// CHECK: {{_.*}} = const 4_usize;
|
||||||
|
// CHECK: {{_.*}} = const true;
|
||||||
|
// CHECK: assert(const true
|
||||||
|
// CHECK: [[x]] = [[array_lit]][2 of 3];
|
||||||
let x: u32 = [0, 1, 2, 3][2];
|
let x: u32 = [0, 1, 2, 3][2];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR boolean_identities.test.DataflowConstProp.diff
|
// EMIT_MIR boolean_identities.test.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn test(
|
||||||
pub fn test(x: bool, y: bool) -> bool {
|
pub fn test(x: bool, y: bool) -> bool {
|
||||||
|
// CHECK-NOT: BitAnd(
|
||||||
|
// CHECK-NOT: BitOr(
|
||||||
(y | true) & (x & false)
|
(y | true) & (x & false)
|
||||||
|
// CHECK: _0 = const false;
|
||||||
|
// CHECK-NOT: BitAnd(
|
||||||
|
// CHECK-NOT: BitOr(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
test(true, false);
|
test(true, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR cast.main.DataflowConstProp.diff
|
// EMIT_MIR cast.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const 257_i32;
|
||||||
let a = 257;
|
let a = 257;
|
||||||
|
// CHECK: [[b]] = const 2_u8;
|
||||||
let b = a as u8 + 1;
|
let b = a as u8 + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,32 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// compile-flags: -Coverflow-checks=on
|
// compile-flags: -Coverflow-checks=on
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
|
|
||||||
// EMIT_MIR checked.main.DataflowConstProp.diff
|
// EMIT_MIR checked.main.DataflowConstProp.diff
|
||||||
#[allow(arithmetic_overflow)]
|
#[allow(arithmetic_overflow)]
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
// CHECK: debug c => [[c:_.*]];
|
||||||
|
// CHECK: debug d => [[d:_.*]];
|
||||||
|
// CHECK: debug e => [[e:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const 1_i32;
|
||||||
let a = 1;
|
let a = 1;
|
||||||
|
|
||||||
|
// CHECK: [[b]] = const 2_i32;
|
||||||
let b = 2;
|
let b = 2;
|
||||||
|
|
||||||
|
// CHECK: assert(!const false,
|
||||||
|
// CHECK: [[c]] = const 3_i32;
|
||||||
let c = a + b;
|
let c = a + b;
|
||||||
|
|
||||||
|
// CHECK: [[d]] = const _;
|
||||||
let d = i32::MAX;
|
let d = i32::MAX;
|
||||||
|
|
||||||
|
// CHECK: assert(!const true,
|
||||||
|
// CHECK: [[e]] = const i32::MIN;
|
||||||
let e = d + 1;
|
let e = d + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,29 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// compile-flags: -Zmir-enable-passes=+GVN,+Inline
|
// compile-flags: -Zmir-enable-passes=+GVN,+Inline
|
||||||
// ignore-debug assertions change the output MIR
|
// ignore-debug assertions change the output MIR
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
|
|
||||||
|
// This test is to check ICE in issue [#115789](https://github.com/rust-lang/rust/issues/115789).
|
||||||
|
|
||||||
struct A {
|
struct A {
|
||||||
foo: Box<[bool]>,
|
foo: Box<[bool]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR default_boxed_slice.main.GVN.diff
|
// EMIT_MIR default_boxed_slice.main.GVN.diff
|
||||||
// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff
|
// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
// ConstProp will create a constant of type `Box<[bool]>`.
|
// ConstProp will create a constant of type `Box<[bool]>`.
|
||||||
|
// FIXME: it is not yet a constant.
|
||||||
|
|
||||||
// Verify that `DataflowConstProp` does not ICE trying to dereference it directly.
|
// Verify that `DataflowConstProp` does not ICE trying to dereference it directly.
|
||||||
|
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// We may check other inlined functions as well...
|
||||||
|
|
||||||
|
// CHECK: {{_.*}} = Box::<[bool]>(
|
||||||
|
// FIXME: should be `{{_.*}} = const Box::<[bool]>`
|
||||||
let a: A = A { foo: Box::default() };
|
let a: A = A { foo: Box::default() };
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
debug x => _2;
|
debug x => _2;
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _4;
|
debug x1 => _4;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _5;
|
debug x2 => _5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
debug x => _2;
|
debug x => _2;
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _4;
|
debug x1 => _4;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _5;
|
debug x2 => _5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
let _6: u8;
|
let _6: u8;
|
||||||
let _8: u8;
|
let _8: u8;
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug x => _6;
|
debug x2 => _6;
|
||||||
let _9: u8;
|
let _9: u8;
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug y => _9;
|
debug y => _9;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
let _6: u8;
|
let _6: u8;
|
||||||
let _8: u8;
|
let _8: u8;
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug x => _6;
|
debug x2 => _6;
|
||||||
let _9: u8;
|
let _9: u8;
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug y => _9;
|
debug y => _9;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
|
@ -13,27 +12,67 @@ enum E {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR enum.simple.DataflowConstProp.diff
|
// EMIT_MIR enum.simple.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn simple(
|
||||||
fn simple() {
|
fn simple() {
|
||||||
|
// CHECK: debug e => [[e:_.*]];
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
// CHECK: [[e]] = const E::V1(0_i32);
|
||||||
let e = E::V1(0);
|
let e = E::V1(0);
|
||||||
let x = match e { E::V1(x) => x, E::V2(x) => x };
|
|
||||||
|
// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
|
||||||
|
// CHECK: [[target_bb]]: {
|
||||||
|
// CHECK: [[x]] = const 0_i32;
|
||||||
|
let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR enum.constant.DataflowConstProp.diff
|
// EMIT_MIR enum.constant.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn constant(
|
||||||
fn constant() {
|
fn constant() {
|
||||||
|
// CHECK: debug e => [[e:_.*]];
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
const C: E = E::V1(0);
|
const C: E = E::V1(0);
|
||||||
|
|
||||||
|
// CHECK: [[e]] = const _;
|
||||||
let e = C;
|
let e = C;
|
||||||
let x = match e { E::V1(x) => x, E::V2(x) => x };
|
// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
|
||||||
|
// CHECK: [[target_bb]]: {
|
||||||
|
// CHECK: [[x]] = const 0_i32;
|
||||||
|
let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR enum.statics.DataflowConstProp.diff
|
// EMIT_MIR enum.statics.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn statics(
|
||||||
fn statics() {
|
fn statics() {
|
||||||
|
// CHECK: debug e1 => [[e1:_.*]];
|
||||||
|
// CHECK: debug x1 => [[x1:_.*]];
|
||||||
|
// CHECK: debug e2 => [[e2:_.*]];
|
||||||
|
// CHECK: debug x2 => [[x2:_.*]];
|
||||||
|
|
||||||
static C: E = E::V1(0);
|
static C: E = E::V1(0);
|
||||||
let e = C;
|
|
||||||
let x = match e { E::V1(x) => x, E::V2(x) => x };
|
// CHECK: [[e1]] = const E::V1(0_i32);
|
||||||
|
let e1 = C;
|
||||||
|
// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
|
||||||
|
// CHECK: [[target_bb]]: {
|
||||||
|
// CHECK: [[x1]] = const 0_i32;
|
||||||
|
let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 };
|
||||||
|
|
||||||
static RC: &E = &E::V2(4);
|
static RC: &E = &E::V2(4);
|
||||||
let e = RC;
|
|
||||||
let x = match e { E::V1(x) => x, E::V2(x) => x };
|
// CHECK: [[t:_.*]] = const {alloc2: &&E};
|
||||||
|
// CHECK: [[e2]] = (*[[t]]);
|
||||||
|
let e2 = RC;
|
||||||
|
|
||||||
|
// CHECK: switchInt({{move _.*}}) -> {{.*}}
|
||||||
|
// FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two
|
||||||
|
// switch branches.
|
||||||
|
// One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can
|
||||||
|
// get by printing MIR directly. It is better to check if there are any bugs in the
|
||||||
|
// MIR passes around this stage.
|
||||||
|
let x2 = match e2 { E::V1(x21) => x21, E::V2(x22) => x22 };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
|
@ -41,6 +80,8 @@ fn statics() {
|
||||||
struct NonZeroUsize(usize);
|
struct NonZeroUsize(usize);
|
||||||
|
|
||||||
// EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff
|
// EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn mutate_discriminant(
|
||||||
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
|
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
|
||||||
fn mutate_discriminant() -> u8 {
|
fn mutate_discriminant() -> u8 {
|
||||||
mir!(
|
mir!(
|
||||||
|
@ -50,7 +91,11 @@ fn mutate_discriminant() -> u8 {
|
||||||
// This assignment overwrites the niche in which the discriminant is stored.
|
// This assignment overwrites the niche in which the discriminant is stored.
|
||||||
place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize;
|
place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize;
|
||||||
// So we cannot know the value of this discriminant.
|
// So we cannot know the value of this discriminant.
|
||||||
|
|
||||||
|
// CHECK: [[a:_.*]] = discriminant({{_.*}});
|
||||||
let a = Discriminant(x);
|
let a = Discriminant(x);
|
||||||
|
|
||||||
|
// CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||||
match a {
|
match a {
|
||||||
0 => bb1,
|
0 => bb1,
|
||||||
_ => bad,
|
_ => bad,
|
||||||
|
@ -68,18 +113,33 @@ fn mutate_discriminant() -> u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR enum.multiple.DataflowConstProp.diff
|
// EMIT_MIR enum.multiple.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn multiple(
|
||||||
fn multiple(x: bool, i: u8) {
|
fn multiple(x: bool, i: u8) {
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
// CHECK: debug e => [[e:_.*]];
|
||||||
|
// CHECK: debug x2 => [[x2:_.*]];
|
||||||
|
// CHECK: debug y => [[y:_.*]];
|
||||||
let e = if x {
|
let e = if x {
|
||||||
|
// CHECK: [[e]] = Option::<u8>::Some(move {{_.*}});
|
||||||
Some(i)
|
Some(i)
|
||||||
} else {
|
} else {
|
||||||
|
// CHECK: [[e]] = Option::<u8>::None;
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
// The dataflow state must have:
|
// The dataflow state must have:
|
||||||
// discriminant(e) => Top
|
// discriminant(e) => Top
|
||||||
// (e as Some).0 => Top
|
// (e as Some).0 => Top
|
||||||
let x = match e { Some(i) => i, None => 0 };
|
// CHECK: [[x2]] = const 0_u8;
|
||||||
// Therefore, `x` should be `Top` here, and no replacement shall happen.
|
// CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8)
|
||||||
let y = x;
|
// CHECK: [[x2]] = [[some]];
|
||||||
|
let x2 = match e { Some(i) => i, None => 0 };
|
||||||
|
|
||||||
|
// Therefore, `x2` should be `Top` here, and no replacement shall happen.
|
||||||
|
|
||||||
|
// CHECK-NOT: [[y]] = const
|
||||||
|
// CHECK: [[y]] = [[x2]];
|
||||||
|
// CHECK-NOT: [[y]] = const
|
||||||
|
let y = x2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
debug x => _2;
|
debug x => _2;
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _4;
|
debug x1 => _4;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _5;
|
debug x2 => _5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
debug x => _2;
|
debug x => _2;
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _4;
|
debug x1 => _4;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _5;
|
debug x2 => _5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,34 +9,34 @@
|
||||||
let mut _8: &&E;
|
let mut _8: &&E;
|
||||||
let mut _10: isize;
|
let mut _10: isize;
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug e => _1;
|
debug e1 => _1;
|
||||||
let _3: i32;
|
let _3: i32;
|
||||||
let _5: i32;
|
let _5: i32;
|
||||||
let _6: i32;
|
let _6: i32;
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug x => _3;
|
debug x1 => _3;
|
||||||
let _7: &E;
|
let _7: &E;
|
||||||
scope 5 {
|
scope 5 {
|
||||||
debug e => _7;
|
debug e2 => _7;
|
||||||
let _9: &i32;
|
let _9: &i32;
|
||||||
let _11: &i32;
|
let _11: &i32;
|
||||||
let _12: &i32;
|
let _12: &i32;
|
||||||
scope 6 {
|
scope 6 {
|
||||||
debug x => _9;
|
debug x2 => _9;
|
||||||
}
|
}
|
||||||
scope 7 {
|
scope 7 {
|
||||||
debug x => _11;
|
debug x21 => _11;
|
||||||
}
|
}
|
||||||
scope 8 {
|
scope 8 {
|
||||||
debug x => _12;
|
debug x22 => _12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _5;
|
debug x11 => _5;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _6;
|
debug x12 => _6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,34 +9,34 @@
|
||||||
let mut _8: &&E;
|
let mut _8: &&E;
|
||||||
let mut _10: isize;
|
let mut _10: isize;
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug e => _1;
|
debug e1 => _1;
|
||||||
let _3: i32;
|
let _3: i32;
|
||||||
let _5: i32;
|
let _5: i32;
|
||||||
let _6: i32;
|
let _6: i32;
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug x => _3;
|
debug x1 => _3;
|
||||||
let _7: &E;
|
let _7: &E;
|
||||||
scope 5 {
|
scope 5 {
|
||||||
debug e => _7;
|
debug e2 => _7;
|
||||||
let _9: &i32;
|
let _9: &i32;
|
||||||
let _11: &i32;
|
let _11: &i32;
|
||||||
let _12: &i32;
|
let _12: &i32;
|
||||||
scope 6 {
|
scope 6 {
|
||||||
debug x => _9;
|
debug x2 => _9;
|
||||||
}
|
}
|
||||||
scope 7 {
|
scope 7 {
|
||||||
debug x => _11;
|
debug x21 => _11;
|
||||||
}
|
}
|
||||||
scope 8 {
|
scope 8 {
|
||||||
debug x => _12;
|
debug x22 => _12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug x => _5;
|
debug x11 => _5;
|
||||||
}
|
}
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug x => _6;
|
debug x12 => _6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,26 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR if.main.DataflowConstProp.diff
|
// EMIT_MIR if.main.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
// CHECK: debug c => [[c:_.*]];
|
||||||
|
// CHECK: debug d => [[d:_.*]];
|
||||||
|
// CHECK: debug e => [[e:_.*]];
|
||||||
|
|
||||||
let a = 1;
|
let a = 1;
|
||||||
|
|
||||||
|
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||||
|
// CHECK: [[b]] = const 2_i32;
|
||||||
let b = if a == 1 { 2 } else { 3 };
|
let b = if a == 1 { 2 } else { 3 };
|
||||||
|
|
||||||
|
// CHECK: [[c]] = const 3_i32;
|
||||||
let c = b + 1;
|
let c = b + 1;
|
||||||
|
|
||||||
|
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||||
|
// CHECK: [[d]] = const 1_i32;
|
||||||
let d = if a == 1 { a } else { a + 1 };
|
let d = if a == 1 { a } else { a + 1 };
|
||||||
|
|
||||||
|
// CHECK: [[e]] = const 2_i32;
|
||||||
let e = d + 1;
|
let e = d + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// compile-flags: -Zmir-enable-passes=+Inline
|
// compile-flags: -Zmir-enable-passes=+Inline
|
||||||
|
|
||||||
// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
|
// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
// After inlining, this will contain a `CheckedBinaryOp`.
|
// After inlining, this will contain a `CheckedBinaryOp`.
|
||||||
// Propagating the overflow is ok as codegen will just skip emitting the panic.
|
// Propagating the overflow is ok as codegen will just skip emitting the panic.
|
||||||
|
|
||||||
|
// CHECK: {{_.*}} = const (0_u8, true);
|
||||||
|
// CHECK: assert(!const true,
|
||||||
let _ = <u8 as std::ops::Add>::add(255, 1);
|
let _ = <u8 as std::ops::Add>::add(255, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR issue_81605.f.DataflowConstProp.diff
|
// EMIT_MIR issue_81605.f.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// Plese find the original issue [here](https://github.com/rust-lang/rust/issues/81605).
|
||||||
|
// This test program comes directly from the issue. Prior to this issue,
|
||||||
|
// the compiler cannot simplify the return value of `f` into 2. This was
|
||||||
|
// solved by adding a new MIR constant propagation based on dataflow
|
||||||
|
// analysis in [#101168](https://github.com/rust-lang/rust/pull/101168).
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn f(
|
||||||
fn f() -> usize {
|
fn f() -> usize {
|
||||||
|
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||||
1 + if true { 1 } else { 2 }
|
1 + if true { 1 } else { 2 }
|
||||||
|
// CHECK: _0 = const 2_usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
// EMIT_MIR large_array_index.main.DataflowConstProp.diff
|
// EMIT_MIR large_array_index.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
// check that we don't propagate this, because it's too large
|
// check that we don't propagate this, because it's too large
|
||||||
|
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
// CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
|
||||||
|
// CHECK: {{_.*}} = const 5000_usize;
|
||||||
|
// CHECK: {{_.*}} = const true;
|
||||||
|
// CHECK: assert(const true
|
||||||
|
// CHECK: [[x]] = [[array_lit]][2 of 3];
|
||||||
let x: u8 = [0_u8; 5000][2];
|
let x: u8 = [0_u8; 5000][2];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR mult_by_zero.test.DataflowConstProp.diff
|
// EMIT_MIR mult_by_zero.test.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn test(
|
||||||
fn test(x : i32) -> i32 {
|
fn test(x : i32) -> i32 {
|
||||||
x * 0
|
x * 0
|
||||||
|
// CHECK: _0 = const 0_i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
|
|
||||||
|
@ -29,18 +28,46 @@ struct Delta<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR offset_of.concrete.DataflowConstProp.diff
|
// EMIT_MIR offset_of.concrete.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn concrete(
|
||||||
fn concrete() {
|
fn concrete() {
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
// CHECK: debug y => [[y:_.*]];
|
||||||
|
// CHECK: debug z0 => [[z0:_.*]];
|
||||||
|
// CHECK: debug z1 => [[z1:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[x]] = must_use::<usize>(const 4_usize) -> {{.*}}
|
||||||
let x = offset_of!(Alpha, x);
|
let x = offset_of!(Alpha, x);
|
||||||
|
|
||||||
|
// CHECK: [[y]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||||
let y = offset_of!(Alpha, y);
|
let y = offset_of!(Alpha, y);
|
||||||
|
|
||||||
|
// CHECK: [[z0]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||||
let z0 = offset_of!(Alpha, z.0);
|
let z0 = offset_of!(Alpha, z.0);
|
||||||
|
|
||||||
|
// CHECK: [[z1]] = must_use::<usize>(const 3_usize) -> {{.*}}
|
||||||
let z1 = offset_of!(Alpha, z.1);
|
let z1 = offset_of!(Alpha, z.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR offset_of.generic.DataflowConstProp.diff
|
// EMIT_MIR offset_of.generic.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn generic(
|
||||||
fn generic<T>() {
|
fn generic<T>() {
|
||||||
|
// CHECK: debug gx => [[gx:_.*]];
|
||||||
|
// CHECK: debug gy => [[gy:_.*]];
|
||||||
|
// CHECK: debug dx => [[dx:_.*]];
|
||||||
|
// CHECK: debug dy => [[dy:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[gx]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
|
||||||
let gx = offset_of!(Gamma<T>, x);
|
let gx = offset_of!(Gamma<T>, x);
|
||||||
|
|
||||||
|
// CHECK: [[gy]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
|
||||||
let gy = offset_of!(Gamma<T>, y);
|
let gy = offset_of!(Gamma<T>, y);
|
||||||
|
|
||||||
|
// CHECK: [[dx]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||||
let dx = offset_of!(Delta<T>, x);
|
let dx = offset_of!(Delta<T>, x);
|
||||||
|
|
||||||
|
// CHECK: [[dy]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||||
let dy = offset_of!(Delta<T>, y);
|
let dy = offset_of!(Delta<T>, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
|
@ -9,11 +8,23 @@ fn escape<T>(x: &T) {}
|
||||||
fn some_function() {}
|
fn some_function() {}
|
||||||
|
|
||||||
// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
|
// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
|
||||||
let mut a = 0;
|
let mut a = 0;
|
||||||
|
|
||||||
|
// CHECK: {{_.*}} = escape::<i32>(move {{_.*}}) -> {{.*}}
|
||||||
escape(&a);
|
escape(&a);
|
||||||
a = 1;
|
a = 1;
|
||||||
|
|
||||||
|
// CHECK: {{_.*}} = some_function() -> {{.*}}
|
||||||
some_function();
|
some_function();
|
||||||
// This should currently not be propagated.
|
// This should currently not be propagated.
|
||||||
|
|
||||||
|
// CHECK-NOT: [[b]] = const
|
||||||
|
// CHECK: [[b]] = [[a]];
|
||||||
|
// CHECK-NOT: [[b]] = const
|
||||||
let b = a;
|
let b = a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
// EMIT_MIR repeat.main.DataflowConstProp.diff
|
// EMIT_MIR repeat.main.DataflowConstProp.diff
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
|
||||||
|
// CHECK-NOT: {{_.*}} = Len(
|
||||||
|
// CHECK-NOT: {{_.*}} = Lt(
|
||||||
|
// CHECK: {{_.*}} = const 8_usize;
|
||||||
|
// CHECK: {{_.*}} = const true;
|
||||||
|
// CHECK: assert(const true
|
||||||
|
|
||||||
|
// CHECK-NOT: [[t:_.*]] = [[array_lit]][_
|
||||||
|
// CHECK: [[t:_.*]] = [[array_lit]][2 of 3];
|
||||||
|
// CHECK: [[x]] = Add(move [[t]], const 0_u32);
|
||||||
let x: u32 = [42; 8][2] + 0;
|
let x: u32 = [42; 8][2] + 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// The struct has scalar ABI, but is not a scalar type.
|
// The struct has scalar ABI, but is not a scalar type.
|
||||||
|
@ -7,7 +6,15 @@
|
||||||
struct I32(i32);
|
struct I32(i32);
|
||||||
|
|
||||||
// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
|
// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug x => [[x:_.*]];
|
||||||
|
// CHECK: debug y => [[y:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[x]] = const I32(0_i32);
|
||||||
let x = I32(0);
|
let x = I32(0);
|
||||||
|
|
||||||
|
// CHECK: [[y]] = const I32(0_i32);
|
||||||
let y = I32(x.0 + x.0);
|
let y = I32(x.0 + x.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR self_assign.main.DataflowConstProp.diff
|
// EMIT_MIR self_assign.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
|
||||||
let mut a = 0;
|
let mut a = 0;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = Add(move {{_.*}}, const 1_i32);
|
||||||
a = a + 1;
|
a = a + 1;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = move {{_.*}};
|
||||||
a = a;
|
a = a;
|
||||||
|
|
||||||
|
// CHECK: [[b]] = &[[a]];
|
||||||
let mut b = &a;
|
let mut b = &a;
|
||||||
|
|
||||||
|
// CHECK: [[b]] = move {{_.*}};
|
||||||
b = b;
|
b = b;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = move {{_.*}};
|
||||||
a = *b;
|
a = *b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
|
// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
let mut a = 0;
|
let mut a = 0;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const 1_i32;
|
||||||
a += 1;
|
a += 1;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const 2_i32;
|
||||||
a += 1;
|
a += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`.
|
// This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`.
|
||||||
// According to Miri, that is UB. However, T-opsem has not finalized that
|
// According to Miri, that is UB. However, T-opsem has not finalized that
|
||||||
|
@ -10,11 +9,17 @@
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
|
// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug x1 => [[x1:_.*]];
|
||||||
|
|
||||||
let mut x: (u8, u8) = (0, 0);
|
let mut x: (u8, u8) = (0, 0);
|
||||||
unsafe {
|
unsafe {
|
||||||
let p = std::ptr::addr_of_mut!(x.0);
|
let p = std::ptr::addr_of_mut!(x.0);
|
||||||
*p.add(1) = 1;
|
*p.add(1) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: [[x1]] = ({{_.*}}.1: u8);
|
||||||
let x1 = x.1; // should not be propagated
|
let x1 = x.1; // should not be propagated
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,34 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// compile-flags: -Zmir-enable-passes=+InstSimplify
|
// compile-flags: -Zmir-enable-passes=+InstSimplify
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
// EMIT_MIR slice_len.main.DataflowConstProp.diff
|
// EMIT_MIR slice_len.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug local => [[local:_.*]];
|
||||||
|
// CHECK: debug constant => [[constant:_.*]];
|
||||||
|
|
||||||
|
// CHECK-NOT: {{_.*}} = Len(
|
||||||
|
// CHECK-NOT: {{_.*}} = Lt(
|
||||||
|
// CHECK-NOT: assert(move _
|
||||||
|
// CHECK: {{_.*}} = const 3_usize;
|
||||||
|
// CHECK: {{_.*}} = const true;
|
||||||
|
// CHECK: assert(const true,
|
||||||
|
|
||||||
|
// CHECK: [[local]] = (*{{_.*}})[1 of 2];
|
||||||
let local = (&[1u32, 2, 3] as &[u32])[1];
|
let local = (&[1u32, 2, 3] as &[u32])[1];
|
||||||
|
|
||||||
|
// CHECK-NOT: {{_.*}} = Len(
|
||||||
|
// CHECK-NOT: {{_.*}} = Lt(
|
||||||
|
// CHECK-NOT: assert(move _
|
||||||
const SLICE: &[u32] = &[1, 2, 3];
|
const SLICE: &[u32] = &[1, 2, 3];
|
||||||
|
// CHECK: {{_.*}} = const 3_usize;
|
||||||
|
// CHECK: {{_.*}} = const true;
|
||||||
|
// CHECK: assert(const true,
|
||||||
|
|
||||||
|
// CHECK-NOT: [[constant]] = (*{{_.*}})[_
|
||||||
|
// CHECK: [[constant]] = (*{{_.*}})[1 of 2];
|
||||||
let constant = SLICE[1];
|
let constant = SLICE[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,16 +37,16 @@
|
||||||
let _8: std::option::Option<S>;
|
let _8: std::option::Option<S>;
|
||||||
let _9: &[f32];
|
let _9: &[f32];
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug a => _7;
|
debug a1 => _7;
|
||||||
debug b => _8;
|
debug b1 => _8;
|
||||||
debug c => _9;
|
debug c1 => _9;
|
||||||
let _11: f32;
|
let _11: f32;
|
||||||
let _12: std::option::Option<S>;
|
let _12: std::option::Option<S>;
|
||||||
let _13: &[f32];
|
let _13: &[f32];
|
||||||
scope 5 {
|
scope 5 {
|
||||||
debug a => _11;
|
debug a2 => _11;
|
||||||
debug b => _12;
|
debug b2 => _12;
|
||||||
debug c => _13;
|
debug c2 => _13;
|
||||||
let _15: SmallStruct;
|
let _15: SmallStruct;
|
||||||
scope 6 {
|
scope 6 {
|
||||||
debug ss => _15;
|
debug ss => _15;
|
||||||
|
@ -54,16 +54,16 @@
|
||||||
let _20: std::option::Option<S>;
|
let _20: std::option::Option<S>;
|
||||||
let _21: &[f32];
|
let _21: &[f32];
|
||||||
scope 7 {
|
scope 7 {
|
||||||
debug a => _19;
|
debug a3 => _19;
|
||||||
debug b => _20;
|
debug b3 => _20;
|
||||||
debug c => _21;
|
debug c3 => _21;
|
||||||
let _23: f32;
|
let _23: f32;
|
||||||
let _24: std::option::Option<S>;
|
let _24: std::option::Option<S>;
|
||||||
let _25: &[f32];
|
let _25: &[f32];
|
||||||
scope 8 {
|
scope 8 {
|
||||||
debug a => _23;
|
debug a4 => _23;
|
||||||
debug b => _24;
|
debug b4 => _24;
|
||||||
debug c => _25;
|
debug c4 => _25;
|
||||||
let _27: BigStruct;
|
let _27: BigStruct;
|
||||||
scope 9 {
|
scope 9 {
|
||||||
debug bs => _27;
|
debug bs => _27;
|
||||||
|
|
|
@ -37,16 +37,16 @@
|
||||||
let _8: std::option::Option<S>;
|
let _8: std::option::Option<S>;
|
||||||
let _9: &[f32];
|
let _9: &[f32];
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug a => _7;
|
debug a1 => _7;
|
||||||
debug b => _8;
|
debug b1 => _8;
|
||||||
debug c => _9;
|
debug c1 => _9;
|
||||||
let _11: f32;
|
let _11: f32;
|
||||||
let _12: std::option::Option<S>;
|
let _12: std::option::Option<S>;
|
||||||
let _13: &[f32];
|
let _13: &[f32];
|
||||||
scope 5 {
|
scope 5 {
|
||||||
debug a => _11;
|
debug a2 => _11;
|
||||||
debug b => _12;
|
debug b2 => _12;
|
||||||
debug c => _13;
|
debug c2 => _13;
|
||||||
let _15: SmallStruct;
|
let _15: SmallStruct;
|
||||||
scope 6 {
|
scope 6 {
|
||||||
debug ss => _15;
|
debug ss => _15;
|
||||||
|
@ -54,16 +54,16 @@
|
||||||
let _20: std::option::Option<S>;
|
let _20: std::option::Option<S>;
|
||||||
let _21: &[f32];
|
let _21: &[f32];
|
||||||
scope 7 {
|
scope 7 {
|
||||||
debug a => _19;
|
debug a3 => _19;
|
||||||
debug b => _20;
|
debug b3 => _20;
|
||||||
debug c => _21;
|
debug c3 => _21;
|
||||||
let _23: f32;
|
let _23: f32;
|
||||||
let _24: std::option::Option<S>;
|
let _24: std::option::Option<S>;
|
||||||
let _25: &[f32];
|
let _25: &[f32];
|
||||||
scope 8 {
|
scope 8 {
|
||||||
debug a => _23;
|
debug a4 => _23;
|
||||||
debug b => _24;
|
debug b4 => _24;
|
||||||
debug c => _25;
|
debug c4 => _25;
|
||||||
let _27: BigStruct;
|
let _27: BigStruct;
|
||||||
scope 9 {
|
scope 9 {
|
||||||
debug bs => _27;
|
debug bs => _27;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
|
@ -12,27 +11,69 @@ struct SmallStruct(f32, Option<S>, &'static [f32]);
|
||||||
struct BigStruct(f32, Option<S>, &'static [f32]);
|
struct BigStruct(f32, Option<S>, &'static [f32]);
|
||||||
|
|
||||||
// EMIT_MIR struct.main.DataflowConstProp.diff
|
// EMIT_MIR struct.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug s => [[s:_.*]];
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
// CHECK: debug a1 => [[a1:_.*]];
|
||||||
|
// CHECK: debug b1 => [[b1:_.*]];
|
||||||
|
// CHECK: debug c1 => [[c1:_.*]];
|
||||||
|
// CHECK: debug a2 => [[a2:_.*]];
|
||||||
|
// CHECK: debug b2 => [[b2:_.*]];
|
||||||
|
// CHECK: debug c2 => [[c2:_.*]];
|
||||||
|
// CHECK: debug ss => [[ss:_.*]];
|
||||||
|
// CHECK: debug a3 => [[a3:_.*]];
|
||||||
|
// CHECK: debug b3 => [[b3:_.*]];
|
||||||
|
// CHECK: debug c3 => [[c3:_.*]];
|
||||||
|
// CHECK: debug a4 => [[a4:_.*]];
|
||||||
|
// CHECK: debug b4 => [[b4:_.*]];
|
||||||
|
// CHECK: debug c4 => [[c4:_.*]];
|
||||||
|
// CHECK: debug bs => [[bs:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[s]] = const S(1_i32);
|
||||||
let mut s = S(1);
|
let mut s = S(1);
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const 3_i32;
|
||||||
let a = s.0 + 2;
|
let a = s.0 + 2;
|
||||||
s.0 = 3;
|
s.0 = 3;
|
||||||
|
|
||||||
|
// CHECK: [[b]] = const 6_i32;
|
||||||
let b = a + s.0;
|
let b = a + s.0;
|
||||||
|
|
||||||
const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);
|
const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);
|
||||||
let SmallStruct(a, b, c) = SMALL_VAL;
|
|
||||||
|
// CHECK: [[a1]] = const 4f32;
|
||||||
|
// CHECK: [[b1]] = const Option::<S>::Some(S(1_i32));
|
||||||
|
// CHECK: [[c1]] = ({{_.*}}.2: &[f32]);
|
||||||
|
let SmallStruct(a1, b1, c1) = SMALL_VAL;
|
||||||
|
|
||||||
static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]);
|
static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]);
|
||||||
let SmallStruct(a, b, c) = *SMALL_STAT;
|
|
||||||
|
|
||||||
let ss = SmallStruct(a, b, c);
|
// CHECK: [[a2]] = const 9f32;
|
||||||
|
// CHECK: [[b2]] = ((*{{_.*}}).1: std::option::Option<S>);
|
||||||
|
// CHECK: [[c2]] = ((*{{_.*}}).2: &[f32]);
|
||||||
|
let SmallStruct(a2, b2, c2) = *SMALL_STAT;
|
||||||
|
|
||||||
|
// CHECK: [[ss]] = SmallStruct(const 9f32, move {{_.*}}, move {{_.*}});
|
||||||
|
let ss = SmallStruct(a2, b2, c2);
|
||||||
|
|
||||||
const BIG_VAL: BigStruct = BigStruct(25., None, &[]);
|
const BIG_VAL: BigStruct = BigStruct(25., None, &[]);
|
||||||
let BigStruct(a, b, c) = BIG_VAL;
|
|
||||||
|
// CHECK: [[a3]] = const 25f32;
|
||||||
|
// CHECK: [[b3]] = ({{_.*}}.1: std::option::Option<S>);
|
||||||
|
// CHECK: [[c3]] = ({{_.*}}.2: &[f32]);
|
||||||
|
let BigStruct(a3, b3, c3) = BIG_VAL;
|
||||||
|
|
||||||
static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]);
|
static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]);
|
||||||
let BigStruct(a, b, c) = *BIG_STAT;
|
// CHECK: [[a4]] = const 82f32;
|
||||||
|
// CHECK: [[b4]] = const Option::<S>::Some(S(35_i32));
|
||||||
|
// CHECK: [[c4]] = ((*{{_.*}}).2: &[f32]);
|
||||||
|
let BigStruct(a4, b4, c4) = *BIG_STAT;
|
||||||
|
|
||||||
// We arbitrarily limit the size of synthetized values to 4 pointers.
|
// We arbitrarily limit the size of synthetized values to 4 pointers.
|
||||||
// `BigStruct` can be read, but we will keep a MIR aggregate for this.
|
// `BigStruct` can be read, but we will keep a MIR aggregate for this.
|
||||||
let bs = BigStruct(a, b, c);
|
// CHECK: [[bs]] = BigStruct(const 82f32, const Option::<S>::Some(S(35_i32)), move {{_.*}});
|
||||||
|
let bs = BigStruct(a4, b4, c4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
// skip-filecheck
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
|
|
||||||
fn foo(n: i32) {}
|
fn foo(n: i32) {}
|
||||||
|
|
||||||
// EMIT_MIR terminator.main.DataflowConstProp.diff
|
// EMIT_MIR terminator.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = 1;
|
let a = 1;
|
||||||
// Checks that we propagate into terminators.
|
// Checks that we propagate into terminators.
|
||||||
|
// CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind
|
||||||
foo(a + 1);
|
foo(a + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,27 @@
|
||||||
// skip-filecheck
|
|
||||||
// unit-test: DataflowConstProp
|
// unit-test: DataflowConstProp
|
||||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||||
|
|
||||||
// EMIT_MIR tuple.main.DataflowConstProp.diff
|
// EMIT_MIR tuple.main.DataflowConstProp.diff
|
||||||
|
|
||||||
|
// CHECK-LABEL: fn main(
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// CHECK: debug a => [[a:_.*]];
|
||||||
|
// CHECK: debug b => [[b:_.*]];
|
||||||
|
// CHECK: debug c => [[c:_.*]];
|
||||||
|
// CHECK: debug d => [[d:_.*]];
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const (1_i32, 2_i32);
|
||||||
let mut a = (1, 2);
|
let mut a = (1, 2);
|
||||||
|
|
||||||
|
// CHECK: [[b]] = const 6_i32;
|
||||||
let b = a.0 + a.1 + 3;
|
let b = a.0 + a.1 + 3;
|
||||||
|
|
||||||
|
// CHECK: [[a]] = const (2_i32, 3_i32);
|
||||||
a = (2, 3);
|
a = (2, 3);
|
||||||
|
|
||||||
|
// CHECK: [[c]] = const 11_i32;
|
||||||
let c = a.0 + a.1 + b;
|
let c = a.0 + a.1 + b;
|
||||||
|
|
||||||
|
// CHECK: [[d]] = (const 6_i32, const (2_i32, 3_i32), const 11_i32);
|
||||||
let d = (b, a, c);
|
let d = (b, a, c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | type Ty = Vec<[u8]>;
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
note: required by a bound in `Vec`
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -4,11 +4,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation
|
||||||
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
|
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
|
||||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
note: required by a bound in `From`
|
note: required by an implicit `Sized` bound in `From`
|
||||||
--> $DIR/issue-20005.rs:1:12
|
--> $DIR/issue-20005.rs:1:12
|
||||||
|
|
|
|
||||||
LL | trait From<Src> {
|
LL | trait From<Src> {
|
||||||
| ^^^ required by this bound in `From`
|
| ^^^ required by the implicit `Sized` requirement on this type parameter in `From`
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized {
|
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized {
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation
|
||||||
LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> {}
|
LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> {}
|
||||||
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
note: required by a bound in `Add`
|
note: required by an implicit `Sized` bound in `Add`
|
||||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||||
help: consider further restricting `Self`
|
help: consider further restricting `Self`
|
||||||
|
|
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ LL | println!("{:?}", foo);
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `dyn Foo`
|
= help: the trait `Sized` is not implemented for `dyn Foo`
|
||||||
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug`
|
note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'a>::new_debug`
|
||||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||||
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@ error: expected identifier, found reserved identifier `_`
|
||||||
LL | fn bad_infer_fn<_>() {}
|
LL | fn bad_infer_fn<_>() {}
|
||||||
| ^ expected identifier, found reserved identifier
|
| ^ expected identifier, found reserved identifier
|
||||||
|
|
||||||
error[E0392]: parameter `_` is never used
|
error[E0392]: type parameter `_` is never used
|
||||||
--> $DIR/infer-arg-test.rs:7:17
|
--> $DIR/infer-arg-test.rs:7:17
|
||||||
|
|
|
|
||||||
LL | struct BadInfer<_>;
|
LL | struct BadInfer<_>;
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `_` to be a const parameter, use `const _: usize` instead
|
= help: if you intended `_` to be a const parameter, use `const _: /* Type */` instead
|
||||||
|
|
||||||
error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
|
error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
|
||||||
--> $DIR/infer-arg-test.rs:18:10
|
--> $DIR/infer-arg-test.rs:18:10
|
||||||
|
|
|
@ -7,11 +7,11 @@ LL | _a: [u8; std::mem::size_of::<&'a mut u8>()]
|
||||||
= note: lifetime parameters may not be used in const expressions
|
= note: lifetime parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error[E0392]: parameter `'a` is never used
|
error[E0392]: lifetime parameter `'a` is never used
|
||||||
--> $DIR/issue-46511.rs:3:12
|
--> $DIR/issue-46511.rs:3:12
|
||||||
|
|
|
|
||||||
LL | struct Foo<'a>
|
LL | struct Foo<'a>
|
||||||
| ^^ unused parameter
|
| ^^ unused lifetime parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }],
|
||||||
= note: type parameters may not be used in const expressions
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-67375.rs:5:12
|
--> $DIR/issue-67375.rs:5:12
|
||||||
|
|
|
|
||||||
LL | struct Bug<T> {
|
LL | struct Bug<T> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,14 @@ LL | let b = &*(&x as *const _ as *const S);
|
||||||
= note: type parameters may not be used in const expressions
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error[E0392]: parameter `S` is never used
|
error[E0392]: type parameter `S` is never used
|
||||||
--> $DIR/issue-67945-1.rs:7:12
|
--> $DIR/issue-67945-1.rs:7:12
|
||||||
|
|
|
|
||||||
LL | struct Bug<S> {
|
LL | struct Bug<S> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ LL | let x: Option<S> = None;
|
||||||
= note: type parameters may not be used in const expressions
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error[E0392]: parameter `S` is never used
|
error[E0392]: type parameter `S` is never used
|
||||||
--> $DIR/issue-67945-3.rs:9:12
|
--> $DIR/issue-67945-3.rs:9:12
|
||||||
|
|
|
|
||||||
LL | struct Bug<S> {
|
LL | struct Bug<S> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ LL | let x: Option<Box<S>> = None;
|
||||||
= note: type parameters may not be used in const expressions
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error[E0392]: parameter `S` is never used
|
error[E0392]: type parameter `S` is never used
|
||||||
--> $DIR/issue-67945-4.rs:8:12
|
--> $DIR/issue-67945-4.rs:8:12
|
||||||
|
|
|
|
||||||
LL | struct Bug<S> {
|
LL | struct Bug<S> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,27 @@
|
||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
|
|
||||||
struct Example<N>;
|
struct S<N>;
|
||||||
//~^ ERROR parameter
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
//~| HELP if you intended `N` to be a const parameter
|
||||||
|
|
||||||
|
// Ensure that we don't emit the const param suggestion here:
|
||||||
|
struct T<N: Copy>;
|
||||||
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
|
||||||
|
type A<N> = ();
|
||||||
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
//~| HELP if you intended `N` to be a const parameter
|
||||||
|
|
||||||
|
// Ensure that we don't emit the const param suggestion here:
|
||||||
|
type B<N: Copy> = ();
|
||||||
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
type C<N: Sized> = ();
|
||||||
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
type D<N: ?Sized> = ();
|
||||||
|
//~^ ERROR type parameter `N` is never used
|
||||||
|
//~| HELP consider removing `N`
|
||||||
|
|
|
@ -1,12 +1,54 @@
|
||||||
error[E0392]: parameter `N` is never used
|
error[E0392]: type parameter `N` is never used
|
||||||
--> $DIR/unused-type-param-suggestion.rs:3:16
|
--> $DIR/unused-type-param-suggestion.rs:3:10
|
||||||
|
|
|
|
||||||
LL | struct Example<N>;
|
LL | struct S<N>;
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `N` to be a const parameter, use `const N: usize` instead
|
= help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0392]: type parameter `N` is never used
|
||||||
|
--> $DIR/unused-type-param-suggestion.rs:9:10
|
||||||
|
|
|
||||||
|
LL | struct T<N: Copy>;
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0392`.
|
error[E0091]: type parameter `N` is never used
|
||||||
|
--> $DIR/unused-type-param-suggestion.rs:13:8
|
||||||
|
|
|
||||||
|
LL | type A<N> = ();
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `N` or referring to it in the body of the type alias
|
||||||
|
= help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead
|
||||||
|
|
||||||
|
error[E0091]: type parameter `N` is never used
|
||||||
|
--> $DIR/unused-type-param-suggestion.rs:19:8
|
||||||
|
|
|
||||||
|
LL | type B<N: Copy> = ();
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `N` or referring to it in the body of the type alias
|
||||||
|
|
||||||
|
error[E0091]: type parameter `N` is never used
|
||||||
|
--> $DIR/unused-type-param-suggestion.rs:22:8
|
||||||
|
|
|
||||||
|
LL | type C<N: Sized> = ();
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `N` or referring to it in the body of the type alias
|
||||||
|
|
||||||
|
error[E0091]: type parameter `N` is never used
|
||||||
|
--> $DIR/unused-type-param-suggestion.rs:25:8
|
||||||
|
|
|
||||||
|
LL | type D<N: ?Sized> = ();
|
||||||
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `N` or referring to it in the body of the type alias
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0091, E0392.
|
||||||
|
For more information about an error, try `rustc --explain E0091`.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
--> $DIR/invalid-inline-const-in-match-arm.rs:5:17
|
||||||
|
|
|
|
||||||
LL | const { (|| {})() } => {}
|
LL | const { (|| {})() } => {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -18,7 +18,7 @@ LL | Pin::new(&mut gen).resume(());
|
||||||
| ^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
note: required by a bound in `CoroutineState`
|
note: required by an implicit `Sized` bound in `CoroutineState`
|
||||||
--> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL
|
--> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -5,11 +5,11 @@ LL | impl Foo<[isize]> for usize { }
|
||||||
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[isize]`
|
= help: the trait `Sized` is not implemented for `[isize]`
|
||||||
note: required by a bound in `Foo`
|
note: required by an implicit `Sized` bound in `Foo`
|
||||||
--> $DIR/dst-sized-trait-param.rs:5:11
|
--> $DIR/dst-sized-trait-param.rs:5:11
|
||||||
|
|
|
|
||||||
LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
|
LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
|
||||||
| ^ required by this bound in `Foo`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `Foo`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is sized
|
LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is sized
|
||||||
|
|
|
@ -6,14 +6,14 @@ LL | Some = std::mem::size_of::<T>(),
|
||||||
|
|
|
|
||||||
= note: type parameters may not be used in enum discriminant values
|
= note: type parameters may not be used in enum discriminant values
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
|
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
|
||||||
|
|
|
|
||||||
LL | enum MyWeirdOption<T> {
|
LL | enum MyWeirdOption<T> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ LL | let x: S = 0;
|
||||||
|
|
|
|
||||||
= note: type parameters may not be used in enum discriminant values
|
= note: type parameters may not be used in enum discriminant values
|
||||||
|
|
||||||
error[E0392]: parameter `S` is never used
|
error[E0392]: type parameter `S` is never used
|
||||||
--> $DIR/issue-67945-1.rs:1:10
|
--> $DIR/issue-67945-1.rs:1:10
|
||||||
|
|
|
|
||||||
LL | enum Bug<S> {
|
LL | enum Bug<S> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ LL | Var = type_ascribe!(0, S),
|
||||||
|
|
|
|
||||||
= note: type parameters may not be used in enum discriminant values
|
= note: type parameters may not be used in enum discriminant values
|
||||||
|
|
||||||
error[E0392]: parameter `S` is never used
|
error[E0392]: type parameter `S` is never used
|
||||||
--> $DIR/issue-67945-2.rs:3:10
|
--> $DIR/issue-67945-2.rs:3:10
|
||||||
|
|
|
|
||||||
LL | enum Bug<S> {
|
LL | enum Bug<S> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
error[E0091]: type parameter `T` is unused
|
error[E0091]: type parameter `T` is never used
|
||||||
--> $DIR/E0091.rs:1:10
|
--> $DIR/E0091.rs:1:10
|
||||||
|
|
|
|
||||||
LL | type Foo<T> = u32;
|
LL | type Foo<T> = u32;
|
||||||
| ^ unused type parameter
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `T` or referring to it in the body of the type alias
|
||||||
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error[E0091]: type parameter `B` is unused
|
error[E0091]: type parameter `B` is never used
|
||||||
--> $DIR/E0091.rs:2:14
|
--> $DIR/E0091.rs:2:14
|
||||||
|
|
|
|
||||||
LL | type Foo2<A, B> = Box<A>;
|
LL | type Foo2<A, B> = Box<A>;
|
||||||
| ^ unused type parameter
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `B` or referring to it in the body of the type alias
|
||||||
|
= help: if you intended `B` to be a const parameter, use `const B: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/E0392.rs:1:10
|
--> $DIR/E0392.rs:1:10
|
||||||
|
|
|
|
||||||
LL | enum Foo<T> { Bar }
|
LL | enum Foo<T> { Bar }
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
16
tests/ui/extern/extern-types-unsized.stderr
vendored
16
tests/ui/extern/extern-types-unsized.stderr
vendored
|
@ -5,11 +5,11 @@ LL | assert_sized::<A>();
|
||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `A`
|
= help: the trait `Sized` is not implemented for `A`
|
||||||
note: required by a bound in `assert_sized`
|
note: required by an implicit `Sized` bound in `assert_sized`
|
||||||
--> $DIR/extern-types-unsized.rs:19:17
|
--> $DIR/extern-types-unsized.rs:19:17
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T>() {}
|
LL | fn assert_sized<T>() {}
|
||||||
| ^ required by this bound in `assert_sized`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T: ?Sized>() {}
|
LL | fn assert_sized<T: ?Sized>() {}
|
||||||
|
@ -27,11 +27,11 @@ note: required because it appears within the type `Foo`
|
||||||
|
|
|
|
||||||
LL | struct Foo {
|
LL | struct Foo {
|
||||||
| ^^^
|
| ^^^
|
||||||
note: required by a bound in `assert_sized`
|
note: required by an implicit `Sized` bound in `assert_sized`
|
||||||
--> $DIR/extern-types-unsized.rs:19:17
|
--> $DIR/extern-types-unsized.rs:19:17
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T>() {}
|
LL | fn assert_sized<T>() {}
|
||||||
| ^ required by this bound in `assert_sized`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T: ?Sized>() {}
|
LL | fn assert_sized<T: ?Sized>() {}
|
||||||
|
@ -49,11 +49,11 @@ note: required because it appears within the type `Bar<A>`
|
||||||
|
|
|
|
||||||
LL | struct Bar<T: ?Sized> {
|
LL | struct Bar<T: ?Sized> {
|
||||||
| ^^^
|
| ^^^
|
||||||
note: required by a bound in `assert_sized`
|
note: required by an implicit `Sized` bound in `assert_sized`
|
||||||
--> $DIR/extern-types-unsized.rs:19:17
|
--> $DIR/extern-types-unsized.rs:19:17
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T>() {}
|
LL | fn assert_sized<T>() {}
|
||||||
| ^ required by this bound in `assert_sized`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T: ?Sized>() {}
|
LL | fn assert_sized<T: ?Sized>() {}
|
||||||
|
@ -71,11 +71,11 @@ note: required because it appears within the type `Bar<A>`
|
||||||
|
|
|
|
||||||
LL | struct Bar<T: ?Sized> {
|
LL | struct Bar<T: ?Sized> {
|
||||||
| ^^^
|
| ^^^
|
||||||
note: required by a bound in `assert_sized`
|
note: required by an implicit `Sized` bound in `assert_sized`
|
||||||
--> $DIR/extern-types-unsized.rs:19:17
|
--> $DIR/extern-types-unsized.rs:19:17
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T>() {}
|
LL | fn assert_sized<T>() {}
|
||||||
| ^ required by this bound in `assert_sized`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | fn assert_sized<T: ?Sized>() {}
|
LL | fn assert_sized<T: ?Sized>() {}
|
||||||
|
|
|
@ -13,5 +13,14 @@ impl Foo for Meeshka {
|
||||||
type Wub = !; //~ ERROR type is experimental
|
type Wub = !; //~ ERROR type is experimental
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn look_ma_no_feature_gate<F: FnOnce() -> !>() {} //~ ERROR type is experimental
|
||||||
|
fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental
|
||||||
|
fn panic() -> ! {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental
|
||||||
|
panic
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,36 @@ LL | type Wub = !;
|
||||||
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error[E0658]: the `!` type is experimental
|
||||||
|
--> $DIR/feature-gate-never_type.rs:16:43
|
||||||
|
|
|
||||||
|
LL | fn look_ma_no_feature_gate<F: FnOnce() -> !>() {}
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
|
||||||
|
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0658]: the `!` type is experimental
|
||||||
|
--> $DIR/feature-gate-never_type.rs:17:26
|
||||||
|
|
|
||||||
|
LL | fn tadam(f: &dyn Fn() -> !) {}
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
|
||||||
|
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0658]: the `!` type is experimental
|
||||||
|
--> $DIR/feature-gate-never_type.rs:21:30
|
||||||
|
|
|
||||||
|
LL | fn toudoum() -> impl Fn() -> ! {
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
|
||||||
|
= help: add `#![feature(never_type)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -7,11 +7,11 @@ LL | type SearchFutureTy<'f, A, B: 'f>
|
||||||
LL | async move { todo!() }
|
LL | async move { todo!() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
note: required by a bound in `<T as SearchableResourceExt<Criteria>>`
|
note: required by an implicit `Sized` bound in `<T as SearchableResourceExt<Criteria>>`
|
||||||
--> $DIR/issue-88287.rs:24:6
|
--> $DIR/issue-88287.rs:24:6
|
||||||
|
|
|
|
||||||
LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
|
LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
|
||||||
| ^ required by this bound in `<T as SearchableResourceExt<Criteria>>`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `<T as SearchableResourceExt<Criteria>>`
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - A: SearchableResource<B> + ?Sized + 'f,
|
LL - A: SearchableResource<B> + ?Sized + 'f,
|
||||||
|
|
|
@ -6,10 +6,10 @@ LL | impl Tsized for () {}
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[()]`
|
= help: the trait `Sized` is not implemented for `[()]`
|
||||||
note: required by a bound in `Tsized`
|
note: required by a bound in `Tsized`
|
||||||
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:14
|
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:17
|
||||||
|
|
|
|
||||||
LL | trait Tsized<P: Sized = [Self]> {}
|
LL | trait Tsized<P: Sized = [Self]> {}
|
||||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Tsized`
|
| ^^^^^ required by this bound in `Tsized`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(exclusive_range_pattern)]
|
#![feature(exclusive_range_pattern)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | fn nya() -> impl Wf<Vec<[u8]>>;
|
||||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
note: required by a bound in `Vec`
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
@ -15,11 +15,11 @@ LL | fn nya2() -> impl Wf<[u8]>;
|
||||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
note: required by a bound in `Wf`
|
note: required by an implicit `Sized` bound in `Wf`
|
||||||
--> $DIR/wf-bounds.rs:7:10
|
--> $DIR/wf-bounds.rs:7:10
|
||||||
|
|
|
|
||||||
LL | trait Wf<T> {
|
LL | trait Wf<T> {
|
||||||
| ^ required by this bound in `Wf`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `Wf`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | trait Wf<T: ?Sized> {
|
LL | trait Wf<T: ?Sized> {
|
||||||
|
@ -32,7 +32,7 @@ LL | fn nya3() -> impl Wf<(), Output = impl Wf<Vec<[u8]>>>;
|
||||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
note: required by a bound in `Vec`
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: `T` doesn't implement `std::fmt::Display`
|
error[E0277]: `T` doesn't implement `std::fmt::Display`
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
|
// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error: constant pattern depends on a generic parameter
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/const-match-pat-generic.rs:8:9
|
--> $DIR/const-match-pat-generic.rs:7:9
|
||||||
|
|
|
|
||||||
LL | const { V } => {},
|
LL | const { V } => {},
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: constant pattern depends on a generic parameter
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/const-match-pat-generic.rs:20:9
|
--> $DIR/const-match-pat-generic.rs:19:9
|
||||||
|
|
|
|
||||||
LL | const { f(V) } => {},
|
LL | const { f(V) } => {},
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match 1u64 {
|
match 1u64 {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0597]: `y` does not live long enough
|
error[E0597]: `y` does not live long enough
|
||||||
--> $DIR/const-match-pat-lifetime-err.rs:29:29
|
--> $DIR/const-match-pat-lifetime-err.rs:28:29
|
||||||
|
|
|
|
||||||
LL | fn match_invariant_ref<'a>() {
|
LL | fn match_invariant_ref<'a>() {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
@ -15,7 +15,7 @@ LL | }
|
||||||
| - `y` dropped here while still borrowed
|
| - `y` dropped here while still borrowed
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/const-match-pat-lifetime-err.rs:39:12
|
--> $DIR/const-match-pat-lifetime-err.rs:38:12
|
||||||
|
|
|
|
||||||
LL | fn match_covariant_ref<'a>() {
|
LL | fn match_covariant_ref<'a>() {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// build-pass
|
// build-pass
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const_pat, exclusive_range_pattern)]
|
#![feature(inline_const_pat, exclusive_range_pattern)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
const MMIO_BIT1: u8 = 4;
|
const MMIO_BIT1: u8 = 4;
|
||||||
const MMIO_BIT2: u8 = 5;
|
const MMIO_BIT2: u8 = 5;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
//~^ WARN the feature `inline_const_pat` is incomplete
|
|
||||||
|
|
||||||
fn uwu() {}
|
fn uwu() {}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
warning: the feature `inline_const_pat` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/pat-match-fndef.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(inline_const_pat)]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: `fn() {uwu}` cannot be used in patterns
|
error: `fn() {uwu}` cannot be used in patterns
|
||||||
--> $DIR/pat-match-fndef.rs:9:9
|
--> $DIR/pat-match-fndef.rs:8:9
|
||||||
|
|
|
|
||||||
LL | const { uwu } => {}
|
LL | const { uwu } => {}
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
const unsafe fn require_unsafe() -> usize {
|
const unsafe fn require_unsafe() -> usize {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
|
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/pat-unsafe-err.rs:11:13
|
--> $DIR/pat-unsafe-err.rs:10:13
|
||||||
|
|
|
|
||||||
LL | require_unsafe();
|
LL | require_unsafe();
|
||||||
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
||||||
|
@ -7,7 +7,7 @@ LL | require_unsafe();
|
||||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
|
error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/pat-unsafe-err.rs:18:13
|
--> $DIR/pat-unsafe-err.rs:17:13
|
||||||
|
|
|
|
||||||
LL | require_unsafe()
|
LL | require_unsafe()
|
||||||
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![warn(unused_unsafe)]
|
#![warn(unused_unsafe)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
warning: unnecessary `unsafe` block
|
warning: unnecessary `unsafe` block
|
||||||
--> $DIR/pat-unsafe.rs:16:17
|
--> $DIR/pat-unsafe.rs:15:17
|
||||||
|
|
|
|
||||||
LL | unsafe {}
|
LL | unsafe {}
|
||||||
| ^^^^^^ unnecessary `unsafe` block
|
| ^^^^^^ unnecessary `unsafe` block
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/pat-unsafe.rs:4:9
|
--> $DIR/pat-unsafe.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![warn(unused_unsafe)]
|
LL | #![warn(unused_unsafe)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: unnecessary `unsafe` block
|
warning: unnecessary `unsafe` block
|
||||||
--> $DIR/pat-unsafe.rs:23:17
|
--> $DIR/pat-unsafe.rs:22:17
|
||||||
|
|
|
|
||||||
LL | unsafe {}
|
LL | unsafe {}
|
||||||
| ^^^^^^ unnecessary `unsafe` block
|
| ^^^^^^ unnecessary `unsafe` block
|
||||||
|
|
|
@ -6,14 +6,14 @@ LL | fn foo<T>() {
|
||||||
LL | static a: Bar<T> = Bar::What;
|
LL | static a: Bar<T> = Bar::What;
|
||||||
| ^ use of generic parameter from outer item
|
| ^ use of generic parameter from outer item
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/inner-static-type-parameter.rs:3:10
|
--> $DIR/inner-static-type-parameter.rs:3:10
|
||||||
|
|
|
|
||||||
LL | enum Bar<T> { What }
|
LL | enum Bar<T> { What }
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,11 @@ LL | impl<'self> Serializable<str> for &'self str {
|
||||||
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
note: required by a bound in `Serializable`
|
note: required by an implicit `Sized` bound in `Serializable`
|
||||||
--> $DIR/issue-10412.rs:1:27
|
--> $DIR/issue-10412.rs:1:27
|
||||||
|
|
|
|
||||||
LL | trait Serializable<'self, T> {
|
LL | trait Serializable<'self, T> {
|
||||||
| ^ required by this bound in `Serializable`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `Serializable`
|
||||||
help: consider relaxing the implicit `Sized` restriction
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
|
||||||
LL | trait Serializable<'self, T: ?Sized> {
|
LL | trait Serializable<'self, T: ?Sized> {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-17904-2.rs:4:12
|
--> $DIR/issue-17904-2.rs:4:12
|
||||||
|
|
|
|
||||||
LL | struct Foo<T> where T: Copy;
|
LL | struct Foo<T> where T: Copy;
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
trait Tr {}
|
trait Tr {}
|
||||||
type Huh<T> where T: Tr = isize; //~ ERROR type parameter `T` is unused
|
type Huh<T> where T: Tr = isize; //~ ERROR type parameter `T` is never used
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
error[E0091]: type parameter `T` is unused
|
error[E0091]: type parameter `T` is never used
|
||||||
--> $DIR/issue-17994.rs:2:10
|
--> $DIR/issue-17994.rs:2:10
|
||||||
|
|
|
|
||||||
LL | type Huh<T> where T: Tr = isize;
|
LL | type Huh<T> where T: Tr = isize;
|
||||||
| ^ unused type parameter
|
| ^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `T` or referring to it in the body of the type alias
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ LL | fn ho_func(f: Option<FuncType>) {
|
||||||
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `dyn for<'a> Fn(&'a isize) -> isize`
|
= help: the trait `Sized` is not implemented for `dyn for<'a> Fn(&'a isize) -> isize`
|
||||||
note: required by a bound in `Option`
|
note: required by an implicit `Sized` bound in `Option`
|
||||||
--> $DIR/issue-18919.rs:7:13
|
--> $DIR/issue-18919.rs:7:13
|
||||||
|
|
|
|
||||||
LL | enum Option<T> {
|
LL | enum Option<T> {
|
||||||
| ^ required by this bound in `Option`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `Option`
|
||||||
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
|
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
|
||||||
--> $DIR/issue-18919.rs:7:13
|
--> $DIR/issue-18919.rs:7:13
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-20413.rs:6:15
|
--> $DIR/issue-20413.rs:6:15
|
||||||
|
|
|
|
||||||
LL | struct NoData<T>;
|
LL | struct NoData<T>;
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
|
error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
|
||||||
--> $DIR/issue-20413.rs:9:36
|
--> $DIR/issue-20413.rs:9:36
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | fn iceman(c: Vec<[i32]>) {}
|
||||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[i32]`
|
= help: the trait `Sized` is not implemented for `[i32]`
|
||||||
note: required by a bound in `Vec`
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -5,11 +5,11 @@ LL | pub fn function(funs: Vec<dyn Fn() -> ()>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)`
|
||||||
note: required by a bound in `Vec`
|
note: required by an implicit `Sized` bound in `Vec`
|
||||||
--> $DIR/issue-23281.rs:8:12
|
--> $DIR/issue-23281.rs:8:12
|
||||||
|
|
|
|
||||||
LL | struct Vec<T> {
|
LL | struct Vec<T> {
|
||||||
| ^ required by this bound in `Vec`
|
| ^ required by the implicit `Sized` requirement on this type parameter in `Vec`
|
||||||
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
|
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
|
||||||
--> $DIR/issue-23281.rs:8:12
|
--> $DIR/issue-23281.rs:8:12
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
type Foo<
|
type Foo<
|
||||||
Unused //~ ERROR type parameter `Unused` is unused
|
Unused //~ ERROR type parameter `Unused` is never used
|
||||||
> = u8;
|
> = u8;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
error[E0091]: type parameter `Unused` is unused
|
error[E0091]: type parameter `Unused` is never used
|
||||||
--> $DIR/issue-30236.rs:2:5
|
--> $DIR/issue-30236.rs:2:5
|
||||||
|
|
|
|
||||||
LL | Unused
|
LL | Unused
|
||||||
| ^^^^^^ unused type parameter
|
| ^^^^^^ unused type parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `Unused` or referring to it in the body of the type alias
|
||||||
|
= help: if you intended `Unused` to be a const parameter, use `const Unused: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ error[E0308]: mismatched types
|
||||||
LL | X = Trait::Number,
|
LL | X = Trait::Number,
|
||||||
| ^^^^^^^^^^^^^ expected `isize`, found `i32`
|
| ^^^^^^^^^^^^^ expected `isize`, found `i32`
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-31910.rs:1:11
|
--> $DIR/issue-31910.rs:1:11
|
||||||
|
|
|
|
||||||
LL | enum Enum<T: Trait> {
|
LL | enum Enum<T: Trait> {
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
|
|
|
@ -45,14 +45,14 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
|
||||||
LL | fn foo(_: T) where Self: Sized {}
|
LL | fn foo(_: T) where Self: Sized {}
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-34373.rs:7:16
|
--> $DIR/issue-34373.rs:7:16
|
||||||
|
|
|
|
||||||
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
|
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused parameter
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
|
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
error[E0392]: parameter `'a` is never used
|
error[E0392]: lifetime parameter `'a` is never used
|
||||||
--> $DIR/issue-36299.rs:1:12
|
--> $DIR/issue-36299.rs:1:12
|
||||||
|
|
|
|
||||||
LL | struct Foo<'a, A> {}
|
LL | struct Foo<'a, A> {}
|
||||||
| ^^ unused parameter
|
| ^^ unused lifetime parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
error[E0392]: parameter `A` is never used
|
error[E0392]: type parameter `A` is never used
|
||||||
--> $DIR/issue-36299.rs:1:16
|
--> $DIR/issue-36299.rs:1:16
|
||||||
|
|
|
|
||||||
LL | struct Foo<'a, A> {}
|
LL | struct Foo<'a, A> {}
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
= help: if you intended `A` to be a const parameter, use `const A: usize` instead
|
= help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
|
||||||
LL | struct Foo<T: ?Hash> {}
|
LL | struct Foo<T: ?Hash> {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: type parameter `T` is never used
|
||||||
--> $DIR/issue-37534.rs:1:12
|
--> $DIR/issue-37534.rs:1:12
|
||||||
|
|
|
|
||||||
LL | struct Foo<T: ?Hash> {}
|
LL | struct Foo<T: ?Hash> {}
|
||||||
| ^ unused parameter
|
| ^ unused type parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue