mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 19:33:16 +00:00
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:
commit
3d68afc9e8
@ -313,10 +313,6 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||
self.type_checker.infcx.tcx
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"nll::subtype"
|
||||
}
|
||||
|
||||
#[instrument(skip(self, info), level = "trace", ret)]
|
||||
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
|
@ -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
|
||||
.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}`
|
||||
.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
|
||||
.label = unused {$param_def_kind}
|
||||
.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 =
|
||||
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 =
|
||||
|
@ -1572,6 +1572,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
|
||||
param_name,
|
||||
param_def_kind: tcx.def_descr(param.def_id),
|
||||
help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
|
||||
usage_spans: vec![],
|
||||
const_param_help,
|
||||
});
|
||||
diag.code(E0091);
|
||||
|
@ -1,5 +1,4 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir_pretty::qpath_to_string;
|
||||
use rustc_lint_defs::builtin::STATIC_MUT_REFS;
|
||||
use rustc_middle::ty::{Mutability, TyCtxt};
|
||||
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;
|
||||
if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind
|
||||
&& 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::ByRef::Yes(rmutbl) = ba.0
|
||||
&& let Some(init) = loc.init
|
||||
&& let Some(var) = path_if_static_mut(tcx, init)
|
||||
&& path_if_static_mut(init)
|
||||
{
|
||||
handle_static_mut_ref(
|
||||
tcx,
|
||||
init.span,
|
||||
var,
|
||||
init.span.shrink_to_lo(),
|
||||
init.span.shrink_to_hi(),
|
||||
loc.span.edition().at_least_rust_2024(),
|
||||
rmutbl,
|
||||
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
|
||||
&& let hir::QPath::Resolved(_, path) = qpath
|
||||
&& let hir::def::Res::Def(def_kind, _) = path.res
|
||||
&& let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
|
||||
def_kind
|
||||
{
|
||||
return Some(qpath_to_string(&tcx, &qpath));
|
||||
return true;
|
||||
}
|
||||
None
|
||||
false
|
||||
}
|
||||
|
||||
fn handle_static_mut_ref(
|
||||
tcx: TyCtxt<'_>,
|
||||
span: Span,
|
||||
var: String,
|
||||
lo: Span,
|
||||
hi: Span,
|
||||
e2024: bool,
|
||||
mutable: Mutability,
|
||||
hir_id: hir::HirId,
|
||||
) {
|
||||
if e2024 {
|
||||
let (sugg, shared) = if mutable == Mutability::Mut {
|
||||
(errors::StaticMutRefSugg::Mut { span, var }, "mutable")
|
||||
(errors::MutRefSugg::Mut { lo, hi }, "mutable")
|
||||
} else {
|
||||
(errors::StaticMutRefSugg::Shared { span, var }, "shared")
|
||||
(errors::MutRefSugg::Shared { lo, hi }, "shared")
|
||||
};
|
||||
tcx.dcx().emit_err(errors::StaticMutRef { span, sugg, shared });
|
||||
} else {
|
||||
let (sugg, shared) = if mutable == Mutability::Mut {
|
||||
(errors::RefOfMutStaticSugg::Mut { span, var }, "mutable")
|
||||
(errors::MutRefSugg::Mut { lo, hi }, "mutable")
|
||||
} else {
|
||||
(errors::RefOfMutStaticSugg::Shared { span, var }, "shared")
|
||||
(errors::MutRefSugg::Shared { lo, hi }, "shared")
|
||||
};
|
||||
tcx.emit_node_span_lint(
|
||||
STATIC_MUT_REFS,
|
||||
|
@ -4,12 +4,12 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
|
||||
use crate::errors;
|
||||
use crate::fluent_generated as fluent;
|
||||
|
||||
use hir::intravisit::Visitor;
|
||||
use hir::intravisit::{self, Visitor};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
|
||||
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::lang_items::LangItem;
|
||||
use rustc_hir::ItemKind;
|
||||
@ -1799,7 +1799,7 @@ fn receiver_is_implemented<'tcx>(
|
||||
|
||||
fn check_variances_for_type_defn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item: &hir::Item<'tcx>,
|
||||
item: &'tcx hir::Item<'tcx>,
|
||||
hir_generics: &hir::Generics<'tcx>,
|
||||
) {
|
||||
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 => {}
|
||||
_ => {
|
||||
let has_explicit_bounds = explicitly_bounded_params.contains(¶meter);
|
||||
report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind);
|
||||
report_bivariance(tcx, hir_param, has_explicit_bounds, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_bivariance(
|
||||
tcx: TyCtxt<'_>,
|
||||
param: &rustc_hir::GenericParam<'_>,
|
||||
fn report_bivariance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param: &'tcx hir::GenericParam<'tcx>,
|
||||
has_explicit_bounds: bool,
|
||||
item_kind: ItemKind<'_>,
|
||||
item: &'tcx hir::Item<'tcx>,
|
||||
) -> ErrorGuaranteed {
|
||||
let param_name = param.name.ident();
|
||||
|
||||
let help = match item_kind {
|
||||
let help = match item.kind {
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
if let Some(def_id) = tcx.lang_items().phantom_data() {
|
||||
errors::UnusedGenericParameterHelp::Adt {
|
||||
@ -1915,6 +1915,49 @@ fn report_bivariance(
|
||||
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 =
|
||||
matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
|
||||
.then_some(());
|
||||
@ -1923,6 +1966,7 @@ fn report_bivariance(
|
||||
span: param.span,
|
||||
param_name,
|
||||
param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
|
||||
usage_spans,
|
||||
help,
|
||||
const_param_help,
|
||||
});
|
||||
@ -1930,6 +1974,77 @@ fn report_bivariance(
|
||||
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> {
|
||||
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
|
||||
/// aren't true.
|
||||
|
@ -1500,33 +1500,33 @@ pub struct StaticMutRef<'a> {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: StaticMutRefSugg,
|
||||
pub sugg: MutRefSugg,
|
||||
pub shared: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum StaticMutRefSugg {
|
||||
#[suggestion(
|
||||
pub enum MutRefSugg {
|
||||
#[multipart_suggestion(
|
||||
hir_analysis_suggestion,
|
||||
style = "verbose",
|
||||
code = "addr_of!({var})",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
Shared {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
var: String,
|
||||
#[suggestion_part(code = "addr_of!(")]
|
||||
lo: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
hi: Span,
|
||||
},
|
||||
#[suggestion(
|
||||
#[multipart_suggestion(
|
||||
hir_analysis_suggestion_mut,
|
||||
style = "verbose",
|
||||
code = "addr_of_mut!({var})",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
Mut {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
var: String,
|
||||
#[suggestion_part(code = "addr_of_mut!(")]
|
||||
lo: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
hi: Span,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1539,36 +1539,10 @@ pub struct RefOfMutStatic<'a> {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: RefOfMutStaticSugg,
|
||||
pub sugg: MutRefSugg,
|
||||
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)]
|
||||
#[diag(hir_analysis_not_supported_delegation)]
|
||||
pub struct NotSupportedDelegation<'a> {
|
||||
@ -1597,12 +1571,29 @@ pub(crate) struct UnusedGenericParameter {
|
||||
pub span: Span,
|
||||
pub param_name: Ident,
|
||||
pub param_def_kind: &'static str,
|
||||
#[label(hir_analysis_usage_spans)]
|
||||
pub usage_spans: Vec<Span>,
|
||||
#[subdiagnostic]
|
||||
pub help: UnusedGenericParameterHelp,
|
||||
#[help(hir_analysis_const_param_help)]
|
||||
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)]
|
||||
pub(crate) enum UnusedGenericParameterHelp {
|
||||
#[help(hir_analysis_unused_generic_parameter_adt_help)]
|
||||
|
@ -1934,10 +1934,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for SameTypeModuloInfer<'_, 'tcx> {
|
||||
self.0.tcx
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"SameTypeModuloInfer"
|
||||
}
|
||||
|
||||
fn relate_with_variance<T: relate::Relate<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
_variance: ty::Variance,
|
||||
|
@ -110,7 +110,7 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
|
||||
|
||||
/// Binds the pattern variable `br` to `value`; returns an `Err` if the pattern
|
||||
/// is already bound to a different value.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn bind(
|
||||
&mut self,
|
||||
br: ty::BoundRegion,
|
||||
@ -133,10 +133,6 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"MatchAgainstHigherRankedOutlives"
|
||||
}
|
||||
|
||||
fn cx(&self) -> TyCtxt<'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) }
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn regions(
|
||||
&mut self,
|
||||
pattern: ty::Region<'tcx>,
|
||||
value: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
debug!("self.pattern_depth = {:?}", self.pattern_depth);
|
||||
if let ty::RegionKind::ReBound(depth, br) = pattern.kind()
|
||||
&& 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>> {
|
||||
// FIXME(non_lifetime_binders): What to do here?
|
||||
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(
|
||||
&mut self,
|
||||
pattern: ty::Const<'tcx>,
|
||||
value: ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), pattern, value);
|
||||
if pattern == value {
|
||||
Ok(pattern)
|
||||
} else {
|
||||
@ -199,6 +193,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
pattern: ty::Binder<'tcx, T>,
|
||||
|
@ -79,6 +79,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
where
|
||||
R: PredicateEmittingRelation<InferCtxt<'tcx>>,
|
||||
{
|
||||
debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
|
||||
debug_assert!(!a.has_escaping_bound_vars());
|
||||
debug_assert!(!b.has_escaping_bound_vars());
|
||||
|
||||
@ -174,9 +175,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
where
|
||||
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!(!b.has_escaping_bound_vars());
|
||||
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
@ -401,10 +401,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"Generalizer"
|
||||
}
|
||||
|
||||
fn relate_item_args(
|
||||
&mut self,
|
||||
item_def_id: DefId,
|
||||
|
@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"Glb"
|
||||
}
|
||||
|
||||
fn cx(&self) -> TyCtxt<'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>> {
|
||||
lattice::super_lattice_tys(self, a, b)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn regions(
|
||||
&mut self,
|
||||
a: ty::Region<'tcx>,
|
||||
b: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
|
||||
|
||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
||||
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
|
||||
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(
|
||||
&mut self,
|
||||
a: ty::Const<'tcx>,
|
||||
|
@ -56,8 +56,6 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
|
||||
where
|
||||
L: LatticeDir<'a, 'tcx>,
|
||||
{
|
||||
debug!("{}", this.tag());
|
||||
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"Lub"
|
||||
}
|
||||
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.fields.tcx()
|
||||
}
|
||||
@ -51,13 +47,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
|
||||
lattice::super_lattice_tys(self, a, b)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn regions(
|
||||
&mut self,
|
||||
a: ty::Region<'tcx>,
|
||||
b: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
|
||||
|
||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
||||
// LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
|
||||
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(
|
||||
&mut self,
|
||||
a: ty::Const<'tcx>,
|
||||
|
@ -28,10 +28,6 @@ impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"TypeRelating"
|
||||
}
|
||||
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.fields.infcx.tcx
|
||||
}
|
||||
@ -71,7 +67,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
||||
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>> {
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
@ -166,12 +162,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn regions(
|
||||
&mut self,
|
||||
a: ty::Region<'tcx>,
|
||||
b: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
|
||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
||||
|
||||
match self.ambient_variance {
|
||||
@ -209,6 +205,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: ty::Const<'tcx>,
|
||||
|
@ -3,37 +3,37 @@ use rustc_middle::thir::{self, *};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
/// [`PatKind::Leaf`].
|
||||
///
|
||||
/// Used internally by [`MatchPair::new`].
|
||||
/// Used internally by [`MatchPairTree::for_pattern`].
|
||||
fn field_match_pairs<'pat>(
|
||||
&mut self,
|
||||
place: PlaceBuilder<'tcx>,
|
||||
subpatterns: &'pat [FieldPat<'tcx>],
|
||||
) -> Vec<MatchPair<'pat, 'tcx>> {
|
||||
) -> Vec<MatchPairTree<'pat, 'tcx>> {
|
||||
subpatterns
|
||||
.iter()
|
||||
.map(|fieldpat| {
|
||||
let place =
|
||||
place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
|
||||
MatchPair::new(place, &fieldpat.pattern, self)
|
||||
MatchPairTree::for_pattern(place, &fieldpat.pattern, self)
|
||||
})
|
||||
.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`.
|
||||
///
|
||||
/// Used internally by [`MatchPair::new`].
|
||||
/// Used internally by [`MatchPairTree::for_pattern`].
|
||||
fn prefix_slice_suffix<'pat>(
|
||||
&mut self,
|
||||
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
|
||||
match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
|
||||
place: &PlaceBuilder<'tcx>,
|
||||
prefix: &'pat [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)| {
|
||||
let elem =
|
||||
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 {
|
||||
@ -62,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
to: if exact_size { min_length - suffix_len } else { suffix_len },
|
||||
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)| {
|
||||
@ -73,19 +73,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
from_end: !exact_size,
|
||||
};
|
||||
let place = place.clone_project(elem);
|
||||
MatchPair::new(place, subpattern, self)
|
||||
MatchPairTree::for_pattern(place, subpattern, self)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
/// Recursively builds a `MatchPair` tree for the given pattern and its
|
||||
impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
||||
/// Recursively builds a match pair tree for the given pattern and its
|
||||
/// subpatterns.
|
||||
pub(in crate::build) fn new(
|
||||
pub(in crate::build) fn for_pattern(
|
||||
mut place_builder: PlaceBuilder<'tcx>,
|
||||
pattern: &'pat Pat<'tcx>,
|
||||
cx: &mut Builder<'_, 'tcx>,
|
||||
) -> MatchPair<'pat, 'tcx> {
|
||||
) -> MatchPairTree<'pat, 'tcx> {
|
||||
// Force the place type to the pattern's type.
|
||||
// FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
|
||||
if let Some(resolved) = place_builder.resolve_upvar(cx) {
|
||||
@ -138,7 +138,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
variance,
|
||||
});
|
||||
|
||||
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
|
||||
subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
|
||||
TestCase::Irrefutable { ascription, binding: None }
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
|
||||
if let Some(subpattern) = subpattern.as_ref() {
|
||||
// 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 }
|
||||
}
|
||||
@ -182,7 +182,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
@ -242,13 +242,17 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
|
||||
Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability),
|
||||
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 }
|
||||
}
|
||||
|
||||
PatKind::Never => TestCase::Never,
|
||||
};
|
||||
|
||||
MatchPair { place, test_case, subpairs, pattern }
|
||||
MatchPairTree { place, test_case, subpairs, pattern }
|
||||
}
|
||||
}
|
||||
|
@ -1032,15 +1032,15 @@ impl<'tcx> PatternExtraData<'tcx> {
|
||||
#[derive(Debug, Clone)]
|
||||
struct FlatPat<'pat, 'tcx> {
|
||||
/// 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.
|
||||
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
|
||||
match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,
|
||||
|
||||
extra_data: PatternExtraData<'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.
|
||||
fn new(
|
||||
place: PlaceBuilder<'tcx>,
|
||||
@ -1048,7 +1048,7 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
|
||||
cx: &mut Builder<'_, 'tcx>,
|
||||
) -> Self {
|
||||
// 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 {
|
||||
span: pattern.span,
|
||||
bindings: Vec::new(),
|
||||
@ -1065,9 +1065,9 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
|
||||
#[derive(Debug)]
|
||||
struct Candidate<'pat, 'tcx> {
|
||||
/// 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.
|
||||
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...
|
||||
// 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.
|
||||
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
|
||||
@ -1206,7 +1206,7 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> {
|
||||
/// Each node also has a list of subpairs (possibly empty) that must also match,
|
||||
/// and a reference to the THIR pattern it represents.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct MatchPair<'pat, 'tcx> {
|
||||
pub(crate) struct MatchPairTree<'pat, 'tcx> {
|
||||
/// This place...
|
||||
///
|
||||
/// ---
|
||||
@ -1629,7 +1629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn create_or_subcandidates<'pat>(
|
||||
&mut self,
|
||||
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!() };
|
||||
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
|
||||
@ -1813,8 +1813,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// [`Range`]: TestKind::Range
|
||||
fn pick_test(&mut self, candidates: &[&mut Candidate<'_, 'tcx>]) -> (Place<'tcx>, Test<'tcx>) {
|
||||
// Extract the match-pair from the highest priority candidate
|
||||
let match_pair = &candidates.first().unwrap().match_pairs[0];
|
||||
let test = self.test(match_pair);
|
||||
let match_pair = &candidates[0].match_pairs[0];
|
||||
let test = self.pick_test_for_match_pair(match_pair);
|
||||
// Unwrap is ok after simplification.
|
||||
let match_place = match_pair.place.unwrap();
|
||||
debug!(?test, ?match_pair);
|
||||
|
@ -12,7 +12,7 @@
|
||||
//! sort of test: for example, testing which variant an enum is, or
|
||||
//! 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 tracing::{debug, instrument};
|
||||
|
||||
@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn simplify_match_pairs<'pat>(
|
||||
&mut self,
|
||||
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
|
||||
match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
|
||||
extra_data: &mut PatternExtraData<'tcx>,
|
||||
) {
|
||||
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
|
||||
|
@ -5,7 +5,7 @@
|
||||
// identify what tests are needed, perform the tests, and then filter
|
||||
// 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 rustc_data_structures::fx::FxIndexMap;
|
||||
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.
|
||||
///
|
||||
/// 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 {
|
||||
TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def },
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
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 rustc_data_structures::fx::FxIndexMap;
|
||||
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 {
|
||||
for flat_pat in pats.iter() {
|
||||
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 {
|
||||
// All the or-alternatives should bind the same locals, so we only visit the first one.
|
||||
self.visit_flat_pat(&pats[0])
|
||||
|
@ -660,9 +660,8 @@ pub(crate) struct RemoveLet {
|
||||
#[diag(parse_use_eq_instead)]
|
||||
pub(crate) struct UseEqInstead {
|
||||
#[primary_span]
|
||||
#[suggestion(style = "verbose", applicability = "machine-applicable", code = "=")]
|
||||
pub span: Span,
|
||||
#[suggestion(style = "verbose", applicability = "machine-applicable", code = "")]
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -566,10 +566,7 @@ impl<'a> Parser<'a> {
|
||||
&& expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
|
||||
{
|
||||
// Likely typo: `=` → `==` in let expr or enum item
|
||||
return Err(self.dcx().create_err(UseEqInstead {
|
||||
span: self.token.span,
|
||||
suggestion: self.token.span.with_lo(self.token.span.lo() + BytePos(1)),
|
||||
}));
|
||||
return Err(self.dcx().create_err(UseEqInstead { span: self.token.span }));
|
||||
}
|
||||
|
||||
if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) {
|
||||
|
@ -3,7 +3,7 @@ use rustc_infer::infer::relate::{
|
||||
};
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
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
|
||||
/// 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> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"MatchAgainstFreshVars"
|
||||
}
|
||||
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
@ -50,7 +46,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
|
||||
self.relate(a, b)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn regions(
|
||||
&mut self,
|
||||
a: ty::Region<'tcx>,
|
||||
@ -59,7 +55,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
|
||||
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>> {
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
@ -83,12 +79,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: ty::Const<'tcx>,
|
||||
b: ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::iter;
|
||||
|
||||
use rustc_ast_ir::Mutability;
|
||||
use tracing::{debug, instrument};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::error::{ExpectedFound, TypeError};
|
||||
use crate::fold::TypeFoldable;
|
||||
@ -58,9 +58,6 @@ impl<I: Interner> VarianceDiagInfo<I> {
|
||||
pub trait TypeRelation<I: Interner>: Sized {
|
||||
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.
|
||||
fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> {
|
||||
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
|
||||
/// is to look up the variance for the item and proceed
|
||||
/// accordingly.
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn relate_item_args(
|
||||
&mut self,
|
||||
item_def_id: I::DefId,
|
||||
a_arg: I::GenericArgs,
|
||||
b_arg: 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 opt_variances = cx.variances_of(item_def_id);
|
||||
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 b: 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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
// and those that derive both `PartialEq` and `Eq`, corresponding
|
||||
|
@ -19,7 +19,15 @@ pub const TR_OK: i32 = 50;
|
||||
// On Windows we use __fastfail to abort, which is documented to use this
|
||||
// exception code.
|
||||
#[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)]
|
||||
pub enum TestResult {
|
||||
@ -96,7 +104,7 @@ pub fn get_result_from_exit_code(
|
||||
let result = match status.code() {
|
||||
Some(TR_OK) => TestResult::TrOk,
|
||||
#[cfg(windows)]
|
||||
Some(STATUS_ABORTED) => TestResult::TrFailed,
|
||||
Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed,
|
||||
#[cfg(unix)]
|
||||
None => match status.signal() {
|
||||
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"),
|
||||
},
|
||||
// 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))]
|
||||
None => TestResult::TrFailedMsg(format!("unknown return code")),
|
||||
#[cfg(any(windows, unix))]
|
||||
|
@ -1,10 +1,6 @@
|
||||
# These defaults are meant for contributors to tools which build on the
|
||||
# compiler, but do not modify it directly.
|
||||
[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.
|
||||
incremental = true
|
||||
# Download rustc from CI instead of building it from source.
|
||||
|
@ -200,4 +200,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
||||
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.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 127913,
|
||||
severity: ChangeSeverity::Warning,
|
||||
summary: "`debug-logging` option has been removed from the default `tools` profile.",
|
||||
},
|
||||
];
|
||||
|
@ -37,6 +37,7 @@ RUN sh /scripts/sccache.sh
|
||||
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
|
||||
|
||||
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-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 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 && \
|
||||
/scripts/check-default-config-profiles.sh && \
|
||||
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
|
||||
python3 ../x.py clippy bootstrap -Dwarnings && \
|
||||
python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
|
||||
|
12
src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh
Executable file
12
src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh
Executable 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
|
@ -2174,6 +2174,14 @@ in src-script.js and main.js
|
||||
padding: 2px 4px;
|
||||
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 {
|
||||
|
@ -117,6 +117,7 @@ pub mod too_long {
|
||||
pub type ReallyLongTypeNameLongLongLong =
|
||||
Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>;
|
||||
|
||||
/// Short doc.
|
||||
pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0;
|
||||
|
||||
/// This also has a really long doccomment. Lorem ipsum dolor sit amet,
|
||||
|
@ -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.
|
||||
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...
|
||||
go-to: "file://" + |DOC_PATH| + "/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html"
|
||||
|
@ -11,7 +11,7 @@ LL | static_bound(&rust_dbg_static_mut);
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | static_bound(addr_of!(rust_dbg_static_mut));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: creating a mutable reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | let _y2 = &mut static_x_mut;
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y2 = addr_of_mut!(static_x_mut);
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
|
||||
--> $DIR/borrowck-access-permissions.rs:10:19
|
||||
|
@ -11,7 +11,7 @@ LL | let sfoo: *mut Foo = &mut SFOO;
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | let sfoo: *mut Foo = addr_of_mut!(SFOO);
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | unsafe { &mut GLOBAL_MUT_T }
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | unsafe { addr_of_mut!(GLOBAL_MUT_T) }
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error[E0507]: cannot move out of a mutable reference
|
||||
--> $DIR/issue-20801.rs:27:22
|
||||
|
@ -11,7 +11,7 @@ LL | c1(&mut Y);
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | c1(addr_of_mut!(Y));
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: creating a mutable reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | c1(addr_of_mut!(Z));
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: creating a mutable reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | borrowck_closures_unique::e(addr_of_mut!(X));
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error[E0594]: cannot assign to `x`, as it is not declared as mutable
|
||||
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46
|
||||
|
@ -11,7 +11,7 @@ LL | let ptr = unsafe { &mut BB };
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | let ptr = unsafe { addr_of_mut!(BB) };
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | (mem::size_of_val(&trails) * 8) as u32
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | (mem::size_of_val(&trails) * 8) as u32
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -19,7 +19,7 @@ LL | println!("{:p}", unsafe { &symbol });
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | println!("{:p}", unsafe { addr_of!(symbol) });
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
@ -8,7 +8,9 @@ error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/inherent-impls-overflow.rs:14:12
|
||||
|
|
||||
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: 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
|
||||
|
|
||||
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: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
|
||||
|
@ -11,7 +11,7 @@ LL | S1 { a: unsafe { &mut X1 } }
|
||||
help: use `addr_of_mut!` instead to create a raw pointer
|
||||
|
|
||||
LL | S1 { a: unsafe { addr_of_mut!(X1) } }
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -7,9 +7,8 @@ LL | B == 2
|
||||
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
|
||||
help: try using `=` instead
|
||||
|
|
||||
LL - B == 2
|
||||
LL + B = 2
|
||||
|
|
||||
LL | B = 2
|
||||
| ~
|
||||
|
||||
error: expected item, found `==`
|
||||
--> $DIR/issue-101477-enum.rs:6:7
|
||||
|
@ -6,9 +6,8 @@ LL | let x == 2;
|
||||
|
|
||||
help: try using `=` instead
|
||||
|
|
||||
LL - let x == 2;
|
||||
LL + let x = 2;
|
||||
|
|
||||
LL | let x = 2;
|
||||
| ~
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
const A: usize ⩵ 2;
|
||||
//~^ ERROR unknown start of token: \u{2a75}
|
||||
//~| ERROR unexpected `==`
|
@ -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
|
||||
|
@ -11,7 +11,7 @@ LL | let _x = &X;
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _x = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||
--> $DIR/reference-to-mut-static-safe.rs:9:15
|
||||
|
@ -8,7 +8,7 @@ LL | let _x = &X;
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _x = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0133]: use of mutable static is unsafe and requires unsafe block
|
||||
--> $DIR/reference-to-mut-static-safe.rs:9:15
|
||||
|
@ -8,7 +8,7 @@ LL | let _y = &X;
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let ref _a = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| +++++++++ +
|
||||
|
||||
error[E0796]: creating a mutable reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let ref mut _a = addr_of_mut!(X);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| +++++++++++++ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (addr_of!(X), &mut Y);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a mutable reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (&X, addr_of_mut!(Y));
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | foo(addr_of!(X));
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -15,7 +15,7 @@ LL | #![deny(static_mut_refs)]
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: creating a mutable reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | let _y = addr_of_mut!(X);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error: creating a shared reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | let ref _a = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| +++++++++ +
|
||||
|
||||
error: creating a shared reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (addr_of!(X), &Y);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: creating a shared reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (&X, addr_of!(Y));
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: creating a shared reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | foo(addr_of!(X));
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -8,7 +8,7 @@ LL | let _y = &X;
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let _y = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a mutable reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let _y = addr_of_mut!(X);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let ref _a = addr_of!(X);
|
||||
| ~~~~~~~~~~~
|
||||
| +++++++++ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (addr_of!(X), &Y);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | let (_b, _c) = (&X, addr_of!(Y));
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0796]: creating a shared reference to a mutable static
|
||||
--> $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
|
||||
|
|
||||
LL | foo(addr_of!(X));
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | let rb = &B;
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | let rb = addr_of!(B);
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: creating a shared reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | let xrb = addr_of!(XB);
|
||||
| ~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-extern-statics-mut.rs:11:13
|
||||
|
@ -11,7 +11,7 @@ LL | static n: &'static usize = unsafe { &n_mut };
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
|
||||
| ~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -11,7 +11,7 @@ LL | static_bound(&static_mut_xc::a);
|
||||
help: use `addr_of!` instead to create a raw pointer
|
||||
|
|
||||
LL | static_bound(addr_of!(static_mut_xc::a));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: creating a mutable reference to mutable static is discouraged
|
||||
--> $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
|
||||
|
|
||||
LL | static_bound_set(addr_of_mut!(static_mut_xc::a));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~ +
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
|
||||
| ~~~~~~~~~~~
|
||||
| ~~~~~~~~~ +
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
//@ ignore-wasm no panic or subprocess support
|
||||
//@ ignore-emscripten no panic or subprocess support
|
||||
//@ ignore-sgx no subprocess support
|
||||
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
|
@ -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
|
||||
left: 2
|
||||
right: 4
|
||||
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
|
||||
left: 2
|
||||
right: 4
|
||||
|
@ -10,7 +10,6 @@
|
||||
//@ ignore-wasm no panic or subprocess support
|
||||
//@ ignore-emscripten no panic or subprocess support
|
||||
//@ ignore-sgx no subprocess support
|
||||
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
|
||||
|
||||
#![cfg(test)]
|
||||
#![feature(test)]
|
||||
|
@ -17,7 +17,7 @@ hello, world
|
||||
testing123
|
||||
---- it_fails stderr ----
|
||||
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
|
||||
left: 2
|
||||
right: 5
|
||||
|
@ -1,9 +1,9 @@
|
||||
//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
|
||||
struct A<T>(B<T>);
|
||||
//~^ 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>>);
|
||||
//~^ ERROR `T` is never used
|
||||
//~^ ERROR `T` is only used recursively
|
||||
trait Foo {}
|
||||
impl<T> Foo for T where T: Send {}
|
||||
impl Foo for B<u8> {}
|
||||
|
@ -15,23 +15,27 @@ LL |
|
||||
LL ~ struct B<T>(Box<A<A<T>>>);
|
||||
|
|
||||
|
||||
error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/issue-105231.rs:2:10
|
||||
error: type parameter `T` is only used recursively
|
||||
--> $DIR/issue-105231.rs:2:15
|
||||
|
|
||||
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: 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
|
||||
--> $DIR/issue-105231.rs:5:10
|
||||
error: type parameter `T` is only used recursively
|
||||
--> $DIR/issue-105231.rs:5:17
|
||||
|
|
||||
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: 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`
|
||||
|
|
||||
@ -44,5 +48,5 @@ LL | struct B<T>(A<A<T>>);
|
||||
|
||||
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`.
|
||||
|
@ -11,11 +11,14 @@ enum SomeEnum<A> { Nothing }
|
||||
|
||||
// Here T might *appear* used, but in fact it isn't.
|
||||
enum ListCell<T> {
|
||||
//~^ ERROR parameter `T` is never used
|
||||
Cons(Box<ListCell<T>>),
|
||||
//~^ ERROR parameter `T` is only used recursively
|
||||
Nil
|
||||
}
|
||||
|
||||
struct SelfTyAlias<T>(Box<Self>);
|
||||
//~^ ERROR parameter `T` is only used recursively
|
||||
|
||||
struct WithBounds<T: Sized> {}
|
||||
//~^ ERROR parameter `T` is never used
|
||||
|
||||
@ -25,4 +28,9 @@ struct WithWhereBounds<T> where T: Sized {}
|
||||
struct WithOutlivesBounds<T: 'static> {}
|
||||
//~^ ERROR parameter `T` is never used
|
||||
|
||||
struct DoubleNothing<T> {
|
||||
//~^ ERROR parameter `T` is never used
|
||||
s: SomeStruct<T>,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -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: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
|
||||
|
||||
error[E0392]: type parameter `T` is never used
|
||||
--> $DIR/variance-unused-type-param.rs:13:15
|
||||
error: type parameter `T` is only used recursively
|
||||
--> $DIR/variance-unused-type-param.rs:14:23
|
||||
|
|
||||
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: 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
|
||||
--> $DIR/variance-unused-type-param.rs:19:19
|
||||
--> $DIR/variance-unused-type-param.rs:22:19
|
||||
|
|
||||
LL | struct WithBounds<T: Sized> {}
|
||||
| ^ 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`
|
||||
|
||||
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 {}
|
||||
| ^ 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`
|
||||
|
||||
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> {}
|
||||
| ^ unused type parameter
|
||||
|
|
||||
= 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`.
|
||||
|
Loading…
Reference in New Issue
Block a user