mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 02:54:00 +00:00
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
@ -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) {
|
||||
match e.kind {
|
||||
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:
|
||||
|
||||
```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:
|
||||
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:
|
||||
|
@ -496,7 +496,7 @@ declare_features! (
|
||||
/// Allow anonymous constants from an inline `const` block
|
||||
(unstable, inline_const, "1.49.0", Some(76001)),
|
||||
/// 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
|
||||
(unstable, intra_doc_pointers, "1.51.0", Some(80896)),
|
||||
// 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`.
|
||||
.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 =
|
||||
the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified
|
||||
.label = re-bound here
|
||||
|
@ -28,6 +28,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||
let tcx = self.tcx();
|
||||
let sized_def_id = tcx.lang_items().sized_trait();
|
||||
let mut seen_negative_sized_bound = false;
|
||||
let mut seen_positive_sized_bound = false;
|
||||
|
||||
// Try to find an unbound in bounds.
|
||||
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||
@ -45,6 +46,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||
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 {
|
||||
// There was in fact a `?Sized` or `!Sized` bound;
|
||||
if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {
|
||||
// There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound;
|
||||
// we don't need to do anything.
|
||||
} 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.
|
||||
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_type_ir::fold::TypeFoldable;
|
||||
|
||||
use std::cell::LazyCell;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
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 => {
|
||||
let pty_ty = tcx.type_of(def_id).instantiate_identity();
|
||||
let generics = tcx.generics_of(def_id);
|
||||
check_type_params_are_used(tcx, generics, pty_ty);
|
||||
check_type_alias_type_params_are_used(tcx, def_id);
|
||||
}
|
||||
DefKind::ForeignMod => {
|
||||
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>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
generics: &ty::Generics,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
|
||||
|
||||
assert_eq!(generics.parent, None);
|
||||
fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||
if tcx.type_alias_is_lazy(def_id) {
|
||||
// Since we compute the variances for lazy type aliases and already reject bivariant
|
||||
// parameters as unused, we can and should skip this check for lazy type aliases.
|
||||
return;
|
||||
}
|
||||
|
||||
let generics = tcx.generics_of(def_id);
|
||||
if generics.own_counts().types == 0 {
|
||||
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 there is already another error, do not emit
|
||||
// an error for not using a type parameter.
|
||||
// If there is already another error, do not emit an error for not using a type parameter.
|
||||
assert!(tcx.dcx().has_errors().is_some());
|
||||
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() {
|
||||
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
|
||||
&& 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 span = tcx.def_span(param.def_id);
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
let param_name = Ident::new(param.name, span);
|
||||
|
||||
// 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,
|
||||
E0091,
|
||||
"type parameter `{}` is unused",
|
||||
param.name,
|
||||
)
|
||||
.with_span_label(span, "unused type parameter")
|
||||
.emit();
|
||||
param_name,
|
||||
param_def_kind: tcx.def_descr(param.def_id),
|
||||
help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
|
||||
const_param_help,
|
||||
});
|
||||
diag.code(E0091);
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
use crate::autoderef::Autoderef;
|
||||
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
||||
use crate::errors;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_errors::{
|
||||
codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
|
||||
};
|
||||
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
@ -21,7 +20,7 @@ use rustc_middle::ty::{
|
||||
};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
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_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
@ -1869,7 +1868,7 @@ fn check_variances_for_type_defn<'tcx>(
|
||||
hir::ParamName::Error => {}
|
||||
_ => {
|
||||
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<'_>,
|
||||
param: &rustc_hir::GenericParam<'_>,
|
||||
has_explicit_bounds: bool,
|
||||
item_kind: ItemKind<'_>,
|
||||
) -> ErrorGuaranteed {
|
||||
let span = param.span;
|
||||
let param_name = param.name.ident().name;
|
||||
let mut err = error_392(tcx, span, param_name);
|
||||
let param_name = param.name.ident();
|
||||
|
||||
let suggested_marker_id = tcx.lang_items().phantom_data();
|
||||
// Help is available only in presence of lang items.
|
||||
let msg = if let Some(def_id) = suggested_marker_id {
|
||||
format!(
|
||||
"consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
|
||||
param_name,
|
||||
tcx.def_path_str(def_id),
|
||||
)
|
||||
} else {
|
||||
format!("consider removing `{param_name}` or referring to it in a field")
|
||||
let help = match item_kind {
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
if let Some(def_id) = tcx.lang_items().phantom_data() {
|
||||
errors::UnusedGenericParameterHelp::Adt {
|
||||
param_name,
|
||||
phantom_data: tcx.def_path_str(def_id),
|
||||
}
|
||||
} else {
|
||||
errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name }
|
||||
}
|
||||
}
|
||||
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 {
|
||||
err.help(format!(
|
||||
"if you intended `{param_name}` to be a const parameter, use `const {param_name}: usize` instead"
|
||||
));
|
||||
}
|
||||
err.emit()
|
||||
let const_param_help =
|
||||
matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
|
||||
.then_some(());
|
||||
|
||||
let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
|
||||
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> {
|
||||
@ -1967,11 +1974,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
|
||||
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) {
|
||||
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
|
||||
}
|
||||
|
@ -1511,3 +1511,27 @@ pub struct NotSupportedDelegation<'a> {
|
||||
#[label]
|
||||
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
|
||||
&& let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr)
|
||||
&& 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) {
|
||||
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}`");
|
||||
if span.is_visible(sm) {
|
||||
let msg = format!("required by this bound in `{short_item_name}`");
|
||||
multispan.push_span_label(span, msg);
|
||||
err.span_note(multispan, descr);
|
||||
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
|
||||
&& let ty::ClauseKind::Trait(trait_pred) = clause
|
||||
{
|
||||
let def_id = trait_pred.def_id();
|
||||
let visible_item = if let Some(local) = def_id.as_local() {
|
||||
// Check for local traits being reachable.
|
||||
let vis = &tcx.resolutions(()).effective_visibilities;
|
||||
// Account for non-`pub` traits in the root of the local crate.
|
||||
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
|
||||
vis.is_reachable(local) || is_locally_reachable
|
||||
} else {
|
||||
// Check for foreign traits being reachable.
|
||||
tcx.visible_parent_map(()).get(&def_id).is_some()
|
||||
};
|
||||
if Some(def_id) == tcx.lang_items().sized_trait()
|
||||
&& 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 mut a = "a";
|
||||
let mut this = "this bound";
|
||||
let mut note = None;
|
||||
let mut help = None;
|
||||
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
|
||||
&& let ty::ClauseKind::Trait(trait_pred) = clause
|
||||
{
|
||||
let def_id = trait_pred.def_id();
|
||||
let visible_item = if let Some(local) = def_id.as_local() {
|
||||
// Check for local traits being reachable.
|
||||
let vis = &tcx.resolutions(()).effective_visibilities;
|
||||
// Account for non-`pub` traits in the root of the local crate.
|
||||
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
|
||||
vis.is_reachable(local) || is_locally_reachable
|
||||
} else {
|
||||
// Check for foreign traits being reachable.
|
||||
tcx.visible_parent_map(()).get(&def_id).is_some()
|
||||
};
|
||||
if Some(def_id) == tcx.lang_items().sized_trait() {
|
||||
// Check if this is an implicit bound, even in foreign crates.
|
||||
if tcx
|
||||
.generics_of(item_def_id)
|
||||
.params
|
||||
.iter()
|
||||
.any(|param| tcx.def_span(param.def_id) == span)
|
||||
{
|
||||
a = "an implicit `Sized`";
|
||||
this = "the implicit `Sized` requirement on this type parameter";
|
||||
}
|
||||
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 {
|
||||
(last.span().shrink_to_hi(), " +")
|
||||
@ -3051,52 +3060,64 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
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 \
|
||||
it you also need to implement `{}`, which is not accessible; \
|
||||
this is usually done to force you to use one of the provided \
|
||||
types that 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
|
||||
.non_blanket_impls()
|
||||
.values()
|
||||
.flatten()
|
||||
.chain(impls_of.blanket_impls().iter())
|
||||
}
|
||||
if let DefKind::Trait = tcx.def_kind(item_def_id)
|
||||
&& !visible_item
|
||||
{
|
||||
note = Some(format!(
|
||||
"`{short_item_name}` is a \"sealed trait\", because to implement it \
|
||||
you also need to implement `{}`, which is not accessible; this is \
|
||||
usually done to force you to use one of the provided types that \
|
||||
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
|
||||
.non_blanket_impls()
|
||||
.values()
|
||||
.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<_>>();
|
||||
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<_>>();
|
||||
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 post = if types.len() > 9 {
|
||||
types.truncate(8);
|
||||
format!("\nand {} others", len - 8)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
help = Some(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 {
|
||||
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 } => {
|
||||
let mut file = None;
|
||||
|
@ -559,10 +559,10 @@ trait TraitAddBuiltinBoundToMethodTypeParameter {
|
||||
#[cfg(not(any(cfail1,cfail4)))]
|
||||
#[rustc_clean(cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[rustc_clean(cfg="cfail5")]
|
||||
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")]
|
||||
#[rustc_clean(cfg="cfail6")]
|
||||
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(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")]
|
||||
#[rustc_clean(cfg="cfail6")]
|
||||
|
@ -1,9 +1,21 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR array_index.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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];
|
||||
}
|
||||
|
@ -1,11 +1,18 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR boolean_identities.test.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn test(
|
||||
pub fn test(x: bool, y: bool) -> bool {
|
||||
// CHECK-NOT: BitAnd(
|
||||
// CHECK-NOT: BitOr(
|
||||
(y | true) & (x & false)
|
||||
// CHECK: _0 = const false;
|
||||
// CHECK-NOT: BitAnd(
|
||||
// CHECK-NOT: BitOr(
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
test(true, false);
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR cast.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
|
||||
// CHECK: [[a]] = const 257_i32;
|
||||
let a = 257;
|
||||
// CHECK: [[b]] = const 2_u8;
|
||||
let b = a as u8 + 1;
|
||||
}
|
||||
|
@ -1,15 +1,32 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Coverflow-checks=on
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
// EMIT_MIR checked.main.DataflowConstProp.diff
|
||||
#[allow(arithmetic_overflow)]
|
||||
|
||||
// CHECK-LABEL: 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;
|
||||
|
||||
// CHECK: [[b]] = const 2_i32;
|
||||
let b = 2;
|
||||
|
||||
// CHECK: assert(!const false,
|
||||
// CHECK: [[c]] = const 3_i32;
|
||||
let c = a + b;
|
||||
|
||||
// CHECK: [[d]] = const _;
|
||||
let d = i32::MAX;
|
||||
|
||||
// CHECK: assert(!const true,
|
||||
// CHECK: [[e]] = const i32::MIN;
|
||||
let e = d + 1;
|
||||
}
|
||||
|
@ -1,18 +1,29 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zmir-enable-passes=+GVN,+Inline
|
||||
// ignore-debug assertions change the output MIR
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
// 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 {
|
||||
foo: Box<[bool]>,
|
||||
}
|
||||
|
||||
// EMIT_MIR default_boxed_slice.main.GVN.diff
|
||||
// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// 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.
|
||||
|
||||
// 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() };
|
||||
}
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
let _6: u8;
|
||||
let _8: u8;
|
||||
scope 2 {
|
||||
debug x => _6;
|
||||
debug x2 => _6;
|
||||
let _9: u8;
|
||||
scope 4 {
|
||||
debug y => _9;
|
||||
|
@ -14,7 +14,7 @@
|
||||
let _6: u8;
|
||||
let _8: u8;
|
||||
scope 2 {
|
||||
debug x => _6;
|
||||
debug x2 => _6;
|
||||
let _9: u8;
|
||||
scope 4 {
|
||||
debug y => _9;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
@ -13,27 +12,67 @@ enum E {
|
||||
}
|
||||
|
||||
// EMIT_MIR enum.simple.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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 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
|
||||
|
||||
// CHECK-LABEL: fn constant(
|
||||
fn constant() {
|
||||
// CHECK: debug e => [[e:_.*]];
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
const C: E = E::V1(0);
|
||||
|
||||
// CHECK: [[e]] = const _;
|
||||
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
|
||||
|
||||
// CHECK-LABEL: 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);
|
||||
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);
|
||||
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)]
|
||||
@ -41,6 +80,8 @@ fn statics() {
|
||||
struct NonZeroUsize(usize);
|
||||
|
||||
// EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn mutate_discriminant(
|
||||
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
|
||||
fn mutate_discriminant() -> u8 {
|
||||
mir!(
|
||||
@ -50,7 +91,11 @@ fn mutate_discriminant() -> u8 {
|
||||
// This assignment overwrites the niche in which the discriminant is stored.
|
||||
place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize;
|
||||
// So we cannot know the value of this discriminant.
|
||||
|
||||
// CHECK: [[a:_.*]] = discriminant({{_.*}});
|
||||
let a = Discriminant(x);
|
||||
|
||||
// CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
match a {
|
||||
0 => bb1,
|
||||
_ => bad,
|
||||
@ -68,18 +113,33 @@ fn mutate_discriminant() -> u8 {
|
||||
}
|
||||
|
||||
// EMIT_MIR enum.multiple.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn multiple(
|
||||
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 {
|
||||
// CHECK: [[e]] = Option::<u8>::Some(move {{_.*}});
|
||||
Some(i)
|
||||
} else {
|
||||
// CHECK: [[e]] = Option::<u8>::None;
|
||||
None
|
||||
};
|
||||
// The dataflow state must have:
|
||||
// discriminant(e) => Top
|
||||
// (e as Some).0 => Top
|
||||
let x = match e { Some(i) => i, None => 0 };
|
||||
// Therefore, `x` should be `Top` here, and no replacement shall happen.
|
||||
let y = x;
|
||||
// CHECK: [[x2]] = const 0_u8;
|
||||
// CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8)
|
||||
// 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() {
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,34 +9,34 @@
|
||||
let mut _8: &&E;
|
||||
let mut _10: isize;
|
||||
scope 1 {
|
||||
debug e => _1;
|
||||
debug e1 => _1;
|
||||
let _3: i32;
|
||||
let _5: i32;
|
||||
let _6: i32;
|
||||
scope 2 {
|
||||
debug x => _3;
|
||||
debug x1 => _3;
|
||||
let _7: &E;
|
||||
scope 5 {
|
||||
debug e => _7;
|
||||
debug e2 => _7;
|
||||
let _9: &i32;
|
||||
let _11: &i32;
|
||||
let _12: &i32;
|
||||
scope 6 {
|
||||
debug x => _9;
|
||||
debug x2 => _9;
|
||||
}
|
||||
scope 7 {
|
||||
debug x => _11;
|
||||
debug x21 => _11;
|
||||
}
|
||||
scope 8 {
|
||||
debug x => _12;
|
||||
debug x22 => _12;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _5;
|
||||
debug x11 => _5;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _6;
|
||||
debug x12 => _6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,34 +9,34 @@
|
||||
let mut _8: &&E;
|
||||
let mut _10: isize;
|
||||
scope 1 {
|
||||
debug e => _1;
|
||||
debug e1 => _1;
|
||||
let _3: i32;
|
||||
let _5: i32;
|
||||
let _6: i32;
|
||||
scope 2 {
|
||||
debug x => _3;
|
||||
debug x1 => _3;
|
||||
let _7: &E;
|
||||
scope 5 {
|
||||
debug e => _7;
|
||||
debug e2 => _7;
|
||||
let _9: &i32;
|
||||
let _11: &i32;
|
||||
let _12: &i32;
|
||||
scope 6 {
|
||||
debug x => _9;
|
||||
debug x2 => _9;
|
||||
}
|
||||
scope 7 {
|
||||
debug x => _11;
|
||||
debug x21 => _11;
|
||||
}
|
||||
scope 8 {
|
||||
debug x => _12;
|
||||
debug x22 => _12;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _5;
|
||||
debug x11 => _5;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _6;
|
||||
debug x12 => _6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,26 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR if.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
// CHECK: debug c => [[c:_.*]];
|
||||
// CHECK: debug d => [[d:_.*]];
|
||||
// CHECK: debug e => [[e:_.*]];
|
||||
|
||||
let a = 1;
|
||||
|
||||
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
// CHECK: [[b]] = const 2_i32;
|
||||
let b = if a == 1 { 2 } else { 3 };
|
||||
|
||||
// CHECK: [[c]] = const 3_i32;
|
||||
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 };
|
||||
|
||||
// CHECK: [[e]] = const 2_i32;
|
||||
let e = d + 1;
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zmir-enable-passes=+Inline
|
||||
|
||||
// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// After inlining, this will contain a `CheckedBinaryOp`.
|
||||
// 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);
|
||||
}
|
||||
|
@ -1,9 +1,18 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// 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 {
|
||||
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
1 + if true { 1 } else { 2 }
|
||||
// CHECK: _0 = const 2_usize;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,10 +1,18 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR large_array_index.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// 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];
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR mult_by_zero.test.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn test(
|
||||
fn test(x : i32) -> i32 {
|
||||
x * 0
|
||||
// CHECK: _0 = const 0_i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
@ -29,18 +28,46 @@ struct Delta<T> {
|
||||
}
|
||||
|
||||
// EMIT_MIR offset_of.concrete.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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);
|
||||
|
||||
// CHECK: [[y]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||
let y = offset_of!(Alpha, y);
|
||||
|
||||
// CHECK: [[z0]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||
let z0 = offset_of!(Alpha, z.0);
|
||||
|
||||
// CHECK: [[z1]] = must_use::<usize>(const 3_usize) -> {{.*}}
|
||||
let z1 = offset_of!(Alpha, z.1);
|
||||
}
|
||||
|
||||
// EMIT_MIR offset_of.generic.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn generic(
|
||||
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);
|
||||
|
||||
// CHECK: [[gy]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
|
||||
let gy = offset_of!(Gamma<T>, y);
|
||||
|
||||
// CHECK: [[dx]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||
let dx = offset_of!(Delta<T>, x);
|
||||
|
||||
// CHECK: [[dy]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||
let dy = offset_of!(Delta<T>, y);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
@ -9,11 +8,23 @@ fn escape<T>(x: &T) {}
|
||||
fn some_function() {}
|
||||
|
||||
// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: {{_.*}} = escape::<i32>(move {{_.*}}) -> {{.*}}
|
||||
escape(&a);
|
||||
a = 1;
|
||||
|
||||
// CHECK: {{_.*}} = some_function() -> {{.*}}
|
||||
some_function();
|
||||
// This should currently not be propagated.
|
||||
|
||||
// CHECK-NOT: [[b]] = const
|
||||
// CHECK: [[b]] = [[a]];
|
||||
// CHECK-NOT: [[b]] = const
|
||||
let b = a;
|
||||
}
|
||||
|
@ -1,9 +1,21 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR repeat.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: 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;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// The struct has scalar ABI, but is not a scalar type.
|
||||
@ -7,7 +6,15 @@
|
||||
struct I32(i32);
|
||||
|
||||
// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: debug y => [[y:_.*]];
|
||||
|
||||
// CHECK: [[x]] = const I32(0_i32);
|
||||
let x = I32(0);
|
||||
|
||||
// CHECK: [[y]] = const I32(0_i32);
|
||||
let y = I32(x.0 + x.0);
|
||||
}
|
||||
|
@ -1,13 +1,26 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR self_assign.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: [[a]] = Add(move {{_.*}}, const 1_i32);
|
||||
a = a + 1;
|
||||
|
||||
// CHECK: [[a]] = move {{_.*}};
|
||||
a = a;
|
||||
|
||||
// CHECK: [[b]] = &[[a]];
|
||||
let mut b = &a;
|
||||
|
||||
// CHECK: [[b]] = move {{_.*}};
|
||||
b = b;
|
||||
|
||||
// CHECK: [[a]] = move {{_.*}};
|
||||
a = *b;
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: [[a]] = const 1_i32;
|
||||
a += 1;
|
||||
|
||||
// CHECK: [[a]] = const 2_i32;
|
||||
a += 1;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// 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
|
||||
@ -10,11 +9,17 @@
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug x1 => [[x1:_.*]];
|
||||
|
||||
let mut x: (u8, u8) = (0, 0);
|
||||
unsafe {
|
||||
let p = std::ptr::addr_of_mut!(x.0);
|
||||
*p.add(1) = 1;
|
||||
}
|
||||
|
||||
// CHECK: [[x1]] = ({{_.*}}.1: u8);
|
||||
let x1 = x.1; // should not be propagated
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zmir-enable-passes=+InstSimplify
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR slice_len.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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];
|
||||
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
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];
|
||||
}
|
||||
|
@ -37,16 +37,16 @@
|
||||
let _8: std::option::Option<S>;
|
||||
let _9: &[f32];
|
||||
scope 4 {
|
||||
debug a => _7;
|
||||
debug b => _8;
|
||||
debug c => _9;
|
||||
debug a1 => _7;
|
||||
debug b1 => _8;
|
||||
debug c1 => _9;
|
||||
let _11: f32;
|
||||
let _12: std::option::Option<S>;
|
||||
let _13: &[f32];
|
||||
scope 5 {
|
||||
debug a => _11;
|
||||
debug b => _12;
|
||||
debug c => _13;
|
||||
debug a2 => _11;
|
||||
debug b2 => _12;
|
||||
debug c2 => _13;
|
||||
let _15: SmallStruct;
|
||||
scope 6 {
|
||||
debug ss => _15;
|
||||
@ -54,16 +54,16 @@
|
||||
let _20: std::option::Option<S>;
|
||||
let _21: &[f32];
|
||||
scope 7 {
|
||||
debug a => _19;
|
||||
debug b => _20;
|
||||
debug c => _21;
|
||||
debug a3 => _19;
|
||||
debug b3 => _20;
|
||||
debug c3 => _21;
|
||||
let _23: f32;
|
||||
let _24: std::option::Option<S>;
|
||||
let _25: &[f32];
|
||||
scope 8 {
|
||||
debug a => _23;
|
||||
debug b => _24;
|
||||
debug c => _25;
|
||||
debug a4 => _23;
|
||||
debug b4 => _24;
|
||||
debug c4 => _25;
|
||||
let _27: BigStruct;
|
||||
scope 9 {
|
||||
debug bs => _27;
|
||||
|
@ -37,16 +37,16 @@
|
||||
let _8: std::option::Option<S>;
|
||||
let _9: &[f32];
|
||||
scope 4 {
|
||||
debug a => _7;
|
||||
debug b => _8;
|
||||
debug c => _9;
|
||||
debug a1 => _7;
|
||||
debug b1 => _8;
|
||||
debug c1 => _9;
|
||||
let _11: f32;
|
||||
let _12: std::option::Option<S>;
|
||||
let _13: &[f32];
|
||||
scope 5 {
|
||||
debug a => _11;
|
||||
debug b => _12;
|
||||
debug c => _13;
|
||||
debug a2 => _11;
|
||||
debug b2 => _12;
|
||||
debug c2 => _13;
|
||||
let _15: SmallStruct;
|
||||
scope 6 {
|
||||
debug ss => _15;
|
||||
@ -54,16 +54,16 @@
|
||||
let _20: std::option::Option<S>;
|
||||
let _21: &[f32];
|
||||
scope 7 {
|
||||
debug a => _19;
|
||||
debug b => _20;
|
||||
debug c => _21;
|
||||
debug a3 => _19;
|
||||
debug b3 => _20;
|
||||
debug c3 => _21;
|
||||
let _23: f32;
|
||||
let _24: std::option::Option<S>;
|
||||
let _25: &[f32];
|
||||
scope 8 {
|
||||
debug a => _23;
|
||||
debug b => _24;
|
||||
debug c => _25;
|
||||
debug a4 => _23;
|
||||
debug b4 => _24;
|
||||
debug c4 => _25;
|
||||
let _27: BigStruct;
|
||||
scope 9 {
|
||||
debug bs => _27;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
@ -12,27 +11,69 @@ struct SmallStruct(f32, Option<S>, &'static [f32]);
|
||||
struct BigStruct(f32, Option<S>, &'static [f32]);
|
||||
|
||||
// EMIT_MIR struct.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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);
|
||||
|
||||
// CHECK: [[a]] = const 3_i32;
|
||||
let a = s.0 + 2;
|
||||
s.0 = 3;
|
||||
|
||||
// CHECK: [[b]] = const 6_i32;
|
||||
let b = a + s.0;
|
||||
|
||||
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.]);
|
||||
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, &[]);
|
||||
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.]);
|
||||
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.
|
||||
// `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
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
fn foo(n: i32) {}
|
||||
|
||||
// EMIT_MIR terminator.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
let a = 1;
|
||||
// Checks that we propagate into terminators.
|
||||
// CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind
|
||||
foo(a + 1);
|
||||
}
|
||||
|
@ -1,13 +1,27 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR tuple.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: 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);
|
||||
|
||||
// CHECK: [[b]] = const 6_i32;
|
||||
let b = a.0 + a.1 + 3;
|
||||
|
||||
// CHECK: [[a]] = const (2_i32, 3_i32);
|
||||
a = (2, 3);
|
||||
|
||||
// CHECK: [[c]] = const 11_i32;
|
||||
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);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ LL | type Ty = Vec<[u8]>;
|
||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Vec`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
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> {
|
||||
| ^^^^^^^^^^ 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
|
||||
|
|
||||
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`
|
||||
|
|
||||
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> {}
|
||||
| ^^^^^^^^^^^^^^^^ 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
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
|
@ -17,7 +17,7 @@ LL | println!("{:?}", foo);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= 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
|
||||
= 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<_>() {}
|
||||
| ^ 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
|
||||
|
|
||||
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: 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
|
||||
--> $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
|
||||
= 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
|
||||
|
|
||||
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`
|
||||
|
||||
|
@ -7,14 +7,14 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }],
|
||||
= note: type parameters may not be used in 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -16,14 +16,14 @@ LL | let b = &*(&x as *const _ as *const S);
|
||||
= note: type parameters may not be used in 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -7,14 +7,14 @@ LL | let x: Option<S> = None;
|
||||
= note: type parameters may not be used in 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -7,14 +7,14 @@ LL | let x: Option<Box<S>> = None;
|
||||
= note: type parameters may not be used in 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -1,4 +1,27 @@
|
||||
#![crate_type="lib"]
|
||||
|
||||
struct Example<N>;
|
||||
//~^ ERROR parameter
|
||||
struct S<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:
|
||||
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
|
||||
--> $DIR/unused-type-param-suggestion.rs:3:16
|
||||
error[E0392]: type parameter `N` is never used
|
||||
--> $DIR/unused-type-param-suggestion.rs:3:10
|
||||
|
|
||||
LL | struct Example<N>;
|
||||
| ^ unused parameter
|
||||
LL | struct S<N>;
|
||||
| ^ unused type parameter
|
||||
|
|
||||
= 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)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 { (|| {})() } => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -18,7 +18,7 @@ LL | Pin::new(&mut gen).resume(());
|
||||
| ^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= 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
|
||||
|
||||
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
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
||||
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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -6,14 +6,14 @@ LL | let x: S = 0;
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -6,14 +6,14 @@ LL | Var = type_ascribe!(0, S),
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -1,14 +1,20 @@
|
||||
error[E0091]: type parameter `T` is unused
|
||||
error[E0091]: type parameter `T` is never used
|
||||
--> $DIR/E0091.rs:1:10
|
||||
|
|
||||
LL | type Foo<T> = u32;
|
||||
| ^ 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
|
||||
|
|
||||
LL | type Foo2<A, B> = Box<A>;
|
||||
| ^ 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
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0392]: parameter `T` is never used
|
||||
error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/E0392.rs:1:10
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
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
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | fn assert_sized<T: ?Sized>() {}
|
||||
@ -27,11 +27,11 @@ note: required because it appears within the type `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
|
||||
|
|
||||
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
|
||||
|
|
||||
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> {
|
||||
| ^^^
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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> {
|
||||
| ^^^
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | fn assert_sized<T: ?Sized>() {}
|
||||
|
@ -13,5 +13,14 @@ impl Foo for Meeshka {
|
||||
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() {
|
||||
}
|
||||
|
@ -48,6 +48,36 @@ LL | type Wub = !;
|
||||
= 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 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`.
|
||||
|
@ -7,11 +7,11 @@ LL | type SearchFutureTy<'f, A, B: 'f>
|
||||
LL | async move { todo!() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
|
||||
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`
|
||||
|
|
||||
LL - A: SearchableResource<B> + ?Sized + 'f,
|
||||
|
@ -6,10 +6,10 @@ LL | impl Tsized for () {}
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[()]`
|
||||
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]> {}
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Tsized`
|
||||
| ^^^^^ required by this bound in `Tsized`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// run-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
|
@ -5,7 +5,7 @@ LL | fn nya() -> impl Wf<Vec<[u8]>>;
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Vec`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
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
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
= 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
|
||||
|
||||
error[E0277]: `T` doesn't implement `std::fmt::Display`
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
// 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
|
||||
--> $DIR/const-match-pat-generic.rs:8:9
|
||||
--> $DIR/const-match-pat-generic.rs:7:9
|
||||
|
|
||||
LL | const { V } => {},
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
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) } => {},
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,7 +1,6 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(inline_const_pat)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
match 1u64 {
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
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>() {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -15,7 +15,7 @@ LL | }
|
||||
| - `y` dropped here while still borrowed
|
||||
|
||||
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>() {
|
||||
| -- lifetime `'a` defined here
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(inline_const)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
@ -1,6 +1,5 @@
|
||||
// build-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(inline_const_pat, exclusive_range_pattern)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(inline_const_pat)]
|
||||
const MMIO_BIT1: u8 = 4;
|
||||
const MMIO_BIT2: u8 = 5;
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![feature(inline_const_pat)]
|
||||
//~^ WARN the feature `inline_const_pat` is incomplete
|
||||
|
||||
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
|
||||
--> $DIR/pat-match-fndef.rs:9:9
|
||||
--> $DIR/pat-match-fndef.rs:8:9
|
||||
|
|
||||
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)]
|
||||
|
||||
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
|
||||
--> $DIR/pat-unsafe-err.rs:11:13
|
||||
--> $DIR/pat-unsafe-err.rs:10:13
|
||||
|
|
||||
LL | require_unsafe();
|
||||
| ^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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()
|
||||
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
@ -1,6 +1,5 @@
|
||||
// check-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![warn(unused_unsafe)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
warning: unnecessary `unsafe` block
|
||||
--> $DIR/pat-unsafe.rs:16:17
|
||||
--> $DIR/pat-unsafe.rs:15:17
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/pat-unsafe.rs:4:9
|
||||
--> $DIR/pat-unsafe.rs:3:9
|
||||
|
|
||||
LL | #![warn(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unnecessary `unsafe` block
|
||||
--> $DIR/pat-unsafe.rs:23:17
|
||||
--> $DIR/pat-unsafe.rs:22:17
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
@ -6,14 +6,14 @@ LL | fn foo<T>() {
|
||||
LL | static a: Bar<T> = Bar::What;
|
||||
| ^ 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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -58,11 +58,11 @@ LL | impl<'self> Serializable<str> for &'self str {
|
||||
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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`
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
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() {}
|
||||
|
@ -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
|
||||
|
|
||||
LL | type Huh<T> where T: Tr = isize;
|
||||
| ^ 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
|
||||
|
||||
|
@ -5,11 +5,11 @@ LL | fn ho_func(f: Option<FuncType>) {
|
||||
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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>`
|
||||
--> $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
|
||||
|
|
||||
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: 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`
|
||||
--> $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
|
||||
|
|
||||
= 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
|
||||
|
||||
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
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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>`
|
||||
--> $DIR/issue-23281.rs:8:12
|
||||
|
|
||||
|
@ -1,5 +1,5 @@
|
||||
type Foo<
|
||||
Unused //~ ERROR type parameter `Unused` is unused
|
||||
Unused //~ ERROR type parameter `Unused` is never used
|
||||
> = u8;
|
||||
|
||||
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
|
||||
|
|
||||
LL | Unused
|
||||
| ^^^^^^ 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
|
||||
|
||||
|
@ -4,11 +4,11 @@ error[E0308]: mismatched types
|
||||
LL | X = Trait::Number,
|
||||
| ^^^^^^^^^^^^^ 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
|
||||
|
|
||||
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`
|
||||
|
||||
|
@ -45,14 +45,14 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
|
||||
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
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
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`
|
||||
|
||||
error[E0392]: parameter `A` is never used
|
||||
error[E0392]: type parameter `A` is never used
|
||||
--> $DIR/issue-36299.rs:1:16
|
||||
|
|
||||
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: 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
|
||||
|
||||
|
@ -15,11 +15,11 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
|
||||
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
|
||||
|
|
||||
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`
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user