Auto merge of #127936 - matthiaskrgr:rollup-ci0eg7k, r=tgross35

Rollup of 8 pull requests

Successful merges:

 - #127418 (Wrap too long type name)
 - #127594 (Fuchsia status code match arm)
 - #127835 (Fix ICE in suggestion caused by `⩵` being recovered as `==`)
 - #127858 (match lowering: Rename `MatchPair` to `MatchPairTree`)
 - #127871 (Mention that type parameters are used recursively on bivariance error)
 - #127913 (remove `debug-logging` default from tools profile)
 - #127925 (Remove tag field from `Relation`s)
 - #127929 (Use more accurate span for `addr_of!` suggestion)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-19 02:05:32 +00:00
commit 3d68afc9e8
63 changed files with 447 additions and 247 deletions

View File

@ -313,10 +313,6 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
self.type_checker.infcx.tcx self.type_checker.infcx.tcx
} }
fn tag(&self) -> &'static str {
"nll::subtype"
}
#[instrument(skip(self, info), level = "trace", ret)] #[instrument(skip(self, info), level = "trace", ret)]
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>( fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
&mut self, &mut self,

View File

@ -382,6 +382,10 @@ hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is no
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
.label = `Self` is not a generic argument, but an alias to the type of the {$what} .label = `Self` is not a generic argument, but an alias to the type of the {$what}
hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is only used recursively
.label = {$param_def_kind} must be used non-recursively in the definition
.note = all type parameters must be used in a non-recursive way in order to constrain their variance
hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
.note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
@ -549,6 +553,8 @@ hir_analysis_unused_generic_parameter =
{$param_def_kind} `{$param_name}` is never used {$param_def_kind} `{$param_name}` is never used
.label = unused {$param_def_kind} .label = unused {$param_def_kind}
.const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead .const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead
.usage_spans = `{$param_name}` is named here, but is likely unused in the containing type
hir_analysis_unused_generic_parameter_adt_help = 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}` 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 = hir_analysis_unused_generic_parameter_adt_no_phantom_data_help =

View File

@ -1572,6 +1572,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
param_name, param_name,
param_def_kind: tcx.def_descr(param.def_id), param_def_kind: tcx.def_descr(param.def_id),
help: errors::UnusedGenericParameterHelp::TyAlias { param_name }, help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
usage_spans: vec![],
const_param_help, const_param_help,
}); });
diag.code(E0091); diag.code(E0091);

View File

@ -1,5 +1,4 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir_pretty::qpath_to_string;
use rustc_lint_defs::builtin::STATIC_MUT_REFS; use rustc_lint_defs::builtin::STATIC_MUT_REFS;
use rustc_middle::ty::{Mutability, TyCtxt}; use rustc_middle::ty::{Mutability, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
@ -12,9 +11,17 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
let hir_id = expr.hir_id; let hir_id = expr.hir_id;
if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind
&& matches!(borrow_kind, hir::BorrowKind::Ref) && matches!(borrow_kind, hir::BorrowKind::Ref)
&& let Some(var) = path_if_static_mut(tcx, expr) && path_if_static_mut(expr)
{ {
handle_static_mut_ref(tcx, span, var, span.edition().at_least_rust_2024(), m, hir_id); handle_static_mut_ref(
tcx,
span,
span.with_hi(expr.span.lo()),
span.shrink_to_hi(),
span.edition().at_least_rust_2024(),
m,
hir_id,
);
} }
} }
@ -24,12 +31,13 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
&& let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
&& let hir::ByRef::Yes(rmutbl) = ba.0 && let hir::ByRef::Yes(rmutbl) = ba.0
&& let Some(init) = loc.init && let Some(init) = loc.init
&& let Some(var) = path_if_static_mut(tcx, init) && path_if_static_mut(init)
{ {
handle_static_mut_ref( handle_static_mut_ref(
tcx, tcx,
init.span, init.span,
var, init.span.shrink_to_lo(),
init.span.shrink_to_hi(),
loc.span.edition().at_least_rust_2024(), loc.span.edition().at_least_rust_2024(),
rmutbl, rmutbl,
stmt.hir_id, stmt.hir_id,
@ -37,38 +45,39 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
} }
} }
fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option<String> { fn path_if_static_mut(expr: &hir::Expr<'_>) -> bool {
if let hir::ExprKind::Path(qpath) = expr.kind if let hir::ExprKind::Path(qpath) = expr.kind
&& let hir::QPath::Resolved(_, path) = qpath && let hir::QPath::Resolved(_, path) = qpath
&& let hir::def::Res::Def(def_kind, _) = path.res && let hir::def::Res::Def(def_kind, _) = path.res
&& let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } = && let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
def_kind def_kind
{ {
return Some(qpath_to_string(&tcx, &qpath)); return true;
} }
None false
} }
fn handle_static_mut_ref( fn handle_static_mut_ref(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
span: Span, span: Span,
var: String, lo: Span,
hi: Span,
e2024: bool, e2024: bool,
mutable: Mutability, mutable: Mutability,
hir_id: hir::HirId, hir_id: hir::HirId,
) { ) {
if e2024 { if e2024 {
let (sugg, shared) = if mutable == Mutability::Mut { let (sugg, shared) = if mutable == Mutability::Mut {
(errors::StaticMutRefSugg::Mut { span, var }, "mutable") (errors::MutRefSugg::Mut { lo, hi }, "mutable")
} else { } else {
(errors::StaticMutRefSugg::Shared { span, var }, "shared") (errors::MutRefSugg::Shared { lo, hi }, "shared")
}; };
tcx.dcx().emit_err(errors::StaticMutRef { span, sugg, shared }); tcx.dcx().emit_err(errors::StaticMutRef { span, sugg, shared });
} else { } else {
let (sugg, shared) = if mutable == Mutability::Mut { let (sugg, shared) = if mutable == Mutability::Mut {
(errors::RefOfMutStaticSugg::Mut { span, var }, "mutable") (errors::MutRefSugg::Mut { lo, hi }, "mutable")
} else { } else {
(errors::RefOfMutStaticSugg::Shared { span, var }, "shared") (errors::MutRefSugg::Shared { lo, hi }, "shared")
}; };
tcx.emit_node_span_lint( tcx.emit_node_span_lint(
STATIC_MUT_REFS, STATIC_MUT_REFS,

View File

@ -4,12 +4,12 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
use crate::errors; use crate::errors;
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use hir::intravisit::Visitor; use hir::intravisit::{self, Visitor};
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::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::{DefKind, Res};
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;
use rustc_hir::ItemKind; use rustc_hir::ItemKind;
@ -1799,7 +1799,7 @@ fn receiver_is_implemented<'tcx>(
fn check_variances_for_type_defn<'tcx>( fn check_variances_for_type_defn<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
item: &hir::Item<'tcx>, item: &'tcx hir::Item<'tcx>,
hir_generics: &hir::Generics<'tcx>, hir_generics: &hir::Generics<'tcx>,
) { ) {
let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id);
@ -1886,21 +1886,21 @@ fn check_variances_for_type_defn<'tcx>(
hir::ParamName::Error => {} hir::ParamName::Error => {}
_ => { _ => {
let has_explicit_bounds = explicitly_bounded_params.contains(&parameter); let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind); report_bivariance(tcx, hir_param, has_explicit_bounds, item);
} }
} }
} }
} }
fn report_bivariance( fn report_bivariance<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
param: &rustc_hir::GenericParam<'_>, param: &'tcx hir::GenericParam<'tcx>,
has_explicit_bounds: bool, has_explicit_bounds: bool,
item_kind: ItemKind<'_>, item: &'tcx hir::Item<'tcx>,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
let param_name = param.name.ident(); let param_name = param.name.ident();
let help = match item_kind { let help = match item.kind {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
if let Some(def_id) = tcx.lang_items().phantom_data() { if let Some(def_id) = tcx.lang_items().phantom_data() {
errors::UnusedGenericParameterHelp::Adt { errors::UnusedGenericParameterHelp::Adt {
@ -1915,6 +1915,49 @@ fn report_bivariance(
item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"), item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
}; };
let mut usage_spans = vec![];
intravisit::walk_item(
&mut CollectUsageSpans { spans: &mut usage_spans, param_def_id: param.def_id.to_def_id() },
item,
);
if !usage_spans.is_empty() {
// First, check if the ADT is (probably) cyclical. We say probably here, since
// we're not actually looking into substitutions, just walking through fields.
// And we only recurse into the fields of ADTs, and not the hidden types of
// opaques or anything else fancy.
let item_def_id = item.owner_id.to_def_id();
let is_probably_cyclical = if matches!(
tcx.def_kind(item_def_id),
DefKind::Struct | DefKind::Union | DefKind::Enum
) {
IsProbablyCyclical { tcx, adt_def_id: item_def_id, seen: Default::default() }
.visit_all_fields(tcx.adt_def(item_def_id))
.is_break()
} else {
false
};
// If the ADT is cyclical, then if at least one usage of the type parameter or
// the `Self` alias is present in the, then it's probably a cyclical struct, and
// we should call those parameter usages recursive rather than just saying they're
// unused...
//
// We currently report *all* of the parameter usages, since computing the exact
// subset is very involved, and the fact we're mentioning recursion at all is
// likely to guide the user in the right direction.
if is_probably_cyclical {
let diag = tcx.dcx().create_err(errors::RecursiveGenericParameter {
spans: usage_spans,
param_span: param.span,
param_name,
param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
help,
note: (),
});
return diag.emit();
}
}
let const_param_help = let const_param_help =
matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds) matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
.then_some(()); .then_some(());
@ -1923,6 +1966,7 @@ fn report_bivariance(
span: param.span, span: param.span,
param_name, param_name,
param_def_kind: tcx.def_descr(param.def_id.to_def_id()), param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
usage_spans,
help, help,
const_param_help, const_param_help,
}); });
@ -1930,6 +1974,77 @@ fn report_bivariance(
diag.emit() diag.emit()
} }
/// Detects cases where an ADT is trivially cyclical -- we want to detect this so
/// /we only mention that its parameters are used cyclically if the ADT is truly
/// cyclical.
///
/// Notably, we don't consider substitutions here, so this may have false positives.
struct IsProbablyCyclical<'tcx> {
tcx: TyCtxt<'tcx>,
adt_def_id: DefId,
seen: FxHashSet<DefId>,
}
impl<'tcx> IsProbablyCyclical<'tcx> {
fn visit_all_fields(&mut self, adt_def: ty::AdtDef<'tcx>) -> ControlFlow<(), ()> {
for field in adt_def.all_fields() {
self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?;
}
ControlFlow::Continue(())
}
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
type Result = ControlFlow<(), ()>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<(), ()> {
if let Some(adt_def) = t.ty_adt_def() {
if adt_def.did() == self.adt_def_id {
return ControlFlow::Break(());
}
if self.seen.insert(adt_def.did()) {
self.visit_all_fields(adt_def)?;
}
}
t.super_visit_with(self)
}
}
/// Collect usages of the `param_def_id` and `Res::SelfTyAlias` in the HIR.
///
/// This is used to report places where the user has used parameters in a
/// non-variance-constraining way for better bivariance errors.
struct CollectUsageSpans<'a> {
spans: &'a mut Vec<Span>,
param_def_id: DefId,
}
impl<'tcx> Visitor<'tcx> for CollectUsageSpans<'_> {
type Result = ();
fn visit_generics(&mut self, _g: &'tcx rustc_hir::Generics<'tcx>) -> Self::Result {
// Skip the generics. We only care about fields, not where clause/param bounds.
}
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result {
if let hir::TyKind::Path(hir::QPath::Resolved(None, qpath)) = t.kind {
if let Res::Def(DefKind::TyParam, def_id) = qpath.res
&& def_id == self.param_def_id
{
self.spans.push(t.span);
return;
} else if let Res::SelfTyAlias { .. } = qpath.res {
self.spans.push(t.span);
return;
}
}
intravisit::walk_ty(self, t);
}
}
impl<'tcx> WfCheckingCtxt<'_, 'tcx> { impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
/// aren't true. /// aren't true.

View File

@ -1500,33 +1500,33 @@ pub struct StaticMutRef<'a> {
#[label] #[label]
pub span: Span, pub span: Span,
#[subdiagnostic] #[subdiagnostic]
pub sugg: StaticMutRefSugg, pub sugg: MutRefSugg,
pub shared: &'a str, pub shared: &'a str,
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub enum StaticMutRefSugg { pub enum MutRefSugg {
#[suggestion( #[multipart_suggestion(
hir_analysis_suggestion, hir_analysis_suggestion,
style = "verbose", style = "verbose",
code = "addr_of!({var})",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
Shared { Shared {
#[primary_span] #[suggestion_part(code = "addr_of!(")]
span: Span, lo: Span,
var: String, #[suggestion_part(code = ")")]
hi: Span,
}, },
#[suggestion( #[multipart_suggestion(
hir_analysis_suggestion_mut, hir_analysis_suggestion_mut,
style = "verbose", style = "verbose",
code = "addr_of_mut!({var})",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
Mut { Mut {
#[primary_span] #[suggestion_part(code = "addr_of_mut!(")]
span: Span, lo: Span,
var: String, #[suggestion_part(code = ")")]
hi: Span,
}, },
} }
@ -1539,36 +1539,10 @@ pub struct RefOfMutStatic<'a> {
#[label] #[label]
pub span: Span, pub span: Span,
#[subdiagnostic] #[subdiagnostic]
pub sugg: RefOfMutStaticSugg, pub sugg: MutRefSugg,
pub shared: &'a str, pub shared: &'a str,
} }
#[derive(Subdiagnostic)]
pub enum RefOfMutStaticSugg {
#[suggestion(
hir_analysis_suggestion,
style = "verbose",
code = "addr_of!({var})",
applicability = "maybe-incorrect"
)]
Shared {
#[primary_span]
span: Span,
var: String,
},
#[suggestion(
hir_analysis_suggestion_mut,
style = "verbose",
code = "addr_of_mut!({var})",
applicability = "maybe-incorrect"
)]
Mut {
#[primary_span]
span: Span,
var: String,
},
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(hir_analysis_not_supported_delegation)] #[diag(hir_analysis_not_supported_delegation)]
pub struct NotSupportedDelegation<'a> { pub struct NotSupportedDelegation<'a> {
@ -1597,12 +1571,29 @@ pub(crate) struct UnusedGenericParameter {
pub span: Span, pub span: Span,
pub param_name: Ident, pub param_name: Ident,
pub param_def_kind: &'static str, pub param_def_kind: &'static str,
#[label(hir_analysis_usage_spans)]
pub usage_spans: Vec<Span>,
#[subdiagnostic] #[subdiagnostic]
pub help: UnusedGenericParameterHelp, pub help: UnusedGenericParameterHelp,
#[help(hir_analysis_const_param_help)] #[help(hir_analysis_const_param_help)]
pub const_param_help: Option<()>, pub const_param_help: Option<()>,
} }
#[derive(Diagnostic)]
#[diag(hir_analysis_recursive_generic_parameter)]
pub(crate) struct RecursiveGenericParameter {
#[primary_span]
pub spans: Vec<Span>,
#[label]
pub param_span: Span,
pub param_name: Ident,
pub param_def_kind: &'static str,
#[subdiagnostic]
pub help: UnusedGenericParameterHelp,
#[note]
pub note: (),
}
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub(crate) enum UnusedGenericParameterHelp { pub(crate) enum UnusedGenericParameterHelp {
#[help(hir_analysis_unused_generic_parameter_adt_help)] #[help(hir_analysis_unused_generic_parameter_adt_help)]

View File

@ -1934,10 +1934,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for SameTypeModuloInfer<'_, 'tcx> {
self.0.tcx self.0.tcx
} }
fn tag(&self) -> &'static str {
"SameTypeModuloInfer"
}
fn relate_with_variance<T: relate::Relate<TyCtxt<'tcx>>>( fn relate_with_variance<T: relate::Relate<TyCtxt<'tcx>>>(
&mut self, &mut self,
_variance: ty::Variance, _variance: ty::Variance,

View File

@ -110,7 +110,7 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
/// Binds the pattern variable `br` to `value`; returns an `Err` if the pattern /// Binds the pattern variable `br` to `value`; returns an `Err` if the pattern
/// is already bound to a different value. /// is already bound to a different value.
#[instrument(level = "debug", skip(self))] #[instrument(level = "trace", skip(self))]
fn bind( fn bind(
&mut self, &mut self,
br: ty::BoundRegion, br: ty::BoundRegion,
@ -133,10 +133,6 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
} }
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx> { impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx> {
fn tag(&self) -> &'static str {
"MatchAgainstHigherRankedOutlives"
}
fn cx(&self) -> TyCtxt<'tcx> { fn cx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -154,13 +150,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
if variance != ty::Bivariant { self.relate(a, b) } else { Ok(a) } if variance != ty::Bivariant { self.relate(a, b) } else { Ok(a) }
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn regions( fn regions(
&mut self, &mut self,
pattern: ty::Region<'tcx>, pattern: ty::Region<'tcx>,
value: ty::Region<'tcx>, value: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> { ) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("self.pattern_depth = {:?}", self.pattern_depth);
if let ty::RegionKind::ReBound(depth, br) = pattern.kind() if let ty::RegionKind::ReBound(depth, br) = pattern.kind()
&& depth == self.pattern_depth && depth == self.pattern_depth
{ {
@ -172,7 +167,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
} }
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
// FIXME(non_lifetime_binders): What to do here? // FIXME(non_lifetime_binders): What to do here?
if matches!(pattern.kind(), ty::Error(_) | ty::Bound(..)) { if matches!(pattern.kind(), ty::Error(_) | ty::Bound(..)) {
@ -185,13 +180,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
} }
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn consts( fn consts(
&mut self, &mut self,
pattern: ty::Const<'tcx>, pattern: ty::Const<'tcx>,
value: ty::Const<'tcx>, value: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), pattern, value);
if pattern == value { if pattern == value {
Ok(pattern) Ok(pattern)
} else { } else {
@ -199,6 +193,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
} }
} }
#[instrument(skip(self), level = "trace")]
fn binders<T>( fn binders<T>(
&mut self, &mut self,
pattern: ty::Binder<'tcx, T>, pattern: ty::Binder<'tcx, T>,

View File

@ -79,6 +79,7 @@ impl<'tcx> InferCtxt<'tcx> {
where where
R: PredicateEmittingRelation<InferCtxt<'tcx>>, R: PredicateEmittingRelation<InferCtxt<'tcx>>,
{ {
debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars());
@ -174,9 +175,10 @@ impl<'tcx> InferCtxt<'tcx> {
where where
R: PredicateEmittingRelation<InferCtxt<'tcx>>, R: PredicateEmittingRelation<InferCtxt<'tcx>>,
{ {
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars());
if a == b { if a == b {
return Ok(a); return Ok(a);
} }

View File

@ -401,10 +401,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
self.infcx.tcx self.infcx.tcx
} }
fn tag(&self) -> &'static str {
"Generalizer"
}
fn relate_item_args( fn relate_item_args(
&mut self, &mut self,
item_def_id: DefId, item_def_id: DefId,

View File

@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
} }
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> { impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"Glb"
}
fn cx(&self) -> TyCtxt<'tcx> { fn cx(&self) -> TyCtxt<'tcx> {
self.fields.tcx() self.fields.tcx()
} }
@ -47,17 +43,17 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
} }
} }
#[instrument(skip(self), level = "trace")]
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
lattice::super_lattice_tys(self, a, b) lattice::super_lattice_tys(self, a, b)
} }
#[instrument(skip(self), level = "trace")]
fn regions( fn regions(
&mut self, &mut self,
a: ty::Region<'tcx>, a: ty::Region<'tcx>,
b: ty::Region<'tcx>, b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> { ) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8 // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions( Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
@ -68,6 +64,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
)) ))
} }
#[instrument(skip(self), level = "trace")]
fn consts( fn consts(
&mut self, &mut self,
a: ty::Const<'tcx>, a: ty::Const<'tcx>,

View File

@ -56,8 +56,6 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
where where
L: LatticeDir<'a, 'tcx>, L: LatticeDir<'a, 'tcx>,
{ {
debug!("{}", this.tag());
if a == b { if a == b {
return Ok(a); return Ok(a);
} }

View File

@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
} }
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> { impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"Lub"
}
fn cx(&self) -> TyCtxt<'tcx> { fn cx(&self) -> TyCtxt<'tcx> {
self.fields.tcx() self.fields.tcx()
} }
@ -51,13 +47,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
lattice::super_lattice_tys(self, a, b) lattice::super_lattice_tys(self, a, b)
} }
#[instrument(skip(self), level = "trace")]
fn regions( fn regions(
&mut self, &mut self,
a: ty::Region<'tcx>, a: ty::Region<'tcx>,
b: ty::Region<'tcx>, b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> { ) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
// LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8 // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions( Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
@ -68,6 +63,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
)) ))
} }
#[instrument(skip(self), level = "trace")]
fn consts( fn consts(
&mut self, &mut self,
a: ty::Const<'tcx>, a: ty::Const<'tcx>,

View File

@ -28,10 +28,6 @@ impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
} }
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"TypeRelating"
}
fn cx(&self) -> TyCtxt<'tcx> { fn cx(&self) -> TyCtxt<'tcx> {
self.fields.infcx.tcx self.fields.infcx.tcx
} }
@ -71,7 +67,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
r r
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
if a == b { if a == b {
return Ok(a); return Ok(a);
@ -166,12 +162,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
Ok(a) Ok(a)
} }
#[instrument(skip(self), level = "trace")]
fn regions( fn regions(
&mut self, &mut self,
a: ty::Region<'tcx>, a: ty::Region<'tcx>,
b: ty::Region<'tcx>, b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> { ) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
match self.ambient_variance { match self.ambient_variance {
@ -209,6 +205,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
Ok(a) Ok(a)
} }
#[instrument(skip(self), level = "trace")]
fn consts( fn consts(
&mut self, &mut self,
a: ty::Const<'tcx>, a: ty::Const<'tcx>,

View File

@ -3,37 +3,37 @@ use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
use crate::build::matches::{FlatPat, MatchPair, TestCase}; use crate::build::matches::{FlatPat, MatchPairTree, TestCase};
use crate::build::Builder; use crate::build::Builder;
impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Builds and returns [`MatchPair`] trees, one for each pattern in /// Builds and returns [`MatchPairTree`] subtrees, one for each pattern in
/// `subpatterns`, representing the fields of a [`PatKind::Variant`] or /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
/// [`PatKind::Leaf`]. /// [`PatKind::Leaf`].
/// ///
/// Used internally by [`MatchPair::new`]. /// Used internally by [`MatchPairTree::for_pattern`].
fn field_match_pairs<'pat>( fn field_match_pairs<'pat>(
&mut self, &mut self,
place: PlaceBuilder<'tcx>, place: PlaceBuilder<'tcx>,
subpatterns: &'pat [FieldPat<'tcx>], subpatterns: &'pat [FieldPat<'tcx>],
) -> Vec<MatchPair<'pat, 'tcx>> { ) -> Vec<MatchPairTree<'pat, 'tcx>> {
subpatterns subpatterns
.iter() .iter()
.map(|fieldpat| { .map(|fieldpat| {
let place = let place =
place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
MatchPair::new(place, &fieldpat.pattern, self) MatchPairTree::for_pattern(place, &fieldpat.pattern, self)
}) })
.collect() .collect()
} }
/// Builds [`MatchPair`] trees for the prefix/middle/suffix parts of an /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
/// array pattern or slice pattern, and adds those trees to `match_pairs`. /// array pattern or slice pattern, and adds those trees to `match_pairs`.
/// ///
/// Used internally by [`MatchPair::new`]. /// Used internally by [`MatchPairTree::for_pattern`].
fn prefix_slice_suffix<'pat>( fn prefix_slice_suffix<'pat>(
&mut self, &mut self,
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
place: &PlaceBuilder<'tcx>, place: &PlaceBuilder<'tcx>,
prefix: &'pat [Box<Pat<'tcx>>], prefix: &'pat [Box<Pat<'tcx>>],
opt_slice: &'pat Option<Box<Pat<'tcx>>>, opt_slice: &'pat Option<Box<Pat<'tcx>>>,
@ -52,7 +52,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| { match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
let elem = let elem =
ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false };
MatchPair::new(place.clone_project(elem), subpattern, self) MatchPairTree::for_pattern(place.clone_project(elem), subpattern, self)
})); }));
if let Some(subslice_pat) = opt_slice { if let Some(subslice_pat) = opt_slice {
@ -62,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
to: if exact_size { min_length - suffix_len } else { suffix_len }, to: if exact_size { min_length - suffix_len } else { suffix_len },
from_end: !exact_size, from_end: !exact_size,
}); });
match_pairs.push(MatchPair::new(subslice, subslice_pat, self)); match_pairs.push(MatchPairTree::for_pattern(subslice, subslice_pat, self));
} }
match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| { match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| {
@ -73,19 +73,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
from_end: !exact_size, from_end: !exact_size,
}; };
let place = place.clone_project(elem); let place = place.clone_project(elem);
MatchPair::new(place, subpattern, self) MatchPairTree::for_pattern(place, subpattern, self)
})); }));
} }
} }
impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
/// Recursively builds a `MatchPair` tree for the given pattern and its /// Recursively builds a match pair tree for the given pattern and its
/// subpatterns. /// subpatterns.
pub(in crate::build) fn new( pub(in crate::build) fn for_pattern(
mut place_builder: PlaceBuilder<'tcx>, mut place_builder: PlaceBuilder<'tcx>,
pattern: &'pat Pat<'tcx>, pattern: &'pat Pat<'tcx>,
cx: &mut Builder<'_, 'tcx>, cx: &mut Builder<'_, 'tcx>,
) -> MatchPair<'pat, 'tcx> { ) -> MatchPairTree<'pat, 'tcx> {
// Force the place type to the pattern's type. // Force the place type to the pattern's type.
// FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
if let Some(resolved) = place_builder.resolve_upvar(cx) { if let Some(resolved) = place_builder.resolve_upvar(cx) {
@ -138,7 +138,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
variance, variance,
}); });
subpairs.push(MatchPair::new(place_builder, subpattern, cx)); subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
TestCase::Irrefutable { ascription, binding: None } TestCase::Irrefutable { ascription, binding: None }
} }
@ -152,7 +152,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
if let Some(subpattern) = subpattern.as_ref() { if let Some(subpattern) = subpattern.as_ref() {
// this is the `x @ P` case; have to keep matching against `P` now // this is the `x @ P` case; have to keep matching against `P` now
subpairs.push(MatchPair::new(place_builder, subpattern, cx)); subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
} }
TestCase::Irrefutable { ascription: None, binding } TestCase::Irrefutable { ascription: None, binding }
} }
@ -182,7 +182,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
super::Ascription { annotation, source, variance: ty::Contravariant } super::Ascription { annotation, source, variance: ty::Contravariant }
}); });
subpairs.push(MatchPair::new(place_builder, pattern, cx)); subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
TestCase::Irrefutable { ascription, binding: None } TestCase::Irrefutable { ascription, binding: None }
} }
@ -231,7 +231,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
} }
PatKind::Deref { ref subpattern } => { PatKind::Deref { ref subpattern } => {
subpairs.push(MatchPair::new(place_builder.deref(), subpattern, cx)); subpairs.push(MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx));
default_irrefutable() default_irrefutable()
} }
@ -242,13 +242,17 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability), Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability),
pattern.span, pattern.span,
); );
subpairs.push(MatchPair::new(PlaceBuilder::from(temp).deref(), subpattern, cx)); subpairs.push(MatchPairTree::for_pattern(
PlaceBuilder::from(temp).deref(),
subpattern,
cx,
));
TestCase::Deref { temp, mutability } TestCase::Deref { temp, mutability }
} }
PatKind::Never => TestCase::Never, PatKind::Never => TestCase::Never,
}; };
MatchPair { place, test_case, subpairs, pattern } MatchPairTree { place, test_case, subpairs, pattern }
} }
} }

View File

@ -1032,15 +1032,15 @@ impl<'tcx> PatternExtraData<'tcx> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct FlatPat<'pat, 'tcx> { struct FlatPat<'pat, 'tcx> {
/// To match the pattern, all of these must be satisfied... /// To match the pattern, all of these must be satisfied...
// Invariant: all the `MatchPair`s are recursively simplified. // Invariant: all the match pairs are recursively simplified.
// Invariant: or-patterns must be sorted to the end. // Invariant: or-patterns must be sorted to the end.
match_pairs: Vec<MatchPair<'pat, 'tcx>>, match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,
extra_data: PatternExtraData<'tcx>, extra_data: PatternExtraData<'tcx>,
} }
impl<'tcx, 'pat> FlatPat<'pat, 'tcx> { impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
/// Creates a `FlatPat` containing a simplified [`MatchPair`] list/forest /// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest
/// for the given pattern. /// for the given pattern.
fn new( fn new(
place: PlaceBuilder<'tcx>, place: PlaceBuilder<'tcx>,
@ -1048,7 +1048,7 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
cx: &mut Builder<'_, 'tcx>, cx: &mut Builder<'_, 'tcx>,
) -> Self { ) -> Self {
// First, recursively build a tree of match pairs for the given pattern. // First, recursively build a tree of match pairs for the given pattern.
let mut match_pairs = vec![MatchPair::new(place, pattern, cx)]; let mut match_pairs = vec![MatchPairTree::for_pattern(place, pattern, cx)];
let mut extra_data = PatternExtraData { let mut extra_data = PatternExtraData {
span: pattern.span, span: pattern.span,
bindings: Vec::new(), bindings: Vec::new(),
@ -1065,9 +1065,9 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
#[derive(Debug)] #[derive(Debug)]
struct Candidate<'pat, 'tcx> { struct Candidate<'pat, 'tcx> {
/// For the candidate to match, all of these must be satisfied... /// For the candidate to match, all of these must be satisfied...
// Invariant: all the `MatchPair`s are recursively simplified. // Invariant: all the match pairs are recursively simplified.
// Invariant: or-patterns must be sorted at the end. // Invariant: or-patterns must be sorted at the end.
match_pairs: Vec<MatchPair<'pat, 'tcx>>, match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,
/// ...and if this is non-empty, one of these subcandidates also has to match... /// ...and if this is non-empty, one of these subcandidates also has to match...
// Invariant: at the end of the algorithm, this must never contain a `is_never` candidate // Invariant: at the end of the algorithm, this must never contain a `is_never` candidate
@ -1126,7 +1126,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
/// Returns whether the first match pair of this candidate is an or-pattern. /// Returns whether the first match pair of this candidate is an or-pattern.
fn starts_with_or_pattern(&self) -> bool { fn starts_with_or_pattern(&self) -> bool {
matches!(&*self.match_pairs, [MatchPair { test_case: TestCase::Or { .. }, .. }, ..]) matches!(&*self.match_pairs, [MatchPairTree { test_case: TestCase::Or { .. }, .. }, ..])
} }
/// Visit the leaf candidates (those with no subcandidates) contained in /// Visit the leaf candidates (those with no subcandidates) contained in
@ -1206,7 +1206,7 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> {
/// Each node also has a list of subpairs (possibly empty) that must also match, /// Each node also has a list of subpairs (possibly empty) that must also match,
/// and a reference to the THIR pattern it represents. /// and a reference to the THIR pattern it represents.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct MatchPair<'pat, 'tcx> { pub(crate) struct MatchPairTree<'pat, 'tcx> {
/// This place... /// This place...
/// ///
/// --- /// ---
@ -1629,7 +1629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn create_or_subcandidates<'pat>( fn create_or_subcandidates<'pat>(
&mut self, &mut self,
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
match_pair: MatchPair<'pat, 'tcx>, match_pair: MatchPairTree<'pat, 'tcx>,
) { ) {
let TestCase::Or { pats } = match_pair.test_case else { bug!() }; let TestCase::Or { pats } = match_pair.test_case else { bug!() };
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats); debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
@ -1813,8 +1813,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// [`Range`]: TestKind::Range /// [`Range`]: TestKind::Range
fn pick_test(&mut self, candidates: &[&mut Candidate<'_, 'tcx>]) -> (Place<'tcx>, Test<'tcx>) { fn pick_test(&mut self, candidates: &[&mut Candidate<'_, 'tcx>]) -> (Place<'tcx>, Test<'tcx>) {
// Extract the match-pair from the highest priority candidate // Extract the match-pair from the highest priority candidate
let match_pair = &candidates.first().unwrap().match_pairs[0]; let match_pair = &candidates[0].match_pairs[0];
let test = self.test(match_pair); let test = self.pick_test_for_match_pair(match_pair);
// Unwrap is ok after simplification. // Unwrap is ok after simplification.
let match_place = match_pair.place.unwrap(); let match_place = match_pair.place.unwrap();
debug!(?test, ?match_pair); debug!(?test, ?match_pair);

View File

@ -12,7 +12,7 @@
//! sort of test: for example, testing which variant an enum is, or //! sort of test: for example, testing which variant an enum is, or
//! testing a value against a constant. //! testing a value against a constant.
use crate::build::matches::{MatchPair, PatternExtraData, TestCase}; use crate::build::matches::{MatchPairTree, PatternExtraData, TestCase};
use crate::build::Builder; use crate::build::Builder;
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub(super) fn simplify_match_pairs<'pat>( pub(super) fn simplify_match_pairs<'pat>(
&mut self, &mut self,
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
extra_data: &mut PatternExtraData<'tcx>, extra_data: &mut PatternExtraData<'tcx>,
) { ) {
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the

View File

@ -5,7 +5,7 @@
// identify what tests are needed, perform the tests, and then filter // identify what tests are needed, perform the tests, and then filter
// the candidates based on the result. // the candidates based on the result.
use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, TestKind}; use crate::build::matches::{Candidate, MatchPairTree, Test, TestBranch, TestCase, TestKind};
use crate::build::Builder; use crate::build::Builder;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::{LangItem, RangeEnd}; use rustc_hir::{LangItem, RangeEnd};
@ -26,7 +26,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Identifies what test is needed to decide if `match_pair` is applicable. /// Identifies what test is needed to decide if `match_pair` is applicable.
/// ///
/// It is a bug to call this with a not-fully-simplified pattern. /// It is a bug to call this with a not-fully-simplified pattern.
pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { pub(super) fn pick_test_for_match_pair<'pat>(
&mut self,
match_pair: &MatchPairTree<'pat, 'tcx>,
) -> Test<'tcx> {
let kind = match match_pair.test_case { let kind = match match_pair.test_case {
TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def },

View File

@ -1,7 +1,7 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::build::expr::as_place::PlaceBase; use crate::build::expr::as_place::PlaceBase;
use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase}; use crate::build::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestCase};
use crate::build::Builder; use crate::build::Builder;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::mir::*; use rustc_middle::mir::*;
@ -152,7 +152,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
} }
} }
fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) { fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
if let TestCase::Or { pats, .. } = &match_pair.test_case { if let TestCase::Or { pats, .. } = &match_pair.test_case {
for flat_pat in pats.iter() { for flat_pat in pats.iter() {
self.visit_flat_pat(flat_pat) self.visit_flat_pat(flat_pat)
@ -260,7 +260,7 @@ where
} }
} }
fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) { fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
if let TestCase::Or { pats, .. } = &match_pair.test_case { if let TestCase::Or { pats, .. } = &match_pair.test_case {
// All the or-alternatives should bind the same locals, so we only visit the first one. // All the or-alternatives should bind the same locals, so we only visit the first one.
self.visit_flat_pat(&pats[0]) self.visit_flat_pat(&pats[0])

View File

@ -660,9 +660,8 @@ pub(crate) struct RemoveLet {
#[diag(parse_use_eq_instead)] #[diag(parse_use_eq_instead)]
pub(crate) struct UseEqInstead { pub(crate) struct UseEqInstead {
#[primary_span] #[primary_span]
#[suggestion(style = "verbose", applicability = "machine-applicable", code = "=")]
pub span: Span, pub span: Span,
#[suggestion(style = "verbose", applicability = "machine-applicable", code = "")]
pub suggestion: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View File

@ -566,10 +566,7 @@ impl<'a> Parser<'a> {
&& expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq))) && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
{ {
// Likely typo: `=` → `==` in let expr or enum item // Likely typo: `=` → `==` in let expr or enum item
return Err(self.dcx().create_err(UseEqInstead { return Err(self.dcx().create_err(UseEqInstead { span: self.token.span }));
span: self.token.span,
suggestion: self.token.span.with_lo(self.token.span.lo() + BytePos(1)),
}));
} }
if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) { if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) {

View File

@ -3,7 +3,7 @@ use rustc_infer::infer::relate::{
}; };
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use tracing::{debug, instrument}; use tracing::instrument;
/// A type "A" *matches* "B" if the fresh types in B could be /// A type "A" *matches* "B" if the fresh types in B could be
/// instantiated with values so as to make it equal to A. Matching is /// instantiated with values so as to make it equal to A. Matching is
@ -32,10 +32,6 @@ impl<'tcx> MatchAgainstFreshVars<'tcx> {
} }
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> { impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
fn tag(&self) -> &'static str {
"MatchAgainstFreshVars"
}
fn cx(&self) -> TyCtxt<'tcx> { fn cx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -50,7 +46,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
self.relate(a, b) self.relate(a, b)
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn regions( fn regions(
&mut self, &mut self,
a: ty::Region<'tcx>, a: ty::Region<'tcx>,
@ -59,7 +55,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
Ok(a) Ok(a)
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "trace")]
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
if a == b { if a == b {
return Ok(a); return Ok(a);
@ -83,12 +79,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
} }
} }
#[instrument(skip(self), level = "trace")]
fn consts( fn consts(
&mut self, &mut self,
a: ty::Const<'tcx>, a: ty::Const<'tcx>,
b: ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { if a == b {
return Ok(a); return Ok(a);
} }

View File

@ -1,7 +1,7 @@
use std::iter; use std::iter;
use rustc_ast_ir::Mutability; use rustc_ast_ir::Mutability;
use tracing::{debug, instrument}; use tracing::{instrument, trace};
use crate::error::{ExpectedFound, TypeError}; use crate::error::{ExpectedFound, TypeError};
use crate::fold::TypeFoldable; use crate::fold::TypeFoldable;
@ -58,9 +58,6 @@ impl<I: Interner> VarianceDiagInfo<I> {
pub trait TypeRelation<I: Interner>: Sized { pub trait TypeRelation<I: Interner>: Sized {
fn cx(&self) -> I; fn cx(&self) -> I;
/// Returns a static string we can use for printouts.
fn tag(&self) -> &'static str;
/// Generic relation routine suitable for most anything. /// Generic relation routine suitable for most anything.
fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> { fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> {
Relate::relate(self, a, b) Relate::relate(self, a, b)
@ -69,17 +66,13 @@ pub trait TypeRelation<I: Interner>: Sized {
/// Relate the two args for the given item. The default /// Relate the two args for the given item. The default
/// is to look up the variance for the item and proceed /// is to look up the variance for the item and proceed
/// accordingly. /// accordingly.
#[instrument(skip(self), level = "trace")]
fn relate_item_args( fn relate_item_args(
&mut self, &mut self,
item_def_id: I::DefId, item_def_id: I::DefId,
a_arg: I::GenericArgs, a_arg: I::GenericArgs,
b_arg: I::GenericArgs, b_arg: I::GenericArgs,
) -> RelateResult<I, I::GenericArgs> { ) -> RelateResult<I, I::GenericArgs> {
debug!(
"relate_item_args(item_def_id={:?}, a_arg={:?}, b_arg={:?})",
item_def_id, a_arg, b_arg
);
let cx = self.cx(); let cx = self.cx();
let opt_variances = cx.variances_of(item_def_id); let opt_variances = cx.variances_of(item_def_id);
relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true) relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
@ -571,7 +564,12 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
mut a: I::Const, mut a: I::Const,
mut b: I::Const, mut b: I::Const,
) -> RelateResult<I, I::Const> { ) -> RelateResult<I, I::Const> {
debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); trace!(
"structurally_relate_consts::<{}>(a = {:?}, b = {:?})",
std::any::type_name::<R>(),
a,
b
);
let cx = relation.cx(); let cx = relation.cx();
if cx.features().generic_const_exprs() { if cx.features().generic_const_exprs() {
@ -579,7 +577,12 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
b = cx.expand_abstract_consts(b); b = cx.expand_abstract_consts(b);
} }
debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b); trace!(
"structurally_relate_consts::<{}>(normed_a = {:?}, normed_b = {:?})",
std::any::type_name::<R>(),
a,
b
);
// Currently, the values that can be unified are primitive types, // Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding // and those that derive both `PartialEq` and `Eq`, corresponding

View File

@ -19,7 +19,15 @@ pub const TR_OK: i32 = 50;
// On Windows we use __fastfail to abort, which is documented to use this // On Windows we use __fastfail to abort, which is documented to use this
// exception code. // exception code.
#[cfg(windows)] #[cfg(windows)]
const STATUS_ABORTED: i32 = 0xC0000409u32 as i32; const STATUS_FAIL_FAST_EXCEPTION: i32 = 0xC0000409u32 as i32;
// On Zircon (the Fuchsia kernel), an abort from userspace calls the
// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
// raises a kernel exception. If a userspace process does not
// otherwise arrange exception handling, the kernel kills the process
// with this return code.
#[cfg(target_os = "fuchsia")]
const ZX_TASK_RETCODE_EXCEPTION_KILL: i32 = -1028;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum TestResult { pub enum TestResult {
@ -96,7 +104,7 @@ pub fn get_result_from_exit_code(
let result = match status.code() { let result = match status.code() {
Some(TR_OK) => TestResult::TrOk, Some(TR_OK) => TestResult::TrOk,
#[cfg(windows)] #[cfg(windows)]
Some(STATUS_ABORTED) => TestResult::TrFailed, Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed,
#[cfg(unix)] #[cfg(unix)]
None => match status.signal() { None => match status.signal() {
Some(libc::SIGABRT) => TestResult::TrFailed, Some(libc::SIGABRT) => TestResult::TrFailed,
@ -105,6 +113,9 @@ pub fn get_result_from_exit_code(
} }
None => unreachable!("status.code() returned None but status.signal() was None"), None => unreachable!("status.code() returned None but status.signal() was None"),
}, },
// Upon an abort, Fuchsia returns the status code ZX_TASK_RETCODE_EXCEPTION_KILL.
#[cfg(target_os = "fuchsia")]
Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => TestResult::TrFailed,
#[cfg(not(unix))] #[cfg(not(unix))]
None => TestResult::TrFailedMsg(format!("unknown return code")), None => TestResult::TrFailedMsg(format!("unknown return code")),
#[cfg(any(windows, unix))] #[cfg(any(windows, unix))]

View File

@ -1,10 +1,6 @@
# These defaults are meant for contributors to tools which build on the # These defaults are meant for contributors to tools which build on the
# compiler, but do not modify it directly. # compiler, but do not modify it directly.
[rust] [rust]
# This enables `RUSTC_LOG=debug`, avoiding confusing situations
# where adding `debug!()` appears to do nothing.
# However, it makes running the compiler slightly slower.
debug-logging = true
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
incremental = true incremental = true
# Download rustc from CI instead of building it from source. # Download rustc from CI instead of building it from source.

View File

@ -200,4 +200,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Warning, severity: ChangeSeverity::Warning,
summary: "`llvm.lld` is enabled by default for the dist profile. If set to false, `lld` will not be included in the dist build.", summary: "`llvm.lld` is enabled by default for the dist profile. If set to false, `lld` will not be included in the dist build.",
}, },
ChangeInfo {
change_id: 127913,
severity: ChangeSeverity::Warning,
summary: "`debug-logging` option has been removed from the default `tools` profile.",
},
]; ];

View File

@ -37,6 +37,7 @@ RUN sh /scripts/sccache.sh
COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/ COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
COPY host-x86_64/mingw-check/check-default-config-profiles.sh /scripts/
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/ COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
@ -46,6 +47,7 @@ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
# We disable optimized compiler built-ins because that requires a C toolchain for the target. # We disable optimized compiler built-ins because that requires a C toolchain for the target.
# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
ENV SCRIPT python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ ENV SCRIPT python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
/scripts/check-default-config-profiles.sh && \
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
python3 ../x.py clippy bootstrap -Dwarnings && \ python3 ../x.py clippy bootstrap -Dwarnings && \
python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \ python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \

View File

@ -0,0 +1,12 @@
#!/bin/bash
# Runs bootstrap (in dry-run mode) with each default config profile to ensure they are not broken.
set -euo pipefail
config_dir="../src/bootstrap/defaults"
# Loop through each configuration file in the directory
for config_file in "$config_dir"/*.toml;
do
python3 ../x.py check --config $config_file --dry-run
done

View File

@ -2174,6 +2174,14 @@ in src-script.js and main.js
padding: 2px 4px; padding: 2px 4px;
box-shadow: 0 0 4px var(--main-background-color); box-shadow: 0 0 4px var(--main-background-color);
} }
.item-table > li > .item-name {
width: 33%;
}
.item-table > li > div {
padding-bottom: 5px;
word-break: break-all;
}
} }
@media print { @media print {

View File

@ -117,6 +117,7 @@ pub mod too_long {
pub type ReallyLongTypeNameLongLongLong = pub type ReallyLongTypeNameLongLongLong =
Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>; Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>;
/// Short doc.
pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0; pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0;
/// This also has a really long doccomment. Lorem ipsum dolor sit amet, /// This also has a really long doccomment. Lorem ipsum dolor sit amet,

View File

@ -16,7 +16,11 @@ assert-property: ("pre.item-decl", {"scrollWidth": "1324"})
// In the table-ish view on the module index, the name should not be wrapped more than necessary. // In the table-ish view on the module index, the name should not be wrapped more than necessary.
go-to: "file://" + |DOC_PATH| + "/lib2/too_long/index.html" go-to: "file://" + |DOC_PATH| + "/lib2/too_long/index.html"
assert-property: (".item-table .struct", {"offsetWidth": "684"})
// We'll ensure that items with short documentation have the same width.
store-property: ("//*[@class='item-table']//*[@class='struct']/..", {"offsetWidth": offset_width})
assert: |offset_width| == "277"
assert-property: ("//*[@class='item-table']//*[@class='constant']/..", {"offsetWidth": |offset_width|})
// We now make the same check on type declaration... // We now make the same check on type declaration...
go-to: "file://" + |DOC_PATH| + "/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html" go-to: "file://" + |DOC_PATH| + "/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html"

View File

@ -11,7 +11,7 @@ LL | static_bound(&rust_dbg_static_mut);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | static_bound(addr_of!(rust_dbg_static_mut)); LL | static_bound(addr_of!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged warning: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-foreign.rs:33:22 --> $DIR/static-mut-foreign.rs:33:22
@ -25,7 +25,7 @@ LL | static_bound_set(&mut rust_dbg_static_mut);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut)); LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: 2 warnings emitted warning: 2 warnings emitted

View File

@ -11,7 +11,7 @@ LL | let _y2 = &mut static_x_mut;
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let _y2 = addr_of_mut!(static_x_mut); LL | let _y2 = addr_of_mut!(static_x_mut);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:10:19 --> $DIR/borrowck-access-permissions.rs:10:19

View File

@ -11,7 +11,7 @@ LL | let sfoo: *mut Foo = &mut SFOO;
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let sfoo: *mut Foo = addr_of_mut!(SFOO); LL | let sfoo: *mut Foo = addr_of_mut!(SFOO);
| ~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -11,7 +11,7 @@ LL | unsafe { &mut GLOBAL_MUT_T }
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | unsafe { addr_of_mut!(GLOBAL_MUT_T) } LL | unsafe { addr_of_mut!(GLOBAL_MUT_T) }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/issue-20801.rs:27:22 --> $DIR/issue-20801.rs:27:22

View File

@ -11,7 +11,7 @@ LL | c1(&mut Y);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | c1(addr_of_mut!(Y)); LL | c1(addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
@ -25,7 +25,7 @@ LL | c1(&mut Z);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | c1(addr_of_mut!(Z)); LL | c1(addr_of_mut!(Z));
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
@ -39,7 +39,7 @@ LL | borrowck_closures_unique::e(&mut X);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | borrowck_closures_unique::e(addr_of_mut!(X)); LL | borrowck_closures_unique::e(addr_of_mut!(X));
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error[E0594]: cannot assign to `x`, as it is not declared as mutable error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46

View File

@ -11,7 +11,7 @@ LL | let ptr = unsafe { &mut BB };
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let ptr = unsafe { addr_of_mut!(BB) }; LL | let ptr = unsafe { addr_of_mut!(BB) };
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -11,7 +11,7 @@ LL | (mem::size_of_val(&trails) * 8) as u32
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32 LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -11,7 +11,7 @@ LL | (mem::size_of_val(&trails) * 8) as u32
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32 LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -19,7 +19,7 @@ LL | println!("{:p}", unsafe { &symbol });
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | println!("{:p}", unsafe { addr_of!(symbol) }); LL | println!("{:p}", unsafe { addr_of!(symbol) });
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
error: aborting due to 1 previous error; 1 warning emitted error: aborting due to 1 previous error; 1 warning emitted

View File

@ -8,7 +8,9 @@ error[E0392]: type parameter `T` is never used
--> $DIR/inherent-impls-overflow.rs:14:12 --> $DIR/inherent-impls-overflow.rs:14:12
| |
LL | type Poly0<T> = Poly1<(T,)>; LL | type Poly0<T> = Poly1<(T,)>;
| ^ unused type parameter | ^ - `T` is named here, but is likely unused in the containing type
| |
| unused type parameter
| |
= help: consider removing `T` or referring to it in the body of the type alias = 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 = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
@ -17,7 +19,9 @@ error[E0392]: type parameter `T` is never used
--> $DIR/inherent-impls-overflow.rs:17:12 --> $DIR/inherent-impls-overflow.rs:17:12
| |
LL | type Poly1<T> = Poly0<(T,)>; LL | type Poly1<T> = Poly0<(T,)>;
| ^ unused type parameter | ^ - `T` is named here, but is likely unused in the containing type
| |
| unused type parameter
| |
= help: consider removing `T` or referring to it in the body of the type alias = 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 = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead

View File

@ -11,7 +11,7 @@ LL | S1 { a: unsafe { &mut X1 } }
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | S1 { a: unsafe { addr_of_mut!(X1) } } LL | S1 { a: unsafe { addr_of_mut!(X1) } }
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -7,9 +7,8 @@ LL | B == 2
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
help: try using `=` instead help: try using `=` instead
| |
LL - B == 2 LL | B = 2
LL + B = 2 | ~
|
error: expected item, found `==` error: expected item, found `==`
--> $DIR/issue-101477-enum.rs:6:7 --> $DIR/issue-101477-enum.rs:6:7

View File

@ -6,9 +6,8 @@ LL | let x == 2;
| |
help: try using `=` instead help: try using `=` instead
| |
LL - let x == 2; LL | let x = 2;
LL + let x = 2; | ~
|
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -0,0 +1,3 @@
const A: usize 2;
//~^ ERROR unknown start of token: \u{2a75}
//~| ERROR unexpected `==`

View File

@ -0,0 +1,24 @@
error: unknown start of token: \u{2a75}
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: Unicode character '⩵' (Two Consecutive Equals Signs) looks like '==' (Double Equals Sign), but it is not
|
LL | const A: usize == 2;
| ~~
error: unexpected `==`
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: try using `=` instead
|
LL | const A: usize = 2;
| ~
error: aborting due to 2 previous errors

View File

@ -11,7 +11,7 @@ LL | let _x = &X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let _x = addr_of!(X); LL | let _x = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0133]: use of mutable static is unsafe and requires unsafe function or block error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/reference-to-mut-static-safe.rs:9:15 --> $DIR/reference-to-mut-static-safe.rs:9:15

View File

@ -8,7 +8,7 @@ LL | let _x = &X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let _x = addr_of!(X); LL | let _x = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0133]: use of mutable static is unsafe and requires unsafe block error[E0133]: use of mutable static is unsafe and requires unsafe block
--> $DIR/reference-to-mut-static-safe.rs:9:15 --> $DIR/reference-to-mut-static-safe.rs:9:15

View File

@ -8,7 +8,7 @@ LL | let _y = &X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let _y = addr_of!(X); LL | let _y = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22 --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22
@ -20,7 +20,7 @@ LL | let ref _a = X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let ref _a = addr_of!(X); LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~ | +++++++++ +
error[E0796]: creating a mutable reference to a mutable static error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26 --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26
@ -32,7 +32,7 @@ LL | let ref mut _a = X;
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let ref mut _a = addr_of_mut!(X); LL | let ref mut _a = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~ | +++++++++++++ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25 --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25
@ -44,7 +44,7 @@ LL | let (_b, _c) = (&X, &mut Y);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let (_b, _c) = (addr_of!(X), &mut Y); LL | let (_b, _c) = (addr_of!(X), &mut Y);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0796]: creating a mutable reference to a mutable static error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29 --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29
@ -56,7 +56,7 @@ LL | let (_b, _c) = (&X, &mut Y);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let (_b, _c) = (&X, addr_of_mut!(Y)); LL | let (_b, _c) = (&X, addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13 --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13
@ -68,7 +68,7 @@ LL | foo(&X);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | foo(addr_of!(X)); LL | foo(addr_of!(X));
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -15,7 +15,7 @@ LL | #![deny(static_mut_refs)]
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let _y = addr_of!(X); LL | let _y = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: creating a mutable reference to mutable static is discouraged error: creating a mutable reference to mutable static is discouraged
--> $DIR/reference-to-mut-static.rs:20:18 --> $DIR/reference-to-mut-static.rs:20:18
@ -29,7 +29,7 @@ LL | let _y = &mut X;
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let _y = addr_of_mut!(X); LL | let _y = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error: creating a shared reference to mutable static is discouraged error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-to-mut-static.rs:28:22 --> $DIR/reference-to-mut-static.rs:28:22
@ -43,7 +43,7 @@ LL | let ref _a = X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let ref _a = addr_of!(X); LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~ | +++++++++ +
error: creating a shared reference to mutable static is discouraged error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-to-mut-static.rs:32:25 --> $DIR/reference-to-mut-static.rs:32:25
@ -57,7 +57,7 @@ LL | let (_b, _c) = (&X, &Y);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let (_b, _c) = (addr_of!(X), &Y); LL | let (_b, _c) = (addr_of!(X), &Y);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: creating a shared reference to mutable static is discouraged error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-to-mut-static.rs:32:29 --> $DIR/reference-to-mut-static.rs:32:29
@ -71,7 +71,7 @@ LL | let (_b, _c) = (&X, &Y);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let (_b, _c) = (&X, addr_of!(Y)); LL | let (_b, _c) = (&X, addr_of!(Y));
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: creating a shared reference to mutable static is discouraged error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-to-mut-static.rs:38:13 --> $DIR/reference-to-mut-static.rs:38:13
@ -85,7 +85,7 @@ LL | foo(&X);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | foo(addr_of!(X)); LL | foo(addr_of!(X));
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -8,7 +8,7 @@ LL | let _y = &X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let _y = addr_of!(X); LL | let _y = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0796]: creating a mutable reference to a mutable static error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static.rs:20:18 --> $DIR/reference-to-mut-static.rs:20:18
@ -20,7 +20,7 @@ LL | let _y = &mut X;
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | let _y = addr_of_mut!(X); LL | let _y = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static.rs:28:22 --> $DIR/reference-to-mut-static.rs:28:22
@ -32,7 +32,7 @@ LL | let ref _a = X;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let ref _a = addr_of!(X); LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~ | +++++++++ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static.rs:32:25 --> $DIR/reference-to-mut-static.rs:32:25
@ -44,7 +44,7 @@ LL | let (_b, _c) = (&X, &Y);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let (_b, _c) = (addr_of!(X), &Y); LL | let (_b, _c) = (addr_of!(X), &Y);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static.rs:32:29 --> $DIR/reference-to-mut-static.rs:32:29
@ -56,7 +56,7 @@ LL | let (_b, _c) = (&X, &Y);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let (_b, _c) = (&X, addr_of!(Y)); LL | let (_b, _c) = (&X, addr_of!(Y));
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static.rs:38:13 --> $DIR/reference-to-mut-static.rs:38:13
@ -68,7 +68,7 @@ LL | foo(&X);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | foo(addr_of!(X)); LL | foo(addr_of!(X));
| ~~~~~~~~~~~ | ~~~~~~~~~ +
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -11,7 +11,7 @@ LL | let rb = &B;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let rb = addr_of!(B); LL | let rb = addr_of!(B);
| ~~~~~~~~~~~ | ~~~~~~~~~ +
warning: creating a shared reference to mutable static is discouraged warning: creating a shared reference to mutable static is discouraged
--> $DIR/safe-extern-statics-mut.rs:15:15 --> $DIR/safe-extern-statics-mut.rs:15:15
@ -25,7 +25,7 @@ LL | let xrb = &XB;
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | let xrb = addr_of!(XB); LL | let xrb = addr_of!(XB);
| ~~~~~~~~~~~~ | ~~~~~~~~~ +
error[E0133]: use of mutable static is unsafe and requires unsafe function or block error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/safe-extern-statics-mut.rs:11:13 --> $DIR/safe-extern-statics-mut.rs:11:13

View File

@ -11,7 +11,7 @@ LL | static n: &'static usize = unsafe { &n_mut };
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | static n: &'static usize = unsafe { addr_of!(n_mut) }; LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -11,7 +11,7 @@ LL | static_bound(&static_mut_xc::a);
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | static_bound(addr_of!(static_mut_xc::a)); LL | static_bound(addr_of!(static_mut_xc::a));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged warning: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-xc.rs:30:22 --> $DIR/static-mut-xc.rs:30:22
@ -25,7 +25,7 @@ LL | static_bound_set(&mut static_mut_xc::a);
help: use `addr_of_mut!` instead to create a raw pointer help: use `addr_of_mut!` instead to create a raw pointer
| |
LL | static_bound_set(addr_of_mut!(static_mut_xc::a)); LL | static_bound_set(addr_of_mut!(static_mut_xc::a));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ +
warning: 2 warnings emitted warning: 2 warnings emitted

View File

@ -11,7 +11,7 @@ LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
help: use `addr_of!` instead to create a raw pointer help: use `addr_of!` instead to create a raw pointer
| |
LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 }; LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
| ~~~~~~~~~~~ | ~~~~~~~~~ +
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -10,7 +10,6 @@
//@ ignore-wasm no panic or subprocess support //@ ignore-wasm no panic or subprocess support
//@ ignore-emscripten no panic or subprocess support //@ ignore-emscripten no panic or subprocess support
//@ ignore-sgx no subprocess support //@ ignore-sgx no subprocess support
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
#![cfg(test)] #![cfg(test)]

View File

@ -1,9 +1,9 @@
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:35:5: thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:34:5:
assertion `left == right` failed assertion `left == right` failed
left: 2 left: 2
right: 4 right: 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:29:5: thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:28:5:
assertion `left == right` failed assertion `left == right` failed
left: 2 left: 2
right: 4 right: 4

View File

@ -10,7 +10,6 @@
//@ ignore-wasm no panic or subprocess support //@ ignore-wasm no panic or subprocess support
//@ ignore-emscripten no panic or subprocess support //@ ignore-emscripten no panic or subprocess support
//@ ignore-sgx no subprocess support //@ ignore-sgx no subprocess support
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
#![cfg(test)] #![cfg(test)]
#![feature(test)] #![feature(test)]

View File

@ -17,7 +17,7 @@ hello, world
testing123 testing123
---- it_fails stderr ---- ---- it_fails stderr ----
testing321 testing321
thread 'main' panicked at $DIR/test-panic-abort.rs:40:5: thread 'main' panicked at $DIR/test-panic-abort.rs:39:5:
assertion `left == right` failed assertion `left == right` failed
left: 2 left: 2
right: 5 right: 5

View File

@ -1,9 +1,9 @@
//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send` //~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
struct A<T>(B<T>); struct A<T>(B<T>);
//~^ ERROR recursive types `A` and `B` have infinite size //~^ ERROR recursive types `A` and `B` have infinite size
//~| ERROR `T` is never used //~| ERROR `T` is only used recursively
struct B<T>(A<A<T>>); struct B<T>(A<A<T>>);
//~^ ERROR `T` is never used //~^ ERROR `T` is only used recursively
trait Foo {} trait Foo {}
impl<T> Foo for T where T: Send {} impl<T> Foo for T where T: Send {}
impl Foo for B<u8> {} impl Foo for B<u8> {}

View File

@ -15,23 +15,27 @@ LL |
LL ~ struct B<T>(Box<A<A<T>>>); LL ~ struct B<T>(Box<A<A<T>>>);
| |
error[E0392]: type parameter `T` is never used error: type parameter `T` is only used recursively
--> $DIR/issue-105231.rs:2:10 --> $DIR/issue-105231.rs:2:15
| |
LL | struct A<T>(B<T>); LL | struct A<T>(B<T>);
| ^ unused type parameter | - ^
| |
| type parameter must be used non-recursively in the definition
| |
= 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: /* Type */` instead = note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0392]: type parameter `T` is never used error: type parameter `T` is only used recursively
--> $DIR/issue-105231.rs:5:10 --> $DIR/issue-105231.rs:5:17
| |
LL | struct B<T>(A<A<T>>); LL | struct B<T>(A<A<T>>);
| ^ unused type parameter | - ^
| |
| type parameter must be used non-recursively in the definition
| |
= 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: /* Type */` instead = note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send` error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
| |
@ -44,5 +48,5 @@ LL | struct B<T>(A<A<T>>);
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
Some errors have detailed explanations: E0072, E0275, E0392. Some errors have detailed explanations: E0072, E0275.
For more information about an error, try `rustc --explain E0072`. For more information about an error, try `rustc --explain E0072`.

View File

@ -11,11 +11,14 @@ enum SomeEnum<A> { Nothing }
// Here T might *appear* used, but in fact it isn't. // Here T might *appear* used, but in fact it isn't.
enum ListCell<T> { enum ListCell<T> {
//~^ ERROR parameter `T` is never used
Cons(Box<ListCell<T>>), Cons(Box<ListCell<T>>),
//~^ ERROR parameter `T` is only used recursively
Nil Nil
} }
struct SelfTyAlias<T>(Box<Self>);
//~^ ERROR parameter `T` is only used recursively
struct WithBounds<T: Sized> {} struct WithBounds<T: Sized> {}
//~^ ERROR parameter `T` is never used //~^ ERROR parameter `T` is never used
@ -25,4 +28,9 @@ struct WithWhereBounds<T> where T: Sized {}
struct WithOutlivesBounds<T: 'static> {} struct WithOutlivesBounds<T: 'static> {}
//~^ ERROR parameter `T` is never used //~^ ERROR parameter `T` is never used
struct DoubleNothing<T> {
//~^ ERROR parameter `T` is never used
s: SomeStruct<T>,
}
fn main() {} fn main() {}

View File

@ -16,17 +16,30 @@ LL | enum SomeEnum<A> { Nothing }
= 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: /* Type */` instead = help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
error[E0392]: type parameter `T` is never used error: type parameter `T` is only used recursively
--> $DIR/variance-unused-type-param.rs:13:15 --> $DIR/variance-unused-type-param.rs:14:23
| |
LL | enum ListCell<T> { LL | enum ListCell<T> {
| ^ unused type parameter | - type parameter must be used non-recursively in the definition
LL | Cons(Box<ListCell<T>>),
| ^
| |
= 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: /* Type */` instead = note: all type parameters must be used in a non-recursive way in order to constrain their variance
error: type parameter `T` is only used recursively
--> $DIR/variance-unused-type-param.rs:19:27
|
LL | struct SelfTyAlias<T>(Box<Self>);
| - ^^^^
| |
| type parameter must be used non-recursively in the definition
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:19:19 --> $DIR/variance-unused-type-param.rs:22:19
| |
LL | struct WithBounds<T: Sized> {} LL | struct WithBounds<T: Sized> {}
| ^ unused type parameter | ^ unused type parameter
@ -34,7 +47,7 @@ LL | struct WithBounds<T: Sized> {}
= 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`
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:22:24 --> $DIR/variance-unused-type-param.rs:25:24
| |
LL | struct WithWhereBounds<T> where T: Sized {} LL | struct WithWhereBounds<T> where T: Sized {}
| ^ unused type parameter | ^ unused type parameter
@ -42,13 +55,25 @@ LL | struct WithWhereBounds<T> where T: Sized {}
= 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`
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:25:27 --> $DIR/variance-unused-type-param.rs:28:27
| |
LL | struct WithOutlivesBounds<T: 'static> {} LL | struct WithOutlivesBounds<T: 'static> {}
| ^ unused type 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`
error: aborting due to 6 previous errors error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:31:22
|
LL | struct DoubleNothing<T> {
| ^ unused type parameter
LL |
LL | s: SomeStruct<T>,
| - `T` is named here, but is likely unused in the containing type
|
= 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: /* Type */` instead
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0392`. For more information about this error, try `rustc --explain E0392`.